Создание объектов 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

Похожие записи

Об автозагрузке в PHP

Статья раскрывает аспекты автозагрузки в PHP с использованием __autoload, spl_autoload_register, автозагрузки через composer (PSR-4) с небольшим экскурсом в историю.

01 декабря 2017 г. в PHP