Ok, eu tive dois grandes projetos nos quais eu controlei o servidor o suficiente para namespace e confie no carregamento automático.
Primeiro. O carregamento automático é incrível. Não se preocupar com requer é uma coisa relativamente boa.
Aqui está um carregador que eu tenho usado em alguns projetos. Verifica se a classe está no namespace atual primeiro e, em seguida, falha se não. A partir daí, é apenas uma manipulação de string para encontrar a classe.
<?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);
}
Pode-se adaptar isso facilmente para uso sem espaços para nome. Supondo que você prefixe as classes do seu plugin / tema de maneira uniforme, você pode apenas testar esse prefixo. Em seguida, use sublinhados no nome da classe como espaços reservados para separadores de diretório. Se você estiver usando muitas classes, provavelmente usará algum tipo de carregador automático de mapa de classes.
Namespaces e ganchos
O sistema de ganchos do WordPress funciona usando call_user_func
(e call_user_func_array
), que recebe nomes de funções como seqüências de caracteres e os chama quando a chamada de função do_action
(e, posteriormente call_user_func
) é feita.
Com espaços para nome, isso significa que você precisará passar nomes de funções totalmente qualificados que incluem o espaço para nome em ganchos.
<?php
namespace WPSE\SomeNameSpace;
add_filter('some_filter', 'WPSE\\SomeNameSpace\\the_function');
function the_function()
{
return 'did stuff';
}
Provavelmente seria melhor fazer uso liberal da __NAMESPACE__
mágica constante se você quiser fazer isso.
<?php
namespace WPSE\SomeNameSpace;
add_filter('some_filter', __NAMESPACE__ . '\\the_function');
function the_function()
{
return 'did stuff';
}
Se você sempre coloca seus ganchos nas aulas, é mais fácil. O padrão cria a instância de uma classe e todos os ganchos no construtor $this
funcionam bem.
<?php
namespace WPSE\SomeNameSpace;
new Plugin;
class Plugin
{
function __construct()
{
add_action('plugins_loaded', array($this, 'loaded'));
}
function loaded()
{
// this works!
}
}
Se você usar métodos estáticos, como eu quero fazer, precisará passar o nome completo da classe como o primeiro argumento da matriz. Isso dá muito trabalho, então você pode simplesmente usar a __CLASS__
constante mágica ou 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 Classes Principais
A resolução do nome da classe do PHP é um pouco instável. Se você for usar as classes principais do WP ( WP_Widget
no exemplo abaixo), deverá fornecer use
instruções.
use \WP_Widget;
class MyWidget extends WP_Widget
{
// ...
}
Ou você pode usar o nome completo da classe - basicamente prefixando-o com uma barra invertida.
<?php
namespace WPSE\SomeNameSpace;
class MyWidget extends \WP_Widget
{
// ...
}
Define
Este é o PHP mais geral, mas me mordeu, então aqui está.
Você pode definir coisas que usará com frequência, como o caminho para o seu plug-in. O uso da instrução define coloca coisas no espaço para nome raiz, a menos que você passe explicitamente o espaço para nome no primeiro argumento de definição.
<?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__));
Você também pode usar a const
palavra-chave on no nível raiz de um arquivo com PHP 5.3 plus. consts
s estão sempre no espaço para nome atual, mas são menos flexíveis que uma define
chamada.
<?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, sinta-se livre para adicionar outras dicas que você possa ter!