Я ищу способ перехватить действие в array_push
, потому что когда он будет извлекать его, каждое значение массива имеет следующую информацию:
class ClassName { var $test = array(); function __set($attr, $value) { $this->$attr = 'My extra value'.$value; } function index(){ array_push($this->test, "some val"); array_push($this->test, "some other val"); print_r($this->test); } } $o = new ClassName(); $o->index();
И ожидал получить что-то вроде:
Array ( [0] => My extra value some val [1] => My extra value some other val )
Но я получаю:
Array ( [0] => some val [1] => some other val )
Спасибо всем
Вместо использования массива вы можете использовать класс, реализующий интерфейс ArrayAccess. Таким образом, у вас есть полный контроль над тем, что происходит, когда вы добавляете к массиву.
http://php.net/manual/en/class.arrayaccess.php
Недостатком является то, что не все функции массива будут работать над объектом (т. Е. Сортировка и т. Д.), Но вы можете нажать так:
$object[] = 'new value';
Альтернативой является просто сделать функцию-обертку для добавления в массив.
public function addToArray($key, $value) { if ($key === null) { $this->test[] = 'My extra value ' . $value; } else { $this->test[$key] = 'My extra value ' . $value; } }
Я не совсем понимаю, о чем вы спрашиваете, но пытаетесь ли вы это сделать:
$this->test['key'] = "some val";
Это позволит вам настроить свой собственный выход красиво. Потому что array_push () выкинет на другой вложенный уровень.
Обновление: может быть, что-то в этом роде?
function push($prefix) { $refl = new ReflectionClass($this); $prop = $refl->getProperties(); foreach($prop as $p) { $this->{$p} = $prefix . $this->{$p}; } }
Чтобы достичь того, что вы ищете, я предлагаю вам создать себе функцию, которая префикс любого значения, независимого от его использования:
function prefix($value) { return 'My extra value '.$value; }
Затем вы можете использовать эту функцию внутри функции index()
:
function index() { $test = array("some val", "some other val"); foreach($test as $value) { $this->test[] = $this->prefix($value); } print_r($this->test); }
Из руководства по PHP:
__set() is run when writing data to inaccessible properties. __get() is utilized for reading data from inaccessible properties.
Это называется только для чтения / записи недоступных свойств. Однако ваша собственность является общедоступной, что означает, что она доступна. Изменение модификатора доступа для защиты решает проблему.
Попробуй это:
class ClassName { private $test = array(); public function __set($attr, $value) { $this->test[$attr] = $value; } public function __get($attr) { return $this->test[$attr]; } public function index(){ array_push($this->test, "some val"); array_push($this->test, "some other val"); return $this->test; } } $o = new ClassName(); $o->setData = 'My extra value'; print_r($o->index());
В руководстве по PHP говорится о магических методах:
__set () запускается при записи данных в недоступные свойства. (Акцент мой)
Поскольку свойство test
находится внутри метода, и функция, которая обращается к нему, находится внутри метода, функция увидит переменную напрямую и не будет использовать волшебный сеттер.
Кроме того, даже если вы попытаетесь использовать array_push на волшебном сеттере вне самого класса, это все равно не сработает. Вы получите ошибку array_push() expects parameter 1 to be array, object given
.
Если вы хотите поддерживать array_push, вы должны написать свой собственный метод push($item)
:
function push($item) { $this->test[] = 'My extra value' . $item }
или:
function push() { $items = func_get_args(); // Using array_map is one of the many ways to do this. // You could also do it with a simpler `foreach` but I like this way. $prepend = function($item) { return 'My extra value' . $item; }; $items = array_map($prepend, $items); array_push($this->test, $items); }
если вы хотите поддерживать одновременное нажатие нескольких элементов.