De acuerdo, he tenido dos grandes proyectos en los que he tenido el control del servidor lo suficiente como para dejar espacio de nombres y confiar en la carga automática.
En primer lugar. La carga automática es impresionante. No preocuparse por las necesidades es algo relativamente bueno.
Aquí hay un cargador que he estado usando en algunos proyectos. Comprueba que la clase esté en el espacio de nombres actual primero, y luego salte si no. Desde allí es solo una manipulación de cadenas para encontrar la clase.
<?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);
}
Uno podría adaptarlo fácilmente para su uso sin espacios de nombres. Suponiendo que prefieres las clases de tu plugin / tema de manera uniforme, simplemente puedes probar ese prefijo. Luego use guiones bajos en el nombre de la clase como marcadores de posición para los separadores de directorios. Si está utilizando muchas clases, es probable que desee utilizar algún tipo de autocargador de mapas de clase.
Espacios de nombres y ganchos
El sistema de enganches de WordPress funciona usando call_user_func
(y call_user_func_array
), que toma los nombres de las funciones como cadenas y las llama cuando se realiza la llamada a la función do_action
(y, posteriormente, call_user_func
).
Con los espacios de nombres, eso significa que deberá pasar nombres de funciones completamente calificados que incluyan el espacio de nombres en los ganchos.
<?php
namespace WPSE\SomeNameSpace;
add_filter('some_filter', 'WPSE\SomeNameSpace\the_function');
function the_function()
{
return 'did stuff';
}
Probablemente sería mejor hacer un uso liberal de la constante __NAMESPACE__
magic si quieres hacer esto.
<?php
namespace WPSE\SomeNameSpace;
add_filter('some_filter', __NAMESPACE__ . '\the_function');
function the_function()
{
return 'did stuff';
}
Si siempre pones tus ganchos en clases, es más fácil. La instancia estándar de creación de una clase y todos los enlaces en el constructor con $this
funcionan bien.
<?php
namespace WPSE\SomeNameSpace;
new Plugin;
class Plugin
{
function __construct()
{
add_action('plugins_loaded', array($this, 'loaded'));
}
function loaded()
{
// this works!
}
}
Si usa métodos estáticos como los que quiero hacer, deberá pasar el nombre de clase completo como el primer argumento de la matriz. Eso es mucho trabajo, así que solo puedes usar magic __CLASS__
constant o 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!
}
}
Usando clases principales
La resolución del nombre de clase de PHP es un poco torpe. Si va a utilizar clases de WP principales ( WP_Widget
en el ejemplo a continuación), debe proporcionar use
enunciados.
use \WP_Widget;
class MyWidget extends WP_Widget
{
// ...
}
O puede usar el nombre de clase completo, básicamente con un prefijo con una barra invertida.
<?php
namespace WPSE\SomeNameSpace;
class MyWidget extends \WP_Widget
{
// ...
}
Define
Esto es PHP más general, pero me mordió, así que aquí está.
Es posible que desee definir cosas que usará a menudo, como la ruta de acceso a su complemento. El uso de la declaración de definición coloca las cosas en el espacio de nombres raíz a menos que pase explícitamente el espacio de nombres al primer argumento de definir.
<?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__));
También puede usar la palabra clave const
en el nivel raíz de un archivo con PHP 5.3 más. consts
s siempre están en el espacio de nombres actual, pero son menos flexibles que una llamada a define
.
<?php
namespace WPSE\SomeNameSpace;
// in the current namespace
const MY_CONST = 1;
// this won't work!
const MY_PATH = plugin_dir_path(__FILE__);
Por favor, siéntase libre de agregar cualquier otro consejo que pueda tener.