Улучшение кода WordPress с помощью современного PHP

Опубликовано: 2022-03-10
Краткое резюме ↬ Из-за обратной совместимости WordPress не использует преимущества новых функций PHP, выпущенных после PHP 5.2.4. К счастью, WordPress скоро потребует PHP 5.6+, а вскоре после этого даже PHP 7.0+. В этой статье представлен обзор функций PHP, недавно доступных для WordPress, и сделана попытка предложить, как их можно использовать для создания лучшего программного обеспечения.

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

Но эти дни скоро закончатся! WordPress обновит свою минимальную поддержку версии PHP, увеличив ее до PHP 5.6 в апреле 2019 года и PHP 7 в декабре 2019 года (если все пойдет по плану). После этого мы, наконец, сможем начать использовать возможности императивного программирования PHP, не опасаясь взлома сайтов наших клиентов. Ура!

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

Эта статья состоит из двух частей:

  1. Наиболее актуальные новые функции
    В версии PHP 5.3, 5.4, 5.5, 5.6 и 7.0 были добавлены дополнительные функции (обратите внимание, что PHP 6 отсутствует), и мы рассмотрим наиболее важные из них.
  2. Создание лучшего программного обеспечения
    Мы более подробно рассмотрим эти функции и то, как они могут помочь нам в создании лучшего программного обеспечения.

Начнем с изучения «новых» возможностей PHP.

Еще после прыжка! Продолжить чтение ниже ↓

Классы, ООП, SOLID и шаблоны проектирования

Классы и объекты были добавлены в PHP 5, поэтому WordPress уже использует эти функции, однако не очень широко и не всесторонне: Парадигма кодирования в WordPress в основном представляет собой функциональное программирование (выполнение вычислений путем вызова функций, лишенных состояния приложения) вместо объекта. -ориентированное программирование (ООП) (выполнение вычислений путем управления состоянием объектов). Поэтому я также описываю классы и объекты и то, как их использовать через ООП.

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

У класса есть свойства и функции, которым можно придать видимость с помощью private (доступных только внутри определяющего класса), protected (доступных внутри определяющего класса и его предков и наследующих классов) и public (доступных отовсюду). Изнутри функции мы можем получить доступ к свойствам класса, добавив к их именам $this-> :

 class Person { protected $name; public function __construct($name) { $this->name = $name; } public function getIntroduction() { return sprintf( __('My name is %s'), $this->name ); } }

Класс превращается в объект с помощью ключевого слова new , после чего мы можем получить доступ к его свойствам и функциям через -> :

 $person = new Person('Pedro'); echo $person->getIntroduction(); // This prints "My name is Pedro"

Наследующий класс может переопределить public и protected функции своих классов-предков и получить доступ к функциям-предкам, добавив перед ними parent:: :

 class WorkerPerson extends Person { protected $occupation; public function __construct($name, $occupation) { parent::__construct($name); $this->occupation = $occupation; } public function getIntroduction() { return sprintf( __('%s and my occupation is %s'), parent::getIntroduction(), $this->occupation ); } } $worker = new WorkerPerson('Pedro', 'web development'); echo $worker->getIntroduction(); // This prints "My name is Pedro and my occupation is web development"

Метод можно сделать abstract , что означает, что он должен быть реализован наследующим классом. Класс, содержащий abstract метод, должен быть сам abstract , что означает, что он не может быть создан; только класс, реализующий абстрактный метод, может быть создан:

 abstract class Person { abstract public function getName(); public function getIntroduction() { return sprintf( __('My name is %s'), $this->getName() ); } } // Person cannot be instantiated class Manuel extends Person { public function getName() { return 'Manuel'; } } // Manuel can be instantiated $manuel = new Manuel();

Классы также могут определять static методы и свойства, которые существуют в самом классе, а не в экземпляре класса как объекта. Доступ к ним осуществляется через self:: изнутри класса и через имя класса + :: извне:

 class Factory { protected static $instances = []; public static function registerInstance($handle, $instance) { self::$instances[$handle] = $instance; } public static function getInstance($handle) { return self::$instances[$handle]; } } $engine = Factory::getInstance('Engine');

Чтобы получить максимальную отдачу от ООП, мы можем использовать принципы SOLID для создания надежной, но легко настраиваемой основы для приложения, а также шаблоны проектирования для решения конкретных проблем проверенным и проверенным способом. Шаблоны проектирования стандартизированы и хорошо задокументированы, что позволяет разработчикам понять, как различные компоненты в приложении связаны друг с другом, и предоставляет способ структурировать приложение упорядоченным образом, что помогает избежать использования глобальных переменных (таких как global $wpdb ). которые загрязняют глобальную окружающую среду.

Пространства имен

Пространства имен были добавлены в PHP 5.3, поэтому в настоящее время они полностью отсутствуют в ядре WordPress.

Пространства имен позволяют организовать кодовую базу структурно, чтобы избежать конфликтов, когда разные элементы имеют одно и то же имя — аналогично каталогам операционной системы, которые позволяют иметь разные файлы с одним и тем же именем, пока они хранятся в разных каталогах. Пространства имен выполняют тот же трюк инкапсуляции для элементов PHP (таких как классы, свойства и интерфейсы), избегая коллизий, когда разные элементы имеют одно и то же имя, помещая их в разные пространства имен.

Пространства имен необходимы при взаимодействии со сторонними библиотеками, поскольку мы не можем контролировать, как будут называться их элементы, что может привести к возможным конфликтам при использовании стандартных имен, таких как «Файл», «Журнал» или «Загрузчик» для наших элементов. Более того, даже в пределах одного проекта пространства имен не позволяют именам классов становиться слишком длинными, чтобы избежать конфликтов с другими классами, что может привести к таким именам, как «MyProject_Controller_FileUpload».

Пространства имен определяются с помощью ключевого слова namespace (размещаются в строке сразу после открытия <?php ) и могут охватывать несколько уровней или подпространств имен (аналогично наличию нескольких подкаталогов при размещении файла), которые разделяются с помощью \ :

 <?php namespace CoolSoft\ImageResizer\Controllers; class ImageUpload { }

Чтобы получить доступ к вышеуказанному классу, нам нужно полностью определить его имя, включая его пространство имен (и начиная с \ ):

 $imageUpload = new \CoolSoft\ImageResizer\Controllers\ImageUpload();

Или мы также можем импортировать класс в текущий контекст, после чего мы можем напрямую ссылаться на класс по его имени:

 use CoolSoft\ImageResizer\Controllers\ImageUpload; $imageUpload = new ImageUpload();

Называя пространства имен в соответствии с установленными соглашениями, мы можем получить дополнительные преимущества. Например, следуя Рекомендации стандартов PHP PSR-4, приложение может использовать механизм автозагрузки Composer для загрузки файлов, тем самым уменьшая сложность и добавляя беспрепятственное взаимодействие между зависимостями. Это соглашение предусматривает включение имени поставщика (например, названия компании) в качестве верхнего подпространства имен, за которым может следовать имя пакета, и только затем следует внутренняя структура, в которой каждое подпространство имен соответствует каталогу с тем же именем. Результат сопоставляет 1 к 1 физическое расположение файла на диске с пространством имен элемента, определенного в файле.

Черты

Трейты были добавлены в PHP 5.4, поэтому в настоящее время они полностью отсутствуют в ядре WordPress.

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

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

Черта определяется с помощью ключевого слова trait , после чего ее можно импортировать в любой класс с use ключевого слова use. В приведенном ниже примере два совершенно не связанных между собой класса Person и Shop могут повторно использовать один и тот же код через трейт Addressable :

 trait Addressable { protected $address; public function getAddress() { return $this->address; } public function setAddress($address) { $this->address = $address; } } class Person { use Addressable; } class Shop { use Addressable; } $person = new Person('Juan Carlos'); $person->setAddress('Obelisco, Buenos Aires');

