Как стать автором
Обновить

Комментарии 35

А скажите пожалуйста, как обстоят дела с обобщениями в PHP 8?

А куда делись остальные 16 "кусочков" (принятых RFC)?


И это не PHP 8, а master бранч (8.0-dev) т.к. фичефриза ещё не было, а значит функционала будет больше.

P.S. Прошу прощения, уже 17 "кусочков". Т.к. судя по всему автоинициализация полей через конструктор — тоже проходит голосование =)

Вы, вероятно, знаете, что PHP является интерпретируемым языком: он не скомпилирован как программа на C, Java или Rust.
Вместо этого он переводится в машинный код — то, что понимает процессор — во время выполнения.

Не процессор, а виртуальная машина (Zend VM). Если бы машинный код исполнялся CPU, никакого бы JIT не нужно было.

Фичи, которые хотелось бы видеть:


  • Асинхронность хотя бы как в JavaScript
  • Дженерики a.k.a. шаблоны
  • Больше возможностей для типизации, например, возможность указать, что аргумент является массивам с элементами такого-то типа

Асинхронность есть в в виде reactphp

Обычно PHP используют в режиме «процесс рождается, чтобы обработать один запрос». ReactPHP рассчитан на работу в режиме демона. PHP не рассчитан на работу в режиме демона, из-за этого в нём часто возникают утечки памяти там, где в других языках не возникают (например, при циклических ссылках объектов, в том числе ссылке не самого себя). К тому же, ReactPHP это сторонняя библиотека, а не единый стандарт.


Ещё есть возможность запустить подпроцесс и таким образом получить полную параллельность. Но это не так удобно, как нативная поддержка в языке.

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);
}
Асинхронность хотя бы как в JavaScript
yield есть, а экосистема — ну что поделать, не нужна среднестатистическому пхп разработчику асинхронность, вот и не популярно.

Дженерики 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 синтаксис новых фич специально стараются сделать не так, как в других языках.

Если вы почитаете чем они это мотивируют, то станет понятно почему — основная причина это не потому что "так лучше и удобнее" а потому что "нам так проще". К сожалению, многие вещи в PHP за прошедшие годы именно по этому принципу и создавались...

Не знал что в пхп можно указывать тип return. В нем даже стандартные функции возвращают что попало.


В своё время недоумевал почему код не работает, пока не узнал что половина функций вертают либо какую-то дату, либо молчаливый скромный false без всяких эксепшенов.

Это уже довольно давно изменилось. Даже ошибки стандартных функций постепенно заменяют на исключения

Я столкнулся с пхп и её проблемами на 7й версии. Если в мире пхп это давно, то питон со своей v3 — это вечность.

Пункт 9 про Stringable — явная ошибка дизайна…

Тоже так подумал.
Лучше бы явно запретили преобразование объекта в строку, если он не реализует интерфейс Stringable.
Который обязывает создать функцию __toString().
Но это поломает кучу легаси кода.

Лучше просто считать, что любая сущность конвертируется в строку, как это сделано во многих других языках.
Ошибка дизайна — это declare(strict_types=1), а Stringable — просто порожденный ею костыль. Первый из многих…

Тип mixed предназначен для явного указания, что параметр или свойство может быть любого типа. Отличается от НЕуказания типа только своей явностью (я не забыл указать тип, просто хочу обрабатывать здесь любые типы). Mixed включает в себя NULL, указать mixed? (mixed nullable) не получится.


Просто сэкономил кому-то минутку гугления ;-)

НЛО прилетело и опубликовало эту надпись здесь
Лет через 10 с PHP 15.
} catch (MySpecialException) {

Это для тех кому лень прописать $e? Или что?
Зачем тогда оставлять (MySpecialException)?
Потому что catch может быть много?

Мне непонятна выгода от написания: catch (MySpecialException) вместо просто catch () или же catch (MySpecialException $e).
Может подразумевается что может быть N ошибок на которые не следует реагировать и K на которые следует? Ну тоже такое себе решение.

Ну потому что например на определенный эксепшен мы захотим сделать ретрай, на другой — просто проигнорируем, а вот у третьего нам уже нужен будет объект, чтобы его залогировать. Как минимум в C# это есть, используется и не является code smell.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации