2011-06-17 119 views
101

我们知道,在JavaScript创建匿名对象是容易的,如下面的代码:PHP创建匿名对象

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 2016-03-18 09:41:04

+0

@Simba - 感谢您指出。您是否想在此页面的StackOverflow上发布答案,以帮助未来的访问者? – 2016-08-19 05:00:28

+1

我不需要;已经有了这个信息的答案(见下文,@ Rizier123)。 – Simba 2016-08-19 09:17:24

回答

29

已经有几年了,但我想我需要保持信息最新!


在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

191

“匿名”在谈论对象时不是正确的术语。最好说“匿名类型的对象”,但这不适用于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

我可以推多个值的数组吗? – 2011-06-17 10:36:19

+1

@CodingFreak:你可以**,但是**:如果数组包含子数组,并且你也希望这些数据作为对象,则需要明确地将每个数据转换为对象。 – Jon 2011-06-17 10:38:12

+5

抱歉的话题。但是,每当我阅读有关PHP的“有趣”结果时,我都会感受到真正的恐惧。 – Areks 2014-12-17 16:37:58

6

如果你想模仿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被盗。

2

在PHP的情况下可以应用这种相同的技术吗?

否 - 因为JavaScript使用原型/直接声明对象 - 在PHP(和许多其他OO语言)中,只能从类创建对象。

所以问题就变成了 - 你能否创建一个匿名类。

答案再次是否定的 - 你如何实例化这个类而不能引用它?

18

是的,这是可能的!使用这个简单的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做。

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 
8

直到最近,我这是怎么创造的飞行物体。

$someObj = json_decode("{}"); 

然后:

$someObj->someProperty = someValue; 

但现在我一起去:

$someObj = (object)[]; 

然后像以前一样:

$someObj->someProperty = someValue; 

当然,如果你已经知道的属性和值你可以像上面提到的那样设置它们:

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

注意:我不知道哪些版本的PHP可以运行,因此您需要注意这一点。但是我认为第一种方法(如果没有属性可以在施工中设置也是短的)应该适用于所有具有json_encode/json_decode的版本