Перейти к основному содержимому

5.07. История PHP

Разработчику Архитектору

История PHP

Зарождение PHP

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

В отличие от многих языков, созданных в академической среде (например, Haskell, ML) или в рамках крупных корпоративных исследовательских программ (Java, C#), PHP возник спонтанно — как инструмент для личных нужд, и лишь позже трансформировался в глобальную инфраструктурную технологию.

Его суть изначально заключалась в встраиваемости — в способности быть вшитым непосредственно в HTML-документы, сохраняя при этом минимальный порог вхождения для веб-мастеров, знакомых с базовыми принципами разметки и логики. Эта идея определила как его взлёт, так и многие критические замечания, сопровождавшие его на протяжении десятилетий.

Назывался язык первоначально как PHP/FI (Personal Home Page / Form Interpreter), и многие до сих пор так его и запоминают - персональная домашняя страница. Технически, это скриптовый язык для веб-приложений, и его история как раз тесно связано с развитием сети.


Веб-программирование до PHP

К моменту появления PHP в 1994–1995 годах веб находился на стадии перехода от простых гипертекстовых документов к интерактивным сервисам. Первыми средствами динамического генерирования контента были:

  • CGI (Common Gateway Interface) — стандарт, позволявший веб-серверу передавать HTTP-запросы внешней программе и возвращать её вывод клиенту. Программы могли быть написаны на любом языке, способном работать в командной строке (C, Perl, shell-скрипты). Однако CGI обладал фундаментальными ограничениями: каждый запрос порождал отдельный процесс, что резко снижало производительность при высокой нагрузке и усложняло управление состоянием между запросами.

  • Perl — де-факто стандарт для веб-скриптинга в середине 1990-х. Благодаря мощным средствам обработки текста, регулярным выражениям и широкому распространению, Perl стал основным инструментом написания CGI-скриптов. Однако его синтаксис, богатый, но насыщенный контекстно-зависимыми конструкциями ($, @, %, $_, @_, grep, map, ссылки и т.д.), представлял значительный барьер для новичков — особенно среди веб-дизайнеров и системных администраторов, не имевших опыта в классическом программировании.

Кроме того, существовала потребность в среде, где логика приложения и представление не были бы строго разделены — в отличие от современных MVC-подходов, тогдашние задачи (формы обратной связи, гостевые книги, счётчики посещений) требовали быстрого внедрения кода непосредственно в HTML-страницы. Идея «вставки» вычислений в разметку, хотя и критикуемая позже с точки зрения архитектурной чистоты, была прагматична и соответствовала практическим условиям эпохи.


PHP/FI и рождение Personal Home Page Tools

В 1994 году датский программист Расмус Лёрдфорд (Rasmus Lerdorf), работавший в то время в компании IBM и параллельно ведший личный сайт, столкнулся с необходимостью отслеживать посещаемость своих резюме и собирать данные из форм.

Для этого он написал набор скриптов на языке C, которые обрабатывали HTTP-запросы и взаимодействовали с HTML-формами. Чтобы упростить повторное использование кода, он обернул эти функции в интерпретируемый скриптовый язык — по сути, надстройку над C-библиотекой. Так в 1995 году появился проект под названием PHP/FI (Personal Home Page / Forms Interpreter).

PHP/FI была интерпретируемая система шаблонов с встроенной логикой: разработчик вставлял в HTML-файлы специальные теги вида <!--...--> или <php>...</php> (в ранних версиях), внутри которых размещал вызовы предопределённых функций: echo, if, while, работа с переменными ($var), доступ к данным формы ($FORM_xxx), простые операции с файлами и базами данных (поддерживался только mSQL — mini SQL, лёгкий СУБД того времени).

Синтаксис был предельно минималистичен.

Например, скрипт для отображения текущей даты и имени пользователя из формы мог выглядеть так:

<HTML>
<BODY>
Привет, <!--$echo $FORM_name;-->!
Сегодня: <!--$echo date("Y-m-d");-->
</BODY>
</HTML>

PHP/FI характерен отсутствием компиляции: каждый запрос приводил к парсингу и интерпретации скрипта «на лету». Это замедляло выполнение, но упрощало развёртывание: не требовалось отдельного этапа сборки, обновление кода происходило мгновенно после сохранения файла.

В 1995 году Лёрдфорд опубликовал исходный код PHP/FI 1.0 под лицензией, близкой к открытой (хотя формально это была «free for non-commercial use» лицензия), что вызвало интерес в узких кругах веб-энтузиастов. Уже к 1996 году PHP/FI 2.0 обрёл более структурированный синтаксис, поддержку переменных, циклов, ветвлений и — принципиально — возможность расширения через встраиваемые C-функции. Это позволило сообществу начать добавлять поддержку новых СУБД (в частности, MySQL), а также модулей для работы с изображениями, почтой и другими внешними сервисами.

Несмотря на растущую популярность, PHP/FI по-прежнему оставался инструментом, а не языком. Его философия была утилитарна: «сделать конкретную задачу как можно проще». Отсутствие строгой типизации, слабая проверка ошибок, глобальная область видимости по умолчанию — всё это считалось особенностями удобства.


PHP 3 (1997–1998)

Переломный момент наступил в 1997 году, когда два израильских программиста — Зеев Сураски (Zeev Suraski) и Андри Мутафчийски (Andi Gutmans) — начали использовать PHP/FI для реализации университетского проекта по электронной торговле. Столкнувшись с ограничениями интерпретатора (отсутствие поддержки пользовательских функций с параметрами, слабая расширяемость), они предложили Лёрдфорду полностью переписать ядро.

Результатом стала PHP 3.0, выпущенная в июне 1998 года. Это был уже полноценный интерпретируемый язык с встраиваемым синтаксисом, обладающий:

  • Чётко определённой грамматикой на основе yacc/bison;
  • Поддержкой пользовательских функций (включая рекурсию);
  • Модульной архитектурой — расширения подключались динамически (через .so/.dll);
  • Встроенной поддержкой множества СУБД: MySQL, PostgreSQL, Oracle, Sybase, Informix, ODBC;
  • Примитивной, но работающей системой обработки ошибок;
  • Встроенным API для сессий и кук.

Синтаксис PHP 3 стал ближе к языку C: фигурные скобки для блоков, схожие операторы (if, for, while, switch), функции объявлялись через function name(...) { ... }. Однако сохранялась ключевая черта: возможность свободного смешивания PHP-кода и HTML:

<?php
if ($user_logged_in) {
?>
<p>Добро пожаловать, <?= htmlspecialchars($username) ?>!</p>
<?php
} else {
?>
<form action="login.php" method="post">
<input type="text" name="login">
<input type="password" name="pass">
<input type="submit">
</form>
<?php
}
?>

Именно в PHP 3 произошла официальная смена названия: аббревиатура PHP была переосмыслена как PHP: Hypertext Preprocessor — рекурсивная акронимия, подчёркивающая природу языка как препроцессора гипертекста. Это было отражение новой архитектурной парадигмы: PHP стал модулем веб-сервера (в первую очередь Apache через mod_php), а не отдельной CGI-программой. Это резко повысило производительность: интерпретатор загружался один раз при старте сервера и оставался в памяти, обрабатывая запросы без порождения новых процессов.

К 1998 году PHP 3 использовался уже на десятках тысяч сайтов. Его успех объяснялся сочетанием трёх факторов:

  1. Низкий порог вхождения: зная HTML и немного логики, можно было начать писать рабочие скрипты за часы, а не недели.
  2. Готовность к работе «из коробки»: дистрибутивы Linux (Red Hat, Debian) стали включать PHP и Apache в базовые наборы, хостинги начали предлагать «PHP-хостинг» как стандартную опцию.
  3. Сообщество и открытость: исходный код был доступен, баги исправлялись быстро, модули писались энтузиастами.

Важно отметить: в PHP 3 ещё не было ООП, исключений, пространств имён. Переменные были слабо типизированы (все скаляры — string, int, float, bool — могли неявно приводиться друг к другу), отсутствовала строгая проверка аргументов функций. Это позволяло писать быстро, но создавало предпосылки для трудноуловимых ошибок — что позже станет постоянной темой критики.


PHP 4 и движок Zend Engine (1999–2000)

К 1999 году рост популярности PHP обнажил узкие места интерпретатора PHP 3: медленная обработка, высокое потребление памяти, отсутствие механизма повторного использования скомпилированного кода. Сураски и Мутафчийски, основав в 1999 году компанию Zend Technologies (от Zeev и Andi), приступили к разработке нового ядра.

Результатом стал Zend Engine — виртуальная машина и компилятор, лёгшие в основу PHP 4, выпущенного 22 мая 2000 года.

Zend Engine ввёл принципиально новую модель выполнения:

  • Исходный код PHP-скрипта сначала лексически разбирался и парсился в абстрактное синтаксическое дерево (AST);
  • AST компилировался в промежуточное представление — опкоды (operation codes);
  • Опкоды выполнялись виртуальной машиной Zend Engine.

Это позволило:

  • Внедрить кэширование опкодов (хотя полноценные решения, например, APC, появятся позже);
  • Значительно ускорить выполнение (по разным оценкам — в 3–10 раз);
  • Улучшить управление памятью: введён счётчик ссылок для автоматического освобождения объектов (garbage collection в PHP 4 был примитивным и не умел обрабатывать циклические ссылки — эта проблема будет решена лишь в PHP 5.3);
  • Сделать интерпретатор более стабильным и расширяемым.

PHP 4 также впервые включил:

  • Поддержку сессий на уровне ядра (ранее — только через расширения);
  • Более надёжную работу с безопасностью: register_globals по умолчанию был отключён (хотя оставался доступным — и многие хостинги его включали, порождая уязвимости);
  • Улучшенную поддержку Unicode (на уровне эксперимента — полноценная поддержка так и не будет реализована до PHP 6, проект которого будет закрыт);
  • Примитивные возможности объектно-ориентированного программирования: классы, наследование, методы, свойства. Однако ООП в PHP 4 оставался «объектами-структурами»: объекты передавались по значению (копировались при присваивании), отсутствовали абстрактные классы, интерфейсы, видимость (public/private/protected), деструкторы работали ненадёжно.

Тем не менее, PHP 4 знаменует переход языка из категории «скриптового инструмента» в разряд промышленных технологий. В 2001–2004 годах на PHP 4 строятся первые масштабные проекты: WordPress (2003), phpBB (2000), osCommerce (2000), MediaWiki (2002, движок Википедии с 2002 по 2005). Хостинги массово предлагают «LAMP-стек» (Linux, Apache, MySQL, PHP) как стандартное решение для веб-приложений.

К 2005 году PHP 4 достиг зрелости: последняя версия — 4.4.9 — выпущена в августе 2008 года, хотя активная разработка прекратилась гораздо раньше в пользу PHP 5.


PHP 5 и Zend Engine II (2004–2008)

Выпуск PHP 5.0.0 13 июля 2004 года стал переломным моментом в истории языка. В отличие от инкрементальных улучшений PHP 4, PHP 5 представлял собой фундаментальную перестройку семантики объектов и введение новых парадигм программирования, которые сделали возможным применение PHP в enterprise-среде. Основой изменений стал Zend Engine II, разработанный той же командой (Zend Technologies), но с учётом критических ограничений предыдущей версии.

Объектно-ориентированное программирование

Если в PHP 4 объекты являлись по сути структурой данных с привязанными функциями, то PHP 5 ввёл концепцию референцируемости по умолчанию: переменная, содержащая объект, теперь хранит ссылку на объект в куче. Это устранило неинтуитивное поведение копирования объектов при присваивании и передаче в функции — одну из главных причин багов в коде PHP 4.

Помимо этого, PHP 5 предложил:

  • Контроль видимости: ключевые слова public, protected, private для методов и свойств. Это позволило инкапсулировать внутреннее состояние объекта и формализовать контракты между компонентами.
  • Абстрактные классы и методы (abstract class, abstract function) — механизм, стимулирующий проектирование через интерфейсы и предотвращающий создание неполных реализаций.
  • Интерфейсы (interface, implements) — средство множественного наследования поведения без наследования состояния, критически важное для гибкой компоновки систем.
  • Магические методы (__construct, __destruct, __get, __set, __call, __toString и др.) — расширяемый механизм перехвата операций над объектом, лёгший в основу паттернов Active Record, Proxy, Lazy Loading и ORM-слоёв.
  • Конструкторы и деструкторы как стандартные точки жизненного цикла объекта; деструкторы в PHP 5 работали надёжнее благодаря улучшенной системе управления ссылками.
  • Клонирование (clone, __clone) — явный механизм создания копий объектов, отделивший операцию копирования от присваивания.

Эти изменения кардинально изменили подход к проектированию. Фреймворки, построенные на PHP 4 (например, early CakePHP), вынуждены были либо радикально переписываться, либо уступать место новым решениям. Уже в 2005–2006 годах появляются фреймворки, изначально архитектурно основанные на возможностях PHP 5: Symfony (2005, Фабьен Потенсье), Zend Framework (2006, Zend Technologies), CodeIgniter (2006), Kohana (форк CodeIgniter, 2007).

PHP 5 не отказался от процедурного стиля — он по-прежнему оставался доступным и широко используемым. Однако появилась альтернатива, позволяющая строить иерархические, тестируемые, расширяемые системы. Это дало толчок формированию профессионального сообщества backend-разработчиков, ориентированных на скорость написания и на качество архитектуры.

Исключения

PHP 4 полагался на глобальные флаги ($php_errormsg), возврат false или null и ручную проверку условий. PHP 5 ввёл полноценную систему исключений на основе ключевых слов try, catch, throw и иерархии классов, наследуемых от базового \Exception.

Хотя обработка ошибок в PHP остаётся гибридной (многие функции по-прежнему возвращают false при сбое и генерируют предупреждения), исключения позволили:

  • Централизовать обработку критических сбоев;
  • Разделять управление потоком (логика приложения) и обработку аномалий;
  • Строить слои абстракции, где низкоуровневые ошибки (например, сбой подключения к БД) преобразуются в высокоуровневые исключения предметной области (UserNotFoundException, PaymentGatewayUnreachableException).

Это стало предпосылкой для внедрения принципов Defensive Programming и Fail-Fast: приложение могло прерывать выполнение и передавать ошибку вверх по стеку вызовов.

Улучшения в работе с расширениями и API

PHP 5 стандартизировал интерфейс для написания расширений на C через Zend API, что упростило интеграцию с внешними библиотеками. В частности:

  • Появился PDO (PHP Data Objects) — унифицированный интерфейс доступа к реляционным СУБД. В отличие от mysql_*, pg_*, oci8_*, PDO обеспечивал единый API с поддержкой подготовленных выражений, транзакций, ошибок через исключения и переключения между драйверами без изменения логики приложения.
  • Был переписан модуль SimpleXML — объектно-ориентированный интерфейс для работы с XML, основанный на libxml2, обеспечивающий интуитивную навигацию по дереву ($xml->book->title).
  • Введён SPL (Standard PHP Library) — набор интерфейсов (Iterator, ArrayAccess, Countable) и классов (SplStack, SplQueue, SplFileInfo), позволяющих интегрировать пользовательские типы данных в языковые конструкции (foreach, count(), $obj[]).

SPL, в частности, заслуживает отдельного внимания: он сделал возможным полиморфизм не только через наследование, но и через реализацию контрактов. Класс, реализующий Iterator, автоматически становился пригодным для итерации в foreach, даже если он не наследовал от какого-либо базового итератора. Это — проявление утиная типизация (duck typing), характерной для динамических языков, но оформленная в виде строгого API.

Безопасность

PHP 5 унаследовал от PHP 4 ряд уязвимостей, связанных с настройками по умолчанию. Наиболее известная — register_globals = On, позволявшая автоматически создавать глобальные переменные из GET/POST/COOKIE-параметров. Хотя в PHP 5 по умолчанию значение изменили на Off, многие хостинги и готовые дистрибутивы (например, XAMPP) сохраняли устаревшую конфигурацию из соображений совместимости, что приводило к массовым уязвимостям типа variable overwrite.

Тем не менее, PHP 5 заложил основы современной безопасности:

  • Усилен контроль над включением внешних ресурсов: директивы allow_url_include (по умолчанию Off с PHP 5.2), open_basedir.
  • Появились встроенные функции для защиты от XSS: htmlspecialchars() получил параметр $double_encode, htmlentities() — поддержку кодировок.
  • В PHP 5.2 (2006) введён модуль filter — системный способ валидации и санитизации входных данных (filter_var($email, FILTER_VALIDATE_EMAIL), filter_input(INPUT_GET, 'id', FILTER_SANITIZE_NUMBER_INT)).

Эти меры были реактивными — они появлялись после массовых атак, — но они демонстрировали сдвиг в парадигме: безопасность переставала быть «проблемой программиста» и становилась частью языковой политики.

Версии 5.1–5.6

После революции 5.0 развитие PHP стало более инкрементальным:

  • PHP 5.1 (2005): введена таймзона по умолчанию, улучшена работа с датами; появился автозагрузчик классов (__autoload()).
  • PHP 5.2 (2006): модуль json включён в ядро (ранее — PECL-расширение); введены анонимные функции (ограниченной функциональности: без use-захвата переменных из замыкания).
  • PHP 5.3 (2009) — важнейший релиз в эпоху PHP 5:
    • Пространства имён (namespace, use) — решение проблемы глобального конфликта имён, критически важное для reuse-компонентов и фреймворков.
    • Замыкания (анонимные функции с use (...) для захвата переменных).
    • Позднее статическое связывание (static:: вместо self::), необходимое для реализации паттернов типа Active Record.
    • __callStatic() — магический метод для перехвата статических вызовов.
    • goto — спорное, но полезное средство для выхода из глубоко вложенных циклов (не для «спагетти-кода»).
    • NOWDOC и HEREDOC с кавычками — удобные синтаксические конструкции для многострочных строк.
  • PHP 5.4 (2012):
    • Trait’ы — механизм горизонтального повторного использования кода, компенсирующий отсутствие множественного наследования классов.
    • Короткий синтаксис массивов ([1, 2, 3] вместо array(1, 2, 3)) и short echo tag (<?= ... ?> включён всегда).
    • Встроенный веб-сервер (php -S localhost:8000) — огромное упрощение для локальной разработки.
    • Поддержка сессий в JSON (альтернатива сериализации).
  • PHP 5.5 (2013):
    • Генераторы (yield) — поддержка ленивых вычислений и итерации по большим объёмам данных без загрузки всего в память.
    • finally в блоках try/catch.
    • Оператор list() в foreach (foreach ($pairs as list($a, $b))).
    • OPcache (на основе проекта Zend Optimizer+) включён в дистрибутив — кэширование опкодов стало стандартом, резко повысив производительность.
  • PHP 5.6 (2014):
    • Константные выражения (const MAX_SIZE = 2 * 1024;).
    • Аргументы-вариадики (function f(...$args)).
    • Распаковка аргументов (f(...$array)).
    • php://input доступен при enable_post_data_reading = Off — важное улучшение для обработки неформатированных тел запросов (например, JSON API).

К 2014 году PHP 5 достиг технического пика: язык обладал современной объектной моделью, механизмами композиции, инструментами для функционального стиля, встроенным кэшированием. Однако нарастал технический долг: производительность всё ещё уступала компилируемым языкам, отсутствовала строгая типизация, JIT-компиляция не рассматривалась всерьёз.

Критически важным событием стало появление в 2012 году Composer — системы управления зависимостями, вдохновлённой npm и pip. Composer, используя репозиторий Packagist, стандартизировал автозагрузку (PSR-0, затем PSR-4) и сделал возможным модульную экосистему: вместо монолитных фреймворков разработчики стали собирать приложения из десятков независимых компонентов (например, monolog/monolog, guzzlehttp/guzzle, symfony/http-foundation). Это изменило культуру PHP: язык перестал быть «сборником скриптов» и стал платформой для композитных приложений.


Провал PHP 6 (2005–2010)

Параллельно с выпуском PHP 5.0 в 2004 году в PHP-сообществе началась работа над PHP 6 — версией, которая должна была стать «окончательным ответом» на критику в адрес языка, в первую очередь — в части поддержки Unicode.

Идея была радикальной: встроить нативную, сквозную поддержку Unicode на уровне ядра — все строки должны были стать UTF-16 (или, в альтернативных вариантах, UTF-8), переменные $_GET, $_POST, $argv — автоматически декодироваться из кодировки запроса, функции работы со строками — оперировать символами, а не байтами. Для этого планировалась полная переработка внутреннего представления строк, изменение ABI расширений и введение новой модели кодировок («internal encoding», «input encoding», «output encoding»).

Однако проект столкнулся с фундаментальными проблемами:

  1. Амбициозность масштаба. Переписывание строкового движка затронуло все модули C-расширений, включая фундаментальные (zlib, mbstring, iconv, mysql). Поскольку расширения разрабатывались независимыми авторами, согласование изменений оказалось практически невозможным.

  2. Отсутствие чёткого технического консенсуса. Внутри команды Zend и core-разработчиков не было единого мнения: использовать ли UTF-16 (как в Java/.NET) или UTF-8 (как в Python 3, Go), как обрабатывать BOM, как совмещать с существующими бинарными протоколами (например, memcached, Redis, raw sockets).

  3. Экономическая нецелесообразность. В 2007–2009 гг. рынок веба резко сместился в сторону AJAX и JSON-API. Серверная часть всё чаще выступала как «тонкий» backend, отдающий данные в UTF-8, а вся работа с представлением (включая интернационализацию) переносилась на JavaScript. Запрос на внутреннюю Unicode-модель ослаб: достаточно было корректно принимать и отдавать UTF-8, не преобразуя её внутри.

  4. Фрагментация и усталость сообщества. Ветка PHP 6 существовала как экспериментальный репозиторий более пяти лет, но не приносила практических выгод. Многие разработчики перешли на PHP 5.3/5.4, игнорируя «вечно готовящийся» PHP 6. В 2010 году проект был официально закрыт, а номер 6 — пропущен (следующей мажорной версией стала PHP 7).

Последствия провала PHP 6 оказались двоякими:

  • Негативные: замедление развития языка на 4–5 лет, потеря доверия к процессу релизов, уход части талантливых разработчиков.
  • Позитивные: осознание необходимости минималистичных, обратно совместимых улучшений; фокус на практических улучшениях (производительность, типизация), а не на «идеологических»; укрепление роли PHP-FIG (Framework Interop Group) как независимого органа стандартизации (PSR-стандарты).

Ирония в том, что задача Unicode-поддержки была решена на уровне практик и инструментов:

  • Все современные HTML-документы декларируют <meta charset="utf-8">;
  • HTTP-заголовки Content-Type: text/html; charset=utf-8 стали стандартом;
  • MySQL перешёл на utf8mb4 как кодировку по умолчанию;
  • Функции mb_* (multibyte string) и intl (интернационализация) остались в виде расширений — их включение стало частью конфигурационной дисциплины, а не языковой обязанности.

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


PHP 7 (2015–2018)

Появление PHP 7.0 3 декабря 2015 года стало самым значительным событием в истории языка после PHP 5.0. Его разработка началась в 2014 году под именем PHP Next Generation (phpng) — инициативы, возглавленной Дмитрием Стоговым (Dmitry Stogov, Zend), с единой целью: в два раза увеличить производительность и снизить потребление памяти.

Zend Engine 3 и AST-based компиляция

Основой PHP 7 стал Zend Engine 3переписанный с нуля движок выполнения:

  • Unified zval — переработанное внутреннее представление переменных. В PHP 5 каждая переменная (zval) содержала указатель на значение и отдельные флаги (refcount, is_ref). В PHP 7 значение хранится непосредственно в zval, а ссылки (references) реализованы через отдельную структуру zend_reference. Это сократило количество аллокаций памяти, уменьшило размер zval с 24 до 16 байт (на 64-битных системах) и ускорило доступ к данным.

  • AST (Abstract Syntax Tree) как промежуточное представление. В PHP 5 компилятор генерировал опкоды напрямую из парсера, что затрудняло оптимизации. В PHP 7 введён явный этап построения AST, после которого запускается оптимизатор, способный выполнять:

    • Константное свёртывание (2 + 3 * 414);
    • Устранение мёртвого кода;
    • Оптимизацию цепочек вызовов (например, count($arr) в условии цикла выносится за пределы).
  • Новый аллокатор памяти (zend_alloc) — более эффективная стратегия управления кучей, учитывающая локальность данных и уменьшающая фрагментацию.

Результаты были впечатляющими: по тестам WordPress, Drupal и Symfony, PHP 7 показал 2–2.5× прирост производительности и снижение потребления памяти на 30–50% по сравнению с PHP 5.6. Серверы, которые ранее обрабатывали 1000 запросов/сек, стали выдерживать 2500+ — без изменения кода приложений.

Синтаксические и семантические нововведения

PHP 7 не ограничился оптимизациями: он заложил основы современного языка:

  • Скалярные типы аргументов (string, int, float, bool) и возвращаемых значений:

    function add(int $a, int $b): int {
    return $a + $b;
    }

    По умолчанию — коэрцитивный режим (неявное приведение: "42"42), но с директивой declare(strict_types=1);строгий (ошибка при несоответствии).

  • Оператор нулевого слияния (??) и безопасная навигация (?-> в PHP 8):

    $name = $_GET['name'] ?? 'guest';
    $city = $user?->getProfile()?->getCity() ?? 'unknown';
  • Анонимные классы — средство для быстрого создания одноразовых реализаций интерфейсов (например, в тестах или коллбэках):

    $logger = new class implements LoggerInterface {
    public function log(string $msg): void { /* ... */ }
    };
  • Группировка use-директив:

    use Symfony\Component\HttpFoundation\{Request, Response, RedirectResponse};
  • Оператор spaceship (<=>) для упрощения пользовательских сортировок:

    usort($users, fn($a, $b) => $a->age <=> $b->age);
  • Error как исключение — критическое изменение семантики ошибок: фатальные ошибки (E_ERROR, E_RECOVERABLE_ERROR) теперь выбрасывают \Error, который наследует от \Throwable (как и \Exception). Это позволило обрабатывать все критические сбои через try/catch, а не через register_shutdown_function().

Эволюция PHP 7.x

  • PHP 7.1 (2016): nullable-типы (?string), void-возврат, класс iterable, улучшения в exceptions (Throwable).
  • PHP 7.2 (2017): объект object как тип, abstract/final для констант, безопасное count() для scalar-значений, удаление устаревших функций (create_function(), each()).
  • PHP 7.3 (2018): гибкие heredoc/nowdoc, is_countable(), трассировка стека в exceptions, улучшения в regexp (PCRE2).
  • PHP 7.4 (2019):
    • Typed properties — строгая типизация полей класса:
      class User {
      public int $id;
      private string $name;
      }
    • Arrow functions — короткий синтаксис замыканий (fn($x) => $x * 2);
    • Preloading — загрузка классов в разделяемую память при старте FPM, устраняющая overhead парсинга на каждый запрос.

PHP 7.x стал периодом консолидации: язык приобрёл черты, ожидаемые от современной платформы (типизация, безопасность, предсказуемость), не теряя при этом прагматизма и обратной совместимости (большинство приложений PHP 5.6 работали на PHP 7.0–7.4 без изменений).


PHP 8 (2020–н.в.)

PHP 8.0, выпущенный 26 ноября 2020 года, знаменует начало третьей эпохи PHP — после «скриптовой» (PHP 3–4) и «объектной» (PHP 5–7). Это уже универсальная платформа с акцентом на надёжность, производительность и выразительность.

JIT-компиляция

Наиболее громким нововведением стал Just-In-Time компилятор, реализованный на основе Tracing JIT (в отличие от Method JIT в Java/.NET). JIT компилирует «горячие» участки байт-кода в нативный машинный код во время выполнения:

  • Цель не веб-ускорении. Для типичного LAMP-стека выигрыш от JIT минимален (I/O-операции доминируют). Основная задача — ускорение вычислительно-ёмких задач: машинное обучение (PHP-ML), обработка изображений, криптография, CLI-утилиты.
  • Два режима: tracing (по умолчанию) и function; настраивается через opcache.jit_buffer_size, opcache.jit.
  • Будущее — основа для компиляции PHP в WebAssembly или нативные исполняемые файлы (проекты как PeachPie уже используют PHP в .NET-среде).

Системная типизация

PHP 8 последовательно продвигает язык к статической проверяемости:

  • Union types (string|int|null) — замена docblock-аннотациям:
    public function parseValue(string|int $input): float|null { ... }
  • Named arguments — вызов функций с указанием параметров по имени, а не позиции:
    mail(to: $user->email, subject: 'Welcome', message: $text);
  • Attributes (аннотации) — нативная замена PHPDoc-тегам:
    #[Route('/api/users')]
    class UserController { ... }
  • Enums (PHP 8.1) — типизированные перечисления:
    enum Status: string {
    case Draft = 'draft';
    case Published = 'published';
    }
  • Readonly properties (PHP 8.1) — неизменяемые поля:
    class User {
    public function __construct(
    public readonly int $id,
    public readonly string $name
    ) {}
    }
  • Pure functions и never-возврат (PHP 8.2):
    #[\ReturnTypeWillChange]
    public function abort(): never {
    throw new RuntimeException('Aborted');
    }

Современные конструкции и безопасность

  • Match-выражение — безопасная и выразительная альтернатива switch:
    $result = match($statusCode) {
    200, 201 => 'success',
    404 => 'not found',
    default => throw new \Exception('Unknown code'),
    };
  • Nullsafe operator (?->) — цепочка вызовов с остановкой при null.
  • Stricter error handling: большинство предупреждений (E_WARNING) преобразованы в \Error.
  • Удаление устаревшего: create_function(), ereg_*, $php_errormsg, magic quotes — полностью исключены.

Производительность и экосистема

  • PHP 8.0–8.3 показывают ~15–30% прироста по сравнению с PHP 7.4 на реальных приложениях (благодаря улучшенному JIT, оптимизациям движка, preloading).
  • Composer 2 (2020) — радикальное ускорение установки зависимостей (в 3–10 раз), поддержка параллельных загрузок.
  • Стандартизация через PSR: PSR-12 (код-стайл), PSR-18 (HTTP Client), PSR-17/7/15 (HTTP Message/Server Request), PSR-14 (Event Dispatcher) — превращают PHP в интероперабельную экосистему, а не набор фреймворков.