PHP в 2020 году

Данная статья является переводом публикации “PHP in 2020” автора Brent.

Не секрет что среди веб-разработчиков и программистов в целом: PHP имеет не самую лучшую репутацию, несмотря на то, что по прежнему является одним из наиболее часто используемых языков для создания веб-приложений. За прошедшие годы PHP зарекомендовал себя в таких вещах как: база грязного кода, неопытные разработчики, несовместимая базовая библиотека, “а почему бы и нет”.

Несмотря на то, что многие аргументы против PHP актуальны и на сегодняшний день, у него есть и светлая сторона: вы можете писать чистые, поддерживаемые, быстрые и надежные приложения.

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

Давайте посмотрим как изменился и даже повзрослел язык PHP за последние несколько лет. Я прошу вас отложить свои предубеждения против него на несколько и минут, и может быть вы удивитесь тому, каков PHP сегодня.

Краткая история

Прежде чем погрузиться в детали, давайте посмотрим как PHP разрабатывается сейчас. В настоящий момент актуальной версией является 7.4, а PHP 8.0 будет следующей после нее версией и выйдет в конце 2020 года.

Начиная с последних версией 5.* основная команда старается поддерживать постоянный годовой цикл выпуска новых версий и за последние 4 года преуспела в этом.

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

В заключение, PHP 5.6 был последним релизом версий 5.*, с выпуском 7.0 началась новая история версий. Если вас интересует, что случилось с PHP 6, то можете послушать соответствующий эпизод подкаста PHP Roundtable.

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

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

Система типов в PHP

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

Сегодня PHP является достаточно уникальным языком: он по-прежнему позволяет писать полностью динамически и слабо-типизированный код, но в тоже время обладает сильной системой опциональных типов. В сочетании со статическим анализом и такими инструментами как Psalm и PHPStan вы можете писать защищенный, строготипизированный и статически проанализированный код.

Рассмотрим например этот фрагмент PHP-кода полностью использующий его современную систему типов:

<?php

declare(strict_types=1);

final class Foo {
    public int $intProperty = 2;

    public ?string $nullableString = null;

    private Bar $bar;

    public function __construct(Bar $bar) {
        $this->bar = $bar;
    }

    public function withInt(int $value): self {
        $clone = clone $this;

        $clone->intProperty = $value;

        return $clone;
    }

    public function unionTypes(int|float $input): void {
        //Union types will be added in PHP 8
    }
}

Честно говоря, в системе типов PHP по-прежнему отсутствует одна важная деталь: дженерики. Есть надежда, что они будут добавлены, но пока нет ничего конкретного по этому поводу. В случае с типизированными массивами вам нужно полагаться на docblock для получения соответствующей поддержки от IDE:

/** @var int[] */
public array $arrayOfInts = [];

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

Синтаксис PHP

Эра 7.* сделал много хорошего с PHP, превратив его в более зрелый язык с точки зрения синтаксиса. Чтобы показать это я сделал неполный список новых возможностей PHP:

Уничтожение массива:

[$a, $b] = $array;
Оператор объединения с null:

$value = $object->property ?? 'fallback if null';

$value = $array['foo'] ?? "fallback if key doesn't exists"; 
Оператор присваивания объединения с null:

public function get(string $input): string 
{
    return $this->cache[$input] ??= $this->sanitize($input);
}
Распределение массива:

$a = [/* … */];
$b = [/* … */];

$mergedArray = [...$a, ...$b];
Вариативные функции:

public function get(Foo ...$foos): void
{
    foreach($foos as $foo) {
        // …
    }
}
Распаковка аргументов:

$this->get(...$arrayOfFoo);
Типизированные свойства:

public int $intProperty;
Стрелочные функции, также известные как короткие замыкания:

$ids = array_map(fn(Post $post): int => $post->id, $posts);
Генераторы:

function make(array $input): Generator
{
    foreach ($input as $item) {
        yield $this->doSomethingWith($item);
    }
}

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

Производительность PHP

Во времена версий 5.* производительность PHP была … в лучшем случае средней. Но в версии 7.0 основная часть ядра PHP была переписана с нуля, что привело к увеличению производительности в два-три раза. Кроме того каждая последующая версии 7.* оказывала положительное влияние на производительность.

Если этих слов не достаточно, то давайте посмотрим на показатели производительности. К счастью, уже многие потратили свое время на тестирование производительности PHP. Я нашел хороший обзор на Kinsta.

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

Когда выйдет PHP 8 в нашем распоряжении окажется JIT-компилятор, который обещает интересные улучшения производительности и позволит входить PHP в новые области кроме веб-разработки.

Фреймворки и экосистема

Перейдем к тому, что было создано сообществом с помощью PHP. Будем честны: PHP это уже не только WordPress, наоборот.

В общем есть две основные платформы для разработки веб-приложений и несколько более мелких: Symfony и Laravel. Конечно существуют также Laminas, Yii, Cake, Code Igniter и т.п. – но если вы хотите знать как выглядит современная PHP-разработка, то хорошо познакомьтесь с одной из двух первых.

Обе платформы имеют большую экосистему пакетов и продуктов. Начиная от административных панелей и CRM до автономных пакетов, CI для профилировщиков, многочисленных сервисов, таких как серверы для веб-сокетов, менеджеры очередей, обработчики для платежных систем; честно говоря их слишком много чтобы перечислить здесь.

Эти фреймворки предназначены для фактической разработки; если вам нужно только чистое управление контентом, то такие платформы как WordPress, CraftCMS и Statamic развиваются вместе с PHP все больше и больше.

Один из способов измерить текущее состояние экосистемы PHP – взглянуть на Packagist, основной репозиторий пакетов для PHP. Вы можете проследить экспоненциальный рост. С +/- 25 миллионами загрузок в день на сегодняшний день, можно сказать что экосистема больше не слабая сторона PHP, как было раньше.

Взгляните на график в котором указано количество пакетов и версий с распределением по времени. Вы можете более подробно с ним познакомиться на сайта Packagist.

Помимо фреймворков приложений и CMS в последние годы, наблюдается рост асинхронных фреймворков. Это фреймворки и сервера, которые написаны на PHP или других языках, которые позволяют пользователям запускать по-настоящему асинхронный PHP-код. Некоторые крупные игроки этого рынка – Swoole, Amp и ReactPHP.

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

Во внутренней рассылке также обсуждалось добавление libuv в ядро. Libuv это библиотека, которую использует для обеспечения асинхронности Node.js. Кто знает, может быть в PHP 8 она будет добавлена в ядро!

Заключение

Надеюсь я смог показать, что PHP значительно эволюционировал за последние годы и вы можете писать на нем чистый и поддерживаемый код.

Если вам интересно как выглядит PHP-код в наши дни, вы можете проверить исходный код одного из [моих] (автора, прим. переводчика) проектов, а также множества пакетов с открытым исходном кодом, которые [мы лично] (компания автора, прим. переводчика) поддерживаем.

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

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