Класс также может состоять из более чем одного трейта:

 trait Exportable { public class exportToCSV($filename) { // Iterate all properties and export them to a CSV file } } class Person { use Addressable, Exportable; }

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

Интерфейсы

Интерфейсы были добавлены в PHP 5, так что WordPress уже использует эту возможность, правда, крайне экономно: всего ядро ​​включает менее десяти интерфейсов!

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

Интерфейсы определяются с помощью ключевого слова interface и должны перечислять только сигнатуры своих методов (т. е. без определения их содержимого), которые должны иметь public видимость (по умолчанию добавление ключевого слова no visibility также делает его общедоступным):

 interface FileStorage { function save($filename, $contents); function readContents($filename); }

Класс определяет, что он implements интерфейс через ключевое слово Implements:

 class LocalDriveFileStorage implements FileStorage { function save($filename, $contents) { // Implement logic } function readContents($filename) { // Implement logic } }

Класс может реализовывать более одного интерфейса, разделяя их , :

 interface AWSService { function getRegion(); } class S3FileStorage implements FileStorage, AWSService { function save($filename, $contents) { // Implement logic } function readContents($filename) { // Implement logic } function getRegion() { return 'us-east-1'; } }

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

Закрытия

Замыкания были добавлены в PHP 5.3, поэтому в настоящее время они полностью отсутствуют в ядре WordPress.

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

До замыканий всякий раз, когда мы передавали функцию в качестве аргумента другой функции, нам приходилось заранее определять функцию и передавать ее имя в качестве аргумента:

 function duplicate($price) { return $price*2; } $touristPrices = array_map('duplicate', $localPrices);

С замыканиями анонимная (т.е. без имени) функция уже может быть передана напрямую в качестве параметра:

 $touristPrices = array_map(function($price) { return $price*2; }, $localPrices);

Замыкания могут импортировать переменные в свой контекст с use ключевого слова use:

 $factor = 2; $touristPrices = array_map(function($price) use($factor) { return $price*$factor; }, $localPrices);

Генераторы

Генераторы были добавлены в PHP 5.5, поэтому в настоящее время они полностью отсутствуют в ядре WordPress.

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

 function xrange($start, $limit, $step = 1) { for ($i = $start; $i <= $limit; $i += $step) { yield $i; } } foreach (xrange(1, 9, 2) as $number) { echo "$number "; } // This prints: 1 3 5 7 9

Объявления аргументов и возвращаемых типов

В разных версиях PHP были введены разные объявления типов аргументов: WordPress уже может объявлять интерфейсы и массивы (чего нет: я едва нашел один экземпляр функции, объявляющей массив в качестве параметра в ядре, и никаких интерфейсов), и будет вскоре появится возможность объявлять вызываемые объекты (добавлено в PHP 5.4) и скалярные типы: bool, float, int и string (добавлено в PHP 7.0). Объявления возвращаемого типа были добавлены в PHP 7.0.

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

Тип аргумента объявляется перед именем переменной аргумента, а тип возвращаемого значения объявляется после аргументов, которым предшествует : :

 function foo(boolean $bar): int { }

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

Принудительный режим используется по умолчанию. Чтобы включить строгий режим, мы должны добавить оператор declare , используемый с объявлением strict_types :

 declare(strict_types=1); function foo(boolean $bar) { }

Новый синтаксис и операторы

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

 function sum(...$numbers) { $sum = 0; foreach ($numbers as $number) { $sum += $number; } return $sum; }

Начиная с PHP 5.6, константы могут включать скалярные выражения, включающие числовые и строковые литералы, а не только статические значения, а также массивы:

 const SUM = 37 + 2; // A scalar expression const LETTERS = ['a', 'b', 'c']; // An array

Начиная с PHP 7.0, массивы также можно определять с помощью define :

 define('LETTERS', ['a', 'b', 'c']);

В PHP 7.0 добавлено несколько новых операторов: оператор объединения Null ( ?? ) и оператор Spaceship ( <=> ).

Оператор объединения Null ?? является синтаксическим сахаром для общего случая необходимости использования троичного кода в сочетании с isset(). Он возвращает свой первый операнд, если он существует и не равен NULL; в противном случае возвращается второй операнд.

 $username = $_GET['user'] ?? 'nobody'; // This is equivalent to: // $username = isset($_GET['user']) ? $_GET['user'] : 'nobody';

Оператор Spaceship <=> используется для сравнения двух выражений, возвращая -1, 0 или 1, когда первый операнд соответственно меньше, равен или больше второго операнда.

 echo 1 <=> 2; // returns -1 echo 1 <=> 1; // returns 0 echo 2 <=> 1; // returns 1

Это наиболее важные новые функции, добавленные в PHP с версий 5.3 по 7.0. Список дополнительных новых функций, не перечисленных в этой статье, можно получить, просмотрев документацию PHP по переходу с версии на версию.

Далее мы анализируем, как максимально использовать все эти новые функции и последние тенденции в веб-разработке для создания более качественного программного обеспечения.

Рекомендации по стандартам PHP

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

Текущие рекомендации следующие:

Группа Рекомендация Описание
Стили кодирования
Стандартизированное форматирование уменьшает когнитивные трения при чтении кода других авторов.
ПСР-1 Базовый стандарт кодирования
ПСР-2 Руководство по стилю кодирования
Автозагрузка
Автозагрузчики упрощают включение файлов, сопоставляя пространства имен с путями файловой системы.
ПСР-4 Улучшенная автозагрузка
Интерфейсы
Интерфейсы упрощают совместное использование кода между проектами, следуя ожидаемым контрактам.
ПСР-3 Интерфейс регистратора
ПСР-6 Интерфейс кэширования
ПСР-11 Контейнерный интерфейс
ПСР-13 Гипермедийные ссылки
ПСР-16 Простой кэш
HTTP
Совместимые стандарты и интерфейсы для независимого подхода к обработке HTTP-запросов и ответов как на стороне клиента, так и на стороне сервера.
ПСР-7 Интерфейсы HTTP-сообщений
ПСР-15 HTTP-обработчики
ПСР-17 HTTP-фабрики
ПСР-18 HTTP-клиент

Думай и кодируй в компонентах

Компоненты позволяют использовать лучшие функции фреймворка, не привязываясь к самому фреймворку. Например, Symfony был выпущен как набор повторно используемых компонентов PHP, которые можно установить независимо от среды Symfony; Laravel, еще одна PHP-инфраструктура, использует несколько компонентов Symfony и выпустила собственный набор повторно используемых компонентов, которые можно использовать в любом PHP-проекте.

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

WordPress должен быть частью такого добродетельного цикла разработки. К сожалению, само ядро ​​WordPress построено не из компонентов (о чем свидетельствует практически полное отсутствие интерфейсов) и, более того, в нем даже нет файла composer.json , необходимого для возможности установки WordPress через Composer. Это связано с тем, что сообщество WordPress не согласовало, является ли WordPress зависимостью сайта (в этом случае его установка через Composer будет оправдана) или это сам сайт (в этом случае Composer может быть неподходящим инструментом для работы) .

На мой взгляд, если мы ожидаем, что WordPress останется актуальным в течение следующих пятнадцати лет (по крайней мере, WordPress в качестве серверной CMS), то WordPress должен быть признан зависимым от сайта и доступен для установки через Composer . Причина очень проста: с помощью всего одной команды в терминале Composer позволяет объявить и установить зависимости проекта от тысяч пакетов, опубликованных в Packagist, что позволяет создавать чрезвычайно мощные приложения PHP в кратчайшие сроки, и разработчики любят работая таким образом. Если WordPress не адаптируется к этой модели, он может лишиться поддержки со стороны сообщества разработчиков и кануть в Лету, так же как FTP потерял популярность после введения развертываний на основе Git.

Я бы сказал, что выпуск Гутенберга уже демонстрирует, что WordPress является зависимостью сайта, а не самим сайтом: Гутенберг рассматривает WordPress как безголовую CMS и может также работать с другими серверными системами, как пример Drupal Gutenberg. Следовательно, Гутенберг ясно дает понять, что CMS, на которой работает сайт, может быть заменена, поэтому ее следует рассматривать как зависимость. Более того, сам Гутенберг должен быть основан на компонентах JavaScript, выпущенных через npm (как объяснил основной коммиттер Адам Сильверстайн), поэтому, если ожидается, что клиент WordPress будет управлять своими пакетами JavaScript через диспетчер пакетов npm, то почему бы не расширить эту логику до бэкэнд для управления зависимостями PHP через Composer?

Теперь хорошие новости: нет необходимости ждать решения этой проблемы, так как WordPress уже можно рассматривать как зависимость сайта и устанавливать его через Composer. Джон П. Блох отразил ядро ​​WordPress в Git, добавил файл composer.json и выпустил его в Packagist, а Bedrock от Roots предоставляет пакет для установки WordPress с настраиваемой структурой папок, поддержкой современных инструментов разработки и повышенной безопасностью. А также темы и плагины; пока они перечислены в каталогах тем и плагинов WordPress, они доступны в WordPress Packagist.

Как следствие, разумным вариантом является создание кода WordPress, не думая о темах и плагинах, а думая о компонентах, делая их доступными через Packagist для использования в любом проекте PHP, а также дополнительно упаковывая и выпуская в виде тем и плагины для конкретного использования WordPress. Если компоненту необходимо взаимодействовать с API-интерфейсами WordPress, то эти API-интерфейсы могут быть абстрагированы за интерфейсом, который, если возникнет необходимость, может быть реализован и для других CMS.

Добавление механизма шаблонов для улучшения слоя просмотра

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

Показательным примером является рендеринг HTML-контента на стороне сервера, который выполняется с помощью простых шаблонов PHP. Этот уровень представления можно улучшить с помощью механизмов шаблонов Twig (от Symfony) и Blade (от Laravel), которые обеспечивают очень краткий синтаксис и мощные функции, которые дают ему преимущество перед простыми шаблонами PHP. В частности, динамические блоки Гутенберга могут легко извлечь выгоду из этих механизмов шаблонов, поскольку их процесс рендеринга HTML блока на стороне сервера отделен от архитектуры иерархии шаблонов WordPress.

Архитектор Приложение для общего пользования

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

Чтобы этот подход был эффективным, необходимо учитывать следующие соображения:

Избегайте фиксированных зависимостей (насколько это возможно)

jQuery и Bootstrap (или Foundation, или <–вставьте свою любимую библиотеку здесь–> ) еще несколько лет назад могли считаться обязательными, однако они неуклонно теряют позиции по сравнению с ванильным JS и новыми встроенными функциями CSS. Следовательно, проект общего пользования, написанный пять лет назад и зависящий от этих библиотек, сегодня может быть уже неподходящим. Следовательно, как правило, чем меньше фиксированных зависимостей от сторонних библиотек, тем более актуальной она окажется в долгосрочной перспективе.

Прогрессивное расширение функциональных возможностей

WordPress — это полноценная CMS-система, которая включает в себя управление пользователями, поэтому поддержка управления пользователями включена в стандартную комплектацию. Однако не каждый сайт WordPress требует управления пользователями. Следовательно, наше приложение должно учитывать это и оптимально работать в каждом сценарии: поддерживать управление пользователями, когда это необходимо, но не загружать соответствующие активы, когда это не требуется. Этот подход также может работать постепенно: скажем, клиенту требуется реализовать форму «Свяжитесь с нами», но у него нет бюджета, поэтому мы кодируем ее, используя бесплатный плагин с ограниченными функциями, а у другого клиента есть бюджет, чтобы купить лицензию у коммерческого плагина. лучшие характеристики. Затем мы можем запрограммировать нашу функциональность по умолчанию на очень базовую функциональность и все чаще использовать функции того из плагинов, которые являются наиболее функциональными, доступными в системе.

Непрерывный обзор кода и документации

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

Рекомендуемая литература : Будьте бдительны: функции PHP и WordPress, которые могут сделать ваш сайт небезопасным

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

Ни одно программное обеспечение не бывает совершенным на 100%: ошибки есть всегда, просто мы их еще не нашли. Таким образом, мы должны убедиться, что, как только проблемы возникнут, их будет легко исправить.

Сделай это проще

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

Сбой во время компиляции лучше, чем во время выполнения

Если часть кода может быть проверена на наличие ошибок либо во время компиляции, либо во время выполнения, то мы должны отдать приоритет решению во время компиляции, чтобы ошибка могла возникнуть и быть устранена на этапе разработки и до того, как приложение попадет в рабочую среду. Например, как const , так и define используются для определения констант, однако, в то время как const проверяется во время компиляции, define проверяется во время выполнения. Таким образом, всегда, когда это возможно, использование const предпочтительнее, чем define .

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

 class Foo { public static function bar() { } } add_action('init', ['Foo', 'bar']); // Not so good add_action('init', [Foo::class, 'bar']); // Much better

По той же причине, что и выше, нам следует избегать использования глобальных переменных (таких как global $wpdb ): они не только загрязняют глобальный контекст и их нелегко отследить, откуда они происходят, но также, если они переименованы, ошибка будет производиться во время выполнения. В качестве решения мы можем использовать контейнер внедрения зависимостей для получения экземпляра требуемого объекта.

Работа с ошибками/исключениями

Мы можем создать архитектуру объектов- Exception , чтобы приложение могло реагировать соответствующим образом в соответствии с каждой конкретной проблемой, либо восстанавливаться после нее, когда это возможно, либо показывать пользователю полезное сообщение об ошибке, когда это невозможно, и в целом регистрировать ошибку для админ для решения проблемы. И всегда защищайте своих пользователей от белого экрана смерти: все неперехваченные Error и Exception могут быть перехвачены с помощью функции set_exception_handler , чтобы вывести на экран нестрашное сообщение об ошибке.

Принять инструменты сборки

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

Существуют разные инструменты для достижения разных целей. Например, существуют инструменты сборки для выполнения задач по сжатию и изменению размера изображений, минимизации файлов JS и CSS и копированию файлов в каталог для создания выпуска, таких как Webpack, Grunt и Gulp; другие инструменты помогают создать каркас проекта, что полезно для создания структуры папок для наших тем или плагинов, таких как Yeoman. Действительно, с таким количеством инструментов просмотр статей, сравнивающих различные доступные инструменты, поможет найти наиболее подходящий для наших нужд.

В некоторых случаях, однако, нет инструментов сборки, которые могут достичь именно того, что нужно нашему проекту, поэтому нам может потребоваться закодировать наш собственный инструмент сборки как расширение самого проекта. Например, я сделал это, чтобы сгенерировать файл service-worker.js, чтобы добавить поддержку Service Workers в WordPress.

Заключение

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

К счастью, эти мрачные дни могут скоро закончиться, и WordPress может снова стать блестящей и захватывающей платформой для написания кода: требование PHP 7.0+, начиная с декабря 2019 года, сделает доступным множество функций PHP, что позволит разработчикам создавать более мощные и более производительное программное обеспечение. В этой статье мы рассмотрели наиболее важные новые функции PHP и способы максимально эффективного их использования.

Недавний выпуск Гутенберга может быть признаком грядущих хороших времен: даже если сам Гутенберг не был полностью принят сообществом, по крайней мере, он демонстрирует готовность включить новейшие технологии (такие как React и Webpack) в ядро. . Такой поворот событий заставляет меня задаться вопросом: если внешний интерфейс может преобразиться, почему бы не распространить его на серверную часть? Когда для WordPress потребуется как минимум PHP 7.0, переход на современные инструменты и методологии может ускориться: поскольку npm стал предпочтительным менеджером пакетов JavaScript, почему бы не сделать Composer официальным менеджером зависимостей PHP? Если блоки — это новая единица для создания сайтов во внешнем интерфейсе, почему бы не использовать компоненты PHP в качестве единицы для включения функций в бэкэнд? И, наконец, если Гутенберг рассматривает WordPress как заменяемую серверную CMS, почему бы уже не признать, что WordPress является зависимостью сайта, а не самим сайтом? Я оставлю эти открытые вопросы для вас, чтобы вы могли поразмыслить над ними.