PHP объектный литерал
в PHP я могу довольно легко указать литералы массива:
array(
array("name" => "John", "hobby" => "hiking"),
array("name" => "Jane", "hobby" => "dancing"),
...
)
но что, если мне нужен массив объектов? Как указать литерал объекта в PHP? Т. е. в javascript это будет:
[
{name: "John", hobby: "hiking"},
{name: "Jane", hobby: "dancing"}
]
9 ответов
Как упоминалось в 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;
начиная с PHP 5.4 возможно использовать короткий синтаксис массива:
$json = [
(object) ['name' => 'John', 'hobby' => 'hiking'],
(object) ['name' => 'Jane', 'hobby' => 'dancing'],
];
Как отмечали другие, в PHP нет объектного литерала, но вы можете "подделать" его, приведя массив к объекту.
С PHP 5.4 это еще более лаконично, потому что массивы могут быть объявлены в квадратные скобки. Например:
$obj = (object)[
"foo" => "bar",
"bar" => "foo",
];
Это даст вам объект со свойствами" foo "и" bar". Однако я не думаю, что это действительно дает много преимуществ по сравнению с использованием ассоциативных массивов. Это просто синтаксис разница.
рассмотрите возможность охвата уникальности и" вкуса " всех используемых вами языков. В JavaScript объектные литералы повсюду. В PHP ассоциативные массивы функционально такие же, как объектные литералы JavaScript, просты в создании и хорошо понятны другим программистам PHP. Я думаю, вам лучше принять этот "аромат", чем пытаться заставить его чувствовать себя как синтаксис объектного литерала JavaScript.
другим способом было бы использовать __set_state()
магический метод:
$object = stdClass::__set_state (array (
'height' => -10924,
'color' => 'purple',
'happy' => false,
'video-yt' => 'AgcnU74Ld8Q'
));
еще немного о методе_ _ set _ state (), откуда он исходит и как он должен использоваться.
в PHP у вас есть ro создать экземпляр, прежде чем вы можете использовать класс. Конечно, вы можете поместить экземпляры в массив позже.
Если вы хотите определить модули в шаблоне объектного литерала "как 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;
ни один из этих шаблонов не облегчает (или даже иногда возможно) тестирование. Но это только доказательство концепции. Технически," нет " нет объекта Literal в PHP, но если вы привыкли к синтаксису JavaScript (который я больше, чем PHP), вы можете подделать его и сделать это. Как вы можете видеть, в PHP это намного более беспорядочно, чем в JavaScript.
мой способ объектные литералы в стиле JavaScript в PHP следующим образом:
сначала я создаю ассоциативный массив следующим образом:
$test = array(
'name' => "test",
'exists' => true
);
тогда я легко делаю это объектом, как это:
$test = (object)$test;
Теперь вы можете проверить это:
echo gettype($test); // "object"
echo $test->name; // "test"
хотя кастинг как (объект) отлично работает на одном иерархическом уровне, он не углубляется. Другими словами, если мы хотим, чтобы объекты на каждом уровне, мы должны сделать что-то вроде:
$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]
]));
это гарантирует, что это объект на самом глубоком уровне.
Если 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 );