uso spl_autoload_register psr namespace example ejemplos clases autocarga php autoload

spl_autoload_register - ¿Cómo uso los espacios de nombres PHP con autocarga?



spl_autoload_register php (12)

Obtengo este error cuando trato de usar autocarga y espacios de nombres:

Error fatal: Clase ''Class1'' no encontrada en /usr/local/www/apache22/data/public/php5.3/test.php en la línea 10

¿Alguien puede decirme qué estoy haciendo mal?

Aquí está mi código:

Class1.php:

<?php namespace Person/Barnes/David { class Class1 { public function __construct() { echo __CLASS__; } } } ?>

test.php:

<?php function __autoload($class) { require $class . ''.php''; } use Person/Barnes/David; $class = new Class1(); ?>


¡Recientemente encontré la respuesta de Tanerkuc muy útil! Solo quería agregar que usar strrpos() + substr() es ligeramente más rápido que explode() + end() :

spl_autoload_register( function( $class ) { $pos = strrpos( $class, ''//' ); include ( $pos === false ? $class : substr( $class, $pos + 1 ) ).''.php''; });


Class1 no está en el alcance global.

Vea a continuación un ejemplo de trabajo:

<?php function __autoload($class) { $parts = explode(''//', $class); require end($parts) . ''.php''; } use Person/Barnes/David as MyPerson; $class = new MyPerson/Class1();

Editar (14-12-2009):

Solo para aclarar, mi uso de "usar ... como" fue para simplificar el ejemplo.

La alternativa fue la siguiente:

$class = new Person/Barnes/David/Class1();

o

use Person/Barnes/David/Class1; // ... $class = new Class1();


Como mencionó Pascal MARTIN, debe reemplazar el ''/' con DIRECTORY_SEPARATOR por ejemplo:

$filename = BASE_PATH . DIRECTORY_SEPARATOR . str_replace(''//', DIRECTORY_SEPARATOR, $class) . ''.php''; include($filename);

También le sugiero que reorganice la estructura del directorio, para que el código sea más legible. Esta podría ser una alternativa:

Estructura de directorios:

ProjectRoot |- lib

Archivo: /ProjectRoot/lib/Person/Barnes/David/Class1.php

<?php namespace Person/Barnes/David class Class1 { public function __construct() { echo __CLASS__; } } ?>

  • Haga el subdirectorio para cada espacio de nombre que esté definido.

Archivo: /ProjectRoot/test.php

define(''BASE_PATH'', realpath(dirname(__FILE__))); function my_autoloader($class) { $filename = BASE_PATH . ''/lib/'' . str_replace(''//', ''/'', $class) . ''.php''; include($filename); } spl_autoload_register(''my_autoloader''); use Person/Barnes/David as MyPerson; $class = new MyPerson/Class1();

  • Usé la recomendación de php 5 para la declaración del autocargador. Si todavía está utilizando PHP 4, reemplácelo con la sintaxis anterior: function __autoload ($ class)

El uso tiene un gotcha, aunque es, con mucho, el método más rápido, también espera que todos los nombres de sus archivos sean minúsculos.

spl_autoload_extensions(".php"); spl_autoload_register();

Por ejemplo:

Un archivo que contenga la clase SomeSuperClass necesitaría ser nombrado somesuperclass.php, este es un gotcha cuando se usa un sistema de archivos sensible a mayúsculas y minúsculas como Linux, si su archivo se llama SomeSuperClass.php pero no es un problema en Windows.

El uso de __autoload en tu código aún puede funcionar con las versiones actuales de PHP, pero se espera que esta característica se desaproveche y finalmente se elimine en el futuro.

Entonces, ¿qué opciones quedan?

Esta versión funcionará con PHP 5.3 y superior y permite los nombres de archivo SomeSuperClass.php y somesuperclass.php. Si usa 5.3.2 y superior, este autocargador funcionará aún más rápido.

<?php if ( function_exists ( ''stream_resolve_include_path'' ) == false ) { function stream_resolve_include_path ( $filename ) { $paths = explode ( PATH_SEPARATOR, get_include_path () ); foreach ( $paths as $path ) { $path = realpath ( $path . PATH_SEPARATOR . $filename ); if ( $path ) { return $path; } } return false; } } spl_autoload_register ( function ( $className, $fileExtensions = null ) { $className = str_replace ( ''_'', ''/'', $className ); $className = str_replace ( ''//', ''/'', $className ); $file = stream_resolve_include_path ( $className . ''.php'' ); if ( $file === false ) { $file = stream_resolve_include_path ( strtolower ( $className . ''.php'' ) ); } if ( $file !== false ) { include $file; return true; } return false; });


Encontré esta joya de Flysystem

spl_autoload_register(function($class) { $prefix = ''League//Flysystem//'; if ( ! substr($class, 0, 17) === $prefix) { return; } $class = substr($class, strlen($prefix)); $location = __DIR__ . ''path/to/flysystem/src/'' . str_replace(''//', ''/'', $class) . ''.php''; if (is_file($location)) { require_once($location); } });


Lanzaré mis dos centavos para principiantes parientes o para lo que no quiera una sencilla configuración de spl_autoload_register () sin toda la teoría: simplemente cree un archivo php para cada clase, nombre ese archivo php igual que su nombre de clase, y mantenga sus archivos de clase en el mismo directorio que tu archivo php en cuestión, entonces esto funcionará:

spl_autoload_register(function ($class_name) { require_once dirname(__FILE__) . DIRECTORY_SEPARATOR . $class_name . ''.php''; });

Buscar en Google las piezas dentro de esta función debe responder cómo funciona. PD: uso Linux, y esto funciona en Linux. La gente de Windows debería probarlo primero.


Su función __autoload recibirá el nombre de clase completo, incluido el nombre del espacio de nombres.

Esto significa que, en su caso, la función __autoload recibirá '' Person/Barnes/David/Class1 '', y no solo '' Class1 ''.

Por lo tanto, debe modificar su código de carga automática para tratar ese tipo de nombre "más complicado"; una solución utilizada a menudo es organizar sus archivos utilizando un nivel de directorio por "nivel" de espacios de nombres y, cuando se carga automáticamente, reemplace '' / '' en el nombre del espacio de nombres por DIRECTORY_SEPARATOR .


Veo que las funciones de autocarga solo reciben el nombre de clase "completo", con todos los espacios de nombre que lo preceden, en los dos casos siguientes:

[a] $a = new The/Full/Namespace/CoolClass(); [b] use The/Full/Namespace as SomeNamespace; (at the top of your source file) followed by $a = new SomeNamespace/CoolClass();

Veo que las funciones de autocarga NO reciben el nombre de clase completo en el siguiente caso:

[c] use The/Full/Namespace; (at the top of your source file) followed by $a = new CoolClass();

ACTUALIZACIÓN: [c] es un error y no es así como funcionan los espacios de nombres. Puedo informar que, en lugar de [c], los dos casos siguientes también funcionan bien:

[d] use The/Full/Namespace; (at the top of your source file) followed by $a = new Namespace/CoolClass(); [e] use The/Full/Namespace/CoolClass; (at the top of your source file) followed by $a = new CoolClass();

Espero que esto ayude.


Yo hago algo como esto:

spl_autoload_register(''AutoLoader''); function AutoLoader($className) { $file = str_replace(''//',DIRECTORY_SEPARATOR,$className); require_once ''classes'' . DIRECTORY_SEPARATOR . $file . ''.php''; //Make your own path, Might need to use Magics like ___DIR___ }


tuvo el mismo problema y acaba de encontrar esto:

Cuando crea una estructura de subcarpetas que coincida con los espacios de nombres de las clases que lo contienen, ni siquiera tendrá que definir un autocargador.

spl_autoload_extensions(".php"); // comma-separated list spl_autoload_register();

Funcionó a las mil maravillas

Más información aquí: http://www.php.net/manual/en/function.spl-autoload-register.php#92514

EDITAR: esto causa un problema en Linux debido a la barra invertida ... Vea aquí la solución de trabajo de Immeëmosol

Espacio de nombres Autoload funciona bajo Windows, pero no en Linux


https://thomashunter.name/blog/simple-php-namespace-friendly-autoloader-class/

Querrá poner sus archivos de clase en una carpeta llamada Clases, que está en el mismo directorio que el punto de entrada en su aplicación PHP. Si las clases usan espacios de nombres, los espacios de nombres se convertirán a la estructura del directorio. A diferencia de muchos otros cargadores automáticos, los guiones bajos no se convertirán en estructuras de directorios (es complicado hacer PHP <5.3 pseudopalabras, junto con PHP> = 5.3 espacios de nombres reales).

<?php class Autoloader { static public function loader($className) { $filename = "Classes/" . str_replace("//", ''/'', $className) . ".php"; if (file_exists($filename)) { include($filename); if (class_exists($className)) { return TRUE; } } return FALSE; } } spl_autoload_register(''Autoloader::loader'');

Deberá colocar el siguiente código en su script PHP principal (punto de entrada):

require_once("Classes/Autoloader.php");

Aquí hay un diseño de directorio de ejemplo:

index.php Classes/ Autoloader.php ClassA.php - class ClassA {} ClassB.php - class ClassB {} Business/ ClassC.php - namespace Business classC {} Deeper/ ClassD.php - namespace BusinessDeeper classD {}


<?php spl_autoload_register(function ($classname){ // for security purpose //your class name should match the name of your class "file.php" $classname = str_replace("..", "", $classname); require_once __DIR__.DIRECTORY_SEPARATOR.("classes/$classname.class.php"); }); try { $new = new Class1(); } catch (Exception $e) { echo "error = ". $e->getMessage(); } ?>