PHP 540 ~ 2 мин.

Создание экземпляров класса без дополнительных круглых скобок

Создание экземпляров класса без дополнительных круглых скобок

Функция «доступа к членам класса при создании экземпляра» была представлена ​​в PHP 5.4.0. С тех пор константы, свойства и методы могут быть доступны во вновь созданном экземпляре без промежуточной переменной, но только если выражение new заключено в круглые скобки:

class Request implements Psr\Http\Message\RequestInterface
 { 
    // ... 
}
 
// OK
$request = (new Request())->withMethod('GET')->withUri('/hello-world');
 
// PHP Parse error: syntax error, unexpected token "->"
$request = new Request()->withMethod('GET')->withUri('/hello-world');

Этот RFC позволяет опускать круглые скобки вокруг new выражения со скобками аргументов конструктора и написать просто new Class()->method():

new Request()->withMethod('GET')->withUri('/hello-world');

Возьмем для примера класс:

class MyClass
{
    const CONSTANT = 'constant';
    public static $staticProperty = 'staticProperty';
    public static function staticMethod(): string { return 'staticMethod'; }
    public $property = 'property';
    public function method(): string { return 'method'; }
    public function __invoke(): string { return '__invoke'; }
}

Так можно теперь написать:

var_dump(
    new MyClass()::CONSTANT,        // string(8)  "constant"
    new MyClass()::$staticProperty, // string(14) "staticProperty"
    new MyClass()::staticMethod(),  // string(12) "staticMethod"
    new MyClass()->property,        // string(8)  "property"
    new MyClass()->method(),        // string(6)  "method"
    new MyClass()(),                // string(8)  "__invoke"
);

Или:

$myClass = MyClass::class;

var_dump(
    new $myClass()::CONSTANT,        // string(8)  "constant"
    new $myClass()::$staticProperty, // string(14) "staticProperty"
    new $myClass()::staticMethod(),  // string(12) "staticMethod"
    new $myClass()->property,        // string(8)  "property"
    new $myClass()->method(),        // string(6)  "method"
    new $myClass()(),                // string(8)  "__invoke"
);
 
var_dump(
    new (trim(' MyClass '))()::CONSTANT,        // string(8)  "constant"
    new (trim(' MyClass '))()::$staticProperty, // string(14) "staticProperty"
    new (trim(' MyClass '))()::staticMethod(),  // string(12) "staticMethod"
    new (trim(' MyClass '))()->property,        // string(8)  "property"
    new (trim(' MyClass '))()->method(),        // string(6)  "method"
    new (trim(' MyClass '))()(),                // string(8)  "__invoke"
);

Стоит также учитывать, что данный RFC не меняет поведение new выражений без круглых скобок аргументов конструктора:

new MyClass::CONSTANT; // продолжит выдавать синтаксическую ошибку
new $myClass::CONSTANT; // продолжит выдавать синтаксическую ошибку
new MyClass::$staticProperty; // продолжит работать как `new (MyClass::$staticProperty)`
new $myClass::$staticProperty; // продолжит работать как `new ($myClass::$staticProperty)`
new $myObject->property; // продолжит работать как `new ($myObject->property)`

Так же этот RFC позволяет опускать круглые скобки вокруг new выражения анонимного класса независимо от того, присутствуют ли круглые скобки в аргументах конструктора:

var_dump(
    // string(8) "constant"
    new class { const CONSTANT = 'constant'; }::CONSTANT,
    // string(14) "staticProperty"
    new class { public static $staticProperty = 'staticProperty'; }::$staticProperty,
    // string(12) "staticMethod"
    new class { public static function staticMethod() { return 'staticMethod'; } }::staticMethod(),
    // string(8) "property"
    new class { public $property = 'property'; }->property,
    // string(6) "method"
    new class { public function method() { return 'method'; } }->method(),
    // string(8) "__invoke"
    new class { public function __invoke() { return '__invoke'; } }(),
);

В заключении можно сказать, что некоторые языки, такие как Kotlin, позволяют создавать экземпляры классов с помощью выражения MyClass(). Опустить ключевое слово new в PHP на данный момент невозможно, поскольку классы и функции могут иметь одно и то же имя (в Kotlin это невозможно). Итак, чтобы добиться этого в PHP, надо сначала отказаться от объявления функций и классов с одинаковыми именами.

Спасибо Валентину Удальцову за вклад по улучшению синтаксиса PHP.

Что думаешь?

Категории
  • PHP 67
  • Заметки 18
  • Безопасность 4
  • Флуд 2
  • Nginx 2
  • ИТ новости 2
  • Видео 1
  • Docker 1
  • Roadmap 1
  • Архитектура 0

Хочешь поддержать сайт?

Делаем из мухи слона

sergeymukhin.com

персональный блог о веб-разработке от Сергея Мухина. Блог был основан в 2018 году, и собирался уделять основное внимание последним тенденциям, учебным пособиям, а также советам и рекомендациям, позволяющим начинающим девелоперам встать быстрее на правильную дорогу веб разработки, но что-то пошло не так 😃

Релизы PHP 8.4

Дата Релиз
4 Июля 2024 Альфа 1
18 Июля 2024 Альфа 2
1 Августа 2024 Альфа 3
13 Августа 2024 Feature freeze
15 Августа 2024 Бета 1
29 Августа 2024 Бета 2
12 Сентября 2024 Бета 3
26 Сентября 2024 RC 1
10 Октября 2024 RC 2
24 Октября 2024 RC 3
7 Ноября 2024 RC 4
21 Ноября 2024 GA

Что нового?