2010-09-04 20 views
11

He tenido un ligero problema con la carga automática en mi espacio de nombres. Como se muestra en el manual de PHP aquí: http://us.php.net/manual/en/language.namespaces.rules.php, debería poder cargar automáticamente las funciones del espacio de nombres con un nombre completo calificado, p. \ glue \ common \ is_email().PHP carga automática en espacios de nombres

Cosa es que tengo una función spl_autoload_register (array ($ import, "load")); dentro del espacio de nombres inicial, pero cada vez que intento llamar a \ glue \ common \ is_email() desde el espacio de nombres inicial, no pasará esa función de autocarga, pero cuando se usa is_email() (en el contexto de una clase) lo hará. No entiendo, el manual dice que puedo cargar automáticamente nombres completos, pero no puedo:

Aquí está mi código:

namespace glue; 

require_once 'import.php'; 

use glue\import as import; 
use glue\core\router as router; 

$import = new import(); 

spl_autoload_register(array($import, "load")); 

/** Works and echos glue\router **/ 
$router = new router(); 

/** Don't do nothing **/ 
$cheese = \glue\common\is_email($email); 

También probé este código así:

namespace glue; 

require_once 'import.php'; 

use glue\import as import; 
use glue\core\router as router; 
use glue\common; 

$import = new import(); 

spl_autoload_register(array($import, "load")); 

/** Works and echos glue\router **/ 
$router = new router(); 

/** Don't do nothing **/ 
$cheese = common\is_email($email); 

y finalmente este código:

namespace glue; 

require_once 'import.php'; 

use glue\import as import; 
use glue\core\router as router; 
use glue\common\is_email as F; 

$import = new import(); 

spl_autoload_register(array($import, "load")); 

/** Works and echos glue\router **/ 
$router = new router(); 

/** Don't do nothing **/ 
$cheese = F($email); 
+1

reetiquetado como PHP5.3 ya que esto es un 5,3-única pregunta. –

Respuesta

13

Ésta es la única respuesta correcta.

Cada espacio de nombres necesita su propia función spl_autoload_register().

también, spl_autoload_register() Sintaxis cambió en 5.3:

spl_autoload_register(__NAMESPACE__ . "\\className::functionName")); 

lo siguiente debe funcionar:

namespace glue; 

require_once 'import.php'; 

use glue\import as import; 
use glue\core\router as router; 

$import = new import(); 

spl_autoload_register(__NAMESPACE__ . "\\$import::load")); 

/** Works and echos glue\router **/ 
$router = new router(); 

/** Don't do nothing **/ 
$cheese = \glue\common\is_email($email); 

Aquí es un poco de vivo código que sólo ¡trabajos!

en ../WebPageConsolidator.inc.php:

class WebPageConsolidator 
{ 
    public function __construct() { echo "PHP 5.2 constructor.\n"; } 
} 

en prueba.php:

<?php 

namespace WebPage; 

class MyAutoloader 
{ 
    public static function load($className) 
    { 
     require '../' . __NAMESPACE__ . $className . '.inc.php'; 
    } 
} 

spl_autoload_register(__NAMESPACE__ . "\\MyAutoloader::load"); 

class Consolidator extends \WebpageConsolidator 
{ 
    public function __construct() 
    { 
     echo "PHP 5.3 constructor.\n"; 

     parent::__construct(); 
    } 
} 

// Output: 
// PHP 5.3 constructor. 
// PHP 5.2 constructor. 

así que sé que funciona.

+0

Parecía que podría funcionar, pero aún no cargará mi función. Estoy empezando a pensar que PHP aún anula esta funcionalidad con su enlace en tiempo de ejecución ... lo que sería un poco asqueroso. – Sammaye

+0

Sí, solo entra en spl_autoload cuando se usa la palabra clave nueva ........ grrr ¿por qué el manual de PHP dice que puedo cargar automáticamente las funciones si no puedo, podría tener que llevar esto a ellas? – Sammaye

+4

La carga ** solo ** funciona con ** clases **. –

0

La idea errónea en la pregunta del OP es probablemente que las funciones/métodos estarían sujetos a carga automática, lo cual no es cierto. La carga automática solo se activa al hacer referencia a las clases.

Dicho esto todavía queda la cuestión acerca de las clases de carga automática en espacios de nombres:

A partir de 2017 el estándar actual PHP-FIG para la carga automática es PSR-4 que proporciona el siguiente código de cargador automático para las clases de espacios de nombres:

<?php 
/** 
* An example of a project-specific implementation. 
* 
* After registering this autoload function with SPL, the following line 
* would cause the function to attempt to load the \Foo\Bar\Baz\Qux class 
* from /path/to/project/src/Baz/Qux.php: 
* 
*  new \Foo\Bar\Baz\Qux; 
* 
* @param string $class The fully-qualified class name. 
* @return void 
*/ 
spl_autoload_register(function ($class) { 

    // project-specific namespace prefix 
    $prefix = 'Foo\\Bar\\'; 

    // base directory for the namespace prefix 
    $base_dir = __DIR__ . '/src/'; 

    // does the class use the namespace prefix? 
    $len = strlen($prefix); 
    if (strncmp($prefix, $class, $len) !== 0) { 
     // no, move to the next registered autoloader 
     return; 
    } 

    // get the relative class name 
    $relative_class = substr($class, $len); 

    // replace the namespace prefix with the base directory, replace namespace 
    // separators with directory separators in the relative class name, append 
    // with .php 
    $file = $base_dir . str_replace('\\', '/', $relative_class) . '.php'; 

    // if the file exists, require it 
    if (file_exists($file)) { 
     require $file; 
    } 
}); 

El texto completo de la especificación se puede encontrar en PSR-4: Autoloader.

El ejemplo de código anterior (y otro para carga automática de múltiples espacios de nombres) se puede encontrar en Example Implementations of PSR-4 (o GitHub: fig-standards/accepted/PSR-4-autoloader-examples.md).

+0

Actualmente, PHP7 permite la carga automática de funciones y métodos en espacios de nombres directamente – Sammaye

+0

Hola @Sammaye, gracias por la pista. ¿Tiene algún enlace con más información a mano? Parece que no puedo encontrar nada sobre ese cambio. – Jpsy

2

Use Composer para autocargar sus clases de PHP.

Salida cómo hacerlo en mi reciente post: https://enterprise-level-php.com/2017/12/25/the-magic-behind-autoloading-php-files-using-composer.html

+0

La razón por la que esto funcionaría ahora es porque php ahora permite la carga automática de las funciones del espacio de nombres – Sammaye

+0

Claro. 7 años después muchas cosas han cambiado jaja. Quería poner aquí una referencia a la nueva forma de hacerlo, ya que aterricé en esta pregunta yo mismo de Google. – EnchanterIO

Cuestiones relacionadas