Добавить метод в 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()