众所周知,在JavaScript中创建匿名对象很容易,如下面的代码所示:
var object = {
p : "value",
p1 : [ "john", "johnny" ] } ;
alert(object.p1[1]) ;
输出:
an alert is raised with value "johnny"
在PHP的情况下可以应用相同的技术吗?我们可以在PHP中创建匿名对象吗?
答案 0 :(得分:215)
在谈论对象时,“匿名”不是正确的术语。最好说“匿名类型的对象”,但这不适用于PHP。
PHP中的所有对象都有一个类。 “默认”类是stdClass
,您可以通过以下方式创建对象:
$obj = new stdClass;
$obj->aProperty = 'value';
您还可以利用casting an array to an object获得更方便的语法:
$obj = (object)array('aProperty' => 'value');
print_r($obj);
但是,请注意,将数组转换为对象可能会为那些无效的PHP变量名称的数组键产生“有趣”的结果 - 例如,here's我的答案显示了什么当钥匙以数字开头时发生。
答案 1 :(得分:32)
已经有好几年了,但我想我需要及时更新信息!
在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
答案 2 :(得分:20)
是的,有可能!使用这个简单的PHP Anonymous Object类。工作原理:
// 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一样。
答案 3 :(得分:13)
直到最近,这就是我动态创建对象的方式。
$someObj = json_decode("{}");
然后:
$someObj->someProperty = someValue;
但现在我选择:
$someObj = (object)[];
然后像以前一样:
$someObj->someProperty = someValue;
当然,如果你已经知道了属性和值,你可以像上面提到的那样设置它们:
$someObj = (object)['prop1' => 'value1','prop2' => 'value2'];
注意:我不知道这适用于哪个版本的PHP,因此您需要注意这一点。但我认为第一种方法(如果没有在构造中设置的属性也很短)应适用于所有具有json_encode / json_decode的版本
答案 4 :(得分: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 。这是从a comment on PHP: Classes and Objects偷来的。
答案 5 :(得分:6)
$obj = (object) ['myProp' => 'myVal'];
答案 6 :(得分:1)
自anonymous classes开始支持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();
答案 7 :(得分:1)
Anoynmus对象wiki
$object=new class (){
};
答案 8 :(得分:0)
在PHP的情况下可以应用相同的技术吗?
否 - 因为javascript使用原型/直接声明对象 - 在PHP(以及许多其他OO语言)中,只能从类创建对象。
所以问题就变成了 - 你能创建一个匿名类。
同样答案是否定的 - 如何在不能引用它的情况下实例化该类?
答案 9 :(得分:0)
如果你想创建具有动态属性的对象(比如在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
答案 10 :(得分:0)
对于想要递归对象的人:
$o = (object) array(
'foo' => (object) array(
'sub' => '...'
)
);
echo $o->foo->sub;
答案 11 :(得分:0)
在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)[],
]);
?>
输出:
[{},{},{}]