PHP对象文字

时间:2012-03-10 07:54:54

标签: php object literals object-literal

在PHP中,我可以很容易地指定数组文字:

array(
    array("name" => "John", "hobby" => "hiking"),
    array("name" => "Jane", "hobby" => "dancing"),
    ...
)

但是,如果我想要对象数组怎么办?如何在PHP中指定对象文字? 即在javascript中它将是:

[
    {name: "John", hobby: "hiking"},
    {name: "Jane", hobby: "dancing"}
]

10 个答案:

答案 0 :(得分:78)

正如BoltClock所提到的,PHP中没有对象文字但是你可以通过简单地将数组类型转换为对象来实现:

$testArray = array(
    (object)array("name" => "John", "hobby" => "hiking"),
    (object)array("name" => "Jane", "hobby" => "dancing")
);

echo "Person 1 Name: ".$testArray[0]->name;
echo "Person 2 Hobby: ".$testArray[1]->hobby;

答案 1 :(得分:60)

从PHP 5.4开始,您还可以使用短数组语法:

$json = [
    (object) ['name' => 'John', 'hobby' => 'hiking'],
    (object) ['name' => 'Jane', 'hobby' => 'dancing'],
];

答案 2 :(得分:8)

正如其他人所说,PHP中没有对象字面值,但您可以通过将数组转换为对象来“伪造”它。

使用PHP 5.4,这更加简洁,因为arrays can be declared with square brackets。例如:

$obj = (object)[
    "foo" => "bar",
    "bar" => "foo",
];

这会给你一个带有“foo”和“bar”属性的对象。但是,我认为这并不比使用关联数组提供更多优势。这只是一种语法差异。

考虑使用您使用的所有语言的独特性和“风味”。在JavaScript中,对象文字遍布各处。在PHP中,关联数组在功能上与JavaScript对象文字相同,易于创建,并且被其他PHP程序员很好地理解。我认为你最好不要接受这种“味道”而不是试图让它感觉像JavaScript的对象文字语法。

答案 3 :(得分:4)

另一种方法是使用__set_state()魔法:

$object = stdClass::__set_state (array (
    'height'   => -10924,
    'color'    => 'purple',
    'happy'    => false,
    'video-yt' => 'AgcnU74Ld8Q'
));

Some more on the __set_state() method, where is it coming from and how is it supposed to be used.

答案 4 :(得分:1)

如果你想在对象文字模式“像JavaScript”中定义模块,你可以这样做:

$object = (object) [
    'config' => (object) [
        'username' => 'Rob Bennet',
        'email' => 'rob@madebyhoundstooth.com'
    ],

    'hello' => function() use(&$object) {
        return "Hello " . $object->config->username . ". ";
    },

    'emailDisplay' => function() use(&$object) {
        return "Your email address is " . $object->config->email;
    },

    'init' => function($options) use(&$object) {
        $object->config = $options;
        $doUsername = $object->hello;
        $doEmail = $object->emailDisplay;
        return $doUsername() . $doEmail();
    }
];

$sayMyInfo = $object->init;

echo $sayMyInfo((object) [
    'username' => 'Logan',
        'email' => 'wolverine@xmen.com'
]);

在这种类型的模块化场景中,我通常会选择facade pattern,我就像这样写我的电话:

Module::action()->item;

Post::get()->title;

这些模式都不容易(有时甚至可能)进行测试。但这只是概念的证明。从技术上讲,“不”在PHP中没有Object Literal,但是如果你习惯了JavaScript语法(我比PHP更常用),你可以伪造它并执行此操作。正如你所看到的,它在PHP中比在JavaScript中要麻烦得多。

答案 5 :(得分:1)

我在PHP 中 JavaScript风格的对象文字的方式如下:

首先,我创建一个这样的关联数组:

speed

然后我很容易把它变成这样的对象:

$test = array(
  'name' => "test",
  'exists' => true
);

现在你可以测试一下:

$test = (object)$test;

答案 6 :(得分:0)

在PHP中,您可以在使用类之前创建实例。当然,您可以稍后将实例放入数组中。

答案 7 :(得分:0)

尽管作为(对象)的转换在单个层次级别上工作正常,但它并没有深入。换句话说,如果我们想要每个级别的对象,我们必须做类似的事情:

$foods = json_decode(json_encode([
  "fruits" => ["apple" => 1, "banana" => 2, "cherry" => 3],
  "vegetables" => ["asparagus" => 4, "broccoli" => 5, "carrot" => 6]
]));

然而,我们不是将多个转换作为对象,而是将整个事物包装在json_encode和json_decode中,如下所示:

error on line 1 at column 1: Encoding error

这确保它是最深层次的对象。

答案 8 :(得分:0)

如果json_decode(json_encode( $array ))对您不利,那么您可以使用类似的一些功能。我不知道哪一个更快。

function deep_cast_object( $o ){
  return deep_cast_object_ref( $o );
}

function deep_cast_object_ref( & $o ){

  if( is_array( $o ))
    $o = (object)$o;

  if( is_object( $o ))
    foreach( $o as & $v )
      deep_cast_object_ref( $v );

  return $o;
}

$obj = deep_cast_object(array(
  'Fractal' => array(
    'of'    => array(
      'bad' => 'design',
    ),
  ),
));

var_dump( $obj );

答案 9 :(得分:-1)

简单的解决方案

$obj = json_decode('{"ape":"kwyjibo"}');
echo $obj->ape;

[output:]
kwyjibo

然后你可以把它包装成一个函数并返回你的文字对象

$obj = literal_object(['key1','val1','key2','val2']);