Рефакторинг #7: Улучшение стиля кодирования в PHP с помощью Rector

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

Забавно, но Rector — это инструмент для рефакторинга, но я бы соврал, если бы не использовал его для изучения пары хороших практик. Действительно, у них есть каталог рефакторингов, готовых к использованию и расширению.

В любом случае, переходим к конфигурационным наборам SetList::CODING_STYLE.

    $rectorConfig->sets([
        LevelSetList::UP_TO_PHP_74,
        SetList::CODE_QUALITY,
        SetList::CODING_STYLE,
    ]);
Вход в полноэкранный режим Выход из полноэкранного режима

Обновления, которые мне очень нравятся

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

Новая строка после утверждения

 class Invoice extends Model
 {
-    protected $appends = ['order_subtotal', 'total'];
-    protected $guarded = [];

+    protected $appends = ['order_subtotal', 'total'];
+
+    protected $guarded = [];
Войти в полноэкранный режим Выйти из полноэкранного режима

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

Разделять несколько утверждений use.

 class Delivered
 {
-    use Dispatchable, InteractsWithSockets, SerializesModels;

+    use Dispatchable;
+    use InteractsWithSockets;
+    use SerializesModels;
Входить в полноэкранный режим Выйти из полноэкранного режима

Мне нравится вот это. Размещая утверждения use одно под другим, мне легче их найти. Также, скрытые жемчужины, если вы добавите/удалите одну из них, они появятся как добавления/удаления при просмотре git diff, вместо изменения в одну строку, на которое уйдет секунда.

Обратите внимание, что правило с новыми строками выше не влияет на утверждения use, они по-прежнему хорошо упакованы вместе.

Упрощение экранирования кавычек

-    return ['message' => 'You're already verified.'];

+    return ['message' => "You're already verified."];
Вход в полноэкранный режим Выйти из полноэкранного режима

О, я виноват в этом. Это довольно частое явление — начинать строку с одинарных кавычек, когда она приятно вписывается в соседние строки, а потом обнаружить, что нужно использовать ‘you’re’ с неудобным обратным слешем. То же самое с использованием двойных кавычек. Какой прекрасный рефактор.

Оберните переменные фигурными скобками

-    return "Service $service does not exist!";

+    return "Service {$service} does not exist!";
Войти в полноэкранный режим Выйти из полноэкранного режима

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

Преобразовать switch в if-else.

-    switch ($event->type) {
-        case 'payment_intent.succeeded':
-            $this->handlePaymentIntentSucceeded($event);
-            break;
-        default:
-            abort(404);
-    }

+    if ($event->type == 'payment_intent.succeeded') {
+        $this->handlePaymentIntentSucceeded($event);
+    } else {
+        abort(404);
+    }

Вход в полноэкранный режим Выйти из полноэкранного режима

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

Сопоставьте исключения catch с их типами

-    } catch (Card $e) {
-        $body = $e->getJsonBody();

+    } catch (Card $card) {
+        $body = $card->getJsonBody();
Вход в полноэкранный режим Выйти из полноэкранного режима

Сначала у меня были некоторые сомнения по поводу этого правила. Мне нравилась короткая версия $e, она была красивой и чистой, но я думаю, что правильное имя исключения дает больше контекста. Хорошо, хорошо, я оставляю этот вариант.

Унаследованный метод с той же видимостью, что и родительский

     use RefreshDatabase;

-    public function setUp():void

+    protected function setUp():void
     {
         parent::setUp();
Вход в полноэкранный режим Выход из полноэкранного режима

Я не замечал этого раньше, но у меня было много тестовых классов, где я устанавливал функцию setUp как public. Я помню, как сделал это однажды в одном тесте, и с тех пор я копировал этот метод 😂.

Не делайте этой ошибки, генерируйте свои тесты с помощью php artisan make:test ExampleTest, и изменяйте заглушки по своему усмотрению с помощью php artisan stub:publish.

Модификации, к которым у меня смешанные чувства

Статические стрелочные функции и закрытия

    $schedule->command('some:dummy-command')
-        ->when(fn() => Carbon::now()->endOfWeek()->isToday());

+        ->when(static fn() => Carbon::now()->endOfWeek()->isToday());
Вход в полноэкранный режим Выход из полноэкранного режима

Существуют два правила, которые на самом деле встречаются довольно часто: префикс стрелочных функций и закрытий с static всегда, когда это возможно. То есть, если закрытию не нужна ссылка $this, его можно сделать статическим. Однако я отказываюсь от этих правил, поскольку RFC отмечает, что они, вероятно, не нужны.

Статические замыкания используются редко: В основном они используются для предотвращения циклов $this, которые делают поведение GC менее предсказуемым. Большинству кода не нужно беспокоиться об этом.

Вы можете пропустить правила, просто добавив их в конфигурацию ректора, например, так:

    $rectorConfig->skip([
        // ...
        StaticArrowFunctionRector::class,
        StaticClosureRector::class,
    ]);
Войти в полноэкранный режим Выйти из полноэкранного режима

Преобразовать пост-инкременты в пре-инкременты

-    $count++;

+    ++$count;
Ввести полноэкранный режим Выйти из полноэкранного режима

Этот вопрос заставил меня сильно задуматься. Зачем мне это нужно? Я проверил выпуск и PR, которые добавили это правило, и выяснил, что это зеркальное правило из PHPStan. Я знаю, что есть некоторые крайние случаи, когда разработчики будут ++ везде, где только можно, в операторах if и ключах массивов, но, черт возьми, это правило сделало много кода немного подозрительным. Или я просто не привык к этому и это на самом деле довольно распространено. Я пропущу это сейчас, возможно, мы снова пересечемся в будущем (PostIncDecToPreIncDecRector).

Преобразование встроенных переменных в sprintfs

-    "Order canceled with reason {$reason}."

+    sprintf('Order canceled with reason %s', $reason)
Вход в полноэкранный режим Выйти из полноэкранного режима

Я не уверен, что понимаю, как версия sprintf является более читабельной, чем инкапсированная. Возможно, если бы я хотел сделать какое-то форматирование, но в существующем проекте форматирование уже было сделано другим способом. Это очень похоже на C, если не учитывать и этот вариант (EncapsedStringsToSprintfRector).

Здесь мы пока делаем паузу. Этот список, конечно, неполный, невозможно охватить все рефакторинги Code Style, которые он может сделать. Мы продолжим изучение других рефакторингов, таких как мертвый код и ранние возвраты, в другом посте. До встречи 🏠.

Оцените статью
devanswers.ru
Добавить комментарий