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

Сейчас я буду убеждать вас использовать статический анализ в PHP



Я помню выход PHP7: появились strict types, скалярные type hint-ы.

Мы начали двигаться в сторону языка со статической типизацией, но типизация не ушла в статику. Концептуально все осталась прежним мы запускаем программу и только в runtime узнаем, что где-то есть неправильный тип. Даже если мы везде явно проставим типы, все ошибки мы не поймаем и можем больно упасть в продакшене.

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

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

Если вы решите углубиться в тему, советую эти видео:



Поехали!


Сергей Жук, Skyeng: Что вообще анализируют статические анализаторы? Они же не только про типы, да?

Валентин Удальцов, Пых: Статический анализ выходит далеко за пределы декларации типов в PHP. Типизация может быть очень многогранна: скажем, это может быть работа с иммутабельность и чистотой. То есть, мы можем гарантировать, что объект определенного класса не меняется в процессе его использования, на нем нет setter-ов.

Мы также можем следить за чистотой функции: смотреть, что она не обращается к IO.

В Psalm еще недавно добавили taint analysis: мы можем проследить данные от источника из внешней среды до какого-то уровня вглубь и понять, что все данные были так или иначе провалидированы. Тогда, с некоторой долей вероятности, у нас нет проблем с безопасностью. Вот еще одна задача, которую может решать статический анализ.

Сергей Жук, Skyeng: А ты вообще разбирался, как это работает? Если мой код не выполняется, получается, он парсится в абстрактное синтаксическое дерево и...

Валентин Удальцов, Пых: Есть статические анализаторы, которые используют autoloading композеровский те же PHPStan и Psalm. Phan по-моему, частично использует runtime, но дальше сам анализ происходит без выполнения.

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

Есть два этапа. На первом Psalm проходит весь код, который ты указал ему явно полностью. Традиционно это папка src и любые другие, которые ты перечислил. Он также заглядывает в vendor, если твой код использует вендорные классы. Это просто сбор данных: он все кэширует, трансформируя данные парсера Попова в некоторые свои сущности.

Потом, при следующих проходах, первый этап повторяется только для тех файлов и зависимостей, которые поменялись. За счёт этого Psalm работает достаточно быстро.

Второй этап это анализ. По умолчанию он проходит только в измененных файлах. Но можно форсировать полный анализ: тогда Psalm поднимет из кеша подготовленные на первом этапе данные и проведет рекурсивный анализ всего и вся.

Сергей Жук, Skyeng: Ты постоянно упоминаешь Psalm а почему не другие?

Валентин Удальцов, Пых: Да все просто. Когда я вообще что-то выбирал, то договорился на работе в Happy Inc., что начинаю новый проект и мы сразу включаем всё на максимум. Посмотрел, что чаще упоминают, сделал базовое сравнение фич. Phan не использовал composer autoloading, насколько помню. В PHPStan было больше плагинов. В Psalm была иммутабельность, еще какие-то вещи, частые релизы, сообщество, а человек, который его развивает, на оплачиваемой должности. Все это подкупило.

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

Бывает и так, что выйдет новый релиз, а там какая-то регрессия или на что-то не написан тест.

Естественно, приходится такое suppress-ить, писать issue. Мой лайфхак: если вы нашли проблему в любом пакете, который ставите, напишите todo, создайте issue, а в todo впишите ссылку на issue. Когда issue закроют, по его url вы найдете все места в коде, где нужно убрать suppress.

С Psalm я так и поступаю: не откатываю версию, я просто пишу suppress-ы и обязательно делаю тикет.

Сергей Жук, Skyeng: А как подсадить на статанализ команду? Люди ждут, что им сейчас всякие хитрые баги найдут, а в реальности все немного иначе.

Валентин Удальцов, Пых: У меня нет опыта внедрения Psalm на большом проекте с кучей людей. Этот момент я признаю. Мне помогло то, что я начинал писать проект один, хотел по полной обмазываться статическим анализом, и сделал это. А когда начали подключаться люди с других проектов, они были поставлены в существующие рамки. Конечно, поначалу я объяснял и показывал, но у нас небольшой техотдел. Так что не сказал бы, что адаптация других ребят заняла много времени.

