67

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

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

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

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

10 回答 10

93

正如 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;
于 2012-03-10T08:16:58.230 回答
69

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

$json = [
    (object) ['name' => 'John', 'hobby' => 'hiking'],
    (object) ['name' => 'Jane', 'hobby' => 'dancing'],
];
于 2013-02-27T19:53:00.003 回答
14

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

在 PHP 5.4 中,这更加简洁,因为数组可以用方括号声明。例如:

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

这将为您提供一个具有“foo”和“bar”属性的对象。但是,我认为这与使用关联数组相比并没有真正提供太多优势。这只是语法差异。

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

于 2013-08-14T16:29:54.250 回答
4

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

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

关于 __set_state() 方法的更多信息,它来自哪里以及应该如何使用它。

于 2013-02-21T09:49:04.597 回答
4

尽管转换为(对象)在单个层次级别上工作得很好,但它并不深入。换句话说,如果我们想要每个级别的对象,我们必须执行以下操作:

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

然而,我们可以像这样将整个东西包装在 json_encode 和 json_decode 中,而不是作为对象进行多次转换:

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

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

要回答 klewis,您可以像这样访问:

echo $foods->vegetables->broccoli;

此示例将输出数字 5。

于 2016-06-08T03:40:59.980 回答
2

在 PHP 中使用 JavaScript 样式的对象文字的方式如下:

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

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

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

$test = (object)$test;

现在你可以测试它了:

echo gettype($test); // "object"
echo $test->name; // "test"
于 2015-07-18T16:46:55.587 回答
0

在 PHP 中,您必须先创建一个实例,然后才能使用一个类。当然,您可以稍后将实例放入数组中。

于 2012-03-10T08:06:58.667 回答
0

如果你想在对象字面量模式“像 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'
]);

在这种模块化场景中,我通常会选择外观模式,我喜欢这样写我的调用:

Module::action()->item;

或者

Post::get()->title;

这些模式都没有使测试变得容易(甚至有时可能)。但这只是概念证明。从技术上讲,“不”在 PHP 中没有 Object Literal,但如果您习惯 JavaScript 语法(我比 PHP 更习惯),您可以伪造它并执行此操作。如您所见,PHP 比 JavaScript 更混乱。

于 2013-06-01T00:50:58.713 回答
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 );
于 2018-07-10T16:50:38.497 回答
-1

简单的解决方案

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

[output:]
kwyjibo

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

$obj = literal_object(['key1','val1','key2','val2']);
于 2021-06-09T17:23:23.117 回答