Добавить метод в std-объект в php
Можно ли добавить метод/функцию таким образом, как
$arr = array(
"nid"=> 20,
"title" => "Something",
"value" => "Something else",
"my_method" => function($arg){....}
);
или, может быть, как это
$node = (object) $arr;
$node->my_method=function($arg){...};
и если это возможно, то как я могу использовать эту функцию/метод?
Ответы
Ответ 1
Вы не можете динамически добавлять метод в stdClass и выполнять его обычным образом. Однако есть несколько вещей, которые вы можете сделать.
В первом примере вы создаете closure. Вы можете выполнить это закрытие, выполнив команду:
$arr['my_method']('Argument')
Вы можете создать объект stdClass и назначить закрытие одного из его свойств, но из-за конфликта синтаксиса вы не можете его напрямую выполнить. Вместо этого вам нужно будет сделать что-то вроде:
$node = new stdClass();
$node->method = function($arg) { ... }
$func = $node->method;
$func('Argument');
Попытка
$node->method('Argument')
создаст ошибку, потому что в stdClass не существует метода "method".
См. этот ответ SO для какого-то пятнающего хакера с использованием магического метода __ call.
Ответ 2
Теперь это можно сделать в PHP 7.1 с анонимными классами
$node = new class {
public $property;
public function myMethod($arg) {
...
}
};
// and access them,
$node->property;
$node->myMethod('arg');
Ответ 3
Начиная с PHP 7 также можно напрямую вызывать свойство анонимной функции:
$obj = new stdClass;
$obj->printMessage = function($message) { echo $message . "\n"; };
echo ($obj->printMessage)('Hello World'); // Hello World
Здесь выражение $obj->printMessage
приводит к анонимной функции, которая затем напрямую выполняется с аргументом 'Hello World'
. Однако перед тем, как вызывать его, необходимо поместить выражение функции в паранетезы, чтобы следующее не получилось:
echo $obj->printMessage('Hello World');
// Fatal error: Uncaught Error: Call to undefined method stdClass::printMessage()