Intereting Posts
Проверка многопользовательской активации темы Сделать мое главное меню меню гамбургеров на всех платформах URL-адрес пользовательского поиска WordPress Получение значения из get_post_custom Доступ к файлам с использованием постоянных ссылок Изменение UserMeta поля Pods с использованием WP Rest API Шаблон WordPress author.php не работает с пользовательской структурой постоянной ссылки! Помогите! Обработка формы: как обработать форму перед выходом и получить доступ к данным из короткого кода Как отображать сообщения с определенным значением в настраиваемом поле в мой цикл? Исправлена ​​высота объекта__состояния () Какова ваша наилучшая практика для выполнения одноразовых скриптов? Добавление заголовка и описания к показанному изображению подстраницы Как добавить «или» вместо и «и» (&) в запросе WordPress? Преобразовать страницу параметров темы, которая будет использоваться в customize.php также? Использование сообщений caller_ get_

Автозагрузка и пространства имен в плагинах и темах WordPress: может ли это работать?

Кто-нибудь использовал автозагрузку и / или пространства имен PHP в плагине или теме?

Мысли об их использовании? Любой вред? Ловушки?

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

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

Сначала. Автозагрузка – это потрясающе. Не беспокоясь о требованиях, это относительно хорошая вещь.

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

<?php spl_autoload_register(__NAMESPACE__ . '\\autoload'); function autoload($cls) { $cls = ltrim($cls, '\\'); if(strpos($cls, __NAMESPACE__) !== 0) return; $cls = str_replace(__NAMESPACE__, '', $cls); $path = PLUGIN_PATH_PATH . 'inc' . str_replace('\\', DIRECTORY_SEPARATOR, $cls) . '.php'; require_once($path); } 

Его можно легко адаптировать для использования без пространств имен. Предполагая, что вы равномерно распределяете классы плагина / темы, вы можете просто проверить этот префикс. Затем используйте символы подчеркивания в имени класса в качестве заполнителей для разделителей каталогов. Если вы используете много классов, скорее всего, вы захотите использовать какой-то автозагрузчик classmap.

Пространства имен и крючки

Система крючков WordPress работает с помощью call_user_funccall_user_func_array ), которая принимает имена функций в виде строк и вызывает их при do_action функции do_action (и, впоследствии, call_user_func ).

В пространствах имен это означает, что вам нужно передать полностью квалифицированные имена функций, которые включают пространство имен в hooks.

 <?php namespace WPSE\SomeNameSpace; add_filter('some_filter', 'WPSE\\SomeNameSpace\\the_function'); function the_function() { return 'did stuff'; } 

Вероятно, было бы лучше использовать либеральную константу __NAMESPACE__ если вы хотите это сделать.

 <?php namespace WPSE\SomeNameSpace; add_filter('some_filter', __NAMESPACE__ . '\\the_function'); function the_function() { return 'did stuff'; } 

