web-dev-qa-db-ja.com

PHPでの匿名オブジェクトの作成

知っているように、JavaScriptで匿名オブジェクトを作成するのは簡単です。次のコードのように:

var object = { 
    p : "value", 
    p1 : [ "john", "johnny" ] } ; 
alert(object.p1[1]) ;

出力:

an alert is raised with value "johnny"

PHPの場合、この同じ手法を適用できますか? PHPで匿名オブジェクトを作成できますか?

126
Sujit Agarwal

数年が経ちましたが、情報を最新に保つ必要があると思います!


Php-7では、匿名クラスを作成できるため、次のようなことができます。

<?php

    class Foo {}
    $child = new class extends Foo {};

    var_dump($child instanceof Foo); // true

?>

これについての詳細は、RFCで読むことができます(受け入れられています): https://wiki.php.net/rfc/anonymous_classes

しかし、私はそれがJavscriptにどのように実装されているのかわかりませんので、javascriptとphpの匿名クラスのいくつかの違いがあるかもしれません。

編集:

投稿されたコメントから、マニュアルへのリンクは次のとおりです。 http://php.net/manual/en/language.oop5.anonymous.php

34
Rizier123

オブジェクトについて話すとき、「匿名」は正しい用語ではありません。 「匿名のオブジェクトtype」と言う方が良いでしょうが、これはPHPには適用されません。

PHPのすべてのオブジェクトにはクラスがあります。 「デフォルト」クラスは stdClass であり、この方法でオブジェクトを作成できます。

$obj = new stdClass;
$obj->aProperty = 'value';

配列をオブジェクトにキャストする を利用して、より便利な構文にすることもできます。

$obj = (object)array('aProperty' => 'value');
print_r($obj);

ただし、配列をオブジェクトにキャストすると、有効なPHP変数名ではない配列キーに対して「興味深い」結果が得られる可能性が高いことに注意してください。たとえば、 here's anキーが数字で始まるときに何が起こるかを示す私の答え。

216
Jon

はい、可能です!この単純な PHP匿名オブジェクト クラスを使用します。使い方:

// define by passing in constructor
$anonim_obj = new AnObj(array(
    "foo" => function() { echo "foo"; }, 
    "bar" => function($bar) { echo $bar; } 
));

$anonim_obj->foo(); // prints "foo"
$anonim_obj->bar("hello, world"); // prints "hello, world"

// define at runtime
$anonim_obj->Zoo = function() { echo "Zoo"; };
$anonim_obj->Zoo(); // prints "Zoo"

// mimic self 
$anonim_obj->prop = "abc";
$anonim_obj->propMethod = function() use($anonim_obj) {
    echo $anonim_obj->prop; 
};
$anonim_obj->propMethod(); // prints "abc"

もちろん、このオブジェクトはAnObjクラスのインスタンスであるため、実際には匿名ではありませんが、JavaScriptのようにメソッドをオンザフライで定義できます。

20
Mihailoff

最近まで、これが私がその場でオブジェクトを作成した方法です。

$someObj = json_decode("{}");

次に:

$someObj->someProperty = someValue;

しかし、今私は一緒に行きます:

$someObj = (object)[];

それから前のように:

$someObj->someProperty = someValue;

もちろん、すでにプロパティと値がわかっている場合は、前述のように内部で設定できます。

$someObj = (object)['prop1' => 'value1','prop2' => 'value2'];

NB:PHPのどのバージョンがこれで機能するのかわかりませんので、そのことに注意する必要があります。しかし、json_encode/json_decodeを含むすべてのバージョンで最初のアプローチ(構築時に設定するプロパティがない場合も短い)が機能するはずだと思います

15
Zuks

JavaScriptを模倣する場合は、クラスObjectを作成して、同じ動作を取得できます。もちろん、これは完全に匿名ではありませんが、機能します。

<?php 
class Object { 
    function __construct( ) { 
        $n = func_num_args( ) ; 
        for ( $i = 0 ; $i < $n ; $i += 2 ) { 
            $this->{func_get_arg($i)} = func_get_arg($i + 1) ; 
        } 
    } 
} 

$o = new Object( 
    'aProperty', 'value', 
    'anotherProperty', array('element 1', 'element 2')) ; 
echo $o->anotherProperty[1];
?>

それはelement 2を出力します。これは PHPに関するコメント:クラスとオブジェクト から盗まれました。

7
kba

配列をオブジェクトに変換する:

$obj = (object)  ['myProp' => 'myVal'];
6
T.Todua

プロパティに値を設定していないときに、未定義のプロパティの警告を受け取らずに、動的プロパティを持つオブジェクト(javascriptなど)を作成する場合

class stdClass {

public function __construct(array $arguments = array()) {
    if (!empty($arguments)) {
        foreach ($arguments as $property => $argument) {
            if(is_numeric($property)):
                $this->{$argument} = null;
            else:
                $this->{$property} = $argument;
            endif;
        }
    }
}

public function __call($method, $arguments) {
    $arguments = array_merge(array("stdObject" => $this), $arguments); // Note: method argument 0 will always referred to the main class ($this).
    if (isset($this->{$method}) && is_callable($this->{$method})) {
        return call_user_func_array($this->{$method}, $arguments);
    } else {
        throw new Exception("Fatal error: Call to undefined method stdObject::{$method}()");
    }
}

public function __get($name){
    if(property_exists($this, $name)):
        return $this->{$name};
    else:
        return $this->{$name} = null;
    endif;
}

public function __set($name, $value) {
    $this->{$name} = $value;
}

}

$obj1 = new stdClass(['property1','property2'=>'value']); //assign default property
echo $obj1->property1;//null
echo $obj1->property2;//value

$obj2 = new stdClass();//without properties set
echo $obj2->property1;//null
0
fredtma

再帰オブジェクトが必要な場合:

$o = (object) array(
    'foo' => (object) array(
        'sub' => '...'
    )
);

echo $o->foo->sub;
0
Jonatas Walker

PHPの場合、この同じ手法を適用できますか?

いいえ-JavaScriptはオブジェクトのプロトタイプ/直接宣言を使用するため、PHP(および他の多くのOO言語)では、オブジェクトはクラスからのみ作成できます。

質問は次のようになります-匿名クラスを作成できますか。

繰り返しますが、答えはノーです。クラスを参照せずにインスタンス化する方法を教えてください。

0
symcbean