Несколько дней назад я переключил свой сервер с порядка 30-ти сайтами на PHP 7. Некоторые из них были достаточно старыми и составляли широкий набор с различных фреймворков и CMS. Вот несколько советов для тех кто еще не решил переходить на PHP 7 или нет.
Начнем с того что я понимаю что есть много людей которые не считают стабильную версию действительно «стабильной» пока она чуть-чуть не повзрослела, ожидая что еще найдутся какие-то баги или несовместимости. С того что я пока видел, пробуя каждый release candidate как только он выходил, совсем безопасно переключиться на PHP 7 как только он выйдет. Я ни разу не заметил какого-то непонятного поведения или вылета которому виной не был бы я сам. Несмотря на то что это новая версия она не несет много несовместимых изменений, то есть по большому счету можете относиться к ней как к просто PHP 5.7 только существенно быстрее.
И скорость действительно впечатляет, даже невероятно как. Для примера простой сайт на PHPixie заработал почти в три раза быстрее практически сравнившись со скоростью Phalcon на PHP 5.6, несколько сайтов на Wordpress показали стабильный прирост в скорости в два раза. Если учесть недавний отчет от Google что потеря даже 10% производительности загрузки страниц приводит к ощутимой потери клиентов, то если вы можете запросто ускорить работу сайта в два раза просто обновив PHP вы получаете больше продаж ничего не потратив. Вспомните об этом, когда будете убеждать своего менеджера перейти на PHP 7. Ничего не убеждает лучше, чем объем продаж.
Несколько замечаний
Расширение mysql больше недоступно, так что если вы еще не перешли на PDO или mysqli то теперь уж точно придется. Благо во многих случаях достаточно просто заменить вызовы к mysql_ функциям на mysqli_.
E_STRICT ошибки реклассифицированы как другие типы ошибок. Если раньше вы их прятали или игнорировали, то теперь они начнут всплывать вместе с другими. Например, вызов нестатических методов статически теперь выбрасывает E_DEPRECATED что создало кучу проблем с Joomla 2.5 который почему-то делает это довольно часто. Также несовместимое наследование теперь классифицируется как E_WARNING. Wordpress уже с февраля тестируется на работу с PHP 7, так что с ним самим проблем никаких нет, правда, несколько плагинов таки оказались несовместимыми.
foreach теперь всегда работает с копией массива, так что все изменения массива во время итерации не повлияют на саму итерацию. На самом деле, во многих случаях оно и так работало и сам случай довольно редкий, но все же в одном из плагинов я на это наткнулся.
Теперь $foo->$bar['baz'] интерпретируется как ($foo->$bar)['baz'] а не $foo->{$bar['baz']} как в PHP 5. Это редкий случай, но тоже попалось в одном из плагинов, и как оказалось в Magento 1.x (core/Mage/Core/Model/Layout.php).
Имейте в виду, что не все расширения уже поддерживают PHP 7. Я уже не могу использовать понравившийся мне XCache, который верно служил мне много лет.
Вряд ли вы встретите какие-то проблемы кроме вышеперечисленных, но если вам интересно то полный список доступен на сайте PHP.
В сумме мне заняло около 5 часов чтобы перевести все сайты на PHP 7. Процесс совсем нетрудный и пакеты доступны уже для всех популярных дистрибутивов. Так что даже если вы собираетесь ждать стабильного релиза (уже совсем недолго), нет никакой причины не приготовить свои сайты к миграции наперед.
P.S.: Фея в заголовке статьи — наш праздничный логотип PHPixie 3, он не совсем в тему, но очень хотелось поделиться. Ну можете считать, что это она PHP 7 несет в мешке.
Комментарии (44)
romy4
18.11.2015 18:36То есть, код
$array = [1,2,3]; foreach ( $array as $k=>&$v ) { $v = get_something_else(); // return 3 4 5 } var_dump($array);
что в итоге даст?jigpuzzled
18.11.2015 18:42+2с & совсем другое дело, тут работать также будет. Имеется ввиду такое:
$a = array(1,2,3); $b = &$a; foreach($a as $v) { echo "$v\n"; unset($a[1]); }
romy4
18.11.2015 18:53+2Понятно, спасибо. Делать unset() внутри foreach никогда не было безопасно.
Sild
19.11.2015 17:36+1Расскажите тогда, как стоит поступать в таких ситуациях?
$a = array("test"=>"1", "test2"=>2, "test3"=>3); $needed = array("test", "test2"); foreach($a as $i => $v) { if(!in_array($i, $needed)) { unset($a[$i]); } }
Ну надо мне провалидировать что-то. Собирать новый массив?romy4
20.11.2015 15:16Нашёл два замечательных поста: [1] Тонкости работы foreach в php [2] References in foreach
Sild
20.11.2015 18:28Наткнулся в комментариях на ещё один пост: http://habrahabr.ru/post/114899/
У меня прям все написанные исходники перед глазами пронеслись. Думал в такие моменты, что нужно больше спать, и переписывал на if-else.romy4
21.11.2015 13:53Да, TheShock умеет «накинуть» :) Там же в комментах, вместо if-else
switch(true){ case isCondFirst(): value = valueFirst(); break; case isCondSecond(): value = valueSecond(); break; case isCondThird(): value = valueThird(); break; default: value = valueDefault(); }
просто нечто.
Xu4
23.11.2015 07:11Я конкретно эту ситуацию имею ввиду:
$a = ['test' => '1', 'test2' => 2, 'test3' => 3]; $filter = ['test', 'test2']; $a = array_intersect_key($a, array_flip($filter));
Если ситуация отличается, то и решение может быть другое. Но вот в данном конкретном случае такой код лучше подойдёт, мне кажется. Как минимум, одной переменной меньше и используются встроенные функции, вместо реализации алгоритма вручную.
dim_s
19.11.2015 10:23А что если?
$a = array(1,2,3); foreach($a as $i => $v) { echo "$v\n"; $a[$i] = $v * 2; } var_dump($a); // ???
romy4
18.11.2015 18:39+2И мне нужен xdebug для отладки, а то без него ой как плохо отлаживать сложные прыжки в коде. Жду, когда они 2.4.0 в релиз выпустят.
jigpuzzled
18.11.2015 18:45Ну на сервере то отладка не пригодиться. Так что это не такая-уж проблема, хотя конечно неприятно разрабатывать на одном а деплоить на другой. Этот пост скорее мотиватор пофиксить у себя все E_STRICT чтобы потом боком не вылезли.
romy4
18.11.2015 18:53Я для себя придерживаюсь железного правила:
и чтобы не было ни одного уведомления в работе. Жаль только, такого очень трудно достичь используя чужие фреймворки.ini_set("error_reporting",65535);
OnYourLips
19.11.2015 13:37+5У вас на prod и dev разные версии PHP?
Мне одному кажется такое недопустимым?
summerwind
18.11.2015 23:38+1Для примера простой сайт на PHPixie заработал почти в три раза быстрее практически сравнившись со скоростью Phalcon на PHP 5.6, несколько сайтов на Wordpress показали стабильный прирост в скорости в два раза.
Странные какие-то сравнения. В два, в три раза… По сравнению с чем? Какие задачи сравнивались? Какие операции?
Если учесть, что в обычных сайтах основная часть времени уходит на запросы к БД, то непонятно, как смена версии PHP могла это ускорить. Или там на сайтах интегралы численными методами высчитываются?)
jigpuzzled
18.11.2015 23:57основная часть времени уходит на запросы к БД
это давно уже совсем не так, вот например бенчмарки от Techempower: www.techempower.com/benchmarks/#section=data-r9&hw=peak&test=fortune&l=sg
По условиям теста запросов у каждого фреймворка получается столько же, но вот скорость сильно отличается
SamDark
19.11.2015 13:24Сегфолтит семёрка пока по-страшному. Правят оперативно, но надо больше тестов. Прошу всех погонять свои проекты и заслать в багтрекер трейсы, дампы или, что вообще лучше всего, короткие кусочки кода, которые PHP валят.
zou
19.11.2015 13:32Сейчас пишу новый проект на семерке. Стремно, но пишу. Пока что не словил ни единого бага, вылета и тд. Расширения спокойно собрал вручную, все что для проекта нужно — работает. Вот интересно что может быть аргументом против запуска нового проекта на РНР 7 на следующий день после его релиза.
SamDark
19.11.2015 14:08Против проверки на тестовом сервере — ничего. Против выката на продакшн много чего. Как минимум стоит спланировать откат до 5.6 в деталях.
Fesor
19.11.2015 14:23У меня коллеги как раз таки из-за сегфолтов php5.6 апнулись на семерку. hhvm как оказалось отвратительно работает с postgresql.
Это я к чему, для любого апдейта должны быть причины. Уж темболее если это апдейта на релиз кандидат или бетку.SamDark
19.11.2015 15:06Думаю, получить от 30% прироста производительности — хороший аргумент за переход на семёрку. Но делать это надо осторожно.
sergebezborodov
19.11.2015 18:30Саш, а как с yii на семерке?
SamDark
19.11.2015 18:48В общем и целом отлично. Код работать будет. Все сегфолты воспроизведены и закинуты в трекер. Большинство Расмус уже поправил.
Новых фич семёрки, конечно же, из за обратной совместимости, не используем пока.sergebezborodov
19.11.2015 19:13интересно очень, дождусь релиза и запущу отдельный сервер с семеркой и налью часть трафа hotwork.ru померяю реальное ускорение
Fesor
19.11.2015 19:23неужели у вас нет старых добрых нагрузочных тестов?
sergebezborodov
19.11.2015 19:32не применяли, в системе 100к суточных визитов, нагрузка растет плавно, поэтому гонять нагрузку в суточные 1млн визитов смысла особо нет
а ливануть пару тыс живого трафа на хорошее дело всегда можно ;)
WellWisher
19.11.2015 13:58Если только отсутствие нужных библиотек, совместимых с PHP 7.
Пока дойдете до релиза думаю что если «вдруг» что-то и появится внезапное, — то всё будет пофикшено.Fesor
19.11.2015 14:02на данный момент есть аж 2 инструмента что бы помочь быстрее мигрировать проекты на php7:
— github.com/Alexia/php7mar
— github.com/sstalle/php7cc
В принципе популярные фреймворки уже совместимы с PHP7. В частности у Symfony небыло никаких проблем.
bolk
20.11.2015 17:10+1Безумству храбрых поём мы песню, конечно. На ветке PHP7 постоянно находятся неприятные баги. Падения, зацикливания, утечки. Например описание сегодняшнего исправления такое: «try{ } finally{} can create infinite chains of exceptions».
maxru
Как и memcached
jigpuzzled
насколько я понимаю внутренности поменялись гораздо сильнее чем сам язык. Как раз поэтому автор XCache написал что пока нет планов на версию для 7-ки.
pherum
что с memcached не так? на homebrew он устанавливается, только доступен из ветки dev-master
видимо выкатят стабильную версию после релиза самого php7
Blumfontein
memcache или memcacheD?