Свежая подборка со ссылками на новости и материалы. В выпуске: PHP 7.2.0 Alpha 1, свежие предложения из PHP Internals, Symfony 3.3.0, Yii 1.1.19 и 2.0.12, нововведния Laravel 5.5, спор о Visual Debt и многое другое. Приятного чтения!
Новости и релизы
- PHP 7.2.0 Alpha 1 — Доступна для тестирования первая альфа-версия новой ветки PHP. Стартовал полугодовой цикл тестирования, финальный выпуск ожидается в ноябре.
Уже по традиции в релизе улучшена производительность. А также среди изменений:
- Libsodium в ядре
- Эмуляции подготовленных выражений
- Множество функций объявлены устаревшими
- Тайпхинт object
- Расширение типа аргумента
- Присвоение по ссылке в list()
- PHP 7.0.20
- PHP 7.1.6
- WordPress 4.8 “Evans”
- HHVM 3.20 — Улучшена совместимость с PHP 7, и начиная с 3.20.2 заявлена успешная работа с Composer. Тем не менее все крупные PHP-проекты уже отказались от поддержки HHVM из-за низкой популярности.
- PHP Odessa Conf — 25 июня пройдет Первая PHP-конференция в Одессе. Среди докладчиков Jordi Boggiano, James Titcumb, и другие.
- DevConf 2017 — 17 июня, Москва — Программа сформирована, в секции Backend несколько докладов посвящены PHP.
PHP
- Короткий синтаксис для анонимных функций — В Internals активно обсуждается возможная реализация коротких лямбд. Ранее рассматривался и был отклонен на голосовании синтаксис с тильдой:
$x ~> $x + 1;
, а также^($x) => $x + $y
. На данный момент рассматриваются следующие возможные варианты:
fn(params) => expr function(params) => expr (params) ==> expr (params) => expr [](params) => expr
- Включить PCS в ядро — Предложение для PHP 7.3 пока не оформленное в официальный RFC. PCS — это модуль, который позволяет писать расширения для PHP на PHP и С одновременно. Подробнее о PCS. Включение такой возможности в ядро позволит переписать многие расширения на PHP. Это, в свою очередь, позволит сильно упростить код, уменьшить число багов, и увеличить количество потенциальных ментейнеров.
Инструменты
- reactphp/http v0.7.0 — HTTP/HTTPS сервер на базе ReactPHP.
- hollodotme/fast-cgi-client — FactCGI клиент для отправки (а)синхронных запросов в PHP-FPM. Слайды, примеры использования с Redis и с RabbitMQ.
- samdark/hydrator — Извлечение данных и заполнение данными объектов. Пост в поддержку.
- phunkie/phunkie — Набор структур для функционального программирования на PHP. Туториал в поддержку.
- gilbitron/sqsd — Демон эмулирует работу Amazon SQSD на локальной машине.
- formapro/pvm — Библиотека для описания схемы процесса (workflow). Поддерживает асинхронные переходы и параллельное выполнение задач.
- Composercat — Десктопное GUI приложение для Composer.
- php-enqueue/enqueue-dev — Очередь сообщений с поддержкой транспортов AMQP (RabbitMQ, ActiveMQ), STOMP, Amazon SQS, Redis, Doctrine DBAL, Filesystem.
Материалы для обучения
Symfony
- Symfony 3.3.0 — Список изменений по категориям.
- Symfony Async EventDispatcher
- Подборка ресурсов для подготовки к сертификации по Symfony
- ЧПУ (SEF URLs) в Symfony 3 — автогенерация slug, настройка и маршрутизация
- Неделя Symfony #544 (29 мая — 4 июня 2017)
- Неделя Symfony #545 (5-11 июня 2017)
Yii
Laravel
- monicahq/monica — Приложение для ведения журнала активностей и сохранений информации о друзьях и семье.
- Интервью с Taylor Otwell
- Кастомные правила валидации в Laravel 5.5
- Авторегистрация пакетов Laravel 5.5 — Благодаря секции extra в composer.json, при подключении сторонних пакетов не будет необходимости вручную указывать провайдеры или фасады.
- Diving Laravel — Туториалы по фреймворку.
Zend
- Zend Framework и PHP 7.1 — Вслед за другими фреймворками ZF переходит на семерку, а также прекращает поддержку HHVM. Новые версии существующих компонентов и новые компоненты будут выходить под 7.1.
- Неделя Zend Framework 2017-06-01
- Неделя Zend Framework 2017-06-08
- Слайды доклада Никиты Попова о статической оптимизаци байткода PHP
- PHP Internals Book — Книга, посвященная внутренностям PHP 5, доступна под лицензией Creative Commons. Текст пополняется информацией о PHP 7.
- Сканер отпечатков пальцев с помощью PHP, Websocket, и React Native
- Асинхронный PHP с помощью ReactPHP: Event Loop и таймеры
- Пример использования блокировок в консольной команде
- Как не надо делать Dependency Injection
- Туториал по PSR-7 с помощью Zend Diactoros
- Перенос констант в ассоциативные массивы
- История одного лендинга
- Методы работы с «тяжёлыми» XML
- Тестирование с Сodeception для чайников: 3 вида тестов
- Как выбрать тот самый PHP-фреймворк. Сравнительное тестирование
- Как получить оффер в Badoo в день собеседования. Часть вторая, для PHP-разработчика
Занимательное
- joaoescribano/UltimaPHP — Сервер популярной некогда игры Ultima Online на PHP.
- 6 файлов, которые являются валидным PHP — GIF, PDF, JPG, которые можно выполнить как PHP.
- Тайпхинты и интерфейсы — визуальный шум? — Jeffrey Way опубликовал видео, в котором рекомендует удалить тайпхинты, интерфейс, и объявление final, называя их визуальным шумом. На что получил ряд критических ответов, например тут, тут, и тут. Энтузиасты даже создали специальный инструмент статического анализа для поиска «визуального шума» — phpvisualdebt.
Спасибо за внимание!
Если вы заметили ошибку или неточность — сообщите, пожалуйста, в личку.
Вопросы и предложения пишите на почту или в твиттер.
Прислать ссылку
Быстрый поиск по всем дайджестам
< Предыдущий выпуск: PHP-Дайджест № 109
Комментарии (51)
andrewnester
12.06.2017 10:34+1Сейчас идёт голосование за интересное RFC — сделать последовательными индексы в массивах, формируемых функциями array_*
https://wiki.php.net/rfc/negative_array_index
Вкратце — скорее всего, не попадёт в PHP 7.2, но возможно будет в PHP 8
olegl84
12.06.2017 12:52+4Вышла бета версия yii2 плагина для IDEA/PhpStorm.
Скачать можно из закладки Beta на https://plugins.jetbrains.com/plugin/9388-yii2-support
или по этой ссылке .
Из нового:
Автокомплит для правил валидации
Автотип для Yii::createObject
Прошу помочь с бета тестированием. Баги пишите в гит хаб: https://github.com/nvlad/yii2support
myrkoxx
12.06.2017 15:31Прошел PHP-FWdays в Киеве. Обещают поделиться видео через одну/две недели. Скорей всего к следующему дайджесту появятся
GraDea
12.06.2017 16:03Кто-то может новичку PHP объяснить смысл https://wiki.php.net/rfc/parameter-no-type-variance
В наследнике появляется возможность забить на тип аргумента в родителе (то есть мы расширяем). В комментах к пуллреквесту срач насчет нарушает ли контрвариация аргумента LSP или нет (вроде как нет). Но у меня вопрос — зачем? Даем пользователям библиотек продолжать использовать свои бестиповые наследники?Nahrimet
12.06.2017 21:32+1Я не могу себе придумать практическое применение этого вброса, который почти наверняка будет вести к нарушению LSP и OCP. Хочу схватиться за голову и бегать…
pbatanov
13.06.2017 11:28Как раз таки этот «вброс» ведет к частично более полному соблюдению LSP, в этом и суть.
Если кратко, то LSP состоит в том, что множество допустимых входных параметров вы можете только расширять, а множество возможных выходных параметров вы можете только сужать.
Сброс тайп-хинта сигнатуры позволит вам реализовать прослойки для управления обратной совместимостью, при этом сигнатуры вы все еще можете определять через phpdocNahrimet
13.06.2017 12:59Откровенно говоря, Ваше краткое определение LSP тоже заставляет хвататься за голову и…
pbatanov
13.06.2017 14:39А я не говорил, что это определение. Это одно из следствий со стороны обсуджаемого вопроса.
Если вы хотите строго по определению, то пожалуйста. Представьте, что у вас есть тип T с методом T::f(A $a). И есть тип S extends T с методом, который отличается только отсутствием тайпхинта S::f($a).
Если сам код методов идентичен, то если свойство q(T x) верно, то и свойство q(S y) тоже будет верным
Таким образом исключение тайпхинта не нарушает LSP, а текущее поведение (фатал парсера) — нарушает. Что подтверждает мое утверждение
ведет к частично более полному соблюдению LSP
Nahrimet
13.06.2017 22:12Во-первых, старайтесь никогда не приводить примеры абстрактных коней в вакууме, так как они за собой влекут точно такие же выводы.
Во-вторых, Вы на основе чего программируете? Реализации? Не ведет это «к частично более полному соблюдению LSP». Если сигнатура гласила Razor::shave(Beard $beard), то, для возможности побрить что-то еще, необходимо не глушить сигнатуру в дочернем классе, а пересматривать решение на уровне интерфейса. Почему не, к примеру, Razor::shave(ShaveableInterface $hairySurface)?
Вы не подумайте, я на Вас бочку не качу)
Просто не в состоянии своё недоумение выразить в полной мере касательно «parameter-no-type-variance». Только и просится фраза «Зачем?!».Fesor
13.06.2017 23:05Только и просится фраза «Зачем?!»
Все началось с какого-то обсуждения в internals где предлагали что-то пофиксить но для того чтобы не ломать обратную совместимость пришлось ваять этот RFC. Все как обычно.
pbatanov
13.06.2017 23:24Основная проблема в том, что контр\ковариантность в пхп пока не смогли, потому что это создает какие то проблемы в разработке енамов.
то если у Razor есть наследники (положим, это библиотека), то изменить сигнатуру указанным образом невозможно, это тут же нарушает LSP для наследников.
Если же сделать нового «правильного» наследника, с нужной сигнатурой, то текущая версия PHP кидается ворнингами (т.к. пока мы живем с инвариантами)
https://externals.io/thread/514
https://wiki.php.net/rfc/return_types#variance_and_signature_validation
Так что это полумера, но это единственное что позволяет перейти от одного интерфейса к другому с сохранением обратной совместимости и без особых костылей. Хотя если вы знаете короткий путь, то готов посмотреть
LastDragon
13.06.2017 13:17Да легко оно представляется, особенно когда есть куча старого кода, который надо поддерживать и рефакторить, более того, в самом rfc об этом написано и даже приведено несколько реальных примеров.
masterjus
13.06.2017 11:57Суть предложения в том, что если у предка указан тайпхинт, то потомок может уже не писать его, он будет взят из предка
По крайней мере я так это понялGraDea
13.06.2017 12:43В комментах указано
// This RFC proposes allowing the type to be widened to be untyped aka any // type can be passed as the parameter. // Any type restrictions can be done via user code in the method body.
То есть ограничения снимаются и дело не просто в отсутствии варнинга.
igordata
13.06.2017 07:24Спасибо! Всегда читаю этот дайджест.
6 файлов, которые являются валидным PHP — GIF, PDF, JPG, которые можно выполнить как PHP.
Примажусь по случаю Как запустить *.jpg как *.php или как предотвратить исполнение загруженных юзером файлов
GraDea
13.06.2017 08:36И про тоже интересно зачем.
В примере есть код:
class WidgetFactory { function create() { return new Widget(); } } class CustomWidgetFactory extends WidgetFactory { function create() { $object = new Widget(); return true; //This is an error that cannot be statically analyzed. } }
Что мешает указать у метода create (): Widget?
Ну помешает вернуть true спецификатор: object, но что делать с остальными объектами, которые несовместимы с Widget?
GraDea
13.06.2017 11:21Подскажите, что в RFC значит Accepted — Pending Implementation?
Corpsee
13.06.2017 11:36Одобрен, но ожидает реализации в коде.
GraDea
13.06.2017 11:40То есть object typehinting скорее всего не ждать в 7.2? И вообще не факт, что оно дойдет до реализации в таком виде?
Corpsee
13.06.2017 11:43+1Видимо да. 7.2 уже в альфе, вряд ли там будет что-то новое.
pronskiy
13.06.2017 11:54Pull request есть https://github.com/php/php-src/pull/2080
Думаю скоро смержат в master
Elfet
14.06.2017 15:10+1Надеюсь это будет
(params) => expr
morozovsk
14.06.2017 16:27тоже подумал, что не плохо было бы сделать как в js, но этот вариант не просто так запихнули на предпоследнюю позицию
//пример $param = 5; [ ($param) => $param*2 ] //может восприниматься парсером так: [$param => $param*2] //[5 => 10] //или так [ function($param) {return $param*2} ]
скорее всего выберут fnElfet
14.06.2017 16:33такой случай не часто встретишь. можно сделать что бы в этом случае парислся как массив, хочешь однозначности в массиве? — оберни в скрбки
[($param => $param*2)]
morozovsk
14.06.2017 16:44это понятно, но магии в php итак хватает, думаю разработчики не пойдут на такой шаг, к тому же это может поломать старые проекты
в общем поживём увидим
а в вашем примере благодаря скобкам что получится массив или функция?
Fesor
14.06.2017 16:58скорее всего выберут fn
function fn() { // bad ass } [fn($x) => $x ** 2]
то есть все те же проблемы и еще большая обратная несовместимость. С другой стороны....
[ ($x => $x**2) ]
уже будет нам говорить что это массив выражений. Скобки неплохой вариант устранения двусмысленности с точки зрения синтаксиса. Вот только парсеру это не помогает особо и этот вариант все равно остается сложным. Ну мол что бы было кошерно надо как-то по первой лексеме понять что у нас тут лямбда.
Потому скорее уж примут
function ($x) => $x ** 2
.morozovsk
14.06.2017 17:14теперь понятно для чего они добавили второй и третий варианты
вообщем будем ждать голосованияFesor
14.06.2017 17:21Пока страждущие могут пользоваться фолдингом в IDE:
https://plugins.jetbrains.com/plugin/8477-php-lambda-folding
LastDragon
14.06.2017 17:45Потому скорее уж примут
Почему не
(params) ==> expr
? Оператор==>
еще свободен, да и набирать не сильно сложнее чем=>
.Fesor
14.06.2017 19:45еще свободен
- потому что проблема не в двусмысленности, ее устраняют скобки. Идея в том что бы поменьше операторов добавлять, хотя с другой стороны идея так же что бы одни и те же операторы сохраняли свой смысл вне зависимости от контекста чего не происходит с
=>
. - потому что профита с точки зрения реализации парсера это не добавляет.
- потому что
=>
лучше чем==>
или~>
.
LastDragon
14.06.2017 20:05- Новый оператор как раз в стиле PHP
- Отследить контекст ему проще?
- Хз, тильда непривычна,
[](params)
как-то странно выглядит, аfunction ($x) =>
совсем не короткий и оттого бессмысленный вариант. ИМХО, выберут между=>
и==>
.
Fesor
14.06.2017 20:132 нет. PHP юзает LR(1) парсер, то есть "не двусмысленно" это когда он может понять что он парсит смотря максимум на одну лексему вперед. Так что "просто" это когда у нас есть кейворд в самом начале выражения. Типа
fn
илиfunction
. Тогда парсер запросто все обработает.
В случае с массивом — скобочка будет для него сигналом что он парсит выражение, а не конструкцию в контексте массивов или генераторов, так что тоже все вроде бы ок. Но вот внутри выражения ламбда или нет — это он может догадаться распарсив список аргументов и это надо будет уже делать хитрости.
3 Между этими вариантами нет смысла что либо выбирать на самом деле. fn удобно и хороший компромис но вводит новое ключевое слово (обратная совместимость). function — длинно, хотя по факту не то что бы сильно:
$items = array_map(function ($row) => $this->hydrator->hydrate($row), $rows); $total = array_reduce($items, function ($sum, $item) => $sum + $item->price()); // vs $items = array_map($row => $this->hydrator->hydrate($row), $rows); $total = array_reduce($items, ($sum, $item) => $sum + $item->price());
LastDragon
14.06.2017 20:29Вот именно что длинно, по сути только
return
выбросили, это явно не то чего всем хочется.
$items = array_map($row => $this->hydrator->hydrate($row), $rows); $items = array_map($row ~> $this->hydrator->hydrate($row), $rows); $items = array_map($row ==> $this->hydrator->hydrate($row), $rows); $items = array_map(function ($row) => $this->hydrator->hydrate($row), $rows); $items = array_map(function ($row) { return $this->hydrator->hydrate($row); }, $rows); $items = array_map(function ($row) { return $this->hydrator->hydrate($row); }, $rows);
Fesor
14.06.2017 23:05это явно не то чего всем хочется.
ну тут как говорится, "хоти в одну руку, а..." Увы приходится идти на компромиссы в пользу простоты сопровождения парсера и отсутствия нарушений обратной совместимости :(
LastDragon
14.06.2017 23:16Имхо, добавлять кривой сахар смысла совсем нет, поэтому или действительно короткий синтаксис (лучше похожий на что есть в других языках) или ничего.
Fesor
14.06.2017 23:58Представьте что вас просят добавить фичу, и вы можете реализовать фичу двумя способами:
- удобный пользователю, то что они хотят, но это усложнит реализацию на порядок и вам придется ее поддерживать годами (дорого)
- чуть менее удобный пользователю, зато намного более простой с точки зрения реализации, не требующий кардинальных изменений. (дешево)
Да, второй вариант всем не понраву, но он решает проблемы какого-то процента пользователей. Либо же не делать ничего. Как бы вы поступили?
Nahrimet
15.06.2017 00:21+1А Вы, как бы поступили?)
Лично на мой взгляд, в php достаточно фич из разряда makeSomethingLikeFooButInAnotherWay. Если можно удержаться от «двусмысленности», то лучше так и поступить.
LastDragon
15.06.2017 07:42Выбрал бы первый вариант (
==>
отношу к нему же) — кривая фича вообще никому не нужна (их тут и так слишком много), если это что-то ломает — есть следующая мажорная версия, а если это слишком сложно — не стал бы делать.Fesor
15.06.2017 11:21Выбрал бы первый вариант
то есть "то что они хотят, но это усложнит реализацию на порядок и вам придется ее поддерживать годами (дорого)".
а если это слишком сложно — не стал бы делать.
Это я к тому что при обсуждении RFC люди примерно так и думают. Либо сделать нормально, что технически невозможно на данный момент, либо не делать ничего.
Но все еще есть процент людей которым фича нужна даже с "лишним" кейвордом в начале.
То есть проблема — люди думают только о себе. Тем кто не видит смысла — фича не обязательная. С другой стороны убрать кейворд и сделать его опциональным в будущем не составляет особо проблемы.
LastDragon
15.06.2017 12:17то есть
Да, однако вы упускаете что поддерживать надо всё, поэтому, в данном случае, нежелание сделать нормально сразу это обычная лень.
Но все еще есть процент людей которым фича нужна даже с "лишним" кейвордом в начале.
Она была нужна давным давно, сейчас смысла в ней не очень много на самом деле. Но вообще дело не в лишнем
function
, а в том что эта запись совсем не короткая, глядишь там еще иuse
придется писать, а то сложно же по другому сделать...Fesor
15.06.2017 15:25нежелание сделать нормально сразу это обычная лень.
вам надо сделать в парсере гиганский кастыль который сможет чекать на N лексем вперед. Я не считаю что это "сделать нормально".
сейчас смысла в ней не очень много на самом деле.
аргументируйте. Есть альтернативы?
глядишь там еще и use придется писать
Почитайте RFC. В частности:
importing used variables from the outer scope implicitly
а то сложно же по другому сделать...это как раз таки сделать не сложно. Сложно с парсером без кейворда в начале выражения.
LastDragon
15.06.2017 16:40аргументируйте. Есть альтернативы?
Что именно аргументировать? Анонимные функции есть давным-давно, короткий синтаксис всего лишь сахар, который первый раз был предложен пару лет назад (там кстати даже pr был...), за это время все уже привыкли к стандартному синтаксису + явный
use
имеет свои преимущества.Fesor
15.06.2017 19:58+1Есть большая разница между "анонимными функциями" и "функциональными выражениями". В JS мире эту разницу тоже не сильно понимают потому пихают arrow functions бездумно.
явный use имеет свои преимущества.
которые не имеют смысла в этом контексте.
за это время все уже привыкли к стандартному синтаксису
примерно так же про синтаксис массивов говорили.
LastDragon
15.06.2017 21:08Есть большая разница между "анонимными функциями" и "функциональными выражениями".
И в чем же эта разница?
примерно так же про синтаксис массивов говорили.
А вот его как раз реализовали правильно :)
- потому что проблема не в двусмысленности, ее устраняют скобки. Идея в том что бы поменьше операторов добавлять, хотя с другой стороны идея так же что бы одни и те же операторы сохраняли свой смысл вне зависимости от контекста чего не происходит с
malinichev
Что-то относительно мало ссылок, или мне так кажется?
pronskiy
В среднем в дайджестах бывает 50-70 ссылок, сейчас ближе к 50