Гаразд, у мене було два великих проекти, де я контролював сервер достатньо, щоб простору імен і покладався на автозавантаження.
Спочатку вгору. Автозавантаження - приголомшливе. Не турбуватися про потреби - це відносно гарна річ.
Ось завантажувач, який я використовував у кількох проектах. Перевіряє, чи спочатку клас перебуває у поточному просторі імен, а потім, якщо ні. Звідти це лише якась струнна маніпуляція для пошуку класу.
<?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
ключове слово на кореневому рівні файлу з PHP 5.3 плюс. 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__);
Будь ласка, не соромтесь додавати будь-які інші поради, які можуть бути у вас!