Создание объектов PHP в стиле JS литеральной нотации
Основные способы создания объектов в JavaScript:
1. Оператор new
var TyapkObject = new Object();
TyapkObject.name = "Тяпк";
TyapkObject.power = 50;
TyapkObject.getName = function() {
return this.name;
}
2. Литеральная нотация
TyapkObject = {
name : "Тяпк",
power: 50,
getName : function()
{
return this.name;
}
}
// или так
var TyapkObject = {};
TyapkObject.name = "Тяпк";
TyapkObject.power = 50;
Использование возможностей анонимных классов PHP 7
Объекты в PHP появились сравнительно поздно и, поэтому для их создания всегда необходим класс. Поддержка анонимных классов была добавлена в PHP 7.
// PHP 7+
$tyapk = new class{
public $name = 'Тяпк';
public $power = 50;
};
В версиях ниже PHP 7 используеются другой механизм
От ассоциативных массивов к объектам PHP
Создаем ассоциативный массив
$tyapk = array(
'name' => "Тяпк",
'power' => 50
);
С помощью привидения типов создаем объект из массива. Массивы преобразуются в object с именами полей, названными согласно ключам массива и соответствующими им значениям, за исключением числовых ключей, которые не будут доступны пока не проитерировать объект.
$tyapk = (object)$tyapk;
echo gettype($tyapk); // "object"
Если необходимо начать с пустого объекта, то это делается следующими способами:
$tyapk = new stdClass();
// или
$tyapk = (object)array();
// или PHP 7+
$tyapk = new \stdClass;
// или PHP 7+
$tyapk = (object)[];
// или PHP 7+
$tyapk = new class{};
А затем к пустому объекту добавляются свойства
$tyapk->name = "Тяпк";
$tyapk->power = 50;
Методы
В JavaScript можно делать так:
TyapkObject.say = function () {
return "Привет!";
};
TyapkObject.say(); // "Привет!"
Начиная с PHP 5.3 в языке появлись замыкания.
$tyapk->say = function() {
return "Привет";
};
А начиная с PHP 7.0 можно делать почти как в JavaScript.
($tyapk->say)(); // "Привет!"
Выражение $tyapk->say() не работает. Всё потому, что методы и свойства класса PHP находятся в разных неймспейсах (можно иметь метод и свойство с одним именем, например say() и say), и когда вы пытаетесь достучать до say(), интерпретатор ничего подходящего среди методов не находит.
Одноко, начиная с PHP 5.4.0, say можно присвоить новой переменной $callSay, которую затем вызвать.
$callSay = $tyapk->say;
echo $callSay();
В отдельных случаях (когда функция обратного вызова не является массивом или строкой) можно воспользоваться магическим методом invoke:
$tyapk->say->__invoke();
Еще можно так:
call_user_func($tyapk->say);
Альтернативой являлась реализация шаблона с магическим методом __call. Покажу на примере анонимного класса, но через обычные классы будет работать и в старых версиях PHP. Напрямую присвоить свойству $say callback нельзя, т.к. в PHP 7 это не поддерживатся, поэтому через конструктор.
$tyapk = new class{
public $name = 'Тяпк';
public $power = 50;
public $say;
public function __construct()
{
$this->say = function() {
return "Привет из свойства!";
};
}
public function __call($name, $args)
{
return call_user_func_array($this->$name, $args);
}
};
$tyapk->say(); // "Привет из свойства!";
Статья написана по мотивам JavaScript-style object literals in PHP Здесь же можно прочитать про шаблон с __call и еще несколько хаков.
Отличное актуальное объяснение на счет вызовов замыканий есть на stackoverflow