Комментарии 35
А куда делись остальные 16 "кусочков" (принятых RFC)?
И это не PHP 8, а master бранч (8.0-dev) т.к. фичефриза ещё не было, а значит функционала будет больше.
я обычно вот эти 2 файла читаю, чтобы обобщить сведения по изменениям в версиях
https://github.com/php/php-src/blob/master/NEWS
https://github.com/php/php-src/blob/master/UPGRADING
Вы, вероятно, знаете, что PHP является интерпретируемым языком: он не скомпилирован как программа на C, Java или Rust.
Вместо этого он переводится в машинный код — то, что понимает процессор — во время выполнения.
Не процессор, а виртуальная машина (Zend VM). Если бы машинный код исполнялся CPU, никакого бы JIT не нужно было.
Фичи, которые хотелось бы видеть:
- Асинхронность хотя бы как в JavaScript
- Дженерики a.k.a. шаблоны
- Больше возможностей для типизации, например, возможность указать, что аргумент является массивам с элементами такого-то типа
Асинхронность есть в в виде reactphp
Обычно PHP используют в режиме «процесс рождается, чтобы обработать один запрос». ReactPHP рассчитан на работу в режиме демона. PHP не рассчитан на работу в режиме демона, из-за этого в нём часто возникают утечки памяти там, где в других языках не возникают (например, при циклических ссылках объектов, в том числе ссылке не самого себя). К тому же, ReactPHP это сторонняя библиотека, а не единый стандарт.
Ещё есть возможность запустить подпроцесс и таким образом получить полную параллельность. Но это не так удобно, как нативная поддержка в языке.
Так tick_handler полностью асинхронный, а yield вообще замена всем async/await, не?
yield
— это синтаксический сахар для высокоуровневого кода. Помимо него нужен некий компонент, который принимает сгенерированные значения, обрабатывает их, не блокируя обработки значений из других генераторов, и возвращает результат в генератор.
Для асинхронности хватило бы и колбэков. Сложность в том, чтобы не блокировать input/output, например, одновременно делать запрос к БД через PDO
и отправлять письмо через SwiftMailer
.
Я могу сделать эти процессы параллельными, реализовав их с нуля, используя разные средства языка. Разработчики библиотек не могут делать свои решения асинхронными, потому что в языке нет единого стандарта. Иногда библиотеки предоставляют асинхронность строго в рамках своего фукнционала, например, Guzzle и ReactPHP.
Помимо него нужен некий компонент, который принимает сгенерированные значения, обрабатывает их, не блокируя обработки значений из других генераторов, и возвращает результат в генератор.
while ($ctx->valid()) {
if ($ctx->current() === 0xDEAD_BEEF) {
$ctx->send(42);
}
}
Такой? Ну не вижу особых проблем написать такое.
Но вообще, имхо, проблема асинхронности в пыхе не в сахаре этом всяком, а в корневых блокирующих функциях IO (в т.ч. классах stdlib, вроде PDO).
P.S. А, я слепой. Как раз про это второй абзац комментария. Да-да, всё верно, солидарен.
Уже много лет нет утечек памяти из-за циклических зависимостей. В 7 версии хорошо обновили GC.
Я тоже хотел возмутиться и протестил =)
Деструктор просто не вызывается при потере контекста такого объекта (с кодом $this->some = $this
в конструкторе) из поля зрения (в моём случае — это пустая функция с телом new Some()
).
Так что допускаю, что он вполне чистится потом вторичным GC (который срабатывает, при завершении работы файла), а не основным (который, всё чистит сразу же, как только пропадает ссылка на переменную) но я бы предложил убедиться на всякий случай. Да и вроде ещё там добавляли другие точки "stop the world"...
Я могу сам попробовать провести такие тесты, более полные, и выложить результат, но чуть попозже, вечерком если.
Специально проверил $this->test = $this
в конструкторе на миллионе итераций внутри функции. Деструктор вызывается, память стабильна. Предполагаю что есть какой-то способ выстрелить в ногу.
Да, действительно. При 10000 объектах (в моём случае) срабатывает штатный GC, подчищающий лишнее.
Тоже самое касается и если по ссылке присвоить.
Предполагаю что есть какой-то способ выстрелить в ногу.
Были какие-то нюансы вроде при создании анонимок. Но сейчас сходу вспомнить не смогу, возможно NightTiger поможет.
Но в любом случае, если обходить GC пыха и самому выделять неконтролируемую память, то да, утечки будут)))
while (true) {
FFI::new('uint64_t', false);
}
Асинхронность хотя бы как в JavaScriptyield есть, а экосистема — ну что поделать, не нужна среднестатистическому пхп разработчику асинхронность, вот и не популярно.
Дженерики a.k.a. шаблоныЕсть в psalm — psalm.dev/docs/annotating_code/templated_annotations
Больше возможностей для типизации, например, возможность указать, что аргумент является массивам с элементами такого-то типаТакже есть в psalm — psalm.dev/docs/annotating_code/type_syntax/array_types
От тайпхинтов самих по себе без каких-либо статических гарантий пользы нет +- никакой
yield
и await
— это не асинхронность, а синтаксический сахар. От языка нужен неблокирующий IO и единый цикл событий.
Статистический анализатор это хорошо, но хотелось бы видеть такой анализ в самом языке.
Иногда кажется, что в PHP синтаксис новых фич специально стараются сделать не так, как в других языках.
Завезли бы сокеты в SPL, но скорее всего не будет, как пример SPLFileObject
Не знал что в пхп можно указывать тип return. В нем даже стандартные функции возвращают что попало.
В своё время недоумевал почему код не работает, пока не узнал что половина функций вертают либо какую-то дату, либо молчаливый скромный false без всяких эксепшенов.
Тоже так подумал.
Лучше бы явно запретили преобразование объекта в строку, если он не реализует интерфейс Stringable.
Который обязывает создать функцию __toString().
Но это поломает кучу легаси кода.
Тип mixed предназначен для явного указания, что параметр или свойство может быть любого типа. Отличается от НЕуказания типа только своей явностью (я не забыл указать тип, просто хочу обрабатывать здесь любые типы). Mixed включает в себя NULL, указать mixed? (mixed nullable) не получится.
Просто сэкономил кому-то минутку гугления ;-)
} catch (MySpecialException) {
Это для тех кому лень прописать $e? Или что?
Зачем тогда оставлять (MySpecialException)?
Мне непонятна выгода от написания: catch (MySpecialException)
вместо просто catch ()
или же catch (MySpecialException $e)
.
Может подразумевается что может быть N ошибок на которые не следует реагировать и K на которые следует? Ну тоже такое себе решение.
PHP 8 в восьми кусочках кода