{"id":233822,"date":"2023-02-24T09:59:00","date_gmt":"2023-02-24T06:59:00","guid":{"rendered":"https:\/\/wordpress.mediadoma.com\/?p=233822"},"modified":"2022-11-11T12:38:05","modified_gmt":"2022-11-11T09:38:05","slug":"como-implementar-un-cargador-automatico-con-espacios-de-nombres-en-su-tema-o-complemento-de-wordpress","status":"publish","type":"post","link":"https:\/\/wordpress.mediadoma.com\/es\/como-implementar-un-cargador-automatico-con-espacios-de-nombres-en-su-tema-o-complemento-de-wordpress\/","title":{"rendered":"C\u00f3mo implementar un cargador autom\u00e1tico con espacios de nombres en su tema o complemento de WordPress"},"content":{"rendered":"\n<p>Si est\u00e1 escribiendo c\u00f3digo orientado a objetos, un cargador autom\u00e1tico es imprescindible. Sin un cargador autom\u00e1tico, necesitar\u00eda agregar una l\u00ednea que incluya el archivo de clase, antes de poder inicializarlo. Puede ser r\u00e1pidamente engorroso cuando trabajas con muchas clases. Un cargador autom\u00e1tico es una funci\u00f3n que se activa cada vez que se crea una instancia de una nueva clase e incluye el archivo de clase antes de que ocurra la instanciaci\u00f3n.<\/p>\n<p>Los espacios de nombres son una forma de estructurar y encapsular su c\u00f3digo y ayudan a evitar colisiones de nombres. Si va a escribir OOP, tambi\u00e9n se recomienda usar espacios de nombres. Tenga en cuenta que puede implementar un cargador autom\u00e1tico sin usar espacios de nombres en su c\u00f3digo OOP.<\/p>\n<p>Puede usar este c\u00f3digo para su tema o complemento de WordPress, o cualquier c\u00f3digo PHP fuera de WordPress, solo modifique las rutas correspondientes. Para este ejemplo, estoy creando un cargador autom\u00e1tico para un tema de WordPress.<\/p>\n<h2>Reglas para el espacio de nombres y la estructura de la clase<\/h2>\n<p>La implementaci\u00f3n de un cargador autom\u00e1tico requerir\u00eda algunas reglas definidas para la estructura de su c\u00f3digo y d\u00f3nde encontrarlas. El uso de espacios de nombres simplifica un poco esto, ya que su espacio de nombres puede hacer referencia a la carpeta en la que se encuentran las clases.<\/p>\n<p>Primero tome una decisi\u00f3n sobre el nombre que debe tener su espacio de nombres. Por lo general, es algo \u00fanico para su c\u00f3digo, por ejemplo, el nombre de su tema. Por ejemplo, el espacio de nombres para el tema de este sitio es <code>AWhitePixelTheme<\/code>. Esto significa que para que funcione el cargador autom\u00e1tico, cualquier clase debe estar dentro de este espacio de nombres.<\/p>\n<pre><code>namespace AWhitePixelTheme;<\/code><\/pre>\n<p>Mi primera regla es que cualquier archivo de clase siempre contendr\u00e1 solo una clase y el nombre de la clase debe ser el mismo que el nombre del archivo. Por ejemplo; una clase <code>MyTest<\/code>debe estar definida dentro de un archivo <code>MyTest.php<\/code>.<\/p>\n<p>Mi segunda regla es c\u00f3mo estructurar las clases en carpetas. Decido que todas las clases van dentro de una carpeta <code>src<\/code>en mi tema. Puedo poner archivos de clase directamente en esta carpeta, y para eso deben estar dentro del espacio de nombres &quot;ra\u00edz&quot; definido anteriormente. Pero si quiero crear subcarpetas y poner archivos de clase en ellas, sus espacios de nombres deben incluir la estructura de carpetas. Por ejemplo, una clase archivo <code>MyTest.php<\/code>que reside en la carpeta <code>src\/Test\/<\/code>, debe tener este espacio de nombres definido:<\/p>\n<pre><code>namespace AWhitePixelThemeTest;<\/code><\/pre>\n<h2>Creaci\u00f3n del cargador autom\u00e1tico<\/h2>\n<p>Me gusta mantener el cargador autom\u00e1tico en un archivo separado y fuera de la <code>src\/<\/code>carpeta que est\u00e1 definida solo para archivos de clase con espacio de nombres. Como ejemplo, crear\u00e9 un archivo <code>autoloader.php<\/code>en la carpeta <code>inc\/<\/code>de mi tema.<\/p>\n<p>PHP tiene una funci\u00f3n de cargador autom\u00e1tico incorporada: <a href=\"https:\/\/www.php.net\/manual\/en\/function.spl-autoload-register.php\" target=\"_blank\" rel=\"noopener nofollow\" class=\"external external_icon\">spl_autoload_register<\/a>. Proporcionas el nombre de la funci\u00f3n del autocargador como par\u00e1metro, y en esa funci\u00f3n obtienes la clase solicitada como argumento (lo que pones despu\u00e9s <code>new<\/code>al instanciar la clase). Al crear instancias de clases con espacios de nombres, por ejemplo <code>new AWhitePixelThemeTestMyTest()<\/code>, la variable proporcionada para esta funci\u00f3n ser\u00eda <code>\"AWhitePixelThemeTestMyTest\"<\/code>.<\/p>\n<p>Agreguemos la funci\u00f3n del cargador autom\u00e1tico y en ella definimos nuestro espacio de nombres requerido para el cargador autom\u00e1tico:<\/p>\n<pre><code>&lt;?php\nspl_autoload_register('awhitepixel_autoloader');\nfunction awhitepixel_autoloader($class) {\n    $namespace = 'AWhitePixelTheme';\n\u00a0\n}<\/code><\/pre>\n<p>Luego, debemos incluir este archivo para que nuestro autocargador est\u00e9 registrado. Como esto est\u00e1 en un tema, agregar\u00e9 el include en el archivo <code>functions.php<\/code>. Si est\u00e1 utilizando esto para un complemento, col\u00f3quelo dentro de sus archivos de complemento. El archivo del autocargador debe agregarse temprano, antes de cualquier instanciaci\u00f3n de clases. Estoy poniendo esto en la primera l\u00ednea de mi <code>functions.php<\/code>:<\/p>\n<pre><code>require_once(get_template_directory(). '\/inc\/autoloader.php');<\/code><\/pre>\n<p>Si lo est\u00e1 utilizando para un tema secundario o un complemento, modifique la ruta seg\u00fan sus necesidades.<\/p>\n<p>Y eso es. Ahora el cargador autom\u00e1tico est\u00e1 en su lugar, pero no est\u00e1 haciendo nada. Volvamos a la funci\u00f3n del cargador autom\u00e1tico y termin\u00e9mosla.<\/p>\n<h2>Escritura y prueba de la funci\u00f3n del cargador autom\u00e1tico<\/h2>\n<p>Primero, debemos asegurarnos de que el nombre de la clase solicitada est\u00e9 realmente dentro de nuestro espacio de nombres. Simplemente verificamos si el nombre de la clase del espacio de nombres proporcionado contiene la cadena del espacio de nombres y, si no, salimos de la funci\u00f3n. Despu\u00e9s de eso, eliminamos el nombre del espacio de nombres de la cadena, para que podamos resolver cualquier subcarpeta y archivo de clase.<\/p>\n<pre><code>&lt;?php\nspl_autoload_register('awhitepixel_autoloader');\nfunction awhitepixel_autoloader($class) {\n    $namespace_name = 'AWhitePixelTheme';\n\u00a0\n    if (strpos($class, $namespace) !== 0) {\n        return;\n    }\n    $class = str_replace($namespace, '', $class);\n}<\/code><\/pre>\n<p>Ahora transformaremos el espacio de nombres proporcionado en una ruta real al archivo. Primero, reemplazaremos cualquier barra invertida <code>\"\"<\/code>en el espacio de nombres con el car\u00e1cter de separador de carpetas; para esto, usamos la constante de PHP <code>DIRECTORY_SEPARATOR<\/code>. Al final a\u00f1adimos un <code>\".php\"<\/code>. Y finalmente, antes de la cadena, agregamos la ruta ra\u00edz completa. Debido a que esto est\u00e1 dentro de un tema, estoy usando <code>get_template_directory()<\/code>. Si est\u00e1 usando esto para un complemento, use un m\u00e9todo que devuelva la ruta completa a su complemento.<\/p>\n<pre><code>    ...\n    $class = str_replace($namespace, '', $class);\n\u00a0\n    $class = str_replace('', DIRECTORY_SEPARATOR, $class). '.php';\n    $directory = get_template_directory();\n    $path = $directory. DIRECTORY_SEPARATOR. 'src'. DIRECTORY_SEPARATOR. $class;\n}<\/code><\/pre>\n<p>Todo lo que tenemos que hacer ahora es verificar si el archivo existe y, si existe, solicitarlo.<\/p>\n<pre><code>    ...\n    $path = $directory. DIRECTORY_SEPARATOR. 'src'. DIRECTORY_SEPARATOR. $class;\n\u00a0\n    if (file_exists($path)) {\n        require_once($path);\n    }\n}<\/code><\/pre>\n<p>\u00a1Eso es todo!<\/p>\n<p>Vamos a probarlo. Cree una subcarpeta <code>Test<\/code>en la carpeta de su tema <code>src\/<\/code>y dentro de ella coloque un archivo php llamado <code>MyTest.php<\/code>. Defina una clase <code>MyTest<\/code>en \u00e9l, siguiendo las reglas para el espacio de nombres: <code>AWhitePixelThemeTest<\/code>. Solo agregar\u00e9 una impresi\u00f3n de &#8216;\u00c9xito&#8217; en la funci\u00f3n de construcci\u00f3n para que podamos ver f\u00e1cilmente que realmente inicializa la clase.<\/p>\n<pre><code>&lt;?php\nnamespace AWhitePixelThemeTest;\n\u00a0\nclass MyTest {\n    public function __construct() {\n        var_dump('Success!');\n    }\n}<\/code><\/pre>\n<p>En nuestro functions.php, despu\u00e9s de solicitar el cargador autom\u00e1tico, simplemente instanciamos la clase:<\/p>\n<pre><code>$test = new AWhitePixelThemeTestMyTest();<\/code><\/pre>\n<p>Actualice su sitio de WordPress y vea que obtiene el mensaje &#8216;\u00a1\u00c9xito!&#8217; emitido.<\/p>\n<p>El cargador autom\u00e1tico cargar\u00e1 autom\u00e1ticamente cualquier archivo de clase que est\u00e9 dentro de nuestro espacio de nombres definido y seguir\u00e1 las reglas correctas. Puede crear instancias de clases desde cualquier lugar dentro de su tema, incluso dentro de las propias clases.<\/p>\n<h2>La funci\u00f3n completa del cargador autom\u00e1tico<\/h2>\n<p>Como referencia, aqu\u00ed est\u00e1 nuestra \u00faltima funci\u00f3n de cargador autom\u00e1tico:<\/p>\n<pre><code>spl_autoload_register('awhitepixel_autoloader');\nfunction awhitepixel_autoloader($class) {\n    $namespace = 'AWhitePixelTheme';\n\u00a0\n    if (strpos($class, $namespace) !== 0) {\n        return;\n    }\n\u00a0\n    $class = str_replace($namespace, '', $class);\n    $class = str_replace('', DIRECTORY_SEPARATOR, $class). '.php';\n\u00a0\n    $directory = get_template_directory();\n    $path = $directory. DIRECTORY_SEPARATOR. 'src'. DIRECTORY_SEPARATOR. $class;\n\u00a0\n    if (file_exists($path)) {\n        require_once($path);\n    }\n}<\/code><\/pre>\n<p><div id=\"PostUnique_PostSource\" style=\"padding-top: 50px\">Fuente de grabaci\u00f3n:  <a target=\"_blank\" rel=\"noopener nofollow\" href=\"\/\/awhitepixel.com\" class=\"external external_icon\">awhitepixel.com<\/a><\/div><\/p>\n","protected":false},"excerpt":{"rendered":"<p>Una gu\u00eda sobre c\u00f3mo escribir un cargador autom\u00e1tico que permita espacios de nombres para su c\u00f3digo orientado a objetos en un tema o complemento de WordPress.<\/p>\n","protected":false},"author":1,"featured_media":224072,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":"","_wp_rev_ctl_limit":""},"categories":[924,892,892,716,716,831,914,1110,914,831,924,840,840,861,861],"tags":[1172],"class_list":["post-233822","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-asignaturas","category-codigo","category-desarrollador","category-guia-para-principiantes","category-otro","category-n-a","category-tutoriales","category-wordpress-2","tag-affiai-es"],"_links":{"self":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/233822","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/comments?post=233822"}],"version-history":[{"count":0,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/posts\/233822\/revisions"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media\/224072"}],"wp:attachment":[{"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/media?parent=233822"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/categories?post=233822"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/wordpress.mediadoma.com\/es\/wp-json\/wp\/v2\/tags?post=233822"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}