Обратиться к приватному методу объекта из замыкания

a_[w]

Новичок
Обратиться к приватному методу объекта из замыкания

Здрасте!

Суть в том, что создаётся объект в котором есть специфические методы обработчики каких-то данных и держать их публичными не очень хорошо. Нужно выдавать к ним доступ только определённым объектам. Пробовал делать через замыкания, но, как оказалось, замыкания не имеют доступ к области видимости объекта в котором создавались. Можно ли как-то сохранить область видимости объекта, чтоб вызывать его приватные методы?

Вот, пример из тутора, который уже не работает, т.к. к $this в замыкании доступа нет.
PHP:
class Dog
{
    private $_name;
    protected $_color;

    public function __construct($name, $color)
    {
         $this->_name = $name;
         $this->_color = $color;
    }

    public function greet($greeting)
    {
         return function() use ($greeting) {
             echo "$greeting, I am a {$this->_color} dog named 
{$this->_name}.";
         };
    }
}

$dog = new Dog("Rover","red");
$dog->greet("Hello");
Задача, в общем-то у меня такая же.
 

Adelf

Administrator
Команда форума
a_[w]
если нужен доступ к методам(даже если только определенным обьектам) - значит они должны быть публичными.
Да, были в сях friendы, но я редко видел чтобы их активно юзали. Ерунда это.
 

korchasa

LIMB infected
a_[w]
Замыкание выполняется в собственном контексте, а не в контексте класса. Там есть только то, что ты в него передаш.
 

HraKK

Мудак
Команда форума
В примере не понял почему не сделать
PHP:
    public function greet($greeting)
    {
      
             echo "$greeting, I am a {$this->_color} dog named 
{$this->_name}.";
    }
-~{}~ 04.11.10 22:33:

Воспользуйтесь паттерном Visitor. Оставьте анальные гланды в покое.
 

korchasa

LIMB infected
И ты его как-то очень странно используешь. Что по твоему мнению должен вернуть return function(... ?
 

HraKK

Мудак
Команда форума
korchasa
За это я ненавижу замыкания. Решают очень маленькую проблему путем создания большой проблемы Три-Н( неумелого, неуместного и неумеренного использования замыканий).
 

korchasa

LIMB infected
Автор оригинала: HraKK Воспользуйтесь паттерном Visitor. Оставьте анальные гланды в покое.
Атомной бомбой лечить кашель? :)

-~{}~ 04.11.10 23:39:

Автор оригинала: HraKK
korchasa
За это я ненавижу замыкания. Решают очень маленькую проблему путем создания большой проблемы Три-Н( неумелого, неуместного и неумеренного использования замыканий).
Ну вот предположим, что я думаю, что знаю замыкания. Что за большая проблема у меня с ними?

-~{}~ 04.11.10 23:40:

Кстати, ты в курсе, что в примере нет замыкания?
 

HraKK

Мудак
Команда форума
Атомной бомбой лечить кашель?
Я не понимаю проблемы, скажем так. Из того что я вижу где может такое понадобится( ну что может родится в моей голове), идеальное решение было бы паттен Визитёр.
 

HraKK

Мудак
Команда форума
Ну вот предположим, что я думаю, что знаю замыкания. Что за большая проблема у меня с ними?
У тебя может и нету, не в этом дело. Ты решаешь ими маленькую проблему, а другие(а их большинство) воспользовавшись правилом Три-Н создают большую проблему.
 

korchasa

LIMB infected
HraKK
Как только в array_walk и прочие разрешат передавать переменные для коллбэков, я с тобой, может быть, соглашусь.
 

HraKK

Мудак
Команда форума
korchasa
за 8 лет стажа мне это понадобилось наверно раза 3 или 4. В половине случаев из-за не знания ООП. Это то из-за чего надо городить мину замедленного действия?
 

korchasa

LIMB infected
HraKK
Ты можешь вот это:
PHP:
        function _filterArrayByMatchInKey($array, $needle)
	{
	  $all_keys = array_keys($array);
	  
	  $callback = function ($key) use ($needle) {
 	    return (false !== strpos($key, $needle));	    
	  };	  
	  $valid_keys = array_filter($all_keys, $callback);
	  
	  $result = array();
	  foreach($valid_keys as $valid_key)
	    $result = array_merge($result, $array[$valid_key]);	    	  
	  return $result;
	}
подсказать, как сделать без eval'а и меньше чем 100 строчками кода?

-~{}~ 04.11.10 23:55:

a_[w]
Разберись как это работает:
PHP:
<?php

class Dog 
{ 
    public $_name; 
    public $_color; 

    public function __construct($name, $color) 
    { 
         $this->_name = $name; 
         $this->_color = $color; 
    } 

    public function greet($greeting) 
    { 
      return function($obj) use ($greeting) { 
        echo "$greeting, I am a {$obj->_color} dog named {$obj->_name}."; 
      }; 
    } 
} 

$dog = new Dog("Rover","red"); 
$callback = $dog->greet("Hello");
$callback($dog);
А вообще HraKK прав, замыкания, сука, опасные.
 

HraKK

Мудак
Команда форума
korchasa
Оно или я что-то не понял?
PHP:
function _filterArrayByMatchInKey($array, $needle)
    {
      $result = array();
      foreach($array as $key => $value)
      {
         if( (false !== strpos($key, $needle)))
         {
         	   $result = array_merge($result, $value);
         }        
      }
      return $result;
    }
Кстати, отучись от такой херни:
PHP:
 foreach($valid_keys as $valid_key)
        $result = array_merge($result, $array[$valid_key]);
 

korchasa

LIMB infected
HraKK
Мда, зря я код склеил. Фишка была в том, что функция фильтрации передавалась снаружи, вместе со всем контекстом. Вот другой пример. Если подскажешь, как переписать "по-правильному", буду благодарен.

ЗЫ: Кстати, нет, спасибо. Наш CS нас устраивает.
 

korchasa

LIMB infected
Автор оригинала: HraKK
Ну и отлично, видишь замыкания не такая уж панацея.
А я не говорил, что они панацея. Просто в некоторых случаях они экономят код, а в некоторых, память. Мой вариант отжирал бы гораздо больше памяти, поэтому его не будет :)
 
Сверху