Хорошо, у меня было два больших проекта, в которых я достаточно контролировал сервер, чтобы иметь пространство имен и полагаться на автозагрузку.
Сначала. Автозагрузка потрясающая. Не беспокоиться о потребностях - это относительно хорошая вещь.
Вот загрузчик, который я использовал на нескольких проектах. Проверяет, чтобы убедиться, что класс сначала находится в текущем пространстве имен, а затем выдает ошибку, если нет. Оттуда это всего лишь некоторые манипуляции с строками, чтобы найти класс.
<?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);
}
Можно легко адаптировать это для использования без пространств имен. Предполагая, что вы префиксируете классы вашего плагина / темы единообразно, вы можете просто проверить этот префикс. Затем используйте подчеркивание в имени класса в качестве заполнителей для разделителей каталогов. Если вы используете много классов, вы, вероятно, захотите использовать какой-нибудь автозагрузчик классов.
Пространства имен и крючки
Система перехватов WordPress работает с использованием call_user_func
(и call_user_func_array
), которое принимает имена функций в виде строк и вызывает их при выполнении вызова функции do_action
(и, следовательно, call_user_func
).
С пространствами имен это означает, что вам нужно передать полностью определенные имена функций, которые включают пространство имен, в хуки.
<?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__
константу или 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
ключевое слово on в корневом уровне файла с 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__);
Пожалуйста, не стесняйтесь добавлять любые другие советы, которые вы можете иметь!