Создание анонимных объектов в php
Как мы знаем, создание анонимных объектов в JavaScript легко, как код ниже:
var object = {
p : "value",
p1 : [ "john", "johnny" ] } ;
alert(object.p1[1]) ;
выход:
an alert is raised with value "johnny"
может ли этот же метод быть применен в случае PHP? Можем ли мы создавать анонимные объекты в PHP?
9 ответов:
прошло уже несколько лет, но я думаю, что мне нужно держать информацию в актуальном состоянии!
в 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.
Edit:
как из комментариев, опубликованных, вот ссылка на руководство сейчас:http://php.net/manual/en/language.oop5.anonymous.php
"анонимный" не является правильной терминологией, когда речь идет об объектах. Лучше было бы сказать "объект анонима тип", но это не относится к PHP.
все объекты в PHP имеют класс. Класс "default" -
stdClass, и вы можете создавать объекты таким образом:$obj = new stdClass; $obj->aProperty = 'value';вы также можете воспользоваться приведение массива к объекту для более удобного синтаксис:
$obj = (object)array('aProperty' => 'value'); print_r($obj);Впрочем, быть рекомендуется, что приведение массива к объекту, вероятно, даст "интересные" результаты для тех ключей массива, которые не являются допустимыми именами переменных PHP - например,здесь мой ответ, который показывает, что происходит, когда ключи начинаются с цифр.
Да, это возможно! Используя этот простой PHP анонимный объект класса. Как это работает:
// 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.
до недавнего времени именно так я создавал объекты на лету.
$someObj = json_decode("{}");затем:
$someObj->someProperty = someValue;а теперь я иду с:
$someObj = (object)[];затем, как и раньше:
$someObj->someProperty = someValue;конечно, если вы уже знаете, свойства и значения вы можете установить их внутри, как уже было сказано:
$someObj = (object)['prop1' => 'value1','prop2' => 'value2'];NB: я не знаю, на каких версиях PHP это работает, поэтому вам нужно будет помнить об этом. Но я думаю, что первый подход (который также короткий если нет свойств для установки при построении) должен работать для всех версий, которые имеют json_encode / json_decode
Если вы хотите имитировать 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. Это было украдено у комментарий к PHP: классы и объекты.
сокращенное:
$obj = (object) ['property' => 'Here we go']; //or// $obj = (object) array('property' => 'Here we go');
может ли этот же метод быть применен в случае PHP?
нет - потому что javascript использует прототипы / прямое объявление объектов-в PHP (и многих других языках OO) объект может быть создан только из класса.
таким образом, вопрос становится - можете ли вы создать анонимный класс.
снова ответ нет - как бы вы создали экземпляр класса, не имея возможности ссылаться на него?
Если вы хотите создать объект (например, в javascript) с динамическими свойствами, не получая предупреждения о неопределенном свойстве, когда вы не установили значение property
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
для тех, кто хочет рекурсивного объекта:
$o = (object) array( 'foo' => (object) array( 'sub' => '...' ) ); echo $o->foo->sub;
Comments