Для тех, у кого много людей и старая кодовая база, в инструментах статического анализа есть такая история, как baseline.

Когда ты добавляешь инструмент в старый проект, там найдется миллион ошибок. Но ты говоришь анализатору: мы признаем, что это есть, но пока не обращаем на это внимание а вот когда мы пишем новое, рассказывай, где проблемы. Это baseline и постепенно, относительно него, разработчики учатся писать код с учетом статического анализа. При этом в Psalm есть несколько уровней, то есть инструмент максимально заточен, чтобы внедрять его постепенно.

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

Сергей Жук, Skyeng: Бывает, анализаторы ругаются на неверные PHP-доки, хотя сам код работает правильно. Да и ты говорил про баги, которые помечаешь todo-шками Есть ли тогда смысл добавлять статанализ наравне с тестами в CI?

Валентин Удальцов, Пых: Добавлять надо, иначе теряется смысл. Идея типизации в том, чтобы снизить энтропию, повысить детерминированность того, что мы пишем. А богатая типизация позволяет писать меньше тестов. Если мы знаем, что где-то есть тип, который возвращает в этом случае null, а в этом string, если мы точно знаем, в каких случаях что возвращается, то не понадобится писать тест, который это проверяет.

Статический анализ это полноценный этап CI, который пробегает до тестов.

Если у тебя типы неверные, что там тестировать? Ты в любом случае накосячил.

Что касается багов в Psalm, обычно это минорные вещи, не самая большая проблема. Если есть реальная проблема, мы формируем issue и костыльком в виде suppress или подсказки с todo-шкой это фиксим. При этом бывают нюансы, которые ты сразу не понимаешь, делаешь issue, а тебе отвечают: Да ты просто здесь вот это не так указал. И скидывают как правильно.

Сергей Жук, Skyeng: Ок, но для таких инструментов свой синтаксис надо учить. И твой код им обрастет. Как ты думаешь, в будущем это всё мигрирует в сам PHP?

Валентин Удальцов, Пых: Я смотрю на свой текущий проект. Он написан как бы не на PHP, а на PHP плюс Psalm. Но это всё-таки далеко от того, чтобы быть прям совсем другим языком. Это не как Haskell и PHP, например.

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

Сергей Жук, Skyeng: Ок, а что бы ты сказал человеку, который сейчас открыл IDE, создал новый проект и думает, добавлять статанализ или ну его?

Валентин Удальцов, Пых: Бизнес-логику, естественно, никакой статический анализ не проверит. А вот типы и все эти совершенные тупые ошибки снижаются процентов на 80. Да, в начале будет сложнее. Но в долгосрочной перспективе это профит. Статический анализ передвигает исправление багов ближе к началу разработки, а это снижает издержки на поддержку проекта.

Ведь всех бесят ошибки с продакшена, когда вместо expected string пришел int, null где-то появился или undefined index. Поэтому разработчик может взвесить все плюсы и минусы, понять, что благодаря статическому анализу вот такие совершенно глупые ошибки исключаются. А еще есть приятный бонус в виде дженериков.

Сергей Жук, Skyeng: А всё же есть какие-то минусы, каких-то кейсы, где вообще не надо использовать стат анализ?

Валентин Удальцов, Пых: Если проект реально большой, а команда привыкла полагаться на runtime издержки на интеграцию могут быть запредельными. Но все равно я бы советовал попробовать baseline внедрить, посмотреть, что как будет. Многие вещи надо в несколько этапов внедрять.

А если вы распиливаете большой монолитный сервис, и по какой-то причине продолжаете на PHP все делать, стоит попробовать.

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

p.s. Найти другие выпуски подкаста вы можете здесь.
Источник: habr.com
К списку статей
Опубликовано: 27.11.2020 10:16:55
0

Сейчас читают

Комментариев (0)
Имя
Электронная почта

Блог компании skyeng

Разработка веб-сайтов

Php

Программирование

Проектирование и рефакторинг

Статический анализ

Psalm

Phpstan

Phan

Категории

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

  • Имя: Макс
    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