D'accord, j'ai eu deux grands projets dans lesquels je maîtrisais suffisamment le serveur pour créer un espace de noms et qui reposait sur le chargement automatique.
Le premier debout. Le chargement automatique est génial. Ne pas s'inquiéter des exigences est une bonne chose
Voici un chargeur que j'ai utilisé sur quelques projets. Vérifie que la classe est d'abord dans l'espace de noms actuel, puis échoue si ce n'est pas le cas. A partir de là, il suffit d'une manipulation de chaîne pour trouver la 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);
}
On pourrait facilement adapter cela pour une utilisation sans espaces de noms. En supposant que vous préfixez les classes de votre plugin / theme de manière uniforme, vous pouvez simplement tester ce préfixe. Ensuite, utilisez des traits de soulignement dans le nom de la classe comme espaces réservés pour les séparateurs de répertoires. Si vous utilisez beaucoup de classes, vous voudrez probablement utiliser une sorte d'autoloader de classmap.
Espaces de noms et crochets
Le système d'accroche de WordPress fonctionne en utilisant call_user_func
(et call_user_func_array
), qui prend les noms de fonction sous forme de chaînes et les appelle à l'appel de la fonction do_action
(et ultérieurement call_user_func
).
Avec les espaces de noms, cela signifie que vous devrez transmettre des noms de fonction complets comprenant l’espace de noms à des points d'ancrage.
<?php
namespace WPSE\SomeNameSpace;
add_filter('some_filter', 'WPSE\\SomeNameSpace\\the_function');
function the_function()
{
return 'did stuff';
}
Il serait probablement préférable de faire un usage libéral de la __NAMESPACE__
constante magique si vous voulez le faire.
<?php
namespace WPSE\SomeNameSpace;
add_filter('some_filter', __NAMESPACE__ . '\\the_function');
function the_function()
{
return 'did stuff';
}
Si vous mettez toujours vos crochets en classe, c'est plus facile. L'instance standard de création d'une classe et tous les points d'ancrage du constructeur $this
fonctionnent correctement.
<?php
namespace WPSE\SomeNameSpace;
new Plugin;
class Plugin
{
function __construct()
{
add_action('plugins_loaded', array($this, 'loaded'));
}
function loaded()
{
// this works!
}
}
Si vous utilisez des méthodes statiques comme je le souhaite, vous devrez passer le nom de classe complet comme premier argument du tableau. C'est beaucoup de travail, vous pouvez donc simplement utiliser la __CLASS__
constante magique 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!
}
}
Utiliser les classes de base
La résolution du nom de classe de PHP est un peu bizarre. Si vous envisagez d'utiliser des classes WP principales ( WP_Widget
dans l'exemple ci-dessous), vous devez fournir des use
instructions.
use \WP_Widget;
class MyWidget extends WP_Widget
{
// ...
}
Ou vous pouvez utiliser le nom de classe complet - en le préfixant simplement par une barre oblique inverse.
<?php
namespace WPSE\SomeNameSpace;
class MyWidget extends \WP_Widget
{
// ...
}
Définit
C'est plus général en PHP, mais ça m’a mordu, alors le voici.
Vous voudrez peut-être définir des éléments que vous utiliserez souvent, tels que le chemin d'accès à votre plugin. L'utilisation de l'instruction define place les éléments dans l'espace de noms racine, à moins que vous ne les transmettiez explicitement au premier argument de 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__));
Vous pouvez également utiliser le const
mot - clé à la racine d'un fichier avec PHP 5.3 plus. consts
s sont toujours dans l’espace de noms actuel, mais sont moins flexibles qu’un define
appel.
<?php
namespace WPSE\SomeNameSpace;
// in the current namespace
const MY_CONST = 1;
// this won't work!
const MY_PATH = plugin_dir_path(__FILE__);
S'il vous plaît n'hésitez pas à ajouter d'autres conseils que vous pourriez avoir!
J'utilise l'autoloading (mon plugin contient de nombreuses classes, en partie parce qu'il inclut Twig), jamais un problème ne m'a été signalé (plugin installé plus de 20 000 fois).
Si vous êtes sûr de ne jamais avoir besoin d'utiliser une installation php ne prenant pas en charge les espaces de noms, tout va bien alors (environ 70% des blogs WordPress actuels ne prennent pas en charge les espaces de noms). Quelques points à noter:
Il semble que je me souvienne que les espaces de noms ne sont pas sensibles à la casse dans php normal, mais le sont quand on utilise fastcgi php sur iis.
De plus, même si vous êtes sûr que le code que vous développez actuellement ne sera utilisé que sur> 5.3.0, vous ne pourrez pas réutiliser de code avec des projets qui n'ont pas ce luxe - c'est la raison principale pour laquelle je ne l'ai pas espaces de noms utilisés sur des projets internes. J'ai trouvé que vraiment namespaces ne pas ajouter que beaucoup en comparaison avec le mal de tête possible d'avoir à supprimer la dépendance sur eux.
la source