Русский
Русский
English
Статистика
Реклама

Php developers

Перевод Эволюция PHP от 5.6 до 8.0 (Часть 1)

20.10.2020 14:07:37 | Автор: admin

Перевод статьи подготовлен в преддверии старта курсаBackend-разработчик на PHP.

Шпаргалка по изменениям в PHP v7.x

PHP_v8.0PHP_v8.0

После релиза PHP версии 7.3 я решил уделить больше внимания развитию PHP: что собственно развивается и в каком направлении искать понимание потенциала и оптимизации этого невероятно популярного языка программирования.

В результате поиска лаконичного списка функций, реализованных PHP за время разработки PHP v7.x, я решил составить список сам - приятное дополнение, которое, я думаю, кому-то тоже может пригодиться.

За основу мы возьмем PHP 5.6 и рассмотрим, что было добавлено и изменено. Я также добавил везде где смог ссылки на официальную документацию по каждой из упомянутых фич, поэтому, если вам вдруг понадобится получить более подробную информацию - пожалуйста.

PHP 7.0

Поддержка анонимных классов

Анонимный класс может использоваться вместо именованного класса:

  • Когда класс не нужно документировать

  • Когда класс во время выполнения используется только один раз

new class($i) {   public function __construct($i) {       $this->i = $i;   }}

Функция целочисленного деления - безопасный способ деления (даже на 0).

Возвращает целочисленный результат деления первого операнда на второй. Если делитель (второй операнд) равен нулю, функция пробрасывает EWARNING и возвращает FALSE.

intdiv(int $numerator, int $divisor)

Добавлен новый оператор объединения с null - ??

$x = NULL;$y = NULL;$z = 3;vardump($x ?? $y ?? $z); // int(3)$x = ["c" => "meaningfulvalue"];vardump($x["a"] ?? $x["b"] ?? $x["c"]); // string(16) "meaningfulvalue"

Добавлен новый оператор - spaceship (космический корабль)(<=>)

Используется для оптимизации и упрощения операций сравнения.

// Преждеf unction orderfunc($a, $b) {return ($a < $b) ? -1 : (($a > $b) ? 1 : 0);}// Используя оператор <=>function orderfunc($a, $b) {return $a <=> $b;}

Объявления скалярных типов

Это всего лишь первый шаг к реализации преимуществ более строго типизированного языка программирования в PHP - v0.5.

function add(float $a, float $b): float {return $a + $b;}add(1, 2); // float(3)

Объявления типов возвращаемых значений

Добавлена возможность возвращать типы помимо скалярных - классы, включая наследование. Хех, упустив при этом возможность сделать это необязательным (что будет введено в v7.1 :))

interface A {static function make(): A;}class B implements A {static function make(): A {return new B();}}

Групповые объявления use

// Явный use синтаксис:use FooLibrary\Bar\Baz\ClassA;use FooLibrary\Bar\Baz\ClassB;use FooLibrary\Bar\Baz\ClassC;use FooLibrary\Bar\Baz\ClassD as Fizbo;// Групповой use синтаксис:use FooLibrary\Bar\Baz{ ClassA, ClassB, ClassC, ClassD as Fizbo };

Делегация генератора

В теле функций генераторов разрешен следующий новый синтаксис:

yield from <expr>

Повышение производительности

PHP 7 почти вдвое быстрее, чем PHP 5.6.

Значительное сокращение использования памяти

Как видно из диаграмм, PHP 7.0 стал громадным шагом вперед с точки зрения производительности и использования памяти. Для страницы с запросами к базе данных версия 7.0.0 более чем в 3 раза быстрее, чем 5.6 с включенным opcache в 2.7 раза быстрее без opcache! С точки зрения использования памяти разница тоже существенная!

Интерфейс Throwable

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

Error и Exception теперь реализуют Throwable.

Иерархия Throwable:

interface Throwable|- Error implements Throwable|- ArithmeticError extends Error|- DivisionByZeroError extends ArithmeticError|- AssertionError extends Error|- ParseError extends Error|- TypeError extends Error|- ArgumentCountError extends TypeError|- Exception implements Throwable|- ClosedGeneratorException extends Exception|- DOMException extends Exception|- ErrorException extends Exception|- IntlException extends Exception|- LogicException extends Exception|- BadFunctionCallException extends LogicException|- BadMethodCallException extends BadFunctionCallException|- DomainException extends LogicException|- InvalidArgumentException extends LogicException|- LengthException extends LogicException|- OutOfRangeException extends LogicException|- PharException extends Exception|- ReflectionException extends Exception|- RuntimeException extends Exception|- OutOfBoundsException extends RuntimeException|- OverflowException extends RuntimeException|- PDOException extends RuntimeException|- RangeException extends RuntimeException|- UnderflowException extends RuntimeException|- UnexpectedValueException extends RuntimeException

Внимание! Вы можете реализовать Throwable только через Error и Exception.

Синтаксис кодирования Unicode \u{xxxxx}

echo "\u{202E}Reversed text"; // выводит Reversed textecho "maana"; // "ma\u{00F1}ana"echo "maana"; // "man\u{0303}ana" "n" комбинирована с символом ~ (U+0303)

Чувствительный к контексту лексер

С этим нововведением глобально зарезервированные словами стала полу-зарезервированными:

callable class trait extends implements static abstract final public protected private constenddeclare endfor endforeach endif endwhile and global goto instanceof insteadof interfacenamespace new or xor try use var exit list clone include includeonce throw arrayprint echo require requireonce return else elseif default break continue switch yieldfunction if endswitch finally for foreach declare case do while as catch die self parent

За исключением того, что по-прежнему запрещено определять константу класса с именем class из-за разрешения имени класса ::class.

Выражения return в генераторах

Единый синтаксис переменных

Поддержка уровня вложенности для функции dirname()

PHP 7.1

Обнуляемые типы

