web-dev-qa-db-ja.com

PHPのstdオブジェクトにメソッドを追加します

次のように、この方法でメソッド/関数を追加することは可能ですか?

$arr = array(
    "nid"=> 20,
    "title" => "Something",
    "value" => "Something else",
    "my_method" => function($arg){....}
);

または多分このように

$node = (object) $arr;
$node->my_method=function($arg){...};

可能であれば、その関数/メソッドをどのように使用できますか?

17
The Alpha

StdClassにメソッドを動的に追加して、通常の方法で実行することはできません。ただし、できることがいくつかあります。

最初の例では、 クロージャ を作成しています。次のコマンドを発行して、そのクロージャを実行できます。

$arr['my_method']('Argument')

StdClassオブジェクトを作成し、そのプロパティの1つにクロージャを割り当てることはできますが、構文の競合のため、直接実行することはできません。代わりに、次のようなことを行う必要があります。

$node = new stdClass();
$node->method = function($arg) { ... }
$func = $node->method;
$func('Argument');

しようとしています

$node->method('Argument')

stdClassにメソッド「メソッド」が存在しないため、エラーが生成されます。

魔法のメソッドを使用した巧妙なハッカーについては、これを参照してください SO回答__ call

16
keelerm

これは、匿名クラスを使用してPHP 7.1で実現できるようになりました。

$node = new class {
    public $property;

    public function myMethod($arg) { 
        ...
    }
};

// and access them,
$node->property;
$node->myMethod('arg');
15

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()
3
goulashsoup