2013-12-09 3 views
2

Я использовал метод __set magic с защищенными свойствами для отслеживания изменений, чтобы мои классы знали, есть ли у них что-то для сохранения. Есть ли способ контролировать свойство типа массива для изменений? Я понимаю, что обычно вы получаете доступ к массиву с помощью ссылки и такие функции, как array_push, не будут запускать метод __set, они будут использовать ссылку на массив.Обнаруживать изменения в массиве в PHP

То, что я хочу, в основном это:

class Skill{ public $Player, $Name, $Level;} 
class Player { 
    protected $Name, /*Other properties*/, $Skills /*Array*/ 
} 

Я тогда же отслеживание всех свойств в проигрывателе, чтобы сказать мне, если потребности инерционности обновляется. (Умение также будет иметь эту функцию, но это показывает основной пример). Кроме того, я хочу заставить их оставаться синхронизированными (это двунаправленная связь).

Есть ли способ сделать это, чтобы он мог вести себя как массив (не хотите проходить класс, чтобы синхронизировать их, если мне не нужно).

ответ

4

Вы можете расширить ArrayObject и прокси Append:

class Skills extends ArrayObject 
{ 
    public function append($value) 
    { 
     // track changes 
     parent::append($value); 
    } 
} 
+0

Это похоже на то, что я хочу. Я проверю его применимость позже. Не знал о ArrayObject. Это действительно здорово. Я должен был бы изменить больше, и это вызовет объект, просто изменив массив отслеживания и давая конструктору имя поля для синхронизации (включая удаление из массива). Короче говоря, это позволяет мне сделать простой класс, чтобы действовать как прокладка, которая составляет 98% того, что я искал. (Я надеялся на отсутствие класса вообще, выполните отслеживание в классе, в котором находится массив, но лучшим решением не всегда является тот, который соответствует вашему первоначальному шаблону). – lassombra

+0

Рад, что это вам поможет, оно немного боком от вашей текущей реализации, но тот факт, что по определению он «ArrayObject реализует IteratorAggregate, ArrayAccess, Serializable, Countable» означает, что вы можете использовать объект как массив (http: //www.php. net/manual/en/class.arrayaccess.php) –

+0

Обратите внимание, что PHP не рассматривает 'ArrayObject' (или' ArrayAccess' и т. д.) как массив. 'array_ *' методы не удастся, оператор '+' завершится неудачно и т. д. – Tgr

1

Вы можете посмотреть что-то вроде runkit_function_redifine(), но неужели это слишком громоздко, чтобы создавать вспомогательные методы для чего вы хотите? например

class Player 
{ 
    private $skills = array(); 

    protected function addSkill($skill) 
    { 
     // Do something. 
     // 

     $this->skills[] = $skill; 
    } 
} 

Или даже обертку для массива, чтобы сделать его чище:

class FancyArray 
{ 
    private $content = array(); 

    public function add($value) 
    { 
     // Do something. 
     // 

     $this->content[] = $value; 
    } 

    public function remove($value){ /* blah */ } 

    public function getContent(){ return $this->content; } 
} 

class Player 
{ 
    protected $skills; 

    public function __construct() 
    { 
     $this->skills = new FancyArray(); 
     $this->skills->add("Ninjitsu"); 
    } 
} 
+0

Это не значит, что это слишком громоздко (раздражает, но выполнимо), но я действительно надеялся на лучшее решение. Я также не хочу писать специальный код для каждого такого элемента (я пытаюсь сделать этот проект как можно более многоразовым, потому что у меня есть еще две работы, которые потребуют почти идентичной архитектуры). Это решение действительно нужно разрабатывать индивидуально для КАЖДОГО такого массива (которого будет много). – lassombra

+0

@lassombra Я не уверен, почему вы рассматриваете последний пример ('FancyArray'), который должен быть индивидуализирован для каждого его исполнения. Это один класс, который вы можете перерабатывать. – Marty

+0

Пропущено эта часть. Это (как и ответ ниже) - это в значительной степени то, что мне нужно. Как я уже сказал, то, что я надеялся, - это способ, которым класс игрока мог контролировать (при условии, что функции массива остаются), изменяется в массиве без написания отдельного класса. К счастью, отдельный класс не требует больших изменений. Теперь проблема заключается в том, что я могу принять только один ответ ... – lassombra

Смежные вопросы