众所周知,在JavaScript中创建匿名对象很容易,如下面的代码:
var object = {
p : "value",
p1 : [ "john", "johnny" ]
};
alert(object.p1[1]);
输出:
an alert is raised with value "johnny"
这个技巧能在PHP中应用吗?我们能在PHP中创建匿名对象吗?
众所周知,在JavaScript中创建匿名对象很容易,如下面的代码:
var object = {
p : "value",
p1 : [ "john", "johnny" ]
};
alert(object.p1[1]);
输出:
an alert is raised with value "johnny"
这个技巧能在PHP中应用吗?我们能在PHP中创建匿名对象吗?
在讨论对象时,“匿名”不是正确的术语。更好的说法是“匿名类型的对象”,但这并不适用于PHP。
在PHP中,所有对象都有一个类。 “默认”类是 stdClass
,您可以使用以下方式创建它的对象:
$obj = new stdClass;
$obj->aProperty = 'value';
你也可以利用将数组转换为对象的 强制类型转换,以获得更方便的语法:
$obj = (object)array('aProperty' => 'value');
print_r($obj);
但是请注意,将数组强制转换为对象可能会导致那些不是有效PHP变量名的数组键产生“有趣”的结果--例如,这里是我的一个答案,展示了当键以数字开头时会发生什么。
已经过了一些年头,但我认为我需要让信息保持最新!
自PHP 7以来,已经可以创建匿名类,因此您可以像这样做:
<?php
class Foo {}
$child = new class extends Foo {};
var_dump($child instanceof Foo); // true
?>
您可以在手册中阅读更多相关信息。
但我不知道它在JavaScript中的实现是否类似,因此JavaScript和PHP中的匿名类可能会有一些差异。
直到最近,这就是我如何即时创建对象的方法。
$someObj = json_decode("{}");
那么:
$someObj->someProperty = someValue;
但现在我会跟随:
$someObj = (object)[];
然后就像之前一样:
$someObj->someProperty = someValue;
当然,如果您已经了解属性和值,您可以像之前提到的那样在内部设置它们:
$someObj = (object)['prop1' => 'value1','prop2' => 'value2'];
注意:我不知道这适用于哪些版本的PHP,因此您需要注意。但我认为第一种方法(如果在构造时没有要设置的属性,则也很短)应该适用于具有json_encode / json_decode的所有版本
是的,这是可能的!使用这个简单的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那样动态定义方法。
$obj = (object) ['myProp' => 'myVal'];
如果您希望模仿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: 类和对象下的评论。
<?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();
$o = (object) array(
'foo' => (object) array(
'sub' => '...'
)
);
echo $o->foo->sub;
来自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)[],
]);
?>
输出:
[{},{},{}]