Два месяца назад я перешёл на PHP7 и в этом посте хочу поделиться нововведениями, которые пришлись по нраву мне больше всего. Во первых, переход на новую ветку PHP обусловлен приростом производительности и уменьшением потребляемых ресурсов, т. е. крупные сайты с PHP7 могут в два раза снизить расходы на хостинг и быстрее генерировать веб-страницу конечному пользователю. Здесь выигрывают сразу и владельцы сайтов, и их посетители.
Это сравнение скорости между версиями 5.6 и 7.0 на различных платформах. Zend Framework даёт прирост скорости на 133%, а WordPress — 129%. Такое улучшение PHP имеет позитивные последствия для бизнеса.
В прошлом году Badoo, WordPress.com, Tumblr и многие другие гиганты перешли на PHP7. Так, например, компании Badoo за счёт снижения CPU в два раза и уменьшения потребления памяти в 8 раз удалось сэкономить 1 млн долларов. Сайт WordPress.com также полностью переведён на PHP7, где прирост производительности действительно заметен:
Быстродействие в новых версиях стало самым крутым и обсуждаемым нововведением. Теперь не нужно заморачиваться по оптимизации каких-то участков кода, а сразу писать понятный и поддерживаемый код. Во вторых, в PHP 7.0 и 7.1 введено большое количество улучшений на уровне синтаксиса и функциональности. Далее на примерах я покажу, что мне понравилось в новых версиях и как эти нововведения поменяют язык PHP в будущем на уровне кода.
Замена тернарного оператора
На замену тернарного оператора пришёл «оператор объединения с null» или «null-коалесцентный оператор». Через два знака вопроса (??) можно указать цепочку значений в одну строку и будет выбрано первое значение, которое не равно null. Раньше этот подход применялся вместе с функцией isset(). Сейчас можно указать даже не существующие переменные и не мучатся c большой вложенностью как с тернарным оператором.
Оператор объединения с null Тернарный оператор и оператор null-coalescing
Групповое объявление классов, констант и функций
Начиная с версии 7.0 появилась возможность группировать объявления импорта классов, функций и констант, находящиеся в одном пространстве имён, в одной строке с помощью оператора use. Это нововведение на уровне синтаксического сахара, которое может наделить объявление имён каких-то компонентов определённой логикой.
Групповые декларации use
Декларация типов и возвращаемых значений
Это самое мощное нововведение для ООП. Теперь при объявлении метода для каждой переменной можно указать свой тип, а также тип данных, который вернёт этот метод. В PHP 7.0 доступны следующие типы: array, callable, bool, float, int, string, имя класса или интерфейса. В версии 7.1 добавили ещё void и iterable. Тип void можно использовать только в возвращаемых значениях функций, которые ничего не возвращают. Псевдо-тип iterable используется в качестве значения массива или объекта, реализующего интерфейс Traversable.
В примере выше отработала принуждающая декларация типов, т. е. PHP динамически привёл значения к нужному типу, когда в переменную с объявленным типом int мы передали string, например. Вместо того, чтобы сгенерировать ошибку, все значения переменных и результат функции был преобразован к указанному типу на лету. Это поведение установлено по умолчанию.
Строгую типизацию можно включить, если в начале скрипта прописать declare(strict_types=1). Все значения должны полностью соответствовать указанным типам. В противном случае будет сгенерирована ошибка TypeError. Строгая типизация не затрагивает весь остальной код и её нужно прописывать для каждого скрипта отдельно.
В версии 7.1 появилась возможность обнулить возвращаемые типы. Это расширяет список возвращаеммых типов до null. Теперь функция может вернуть какой-то явно указанный тип или null. Достигается такое поведение путём добавления префикса в виде знака вопроса к указанному типу:
Декларация типов и возвращаемых значений выводит PHP на новый уровень и эти нововведения мне нравятся больше всего, т. к. со стороны разработчика повышается читабельность кода; чёткая согласованность входных и выходных данных; программист может быстрее понять, чего ожидать от функции; легче документировать код; появляется возможность изменять типы данных на лету. Это основополагающая функциональность PHP7, которой не знать уже сейчас недопустимо.
Декларация скалярных типов Декларация возвращаемых значений Обнуляемые типы Ничего не возвращающие функции Псевдо-тип iterable
Обработка ошибок и исключений
В PHP 7.0 появился новый класс для внутренних ошибок Error и интерфейс исключений Throwable. Теперь Error и старый класс Excetion реализуют Throwable (пользовательские классы не могут реализовывать данный интерфейс). Exception можно использовать для отлова исключений, которые будут обработаны и выполнение программы продолжится. Класс Error служит для необратимых исключений и выбрасывается в случае ошибки PHP или на уровне ошибок разработчиков.
Большинство ошибок уровня E_ERROR или E_RECOVERABLE_ERROR будут выбрасывать Error, но некоторые будут выбрасывать объекты подклассов: ArithmeticError, AssertionError, ParseError, DivisionByZeroError, TypeError и ArgumentCountError (с версии 7.1). Эти подклассы ошибок не могут быть брошены самостоятельно, а только лишь словлены. Иерархию всех исключений можно представить в виде дерева:
Начиная с версии 7.1 появилась возможность в блоке catch обрабатывать сразу несколько исключений, перечисляя их через символ вертикальной черты. Может быть полезно для обработки одинаковых по логике ошибок или пользовательских исключений.
На место фатальных ошибок пришли исключения, которые могут быть обработаны и позволяют корректно завершить программу в случае каких-то косяков. Это добавляет гибкости PHP-приложению.
Предопределённые исключения Изменения в обработке ошибок и исключений Обработка нескольких исключений в одном блоке catch
Остальные нововведения одним списком
Нововведения в PHP7+ это лишь начало большого перехода на новый уровень языка. С каждым релизом приложения будут становиться быстрее и безопаснее. На версии 7.0 и 7.1 нужно отреагировать уже сегодня и будь в курсе новых тенденций PHP, дабы не выпадать из сферы. Ниже привожу одним списком остальные нововведения:
жение return в генераторах ↩ 7.0 Делегация генератора с помощью конструкции yield from ↩ 7.0 Новая функция intdiv() для целочисленного деления ↩ 7.0 session_start() принимает массив опций ↩ 7.0 Новая функция preg_replace_callback_array() ↩ 7.0 Новые функции random_bytes() и random_int() ↩ 7.0 list() может раскрывать объекты реализующие ArrayAccess ↩ 7.0 Обращение к методам и свойствам класса при клонировании (clone $foo)->bar() ↩ 7.1 Короткий синтаксис для list() ↩ 7.1 Публичные и приватные константы классов ↩ 7.1 Поддержка ключей в list() ↩ 7.1 Поддержка отрицательных смещений для строк ↩ 7.1 Расширены функции openssl_encrypt() и openssl_decrypt() ↩ 7.1 Преобразование callable в Closure с помощью Closure::fromCallable() ↩ 7.1 Новая функция pcntl_async_signals() ↩ 7.1 Поддержка Server Push в CURL 7.46 ↩
denisyuk.by
О языке PHP
PHP – это язык программирования, который в основном применяется в веб-разработке, как правило, в части back-end. PHP имеет достаточно длинную историю – его первая версия появилась более 20 лет назад, в 1995 году. За это время было выпущено 7 версий PHP, последняя из которых появилась в декабре 2015 года. О ней и пойдет речь в этой статье.
PHPNG
Релиз PHP 7.0 стал в своем роде прорывом, так как он основывался на phpng – экспериментальном и активно развивающимся проекте PHP, название которого расшифровывается как “PHP Next Generation” – «Следующее поколение PHP». Данную технологию можно было использовать и в предыдущих версиях PHP, однако именно в PHP 7 она была введена как основополагающая. При ее разработке была поставлена цель повысить производительность PHP, но при этом не потерять совместимость.
Zend Engine
PHP 7 основан на третьей версии Zend Engine, в которой был развит проект phpng.
Нововведения
В первую очередь новшества в PHP 7 коснулись самых важных для разработки приложений параметров – это производительность и потребление памяти.
Основное изменение, о котором в первую очередь упоминают в разговоре о PHP 7, это улучшение производительности: показатели PHP 7 приближены к показателям HHVM (разработанной Facebook системы, которая позволяет ускорить преобразование PHP-кода в несколько раз). Не последней причиной этого стало то, что соучредитель Zend Technologies (компании-разработчика ядра PHP) Зеев Сураски рассматривает HHVM как одного из конкурентов Zend. А ведущий разработчик PHP 7 компании Zend Technologies и автор phpng Дмитрий Стогов заверяет, что разница в производительности PHP 5.0 и PHP 7 на синтетическом тесте bench.php составляет 14 раз. На практике большинство пользователей склоняются к мнению, что PHP 7 примерно в два раза быстрее предыдущей версии.
HHVM использует так называемую JIT (Just-In-Time) компиляцию для преобразования кода – несмотря на то, что JIT в 7 версии PHP не появился, PHP 7 поддерживает более хорошую миграцию, которая и позволяет улучшить производительность в разы. Именно новый уровень производительности Дмитрий Стогов выделяет в качестве главной особенности PHP 7.
Улучшение производительности удалось добиться и благодаря тому, что компилятор теперь генерирует более эффектный и короткий байт-код.
В наше время крайне важно думать о пользователях не только стационарных, но и мобильных устройств, поэтому разработчики PHP 7 улучшили исполнения движка и снизили потребление памяти, а также добавили возможность использовать нативное локальное хранилище. К тому же PHP 7 позволяет выполнять асинхронные задачи.
Кстати, при разработке учитывались и популярные тенденции по сокращению потребления ресурсов планеты, поэтому PHP 7 имеет возможность обрабатывать больше трафика, используя все те же ресурсы сервера.
Новые функции
В PHP 7 есть множество новых функций, каждая из которых делает разработку более удобной и простой. Далее вы можете ознакомиться с некоторыми из них.
Два новых класса исключений (Exception и Error) – если в предыдущих версиях PHP нельзя было обрабатывать фатальные ошибки, то в новом релизе приводящие к этому действия выбрасывают исключения, то есть завершение скрипта не произойдет.
Анонимные классы – теперь PHP 7 поддерживает этот вид классов, который часто используют в C++ и Java для выполнения callback-функций. Эти классы в основном используются для создания простых элементов:
Анонимные классы могут быть вложенными, но при этом им не будут доступны protected или private-свойства внешнего класса.
Возможность указывать скалярные типы (Scalar Type Hints) — в предыдущих версиях PHP можно было указывать тип принимаемых значений; теперь вы также можете указывать и скалярные типы:
Это нововведение направлено на облегчение написания кода и улучшение его читабельности. А вот использование этих значений в качестве имен классов категорически запрещено, т.к. это может привести к критическим ошибкам.
Сокращенная конструкция use — в PHP 7 появилась возможность объединять декларирование групп use, что, несомненно, положительно отразится как на скорости работы, так и на восприятии кода:
Новые операторы Null coalescing operator (??) и Combined Comparison Operator (<=>, также он известен как Spaceship Operator) – эти два новых оператора, которых некоторые относят к синтаксическому сахару, помогут написать более лаконичный и понятный код.
Null coalescing operator – это оператор объединения, который проверяет, существует ли переменная, и возвращает ее значение (либо значение по умолчанию):
Combined Comparison Operator – это оператор сравнения, который пригодится для использования в callback-функциях для usort(). Он сравнивает два значения и, в зависимости от результата, возвращает -1, 0 или 1:
Приоритет данной операции равен приоритетам других операций сравнения, при этом его нельзя связать с предыдущим вызовом, т.к. это неассоциативный оператор.
Функция assert() — в PHP 7 эта функция обрабатывается особым образом для того, чтобы были исключены накладные расходы; вы можете использовать ее для отладки, а в дальнейшем отключать.
Фильтрация unserialize() – это новшество обеспечит безопасность сериализации объектов. Разработчик сам сможет определить, какие классы должны подвергнуться обработке, а какие нет.
Представление целых чисел в виде 64-битных в PHP 7 для Windows x64: теперь PHP поддерживает строки длиной больше 231 байт в 64-битных сборках.
Делегирование генераторов – при помощи <expr> сложный генератор можно разделить на несколько более мелких. Как и некоторые другие нововведения, данное новшество направлено на написание более чистого и удобного для повторного использования кода.
Появление нового класса IntlChar – он увеличивает набор возможностей библиотеки для локализации приложений International Components for Unicode и имеет методы класса и константы для работы с Unicode.
Возможность определять массивы как значения констант, которые объявляются через define().
Возможность присваивать зарезервированные ключевые слова именам методов.
Появление нового идентификатора простых значений PHP_INT_MIN.
Что касается старых функций, то часть самых невостребованных возможностей была исключена: к примеру, были удалены ASP и script-теги, а также регулярные выражения, совместимые с POSIX, и расширение ext/mysql.
PHP и веб-серверы
PHP широко применяется при написании множества веб-приложений, т.к. этот язык совместим с различными веб-серверами (Apache, Nginx, IIS), базами данных (MySQL, Postgre, MongoDB и т.д.), а также операционными системами. Поэтому уже традиционно нововведения коснулись не только языка в целом, но и тех его сторон, которые связаны с хостингом.
В первую очередь в PHP 7 было введено Abstract syntax tree (AST) – абстрактное синтаксическое дерево, которое является промежуточным звеном в компиляционном процессе. Именно на этой модели теперь основан синтаксический анализатор. Благодаря этому теперь можно создавать более производительный операционный код.
Еще одним нововведением является Uniform Variable Syntax – универсальный синтаксис для переменных. Это позволяет, с одной стороны, решить часть несоответствий, которые связаны с вычислением значений переменных, но, с другой стороны, создает необходимость переписывать некоторые редко используемые части кода.
Еще раз вернемся к увеличению производительности PHP 7: это благоприятно отразиться на функционале всех хостингов, ведь они смогут увеличить количество своих пользователей без увеличения количества серверов или других улучшений.
Одной из причин повышения производительности является оптимизация структуры внутренних данных, что значительно улучшило процесс работы с памятью.
Нельзя не сказать о некоторых проблемах обратной совместимости, которые могут возникнуть при переходе на PHP 7. Например, теперь нельзя использовать несколько выражений default в switch, т.к. в противном случае вы увидите ошибку. Однако в целом эти проблемы незначительны на фоне тех новых возможностей, которые предлагает PHP 7.
Вывод
Релиз PHP 7 – это не просто выпуск новой версии PHP, но определенная отправная точка для следующих PHP-версий нового поколения. Результатами множества нововведений PHP 7 стал более чистый, удобный и понятный код, значительно увеличенная продуктивность и многое другое, что вы можете самостоятельно оценить, обновив виртуальный сервер до седьмой версии PHP.
timeweb.com
PHP 7. Обновленный синтаксис
Статья содержит новые возможности и особенности PHP7. Не все, но наиболее заметные и интересные.
Установка PHP7
Стабильные версии PHP 7 с официального сайта. Один из вариантов получения сборки PHP7 и его модулей можно — репозиторий fedoraproject.
Универсальный синтаксис работы с переменными
Одно из заметных нововведений этой версии — это «Универсальный синтаксис работы с переменными» (Uniform Variable Syntax).
Добавлены ранее недоступные операций с переменными:
// php 7 echo (‘get_’.$func_name)(); // 555
$foo()['bar']() [$obj1, $obj2][0]->prop
Это должно упростить обращение к необходимым данным и избавить от промежуточных переменных, но не стоит забывать, что злоупотребляя новым синтаксисом можно запутать код.
Из-за этого нововведения, интерпретатор станет иначе смотреть на некоторые конструкции. В официальном документе описаны случаи этих интерпретаций. Вот один из них:
$$foo['bar']['baz']; // исходный код // интерпретатор php 5 // сначала будет получено значение $foo['bar']['baz'] // затем это значение будет использовано в качестве имени переменной для получение результата ${$foo['bar']['baz']}; // интерпретатор php 7 // сначала будет получено значение $foo // затем это значение будет использовано в качестве имени переменной массива для обращения к элементу ['bar']['baz'] ($$foo)['bar']['baz'];
Теперь такие конструкции необходимо читать «слева-направо», последовательно передавая значение следующему оператору. Непосредственно это правило позволило существовать таким командам и читать их единственно правильным способом:
$foo()['bar']()
Это непременно необходимо учитывать при переходе на версию PHP 7.
Во всех подобных конструкциях необходимо добавить фигурные скобки, чтобы явно указать интерпретатору, как ему необходимо поступить:
Объявления возвращаемых типов (функции, методом или замыканием)
string, int, float, bool, array, callable, self (в методах класса), parent (в методах класса), Closure (замыкание), имя класса или имя интерфейса При попытке функцией вернуть другой тип — будет получена ошибка «Uncaught TypeError». При наследовании методов нужно соблюдать тип возвращаемых данных родительского метода.
Пример объявления функции с ожидаемым типом:
function return_array(): array{ return array('Hi!'); }
Типы переменных в определении функций (string, int, float, bool)
// php 7 function echo_number(int $number){ echo $number; } echo_number(123); // выведет 123 echo_number('text'); // при включенном режиме strict выкинет иключение: Uncaught TypeError: Argument 1 passed to echo_number()
Запрещено создавать классы с именами: `int`, `string`, `float`,`bool` Кстати именно это и позволило использовать эти типы при объявлении функций
Анонимные классы
$newClass = new class{ function who_i(){ echo 'Я метод анонимного класса'; } }; echo $newClass->who_i();
Поддержка юникод управляющих последовательностей
echo "u{1F427}"; // пингвин, обратите внимание, что кавычки должны быть двойные
Группировка объявлений `use`
// php 5 use somenamespaceClassA; use somenamespaceClassB as B; use function somenamespacefn_a; use function somenamespacefn_b; use const somenamespaceConstA; use const somenamespaceConstB; // php 7 use somenamespace{ClassA, ClassB as B}; use function somenamespace{fn_a, fn_b}; use const somenamespace{ConstA, ConstB};
Целочисленное деление intdiv()
echo intdiv(7, 2); // 3
Обещают рост производительности, благодаря новому низкоуровнему коду
Вы можете помочь и перевести немного средств на развитие сайта
itnan.ru
Изменения производительности PHP 7
PHP 7 будет вдвое быстрее? Ни в коем случае, этого не может быть. Как может язык иметь такое радикальное различие в скорости? Хорошо, есть ряд крупных изменений в ядре PHP, которые значительно уменьшают нагрузку на CPU и использование памяти. Исполнитель работает быстрее и потребляет значительно меньше памяти. Для иллюстрации, программа, ранее потребовавшая 300 миллионов инструкций CPU в PHP 5, потребует всего лишь около 200 миллионов в PHP 7; приблизительно 30% сокращение использования CPU. Кроме того, компилятор генерирует более эффективный байт-код (примерно на 30% меньше строк). В итоге это приведёт к намного более эффективному (и быстрому) коду.
В дополнение к тем главным изменения производительности, сам синтаксический анализатор языка был полностью переписан с помощью надлежащих принципов информатики. Синтаксический анализатор теперь основан на модели Абстрактного синтаксического дерева. В абстрактном синтаксическом дереве каждый узел дерева обозначает конструкцию, происходящую в исходном коде. Синтаксис абстрактен в том смысле, что он не представляет каждую деталь, появляющуюся в реальном синтаксисе. Например, группировка круглых скобок будет неявной, и синтаксические конструкции, такие как if-условие-then, могут быть представлены как единый узел с тремя ответвлениями.
Лексический анализатор теперь контекстно-зависим с поддержкой полузарезервированных слов. Это означает, что зарезервированные слова могут теперь использоваться в качестве имён для атрибутов, констант и методов в классах, интерфейсах и трейтов. Например, теперь вы можете иметь метод класса под названием «for» или «if».
Проблемы миграции на PHP 7
Наиболее важный вопрос, который стоит рассмотреть, прежде чем начать работу над перемещением всех ваших приложений, будет «на какие проблемы мне стоит обратить внимание при миграции на PHP 7?» К счастью, на самом деле не так много проблем, с которыми вы должны столкнуться, если у вас нет кода, написанного в те времена, когда PHP 4 был крутым.
Сейчас имеются некоторые новые зарезервированные слова, следовательно, вам нужно проверить и убедиться, что нет классом с такими именами:
bool;
int;
float;
string;
null;
false;
true;
resource;
object;
mixed;
numeric.
Определённые синтаксические переменные в PHP 7 будут иметь другое значение, в сравнении с PHP 5. Это изменение упоминалось как Uniform Variable Syntax. Вы, конечно, должны избегать писать код по такому уродливому и не самодокументирующемуся образу в любом случае, но, к сожалению, у нас у всех есть устаревший код. Здесь нужно быть внимательным, потому что не будут брошены исключения компиляции, т. к. такой синтаксис всё ещё допустим, только с другим смыслом. Вот некоторые примеры:
$$foo['bar']['blah'] // В PHP5 означает: ${$foo['bar']['blah']} // В PHP7: ($$foo)['bar']['blah'] /*************/ $foo->$bar['blah'] // В PHP5 означает: $foo->{$bar['blah']} // В PHP7: ($foo->$bar)['blah'] /*************/ $foo->$bar['blah']() //В PHP5 означает: $foo->{$bar['blah']}() //В PHP7: ($foo->$bar)['blah']() /*************/ Foo::$bar['blah']() //В PHP5 означает: Foo::{$bar['blah']}() //В PHP7: (Foo::$bar)['blah']()
Много устаревших (deprecated) функций наконец удалены, в том числе:
Расширение EREG;
Старое mysql расширение (надо надеяться вы уже используете mysqli или PDO);
Статический вызов нестатических методов;
Оператор & (например: $x =& new X;) (новые объекты не могут быть присвоены по ссылке, прим. перев.);
Модификатор ‘eval’ для функции preg_replace;
Конструкторы в стиле PHP 4 теперь считаются устаревшими (deprecated) (т.е. методы конструктора с именем класса).
Новые функции PHP 7
PHP 7 имеет много по-настоящему классных и давно ожидаемых функций. Вот некоторые самые интересные.
Fatal Errors
Все действия, приводившие к «фатальным ошибкам» в PHP 5, теперь бросают отлавливаемые исключения в PHP 7. Это означает, что вы всегда можете завершить работу корректно.
Встроенное покрытие кода
Phpdbg отладчик, встроенный в PHP 5.6 (о котором, к сожалению, почти никто не знает) был расширен поддержкой покрытия кода, которая отлично подходит для модульного тестирования.
Описание типа возврата
Теперь вы можете явно указывать тип возврата функции:
class Foo { public function bar() : int { //do whatever } }
В вышеупомянутом коде, если функция bar() вернёт значение не целочисленного типа, будет брошено исключение TypeError.
Scalar Type Hinting
Вероятно, более всего ожидаемая фича PHP 7 — это подсказки скалярного типа. К сожалению, она и самая неутешительная. Как можно было бы ожидать, синтаксис будет выглядеть следующим образом:
class Foo { public function bar(int $a, string $b, float $c) { var_dump($a, $b, $c); } }
Это выглядит здорово, точно так же, как мы все и хотели. Но, к сожалению, поведение по умолчанию вообще не такое, как ожидалось:
Как же так получилось? Функция не следовала строго типам и не выдала исключение или, хотя бы, предупреждение, как можно было бы ожидать, а просто привела к указанным типам. Это называется принудительное приведение скалярных типов (Coercive Scalar Type Declaration). Печально, но есть способ заставить строго проверять типы:
Отлично, проблема решена. Нет! Это, к сожалению, работает только в конкретном файле. Т.е. каждый файл должен явно объявить строгий ввод типов. Каждый файл. Вы не можете просто кинуть объявление в фронт-контроллере или загрузчике. Каждый файл.
Анонимные классы
Новый релиз PHP поддерживает анонимные классы. Вот как это выглядит:
class Foo { public function bar() { $x = new class($this) { private $blah; public function __construct(Foo $foo){ $this->foo = $foo; } }; } }
Отчасти, это может быть круто для написания модульных тестов, но по большей части это попадает под антипаттернт из Java-envy.
Оператор объединения со значением Null
Оператор объединения с Null должен быть довольно изящной новой фичей. Он работает как типичный оператор объединения, который вы могли использовать в запросе MySQL. Вот как это выглядит:
$foo = $bar ?? $blah ?? $blorp;
Результатом $foo будет первое не null значение в цепочке. Этот оператор, безусловно, может сохранить несколько строк кода и сделать их чище; отлично подходит для присвоения значений по умолчанию.
Оператор «космический корабль»
Следующая крутая фича известна как оператор «космический корабль» (первоначально назывался Combined Comparison Operator).
// Код в PHP 5: $result = ($a < $b) ? -1 : (($a > $b) ? 1 : 0); // Может быть уменьшен до такого в PHP 7: $result = $a <=> $b;
Вот список некоторых других функций, которых можно ожидать в PHP 7:
Zend Engine 3 (повышение производительности и поддержка 64-разрядного integer в Windows);
Процесс компиляции, основанный на AST;
Добавлено Closure::call();
Независимый от платформы побитовый сдвиг;
Делегация генераторов;
Возможность задания юникод символов в виде кодов;
Более простой и последовательный доступный CSPRNG API;
Сокращённый синтаксис для импорта нескольких элементов из пространства имён.
Источники:
Себастьян Бергман, создатель PHPUnit — Мюнхенская WebTech конференция 2015 года.
ahrameev.ru
Релиз PHP 7 запланирован на конец ноября 2015 года. В новой версии PHP появились интересные синтаксические плюшки, новые функции а также самые долгожданные изменения коснулись ядра интерпретатора — проект phpng, увеличивает скорость обработки скриптов практически вдвое по сравнению с PHP 5.x, плюс более эффективный менеджер памяти.
бенчмарк PHP7
Итак, что изменилось?
Combined Comparison Operator
Объединенный оператор сравнения (spaceship operator — корабль) — шоткат для операция трехстороннего сравнения двух операндов. Записывается в форме x = a <=> b. Возвращает одно из трех значений:
Оператор имеет одинаковый приоритет с операциями сравнения (`==`, `!=`, `===`, `!==`) и работает также как и операторы (`<`, `>=`, …). Также корабль не ассоциативен, то есть вы НЕ МОЖЕТЕ связать его с предыдущим вызовом (например `1 <=> 2 <=> 3`).
Объекты данным оператором сравнивать нельзя.
RFC: Combined Comparison Operator
?? — Оператор объединения со значением NULL
Оператор является сокращенным вариантом вызова isset в тернарном операторе ?:.
Пример
Null Coalesce Operator
Скалярные типы
Теперь в объявлениях переменных можно указывать их тип, даже если они являются скалярными (числа и строки). По умолчанию используется кастинг для приведения к заданному типу, если вы хотите имееть более жесткий контроль, можно включить strict режим, тогда при присвоении переменной значения, тип которого отличается от объявленного, будет выброшено исключение TypeError.
Типы:
Пример
Чтобы включить строгий strict режим проверки, нужно в начале (каждого) файла, добавить вызов
declare(strict_types=1);
Этот режим помимо обработки параметров влияет на возвращаемые значения! В строгом режиме запрещен любой кастинг кроме конвертации int => float (но не наоборот)
Важно: Strict mode работает только по месту вызова функции, то есть если описание функции находится в файле с объявлением strict_types=1, а вызывается она из другого файла без strict_types, то никакой строгой типизации не будет!
Необратимые изменения Классы с именами `int`, `string`, `float`, and `bool` теперь запрещены. Любое использование классов с этими названиями приведет к фатальным ошибкам.
Scalar Type Declarations
Объявления возращаемых типов
Добавлена возможность указать тип переменной, возвращаемой функцией или методом или замыканием.
Следующие типы поддерживаются:
При использовании наследования в классах, дочерние методы должны соблюдать объявления возвращаемых типов указанные в родительском классе / интерфейсе
Объявление метода `D::test() : B` вызовет `E_COMPILE_ERROR` потому что многовариантность не дозволена. Для того чтобы метод `D::test()` заработал, нужно указать что он возвращает нечто типа `A`.
В этот раз выполнение закончится эксепшном `TypeError`, потому что `null` не валидный возвратный тип, валидацию пройдет только экземпляр клааса `A`.
Return Type Declarations
Анонимные классы. Да!
Аноимные классы подходят для небольших задач. Из часто используют в языках например C# или Java для выполнения колбэков.
Анонимные классы позволяют делать тоже самое что и обычные классы: передавать данные в конструктор, наследовать другие классы, использовать трейты и т.п.
Анонимные классы поддерживают вложенность. Вложенные классы не будут иметь доступа к private/protected свойствам внешнего класса. Если такое необходимо, то нужно передать эти данные через конструктор вложенного класса.
Anonymous Classes
Поддержка юникод управляющих (escape-) последовательностей
Теперь в "строках" и объявлениях heredoc можно использовать uXXXX последовательности для описания символов юникод
Unicode Codepoint Escape Syntax
Метод call() у замыканий
Новый метод `call()` — шоткат для выполнения лямбды с прикрепленным объектом выполнения.
Closure::call
Фильтрация `unserialize()`
Новый функционал направлен на обеспечение безопасности сериализации объектов, предотвращает возможные code injection атаки, давая возможность разработчику указать какие классы могут обрабатываться, а какие игнорироваться.
Filtered unserialize()
Класс IntlChar
Новый класс IntlChar расширяет функциональность ICU (библиотека для локализации приложений International Components for Unicode) Класс содержит статические методы и константы для работы с юникодом.
Для использования должно быть установлено расширение Intl.
Необратимые изменения Классы в глобальном пространстве не могут называться IntlChar.
IntlChar class
Ожидания — Expectations
Обратно совместимое расширение для классической функции `утверждения` (assert).
Если первый параметр функции равен false, то бросается исключение / выводится ошибка с AssertionError (второй параметр).
Assert позволяет отлаживать скрипты, при этом в продакш окружении вызовы будут игнорировать интерпритатором, т.е. ничего не стоить в плане ресурсов.
Добавлены две настройки PHP.ini, по-умолчанию:
Expectations
Группировка объявлений `use`
Если у импортируемых классов общее пространство имен, можно объединить их импорт в группу (это относится к классам, функциям, константам, интерфейсам)
Group use Declarations
Возврат выражений в генераторах
Generator Return Expressions Позволяет использовать `return (expression)` в генераторах. Значение может быть получено вызовом метода `Generator::getReturn()`, только по завершении работы генератора.
Возможность явно вернуть последнее значение — хорошая возможность, которая упрощает работу с генераторами. Теперь не нужно проверять является ли значение последним. просто вызываем getReturn.
Generator Return Expressions
Делегирование генераторов
Generator Delegation Построено на основе возможности возврата выражений из генератора. Используется новый синтаксис:
<expr> будет вызываться до тех пор, пока возвращает данные, затем выполнения продолжится в вызывающем генераторе. Это позволяет разбить сложный генератор на несколько маленьких — что способствует более чистому коду и его реюзабельности.
Generator Delegation
Целочисленное деление intdiv()
Функция intdiv() позволяет делить числа на выходе получая целые числа.
Необратимые изменения Ключевое слово `intdiv` зарезервировано для глобального контекста.
Теперь возможно передавать параметры функции session_start(). Опции — стандартные настройки сессий из php.ini.
Добавился новая настройка для сессий `session.lazy_write`, по-умолчанию включена.
Introduce session_start() Options
www.skillz.ru
Зачем обновляться?
Одним из важнейших для меня и, наверное, для большинства web-разработчиков, изменений является рост производительности, сравнимое с производительностью HHVM. Как я писал ранее про оптимизацию скорости сайтов, смена версии PHP с 5.3 на 5.6 дала прирост скорости в 2 раза. Примерно такая же разница между версиями 5.6 и 7. Конечно, это не повод пренебрегать качеством кода, ведь, если считать в среднем по больнице, никакой самый быстрый компьютер не решит проблему плохого кода.
Расширения ereg и mysql полностью удалены, тогда как в предыдущих выпусках они были объявлены устаревшими. Прошло достаточно времени для того, чтобы проекты, отношение разработчиков к которым небезразлично, перестали от них зависеть и стали использовать хотя бы preg и mysqli. То же самое касается нескольких функций. Подробнее об устаревшем и удалённом в PHP 7 можно узнать на официальной wiki-документации.
Добавлены некоторые нововведения в синтаксис: строгая типизация, null-коалесцентный оператор, анонимные классы и многое другое. Но они навряд ли скоро появятся в проектах, рассчитанных на широкую массу, ввиду оглядки на обратную совместимость (например, CMS или фреймворки).
Производительность
В сети можно встретить множество синтетических и реальных тестов производительности разных версий PHP и HHVM, которые говорят только об одном — с каждой версией PHP веб становится быстрее и быстрее. Большинство же моих проектов работают на MODX Revolution и CodeIgniter 3. И, естественно, мне было любопытно узнать, что изменится после смены версии PHP.
MODX Evolution
Конечно, я бы мог проверить изменение производительности и для MODX Evolution, но в этой системе очень много кода, зависящего от, как я написал выше, удалённых расширений PHP. Однако, в версии MODX Evolution 1.1RC, подготовленной пользователем dmi3yy, появилась полная поддержка PHP 7.
MODX Revolution
Итак, я взял несколько сайтов, работающих на PHP 5.6. Измеряю я обычно количество запросов и время на генерацию страницы. Логично предположить, что количество запросов мало коррелирует с версией PHP, но лишним добавить и эту информацию не будет. Начиная с версии MODX Revolution 2.5 реализована полная совместимость с PHP 7. До этого была лишь частичная поддержка PHP 7, ввиду чего у меня не работала админка, хотя сам сайт отлично работал.
Сайт №1
Версия PHP
Кэширование
Запросов
Время, с
5.6
156
1.18
5.6
17
0.25
7
161
0.43
7
17
0.02
Сайт №2
PHP 5.6, без кэширования — 166 запросов, 0.66 с.
PHP 5.6, с кэшированием — 3 запроса, 0.06 с.
PHP 7, без кэширования — 166 запросов 0.34 с.
PHP 7, с кэшированием — 3 запроса, 0.04 с.
Сайт №3
PHP 5.6, без кэширования — 177 запросов, 1.82 с.
PHP 5.6, с кэшированием — 10 запросов, 0.39 с.
PHP 7, без кэширования — 177 запросов, 0.51 с.
PHP 7, с кэшированием — 10 запросов, 0.18 с.
Как видно, переключение версии PHP на последнюю положительно сказалось на производительности сайтов, увеличив её в 1.5-3 раза, а кое-где (например, на главной странице моего сайта) даже в 10 раз.
CodeIgniter 3
Я не могу похвастаться большим количеством проектов на CodeIgniter, но даже они обязывают внимательно относиться к производительности, так как количество статей и уникальных посетителей в месяц на одном из них исчисляется тысячами. На данный момент я занимаюсь оптимизацией и рефакторингом одного из них, где и без перехода на PHP 7 производительность кое-где возросла в несколько раз. В ближайшее время, когда я закончу текущую работу, я обязательно напишу о результатах смены версии.
Синтаксис
Синтаксис претерпел некоторые изменения, которые повлияют на обратную совместимость. Помимо официальной документации советую изучить примеры кода на GitHub, например, эти: https://github.com/afym/php-7-examples.
Кому не стоит обновляться
Не стоит обновляться тем, чьи проекты основаны на расширениях, удалённых в новом PHP. Также стоит поискать в интернете информацию о незначительных изменениях синтаксиса, так как есть моменты, нарушающие обратную совместимость. Конечно, таких случаев один на тысячу, если не реже, но лучше перестраховаться.
Хостинг-провайдеры
Выпуск PHP 7 состоялся относительно недавно, поэтому не все хостинг-провайдеры дают возможность опробовать новинку. Например, beget уже позволяет порадоваться скоростью, а в timeweb, наверное, считают PHP 7 недостаточно стабильным.
Чужой опыт
Tumblr
Вывод
За переход на последнюю версию PHP больше «За», чем «Против». Поэтому, если вам охота лёгкой оптимизации, обновляйте PHP.
quasi-art.ru
Наконец, в свет вышла PHP 7.1, новая минорная версия PHP, которая включает в себя ряд новых функций, изменений и исправления ошибок. В настоящей статье мы рассмотрим некоторые новые замечательные функции PHP 7.1, а именно:
Итерируемый псевдотип
Замыкания через функции обратного вызова
Синтаксис с квадратными скобками для списка ()
Поддержка ключей в списке
Видимость констант класса
Типы, допускающие значение null
Функции типа void
Захват исключений разных типов
Исключение «Слишком мало аргументов»
Для вашего удобства по ходу статьи я также буду ссылаться на соответствующие RFC.
Перед тем как мы начнем: А вы хотели бы попробовать PHP 7.1, не устраивая бардак с вашей текущей средой программирования? Тогда Docker – это ваш лучший друг! PHP 7.1 можно запросто настроить при помощи Docker, используя одно из этих образов.
Чтобы запустить контейнер 7.1:
docker run -v /Users/apple/Workplace/php/:/php -it php:7.1-rc bash
Это позволит загрузить (если на вашем локальном устройстве уже не сохранены подобные файлы) образы Docker для php:7.1-rc, после чего запустите контейнер и зайдите в него, используя всплывающие подсказки. Перенесите карты опций -v /Users/apple/Workplace/php/:/php из директории /Users/apple/Workplace/php центрального компьютера в директорию /php внутри контейнера Docker. Таким образом, все файлы внутри /Users/apple/Workplace/php будут доступны в директории контейнера /php. Теперь заходим в директорию /php.
cd /php
Супер! Теперь мы готовы опробовать новые функции PHP 7.1.
1. Итерируемый псевдотип
Предположим, у нас есть функция getUserNames, которая принимает перечень пользователей и возвращает их имена в виде списка.
function getUserNames($users) { return nikicmap(function($user){ return $user->name; }, $users); }
Примечание: Здесь мы используем библиотеку nikic/iter.
Параметр $users может быть представлен массивом или объектом с реализацией функции Traversable. До выхода PHP 7 было невозможно задать для данной функции какие-либо подсказки относительно типа, поскольку не существовало общего типа, который одновременно соответствовал бы и массиву и объекту Traversable.
Для решения данной проблемы в PHP 7.1 был реализован новый псевдотип iterable, который мы можем использовать для того, что задать значения типа для всего, что может быть итерировано с использованием foreach.
Теперь данная функция может принимать массивы, итерируемые объекты и генераторы.
См. RFC
2. Замыкания через функции обратного вызова
Данный функционал позволяет нам создавать механизмы замыкания через любую вызываемую функцию. Давайте посмотрим один пример, чтобы лучше с этим разобраться.
class MyClass { public function getCallback() { return Closure::fromCallable([$this, 'callback']); } public function callback($value) { echo $value . PHP_EOL; } } $callback = (new MyClass)->getCallback(); $callback('Hello World');
Наверняка, это не самый лучший пример, чтобы объяснить, зачем нам нужна эта функция, но при помощи него можно проиллюстрировать, как именно она работает. Применение функции Closure::fromCallable имеет ряд преимуществ по сравнению с более традиционными методами.
Улучшенный механизм исправления ошибок – При работе с Closure::fromCallable ошибки отображаются в нужном месте, а не там, где мы используем вызываемую функцию. Это значительно упрощает процесс исправления багов.
Перенос объемов – Пример выше будет нормально работать, даже если callback – это частный/защищенный (private/protected) метод MyClass.
Производительность – Подобная функция также повышает производительность, позволяя избежать избыточных проверок того, что данная вызываемая функция действительно является вызываемой.
См. RFC
3. Синтаксис с квадратными скобками для списка ()
Синтаксис коротких массивов был одной из потрясающих функций, добавленных в PHP 5.4, что сделало работу с массивами намного проще и удобнее. Теперь синтаксис краткого перечня позволяет нам использовать квадратные скобки вместо list() для присвоения массиву переменных.
До выхода PHP7 функция list() поддерживала только проиндексированные числами массивы, индекс которых начинается с нуля. Мы не могли использовать данную функцию с ассоциативными массивами.
Теперь новый функционал позволяет нам указывать ключи при деструктуризации массивов.
Константы класса помогают нам задать значимое имя для значения, которое используется в данном классе. Эти константы всегда были публичными, и доступ к ним можно было получить из внешнего класса. Но ведь мы далеко не всегда хотим выставлять их на обозрение внешнему миру, не так ли? В версии PHP7.1 мы можем приписать константам класса модификаторы видимости точно так же, как мы делаем с методами и свойствами.
class PostValidator { protected const MAX_LENGTH = 100; public function validateTitle($title) { if(strlen($title) > self::MAX_LENGTH) { throw new Exception("Title is too long"); } return true; } }
Здесь константа MAX_LENGHT является внутренней константой класса PostValidator, и мы не хотим, чтобы это значение было доступно для внешнего мира.
См. RFC
6. Типы, допускающие значение null
Этот функционал позволяет нам задать подсказки относительно типа функции, позволяя при этом использовать значения null в качестве параметра или возврата. Мы можем задать параметру или результату тип Null, поставив знак вопроса (?) перед подсказкой типа.
function sayHello(?string $name) { echo "Hello " . $name . PHP_EOL; } sayHello(null); // Hello sayHello("John"); //Hello John
Точно также это работает и для возврата.
class Cookie { protected $jar; public function get(string $key) : ?string { if(isset($this->jar[$key])) { return $this->jar[$key]; } return null; } }
См. RFC
7. Функции типа void
Начиная с версии PHP 7, мы можем задавать тип значения, которое функция должна возвращать на выходе. Иногда бывают случаи, когда необходимо указать, что функция не должна возвращать никакого значения вообще.
class Cookie { protected $jar; public function set(string $key, $value) : void { $this->jar[$key] = $value; } }
Когда для возврата задано значение void, функция либо должна упускать оператор возврата вообще, либо может иметь пустой оператор возврата. Функция не должна возвращать никаких значений.
См. RFC
8. Захват исключений разных типов
При работе с исключениями иногда нам может потребоваться обрабатывать несколько исключений одним и тем же способом. Обычно для работы с разными типами исключений нам пришлось бы создать несколько отдельных блоков захвата.
try { // somthing } catch(MissingParameterException $e) { throw new InvalidArgumentException($e->getMessage()); } catch(IllegalOptionException $e) { throw new InvalidArgumentException($e->getMessage()); }
В версии PHP 7.1 мы можем работать с множественными исключениями в рамках одного общего блока захвата.
Множественные исключения разделяются при помощи одного символа конвейеризации. Это позволит избежать дублирования одного и того же кода для работы с различными типами исключений.
Read RFC
9. Исключение «Слишком мало аргументов»
Как и в PHP 7, мы можем вызвать функцию с меньшим количеством аргументов, чем фактически требуется. В таком случае среда только выдаст предупреждение об отсутствующих аргументах, но продолжит выполнение функции. Иногда это может привести к странному или неожиданному поведению функции.
В версии PHP 7.1 вызов функции без необходимых параметров приведет к срабатыванию исключения ошибки ArgumentCountError.
function sayHello($name) { echo "Hello " . $name; } sayHello(); // Fatal error: Uncaught ArgumentCountError: Too few arguments to function sayHello(), 0 passed in...
Срабатывание исключения поможет нам немедленно решать подобные проблемы, избегая неожиданного поведения функции. Однако, данное изменение является несовместимым с более ранними версиями и может повредить вашим текущим приложениями. Поэтому рекомендуем убедиться, что с вашими приложениями все в порядке, перед тем как переходить на более новую версию.
См. RFC
Итоги
В рамках данной статьи мы обсудили некоторые важные функции, добавленные в версию PHP 7.1. Для того чтобы узнать больше о новых функциях и изменениях PHP 7.1, рекомендуем ознакомиться с официальным руководством по переходу с более ранних версий. Я пропустил какую-нибудь важную функцию? Напишите в комментариях ниже 🙂
devacademy.ru
Стоит ли переходить на PHP 7?
На данный момент самое простое, что вы можете сделать для увеличения производительности сайта, это перейти на PHP 7.0.x. Прирост скорости также зависит от того, как написан ваш проект. Если вы еще сомневаетесь, покажем некоторые сравнения:
Бенчмарки PHP 5.6 vs PHP 7 для нектоторых фреймфорков (Zend framework, Magento, Drupal, Mediawiki, WordPress, Laravel, SugarCRM и др):
По всем фреймворкам прирост производительности значительный. Давайте посмотрим, как обстоит дело с функциями и конструкциями ядра: