Это не легаси-код, это PHP +51


AliExpress RU&CIS



За последний год разработчики Vimeo писали код бэкенда на множестве языков — PHP, Go, Ruby, Python, NodeJS, Java, C, C++ и немного на Rust.

В 2004 году мы начинали всего с одного: PHP. Это был идеальный язык для новых стартапов наподобие Vimeo. Интерпретатор PHP позволял предпринимателям быстро разрабатывать прототипы и имел большую стандартную библиотеку, позволявшую избавиться от мороки с повседневными задачами типа отправки писем и доступа к базам данных.

Большинство стартапов развалилось, однако некоторые из них, взявшие за основу PHP, по-прежнему были живы спустя десяток лет. Немногие из них добилась резкого роста, а в дальнейшем кое-кто из этих стартапов (самым заметный пример — это Facebook) решил, что PHP является узким местом, и начал мигрировать с него. Для этого исхода было две серьёзные причины: производительность PHP и сложность поддержки больших кодовых баз PHP.


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

С 2004 года за десять лет Vimeo вырос во много раз, и наша кодовая база PHP росла вместе с ним, но мы не выросли настолько, чтобы эти проблемы встали перед нами в полную силу. Однако когда Facebook публично отказался от использования PHP, некоторые разработчики решили, что PHP постепенно становится FORTRAN эпохи Интернета. Новая волна бэкенд-разработчиков начала планировать, как нам преобразовать 500 тысяч строк кода на PHP в набор лучше спроектированных, более производительных и удобных для тестирования сервисов на Go.

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

Слова «PHP стал лучше» не в полной мере описывают его преобразование. За последние шесть лет в два с лишним раза уменьшилось время выполнения кода на PHP, значительно выросло сообщество разработчиков и появилась популярная тенденция совершенствования кодовых баз на PHP (старых и новых) на основе выводов, сделанных исходя из статического анализа.

Для проникновения усовершенствований PHP в Vimeo потребовалось какое-то время. Сначала нам пришлось избавиться от старой версии PHP (5.4), работавшей в продакшене долгие годы уже после истечения её «срока годности». Благодаря миграции на PHP 7 значительно ускорилась реакция бэкенда; кроме того, улучшенный синтаксис PHP 7 позволил нашим разработчикам писать чуть более чистый код с полной поддержкой типов возвращаемых значений и параметров.

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

Статический анализ — это круто


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

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

Базовая функциональность Psalm приблизительно похожа на контроль типов в TypeScript, а также позаимствовала кое-какие идеи у созданного Facebook языка Hack (производного от PHP). Psalm сообщает разработчику, когда код на PHP может вызвать ошибку несоответствия типов в продакшене, а также когда логика непонятна. Кроме того, инструмент имеет дополнительную функциональность наподобие обнаружения неиспользуемых классов и методов, позволяя автоматически устранять многие найденные проблемы.

Использование Psalm в нашем конвейере CI в течение последних нескольких лет преобразовало подход к написанию кода на PHP в Vimeo: Psalm обеспечил нам уверенность в том, что можно вносить крупномасштабные изменения, не беспокоясь о том, что всё целиком сломается.

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

Я создал Psalm для решения своих проблем, но когда мы выпустили его в open source, он смог помочь и проблемы множества других людей. Недавно Psalm помог нам выявить кучу уязвимостей защиты в нашей кодовой базе ещё до того, как ими могли воспользоваться злоумышленники.

Если кто-то из читающих это работает с крупным легаси-проектом на PHP, в который боится вносить большие изменения, то я крайне рекомендую использовать инструмент контроля типов на основе статического анализа. Psalm (и подобные ему инструменты) могут избавлять от существующих в кодовой базе проблем, позволяя постепенно повышать качество кода.

Старый код необязательно является легаси


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

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

На протяжении многих лет мы совершили несколько попыток использовать другое ORM, но ни одно из предложений не разрабатывалось как ответ на новые потребности бизнеса; скорее, их создание было мотивировано разочарованием в шаблоне ActiveRecord.

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

  • Эффективно выполняет свою задачу
  • Прост для статического анализа
  • Хорошо протестирован
  • Идиоматичен

К счастью, созданное нами ORM удовлетворяет всем четырём критериям.

Кроме того, сохранение надёжного старого кода даёт нам возможность сосредоточить усилия разработчиков на том, что приносит бизнесу материальную выгоду, и в соответствии с договором я обязан (но в то же время и рад) сказать, что в последнее время Vimeo находится на подъёме, выпустив множество отличных продуктов наподобие Vimeo Record.

«PHP не обязан быть ужасным»


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

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

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



На правах рекламы


Эпичные серверы — это виртуальные серверы для размещения сайтов от маленького блога на Wordpress до серьёзных проектов и порталов с миллионной аудиторией. Создайте собственный тарифный план в пару кликов, максимальная конфигурация — 128 ядер CPU, 512 ГБ RAM, 4000 ГБ NVMe!




Комментарии (49):

  1. vtvz_ru
    /#22536474

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

    • isaev_ars
      /#22536706

      У каждого языка своя направленность, а когда пытаются засунуть один язык везде… Вот это удручает, что приложения пишутся вот так

      • shurkandak
        /#22536820

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

        • unC0Rr
          /#22537176

          Но исходники это в первую очередь не текст, а программа на каком-то языке, текстовое представление AST, которое удобнее обрабатывать специализированным инструментом, нежели обычным текстовым редактором. А поскольку языки все разные, то единый инструмент вряд ли возможен, и даже плагины для всех языков в одной IDE будут иметь достаточно большие отличия в поведении.

    • Compolomus
      /#22536808

      Ну можно сделать велосипед с архивом, куда придётся ложить ещё и интепритатор. Компиляция в бинарь была бы мега пушка, можно было бы хотя бы простые консольные штуки пилить, с ui сложнее

      • roxblnfk
        /#22537002

        Да всё это было. Просто с ростом культуры кода забылось.
        Могу поделиться упакованными екзешниками php 4.4 под винду, которые весят от 635кб до 1434кб (в зависимости от комплектации). При запуске выполняют рядом лежащий index.php (зловонный Index.php с демонстрацией окошек прилагаю)
        https://yadi.sk/d/oZmQ9bQGgXawjQ
        Естественно, можно было бы весь код упаковать в 1 файл, но тут весь смысл в переносе компилятора на любую машину с возможностью в блокноте написать нужный код. В армии это особенно принесло пользу — надо было написать скрипт по умному переименованию сотен-тысяч mp3-файлов (убрать префиксы и прочий мусор из названий). Накидал код в блокноте и готово.
        php5 упаковывать уже накладно (выходит более 5мб), поэтому лучше dll класть в папочку и таскать с собой. Решения есть и под php7. Странно, что под php8 пока всё выглядит немного уныло даже с ffi уже в комплекте. Но это вопрос времени, как мне кажется.

        • Compolomus
          /#22537364

          Это как я понял просто скомпиленый php.exe с нужными расширениями, я подобный компилил для андройда, во времена когда не было всяких ksweb

      • Ostrie_Brevna
        /#22541554

        Может, в настоящее время вместо велосипеда с архивом решением имеет право стать Docker-контейнер?

    • Shatun
      /#22536968

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

      • FODD
        /#22538248

        Есть — https://www.npmjs.com/package/pkg
        Правда под виндой у меня бинарник выходил больше 40мб точно

        • Shatun
          /#22538524

          Это разве не упаковка ноды вместе с исходниками? Если да то не вижу причин почему на пхп так нельзя сделать

    • yawa
      /#22537052

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

    • censor2005
      /#22537098 / +1

      Есть DevelNext, этакий гибрид из Java-runtime и php. Интересная вещь, жаль, что не очень широкие возможности. Писал на нём маленькое приложение

    • muxa_ru
      /#22538308

      Но, к сожалению, я не нашел популярного способа хотя бы упаковать PHP код в бинарник

      Было что-то лет пятнадцать назад, но особо не взлетело.

    • SerafimArts
      /#22538588

      В PHP меня расстраивает только один факт: я не могу писать на нем все-все-все, как на NodeJS.

      Можете. На чистом PHP без каких-либо дополнительных экстеншенов, которые идут через pecl. У меня пока не возникало такой задачи, где бы на пыхе это нельзя было реализовать.


      Разве что сталкивался с проблемами uint64_t, в OpenGL, но оно обходилось явным выделением памяти под этот тип, а оверфлоу будет только при касте к пыховскому инту (который не unsigned).


      А так, я бы с удовольствием пилил на нем и мобильные приложения, и десктоп, и cli утилиты.

      И кто мешает? С мобилой сложнее, нужно через terminus запускать, а не паковать в apk. Но в теории можно придумать и нормальный запуск. Не копал в этом направлении от слова "вообще", но раз на сишке можно писать под мобилу, значит и на пыхе можно, просто чуть иначе перепаковать бинарь.


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

      Тут или шашечки, или ехать. Java, JS или любой другой платформонезависимый код поставляется с рантаймом. Никто не мешает поставлять в своей сборке и бинарь рантайма, как это делается, например, в случае с IDEA. С точки зрения реюзабельности — это самый профитный вариант.




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

      • Shatun
        /#22538986

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

        • SerafimArts
          /#22540302

          Про джаву не совсем правда-она вполне успешно компилируется в бинарь

          Признаться, подобных подходов вообще ни разу не встречал. Ну или не обращал внимания просто… Буду знать, спасибо.

    • georgeneversleep
      /#22541450 / +1

      Без обид, но те, кто пишет на js все-все-все (особенно мобилки и десктоп), будут гореть в аду. Производительность этого всего-всего-всего никакая-никакая-никакая. Только php в этом формате нам и не хватает для полного счастья. Консольные утилиты — ок, в этой области претензий нет.

      • stokker
        /#22543494

        Наоборот, тенденция в мире такая, что все хотят один язык для всего. Поэтому Go, JS, C#, Kotlin, etc — все хотят пролезть во всё.

        • Alexrook
          /#22545172

          Для всего не выйдет, как ни крути. Ибо любой язык с GB никогда не вступят на территорию, где главенствуют C, C++, ну и Rust в последнее время. В то же время все эти языки никогда не подойдут для целей, для которых создавались PHP, Python или JS.

    • RC_Cat
      /#22542894

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

      • trawl
        /#22546316

        После доклада Дмитрия Стогова о JIT на PHPFest 2020 был вопрос:


        Планируется ли версия PHP, которая будет компилировать код в бинарник (по аналогии с C или Go)

        Дмитрий ответил:


        Нет, не планируется, хотя в принципе я не вижу ничего сложного — для этого всё уже есть… Если вы хотите распространять close source проекты и зарабатывать деньги, тогда пожалуйста, сами делайте

        • sumanai
          /#22548124

          бинарник

          close source проекты

          Нда, ответил на совсем другой вопрос.

    • antonkrechetov
      /#22544290

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

      Здесь должна быть шутка про «Один пацан писал все на JavaScript...»

      • Calc
        /#22545046

        ну и шутки про js тоже не надо забывать

        Картинка
        image

    • elCreator
      /#22545310

      Есть babel-preset-php, который синтаксис PHP7, кроме деструкторов, ссылок, die(), суперглобальных массивов с данными запроса и еще некоторых моментов транспилирует в JS, который можно обернуть в Cordova/PhoneGap и получить десктопное или мобильное приложение.
      Реальных проектов не видел.

  2. Wyrd
    /#22539804

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

    • m0rtis
      /#22540988 / +2

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

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

    • sumanai
      /#22541664

      Сообщество PHP 2004 года и даже 2014 это разные вещи. Я уж молчу про сейчас, когда инструментов более чем достаточно.

  3. oz0ne
    /#22539998

    Жду момента когда на пхп из коробки можно будет легко и просто написать самостоятельный микросервис, как на ноде например. Без установки отельного веб сервера, без swoole и roadrunner, без танцев с pthreads. Это будет новый виток эволюции.

    • mokaton
      /#22540196

      Скорее всего к этому таки придут, но еще надо подождать пару лет.

    • VolCh
      /#22540296

      А кто мешает? Я писал такое ещё на PHP3. Открываем сокет слушаем обрабтывае. Да, синхронно, да однопоточно, да память текла во всю тогда… Сейчас со многим лучше. Генераторы вон можно прикрутить

      • oz0ne
        /#22540298

        Какой смысл с однопоточного сервера? Мы же о серьезных вещах говорим.

        • SerafimArts
          /#22540306

          А ничего, что в ноду многопоточность только недавно завезли (и то не факт, что прикрутили к эвентлупу, тут надо жсников спрашивать), а раньше как бы никого это и не волновало особо? В чём отличия-то?

          • Calc
            /#22545060 / -1

            в ноду многопоточность только недавно завезли

            А об этом все забывают, один случайный sleep в 15м году убивал весь сервер :)

        • VolCh
          /#22544100

          Автомасштабирование в кубере или ещ' где настраиваем — полушутка

    • oxidmod
      /#22542074

      Чем вам вебсервер не угодил? Как по мне, то это замечательно, что в пыхе нет веб-сервера для прода. Бери любой под свои потребности и не парься.

      • oz0ne
        /#22542786

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

        • sumanai
          /#22542930

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

          • VolCh
            /#22544124

            Фреймворки и прочее будут на пхп обычно, то есть средний пхп-разработчик может зайти и разобраться в ожидаемом поведение

        • oxidmod
          /#22543014

          Ну вот как раз для этого и есть подходящие решения! И это здорово, как по мне

      • VolCh
        /#22544106

        Хотелось бы все-таки, чтобы -S годился для прода просто как запускальщик index.php условного для микросервисов

        • oxidmod
          /#22544410

          Зачем, если есть nginx \ swoole?

          • VolCh
            /#22548406

            За второй не скажу, но с первым в докерах или типа того постоянно нюансы: их в один контейнер помещать с супервизор или системд или в разные. Чистую статику из пхп-фрейма как веб-серверу давать. Пользовательскую.


            Да и вообще, два компонента обычно сложнее в разработке, разворачивание поддержке чем один.

    • Calc
      /#22545054

      php-cli через supervisord? :)
      И забудете о всех межпроцессорных штуках
      Нужно пообщаться между скриптами — memcached, реббит, редис

      • aleks_raiden
        /#22545342

        а почему забыть? IPC вроде есть под PHP

        • VolCh
          /#22548408

          По памяти он именно "вроде", просто биндинги

  4. mokaton
    /#22540200

    Отвратительный перевод. Если вы постите перевод статьи из гуглтранслейта — это плохо. Хотя бы вычитывайте после автоперевода статью.