在PHP中创建匿名对象

155

众所周知,在JavaScript中创建匿名对象很容易,如下面的代码:

var object = { 
    p : "value", 
    p1 : [ "john", "johnny" ]
};

alert(object.p1[1]);

输出:

an alert is raised with value "johnny"

这个技巧能在PHP中应用吗?我们能在PHP中创建匿名对象吗?


1
注意:这是一个旧问题,所以被接受的答案已经过时。现在PHP 7已经添加了所需的功能。请参见@Rizier123下面的答案。 - Simba
@Simba - 感谢您指出这个问题。您是否愿意在此页面上发布一个答案,以帮助未来的访问者? - Sujit Agarwal
1
我不需要,因为已经有一个包含此信息的答案了(请参见下面,由@Rizier123提供)。 - Simba
这个回答根本没有回答问题啊?不确定为什么标记为被接受。 - undefined
12个回答

244

在讨论对象时,“匿名”不是正确的术语。更好的说法是“匿名类型的对象”,但这并不适用于PHP。

在PHP中,所有对象都有一个类。 “默认”类是 stdClass,您可以使用以下方式创建它的对象:

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

你也可以利用将数组转换为对象的 强制类型转换,以获得更方便的语法:

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

但是请注意,将数组强制转换为对象可能会导致那些不是有效PHP变量名的数组键产生“有趣”的结果--例如,这里是我的一个答案,展示了当键以数字开头时会发生什么。


1
我可以同时推送多个值的数组吗? - Sujit Agarwal
2
@CodingFreak:你可以这样做,但是:如果数组包含子数组并且你也想将它们作为对象处理,那么你需要显式地将每个子数组转换为对象。 - Jon

40

已经过了一些年头,但我认为我需要让信息保持最新!

自PHP 7以来,已经可以创建匿名类,因此您可以像这样做:

<?php

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

    var_dump($child instanceof Foo); // true

?>

您可以在手册中阅读更多相关信息。

但我不知道它在JavaScript中的实现是否类似,因此JavaScript和PHP中的匿名类可能会有一些差异。


@risyasin 谢谢,已更新答案并在其中放置了手册链接。 - Rizier123
将您的答案标记为正确,以跟上php7的最新更改。感谢@Rizier123。 - Sujit Agarwal
9
这很有趣,但它并没有真正回答问题,因为原帖问的是如何方便地初始化一个具有多个成员的对象而不创建一个类。我不确定在PHP中匿名类是否可以用来做到这一点,如果可以,你没有解释如何实现。 - amh15

30

直到最近,这就是我如何即时创建对象的方法。

$someObj = json_decode("{}");

那么:

$someObj->someProperty = someValue;

但现在我会跟随:

$someObj = (object)[];

然后就像之前一样:

$someObj->someProperty = someValue;

当然,如果您已经了解属性和值,您可以像之前提到的那样在内部设置它们:

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

注意:我不知道这适用于哪些版本的PHP,因此您需要注意。但我认为第一种方法(如果在构造时没有要设置的属性,则也很短)应该适用于具有json_encode / json_decode的所有版本


2
这与 $someObj = new \stdClass() 有何不同? - JamesNZ

22

是的,这是可能的!使用这个简单的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那样动态定义方法。


你可以使用 create_function 来模拟匿名函数。 - Mihailoff
我认为他只是想要一种整洁的方式来初始化一个带有某些值的stdClass对象。你能用你的方法做到吗? - amh15

12
将数组转换为对象(但不递归到子级)。
$obj = (object)  ['myProp' => 'myVal'];

Please do not use bold. - user31782

7

如果您希望模仿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];
?>

这将输出元素2。这段话来源于PHP: 类和对象下的评论。


5
自 PHP 7.0 起,支持匿名类,这是与本问题提供的 JavaScript 示例最接近的类比。
<?php
$object = new class {
    var $p = "value";
    var $p1 = ["john", "johnny"];
};

echo $object->p1[1];

属性的可见性声明不能省略(我只是使用var,因为它比public更短)。

与JavaScript一样,您也可以为类定义方法:

<?php
$object = new class {
    var $p = "value";
    var $p1 = ["john", "johnny"];
    function foo() {return $this->p;}
};

echo $object->foo();

2
匿名对象 wiki

$object=new class (){


};


1
对于想要递归对象的人:
$o = (object) array(
    'foo' => (object) array(
        'sub' => '...'
    )
);

echo $o->foo->sub;

1

来自PHP文档的更多示例:

<?php

$obj1 = new \stdClass; // Instantiate stdClass object
$obj2 = new class{}; // Instantiate anonymous class
$obj3 = (object)[]; // Cast empty array to object

var_dump($obj1); // object(stdClass)#1 (0) {}
var_dump($obj2); // object(class@anonymous)#2 (0) {}
var_dump($obj3); // object(stdClass)#3 (0) {}

?>

$obj1和$obj3是相同类型的,但$obj1 !== $obj3。此外,所有三个都可以json_encode()为一个简单的JS对象 {}:

<?php

echo json_encode([
    new \stdClass,
    new class{},
    (object)[],
]);

?>

输出:

[{},{},{}]

https://www.php.net/manual/en/language.types.object.php


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接