Изменения языка PHP для рефакторинга

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

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

В целом же по моим наблюдениям в течении последних 20 лет php движется в сторону увеличения вариативности и динамических возможностей языка.

Обращения к результатам методов

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

Функции с неизвестным числом параметров

Если до версии php 8.0 необходимо было всегда использовать ...array_values, а до версии php 5.6 такой возможности вообще не было, то с появлением именованных аргументов функции все стало гораздо проще и можно просто писать ...$vars передавая массив значений. Это еще одно упрощение, которое можно пока не внедрять, и мы пойдем от простого и незначительного к более сложному и значимому.

Избавляемся от плохого кода сохраняя обратную совместимость

DIRECTORY_SEPARATOR с версии php 7 больше не нужен, можно писать просто /, но можно и оставить, но опять же громоздкость константы конечно усложняет чтение кода.

Далее действительно идет то, что важно исправить на проекте с устаревшим легаси кодом.

Этим на проекте можно заняться в первую очередь, так как обратная совместимость здесь сохраняется

$$this→property писать с версии php 7 уже нельзя, а вот ${$this→property} — можно писать и в новых версиях и в версии php 5.etc…

Функция list() не может быть пустой, можно сохранить функцию, но определить хотя бы некоторые из переменных для сопоставления.

Смена синтаксиса

Для тех у кого уж совсем старый легаси - функции call_user_method/_array устарели с php 4.1 вместо них call_user_func/_array

Возвращаемся к пресловутому switch - с версии php 8 switch заменили на match

С версии php 8 __autoload сменился на spl_autoload_register

Также с версии php 8:

create_function, each больше не существуют

$array{"key"} больше не работает

Вызов crypt() без явной передачи соли больше не поддерживается

Логика работы приложения

Самые важные изменения происходят именно с логикой языка, потому как в принципе развитие языка — это и есть развитие его логики в отличии от человеческих языков где меняется именно синтаксис или морфология слов.

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

  • В цикле foreach с версии php 7 указатель не смещается, то есть current не меняется, и там где обращались через него необходимо задать точное смещение
  • Если ранее в цикле foreach добавлялись элементы к массиву и это ни на что не влияло, с версии php 7 эти значения попадут в массив и их нужно будет вынести из цикла.
  • Побитовые смещения на отрицательную величину с версии php 7 выбрасывают исключения
  • При делении на ноль в php 7 вместо falsr выводится INF или при попытке получить остаток от деления на ноль NAN
  • Шестнадцатеричные числа с версии php 7 больше не выводятся как числа
  • С версии php 7 нельзя больше передавать объект по ссылке
  • К ошибкам приведут статические вызовы нестатических свойств и методов с версии php 7
  • Больше нельзя использовать не объявленные свойства класса
  • С php 7 невозможно задать более одного блока default в операторе switch
  • Более строгое сравнение 0 и строки, теперь при нестрогом сравнении с версии php 8 нам все равно будет выведено false
  • Match и mixed теперь зарезервированные слова и их нужно удалить из старого легаси кода, иначе это приведет к ошибкам
  • С php 8 методы с именем как у класса больше не интерпретируются как конструкторы

Также с версии php 8:

  • Нумерация массивов теперь идет с n n++ etc…
  • Смена приоритета в конкатенации

echo "Сумма: " . $a + $b;

ранее интерпретировалось как:

echo ("Сумма: " . $a) + $b;

сейчас интерпретируется так:

echo "Сумма:" . ($a + $b);

  • substr(), mb_substr(), iconv_substr() и grapheme_substr() теперь последовательно фиксируют смещения за пределы границы строки
  • Имя анонимного класса будет включать имя первого родителя или интерфейса
  • data:// больше недоступна для записи
  • Функцию array_key_exists() больше нельзя вызывать с объектами.

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

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

Начать дискуссию