function answer(): ?int {return null; // ок}function answer(): ?int {return 42; // ок}function answer(): ?int {return new stdclass(); // ошибка}function say(?string $msg) {if ($msg) {echo $msg;}}say('hello'); // ок - выводит hellosay(null); // ок - ничего не выводитsay(); // ошибка - отсутствует параметрsay(new stdclass); // ошибка - не подходящий тип

Ничего не возвращающие функции

function shouldreturnnothing(): void {return 1; // Fatal error: A void function must not return a value}

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

Функция с типом возврата void или void функция может либо возвращать неявно, либо иметь оператор возврата без значения:

function lacksreturn(): void {// валидно}

Псевдотип Iterable

Обычно функция принимает или возвращает array или объект, реализующий Traversable, который используется с foreach. Однако, поскольку array является примитивным типом, а Traversable - интерфейсом, в настоящее время нет способа использовать объявление типа для параметра или возвращаемого типа, чтобы указать, что значение является итерируемым.

function foo(iterable $iterable) {foreach ($iterable as $value) {// }}

iterable также может использоваться в качестве возвращаемого типа, чтобы указать, что функция вернет итерируемое значение. Если возвращаемое значение не является массивом или экземпляром Traversable, будет проброшена TypeError.

function bar(): iterable {return [1, 2, 3];}

Параметры, объявленные как iterable могут использовать null или массив в качестве значения по умолчанию.

function foo(iterable $iterable = []) {// }

Closure из callable

class Closure {public static function fromCallable(callable $callable) : Closure {}}

Синтаксис квадратных скобок для деструктуририрующего присваивания в массиве

$array = [1, 2, 3];// Присваивает $a, $b и $c значения соответствующих элементов массива $array с ключами, пронумерованными от нуля[$a, $b, $c] = $array;// Присваивает $a, $b и $c значения элементов массива $array с ключами "a", "b" и "c" соответственно["a" => $a, "b" => $b, "c" => $c] = $array;

Синтаксис квадратных скобок для list()

$powersOfTwo = [1 => 2, 2 => 4, 3 => 8];list(1 => $oneBit, 2 => $twoBit, 3 => $threeBit) = $powersOfTwo;

Видимость констант класса

class Token {    // Константы по умолчанию public   const PUBLICCONST = 0;// Константы также могут иметь определенную пользователем видимостьprivate const PRIVATECONST = 0;protected const PROTECTEDCONST = 0;public const PUBLICCONSTTWO = 0;// Константы могут иметь только один список объявлений видимостиprivate const FOO = 1, BAR = 2;}

Перехват нескольких типов исключений

try {// Какой-то код} catch (ExceptionType1 | ExceptionType2 $e) {// Код обработки исключения} catch (\Exception $e) {// }

В ближайшие дни мы опубликуем вторую часть статьи, а прямо сейчас приглашаем вас записаться на бесплатный вебинар в рамках которого наши эксперты ответят на все интересующие вас вопросы.

Читать ещё:

Подробнее..

Перевод Эволюция PHP от 5.6 до 8.0 (Часть 2)

25.10.2020 22:04:29 | Автор: admin

Перевод статьи подготовлен в преддверии старта курсаBackend-разработчик на PHP

(Читать первую часть)


PHP 7.2

Расширение типа параметра

<?phpclass ArrayClass {public function foo(array $foo) { /*  / }}// Этот RFC предлагает разрешить расширение типа до нетипизированного, т.е. в качестве параметра может быть передан любой тип.// Любые ограничения типа могут быть отработаны с помощью пользовательского кода в теле метода.class EverythingClass extends ArrayClass {public function foo($foo) { /  / }}

Подсчет неисчислимых объектов

Вызов функции count() для скаляра или объекта, который не реализует интерфейс Countable возвращает 1 (что нелогично).

В этой версии добавлено предупреждение при вызове count() с параметром, который является скаляром, null или объектом, который не реализует Countable.

Завершающие запятые в групповом use синтаксисе

use Foo\Bar{ Foo, Bar, Baz, };

Хеширование пароля с помощью Argon2

Существующие функции password_* обеспечивают упрощенный интерфейс с прямой совместимостью для хеширования паролей. Этот RFC предлагает для использования в функциях password_* реализацию Argon2i (v1.3) в качестве безопасной альтернативы.

Отладка эмуляции подготовленного запроса PDO

$db = new PDO();// работает с запросами без связанных значений$stmt = $db->query('SELECT 1');vardump($stmt->activeQueryString()); // => string(8) "SELECT 1"$stmt = $db->prepare('SELECT :string');$stmt->bindValue(':string', 'foo');// возвращает не распаршенный запрос до выполненияvardump($stmt->activeQueryString()); // => string(14) "SELECT :string"// возвращает распаршенный запрос после выполнения$stmt->execute();vardump($stmt->activeQueryString()); // => string(11) "SELECT 'foo'"

PHP 7.3

JSON_THROW_ON_ERROR

Отсутствие адекватного способа обработки ошибок при использовании JSON было проблемой довольно долгое время, и веб-разработчики во всем мире рассматривали это как огромный недостаток языка.

До PHP v7.2 нам нужно было использовать обходное решение, чтобы получать ошибки из JSON, и оно не отличалось ни надежностью, ни изяществом в своей работе;

Вот пример:

jsondecode("{");jsonlasterror() === JSONERRORNONE // результат falsejsonlasterrormsg() // результат "Syntax error"

Итак, давайте же посмотрим, как мы можем использовать этот новый синтаксический сахар:

use JsonException;try {   $json = json_encode("{", JSON_THROW_ON_ERROR);   return base64_encode($json);} catch (JsonException $e) {   throw new EncryptException('Could not encrypt the data.', 0, $e);}

Как видно из предыдущего кода, функция json_encode теперь имеет необязательный параметр JSON_THROW_ON_ERROR - с ним она перехватит ошибку и отобразит ее с помощью следующих методов исключений:

$e->getMessage(); // как jsonlasterrormsg()

$e->getCode(); // как jsonlasterror()

Добавлена функция iscountable

// До:if (isarray($foo) || $foo instanceof Countable) {// $foo является countable}// Послеif (iscountable($foo)) {// $foo является countable}

Добавлены функции массива arraykeyfirst (), arraykeylast ()

$firstKey = arraykeyfirst($array);$lastKey = arraykeylast($array);

Добавлена встроенная поддержка samesite cookie

Теперь есть две опции для cookie, использующего флаг samesite: Lax (нестрогий) и Strict (строгий). Разница между Lax и Strict заключается в доступности файла cookie в запросах, исходящих из другого регистрируемого домена с использованием метода HTTP GET. Файлы cookie, использующие Lax, будут доступны по GET, исходящему из другого регистрируемого домена, тогда как файлы cookie, использующие Strict, не будут доступны в GET запросе. Для POST методов разницы нет: браузер не должен разрешать доступ к cookie в POST запросе, исходящем из другого регистрируемого домена.

Set-Cookie: key=value; path=/; domain=example.org; HttpOnly; SameSite=Lax|Strict

Обновление PCRE до PCRE2

Улучшение хеширования паролей с помощью Argon2

Существующие password_* функции обеспечивают упрощенный интерфейс с прямой совместимостью для хеширования паролей. Этот RFC предлагает для использования в password_* функциях реализацию Argon2id в качестве безопасной альтернативы первоначально предложенному Argon2i.

Завершающая запятая в вызовах функций

$newArray = array_merge($arrayOne,$arrayTwo,['foo', 'bar'],// в вызовах функций можно использовать запятую);

Присвоение по ссылкам в list()

$array = [1, 2];list($a, &$b) = $array;

Это эквивалентно следующему:

$array = [1, 2];$a = $array[0];$b =& $array[1];

Устарели не чувствительные к регистру константы

PHP 7.4

Типизированные свойства

class User {   public int $id;   public string $name;   public function __construct(int $id, string $name) {       $this->id = $id;       $this->name = $name;   }}

FFI (Foreign Function Interface)

FFI - одна из фич, которые сделали Python и LuaJIT очень полезными для быстрого прототипирования. Он позволяет вызывать функции C и использовать типы данных C из чисто скриптового языка и, следовательно, более продуктивно разрабатывать системный код. Для PHP FFI открывает способ писать расширения PHP и биндинги к библиотекам C на чистом PHP.

Присваивающий оператор объединения с Null

// Следующие строчки делают одно и то же$this->request->data['comments']['userid'] = $this->request->data['comments']['userid'] ?? 'value';// Вместо повторения переменных с длинными именами используется присваивающий оператор объединения$this->request->data['comments']['user_id'] ??= 'value';

Предварительная загрузка

PHP использует кеши опкодов уже много лет (APC, Turck MMCache, Zend OpCache). Они дают значительный прирост производительности, ПОЧТИ полностью устраняя накладные расходы на перекомпиляцию PHP кода. Предварительная загрузка будет контролироваться только одной новой директивой php.ini - opcache.preload. Используя эту директиву, мы определяем PHP файл, который возьмет на себя задачу предварительной загрузки. После загрузки этот файл полностью выполняется - и может предварительно загружать другие файлы, инклюдя их или используя функцию opcachecompilefile() .

Всегда доступное хеш расширение

Это делает хеш расширение (ext/hash) всегда доступным, схожим образом с date. Хеш расширение предоставляет очень ценную утилиту со множеством алгоритмов хеширования, которая чрезвычайно полезна в современных приложениях, причем не только в коде юзерленда, но и во многом случаях во внутреннем коде.

На пути к PHP 8.0

JIT

В двух словах, когда вы запускаете PHP программу, Zend Engine парсит код в абстрактное синтаксическое дерево (abstract syntax tree - AST) и преобразует его в опкоды. Опкоды - это единицы выполнения для виртуальной машины Zend (Zend VM). Опкоды довольно низкоуровневые, поэтому их гораздо быстрее переводить в машинный код, чем исходный код PHP. В ядре PHP есть расширение OPcache для кеширования этих опкодов.

JIT - это метод, который компилирует части кода во время выполнения, так что вместо них можно использовать скомпилированную версию.

Это одна из последних и самых больших стратегий оптимизации PHP, которая все еще актуальна. Инженеры PHP с нетерпением ждут возможности увидеть, сколько новый подход сможет выжать из их приложений. Очень хочу увидеть это сам.

Стабильные typeErrors для внутренних функций

Сделайте так, чтобы API синтаксического анализа внутренних параметров всегда генерировали TypeError, если синтаксический анализ завершается неудачно. Следует отметить, что это также включает ArgumentCountError (дочерний элемент TypeError) для случаев, когда было передано слишком мало/много аргументов.

Сравнение производительности

Я составил простой тест, который поможет легко сравнить производительность различных версий PHP (с использованием Docker). Он даже позволил бы легко проверять производительность новых версий PHP, просто добавляя новые имена контейнеров.

Тестировалось на Macbook pro, Intel Core i7 2,5 ГГц.

PHP version : 5.6.40--------------------------------------test_math                 : 1.101 sec.test_stringmanipulation   : 1.144 sec.test_loops                : 1.736 sec.test_ifelse               : 1.122 sec.Mem: 429.4609375 kb Peak mem: 687.65625 kb--------------------------------------Total time:               : 5.103PHP version : 7.0.33--------------------------------------test_math                 : 0.344 sec.test_stringmanipulation   : 0.516 sec.test_loops                : 0.477 sec.test_ifelse               : 0.373 sec.Mem: 421.0859375 kb Peak mem: 422.2109375 kb--------------------------------------Total time:               : 1.71PHP version : 7.1.28--------------------------------------test_math                 : 0.389 sec.test_stringmanipulation   : 0.514 sec.test_loops                : 0.501 sec.test_ifelse               : 0.464 sec.Mem: 420.9375 kb Peak mem: 421.3828125 kb--------------------------------------Total time:               : 1.868PHP version : 7.2.17--------------------------------------test_math                 : 0.264 sec.test_stringmanipulation   : 0.391 sec.test_loops                : 0.182 sec.test_ifelse               : 0.252 sec.Mem: 456.578125 kb Peak mem: 457.0234375 kb--------------------------------------Total time:               : 1.089PHP version : 7.3.4--------------------------------------test_math                 : 0.233 sec.test_stringmanipulation   : 0.317 sec.test_loops                : 0.171 sec.test_ifelse               : 0.263 sec.Mem: 459.953125 kb Peak mem: 460.3984375 kb--------------------------------------Total time:               : 0.984PHP version : 7.4.0-dev--------------------------------------test_math                 : 0.212 sec.test_stringmanipulation   : 0.358 sec.test_loops                : 0.205 sec.test_ifelse               : 0.228 sec.Mem: 459.6640625 kb Peak mem: 460.109375 kb--------------------------------------Total time:               : 1.003

Если вы хотите запустить тесты сами, вы можете найти код в репозитории ниже.

meskis/php-bench

Бенчмарки от PHP 5.6 и выше

Мне очень понравилась компиляция визуальной производительности всех основных версий от 5.6 и выше от servebolt.com. См. результаты в таблицах ниже.

Сводка по производительности

PHP 7.0.0 стал важной вехой со значительно улучшенной производительностью и меньшим использованием памяти, но у специалистов по сопровождению уже PHP попросту заканчиваются идеи по его улучшению. Один из оставшихся моментов - JIT (Just in time) компиляция. И она придет с PHP 8.0.

Направление развития

В версиях PHP 7.x прослеживается путь к более типизированному (и немного более объектному) и современному языку программирования. PHP любит перенимать изящные и полезные функции других языков программирования.

Вскоре мы можем увидеть еще несколько замечательных функций, таких как:

С их появлением в конвейере разработчики PHP присоединятся к группе пользователей современного языка. Идеального языка не существует, но PHP уверенно прокладывает путь в будущее.

TL;DR

Чтобы еще больше все сократить, я выбрал наиболее важные по моему мнению изменения, учитывая последнюю версию версию на момент написания статьи - PHP 7.3. Вот они:

Ссылки

https://wiki.php.net/rfc

https://www.cloudways.com/blog/php-5-6-vs-php-7-symfony-benchmarks/

https://servebolt.com/articles/wordpress-5-0-php-7-2-vs-php-7-3-performance-and-speed-benchmark/


Узнать подробнее о курсе.


Подробнее..

Категории

Последние комментарии

  • Имя: Макс
    24.08.2022 | 11:28
    Я разраб в IT компании, работаю на арбитражную команду. Мы работаем с приламы и сайтами, при работе замечаются постоянные баны и лаги. Пацаны посоветовали сервис по анализу исходного кода,https://app Подробнее..
  • Имя: 9055410337
    20.08.2022 | 17:41
    поможем пишите в телеграм Подробнее..
  • Имя: sabbat
    17.08.2022 | 20:42
    Охренеть.. это просто шикарная статья, феноменально круто. Большое спасибо за разбор! Надеюсь как-нибудь с тобой связаться для обсуждений чего-либо) Подробнее..
  • Имя: Мария
    09.08.2022 | 14:44
    Добрый день. Если обладаете такой информацией, то подскажите, пожалуйста, где можно найти много-много материала по Yggdrasil и его уязвимостях для написания диплома? Благодарю. Подробнее..
© 2006-2024, personeltest.ru