Если вы всегда ставите свои крючки в классы, это проще. Стандартный экземпляр экземпляра класса и всех крючков в конструкторе с $this отлично работает.

 <?php namespace WPSE\SomeNameSpace; new Plugin; class Plugin { function __construct() { add_action('plugins_loaded', array($this, 'loaded')); } function loaded() { // this works! } } 

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

 <?php namespace WPSE\SomeNameSpace; Plugin::init(); class Plugin { public static function init() { add_action('plugins_loaded', array(__CLASS__, 'loaded')); // OR: add_action('plugins_loaded', array(get_class(), 'loaded')); } public static function loaded() { // this works! } } 

Использование основных классов

Разрешение имен классов PHP немного неудобно. Если вы собираетесь использовать основные классы WP ( WP_Widget в приведенном ниже примере), вы должны предоставить операторы use .

 use \WP_Widget; class MyWidget extends WP_Widget { // ... } 

Или вы можете использовать полное имя класса – в основном просто префикс его с обратной косой чертой.

 <?php namespace WPSE\SomeNameSpace; class MyWidget extends \WP_Widget { // ... } 

Определяет

Это более общий PHP, но он укусил меня, так что вот оно.

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

 <?php namespace WPSE\SomeNameSpace; // root namespace define('WPSE_63668_PATH', plugin_dir_path(__FILE__)); // in the current namespace define(__NAMESPACE__ . '\\PATH', plugin_dir_path(__FILE__)); 

Вы также можете использовать ключевое слово const на корневом уровне файла с PHP 5.3 plus. consts s всегда находятся в текущем пространстве имен, но менее гибки, чем вызов define .

 <?php namespace WPSE\SomeNameSpace; // in the current namespace const MY_CONST = 1; // this won't work! const MY_PATH = plugin_dir_path(__FILE__); 

Пожалуйста, не стесняйтесь добавлять любые другие советы, которые у вас могут быть!

Вот ответ 2017 года.

Автозагрузка – это потрясающе. Пространство имен является удивительным.

Хотя вы можете опрокинуть ее самостоятельно, в 2017 году наиболее разумно использовать великолепный и вездесущий Composer для обработки ваших требований PHP. Композитор поддерживает автозагрузку PSR-0 и PSR-4 , но первый из них устарел с 2014 года, поэтому используйте PSR-4. Это уменьшает сложность ваших каталогов.

Мы сохраняем каждый из наших плагинов / тем в своем собственном репозитории Github, каждый со своим собственным файлом composer.lock файлом composer.lock .

Вот структура каталогов, которую мы используем для наших плагинов. (У нас на самом деле нет плагина под названием awesome-plugin , но мы должны.)

 plugins/awesome-plugin/bootstrap.php plugins/awesome-plugin/composer.json plugins/awesome-plugin/composer.lock plugins/awesome-plugin/awesome-plugin.php plugins/awesome-plugin/src/* plugins/awesome-plugin/vendor/autoload.php plugins/awesome-plugin/vendor/* 

Если вы предоставите соответствующий файл composer.json , Composer обрабатывает интервал между именами и автозагрузку.

 { "name": "awesome-company/awesome-plugin", "description": "Wordpress plugin for AwesomeCompany website, providing awesome functionality.", "type": "wordpress-plugin", "autoload": { "psr-4": { "AwesomeCompany\\Plugins\\AwesomePlugin\\": "src" } } } 

Когда вы запускаете composer install , он создает каталог vendor/autoload.php файл vendor/autoload.php , который будет автоматически загружать все ваши файлы с именами в src/ и любые другие библиотеки, которые могут потребоваться.

Затем в верхней части основного файла плагина (который для нас является awesome-plugin.php ), после ваших метаданных плагина, вам просто нужно:

 // Composer autoloading. require_once __DIR__ . '/vendor/autoload.php'; ... 

Бонусная функция

Не обязательно, но мы используем шаблон Bedrock WordPress для использования Composer с самого начала. Затем мы можем использовать Composer для сборки плагинов, которые нам нужны с помощью Composer, включая ваш собственный плагин, который вы написали выше. Кроме того, благодаря WPackagist , вы можете потребовать любой другой плагин из WordPress.org (см. Пример cool-theme и cool-plugin ниже).

 { "name": "awesome-company/awesome-website", "type": "project", "license": "proprietary", "description": "WordPress boilerplate with modern development tools, easier configuration, and an improved folder structure", "config": { "preferred-install": "dist" }, "repositories": [ { "type": "composer", "url": "https://wpackagist.org" }, { // Tells Composer to look for our proprietary Awesome Plugin here. "url": "https://github.com/awesome-company/awesome-plugin.git", "type": "git" } ], "require": { "php": ">=5.5", "awesome-company/awesome-plugin": "dev-production", // Our plugin! "wpackagist-plugin/cool-plugin": "dev-trunk", // Someone else' plugin "wpackagist-theme/cool-theme": "dev-trunk", // Someone else' theme "composer/installers": "~1.2.0", // Bedrock default "vlucas/phpdotenv": "^2.0.1", // Bedrock default "johnpbloch/wordpress": "4.7.5", // Bedrock default "oscarotero/env": "^1.0", // Bedrock default "roots/wp-password-bcrypt": "1.0.0" // Bedrock default }, "extra": { // This is the magic that drops packages with the correct TYPE in the correct location. "installer-paths": { "web/app/mu-plugins/{$name}/": ["type:wordpress-muplugin"], "web/app/plugins/{$name}/": ["type:wordpress-plugin"], "web/app/themes/{$name}/": ["type:wordpress-theme"] }, "wordpress-install-dir": "web/wp" }, "scripts": { "test": [ "vendor/bin/phpcs" ] } } 

Примечание 1: Комментарии не являются законными в JSON, но я более подробно объяснил вышеприведенный файл.

Примечание 2: Я сократил некоторые бит файла шаблона Bedrock для краткости.

Примечание 3: Вот почему поле type в первом файле composer.json является значительным. Композитор автоматически помещает его в каталог web/app/plugins .

Я использую автозагрузку (поскольку мой плагин имеет множество классов – отчасти потому, что он включает Twig), никогда не было проблемы, которая была доведена до моего внимания (плагин установлен> 20 000 раз).

Если вы уверены, что вам никогда не понадобится использовать php-установку, которая не поддерживает пространства имен, то опять вы в порядке (~ 70% текущих блогов WordPress не поддерживают пространства имен). Несколько замечаний:

Я, кажется, помню, что пространства имен не чувствительны к регистру в обычном php, но при использовании fastcgi php на iis – это вызывает некоторые головные боли, если вы тестируете на linux и не обнаруживаете букву изгоев в нижнем регистре.

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