PHP объектный литерал - PullRequest
       37

PHP объектный литерал

51 голосов
/ 10 марта 2012

В PHP я могу довольно легко указать литералы массива:

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

Но что, если я хочу массив объектов?Как я могу указать литерал объекта в PHP?Т.е. в javascript это будет:

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

Ответы [ 9 ]

82 голосов
/ 10 марта 2012

Как уже упоминалось в 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;
62 голосов
/ 27 февраля 2013

Начиная с PHP 5.4, вы также можете использовать синтаксис короткого массива:

$json = [
    (object) ['name' => 'John', 'hobby' => 'hiking'],
    (object) ['name' => 'Jane', 'hobby' => 'dancing'],
];
9 голосов
/ 14 августа 2013

Как уже отмечали другие, в PHP нет литерала объекта, но вы можете "подделать" его, приведя массив к объекту.

В PHP 5.4 это еще более кратко, поскольку массивы могут быть объявлены в квадратных скобках . Например:

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

Это даст вам объект со свойствами "foo" и "bar". Однако я не думаю, что это действительно дает много преимуществ по сравнению с использованием ассоциативных массивов. Это просто разница в синтаксисе.

Подумайте об уникальности и вкусе всех языков, которые вы используете. В JavaScript объектные литералы повсюду. В PHP ассоциативные массивы функционально аналогичны литералам объектов JavaScript, их легко создавать и хорошо понимают другие программисты PHP. Я думаю, что вам лучше принять этот «вкус», чем пытаться заставить его чувствовать себя как объектный буквальный синтаксис JavaScript.

4 голосов
/ 21 февраля 2013

Другой способ - использовать магический метод __set_state():

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

Еще немного о методе __set_state (), откуда он и какэто должно быть использовано.

1 голос
/ 08 июня 2016

Хотя приведение в качестве (объекта) прекрасно работает на одном иерархическом уровне, оно не углубляется.Другими словами, если мы хотим, чтобы объекты на каждом уровне, мы должны были сделать что-то вроде:

$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]
]));

Это гарантирует, что это объект на самом глубоком уровне.

1 голос
/ 18 июля 2015

Мой способ Литералы объекта в стиле JavaScript в PHP выглядит следующим образом:

Сначала я создаю ассоциативный массив, подобный этому:

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

Тогда я легко превращаю его в такой объект:

$test = (object)$test;

Теперь вы можете проверить это:

echo gettype($test); // "object"
echo $test->name; // "test"
0 голосов
/ 10 июля 2018

Если 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 );
0 голосов
/ 01 июня 2013

Если вы хотите определить модули в шаблоне литералов объекта «как 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.

0 голосов
/ 10 марта 2012

В PHP вы можете создать экземпляр, прежде чем сможете использовать класс.Конечно, вы можете поместить экземпляры в массив позже.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...