que - php namespace global
Creando objetos a partir de variables usando espacios de nombres y carga automática en PHP (3)
EDITAR con mi propio comentario después
Creo que el problema es que cuando PHP está analizando el archivo para "compilar", primero traduce los nombres de clase a su nombre completo. Así que el índice se traducirá a Controlador / Inicio / Índice. Después de eso, es cuando PHP traduce las variables en su valor. Entonces, si uso una variable como nombre de clase, no calificará su nombre, porque ese paso ya ha ocurrido. Y por eso no está encontrando la clase. Eso es solo una suposición, pero lo más probable es que sea así Blockquote
Edición final
Estoy usando UniversalClassLoader del proyecto Symfony2 para cargar automáticamente mis clases, pero he encontrado un error extraño que no puedo resolver.
La carga automática funciona bien, pero luego me encontré con este problema:
$controller = new Index(); // It works!
$controller_name = "Controller//Home//Index";
$controller2 = new $controller_name(); // It works!
$controller_name = "Index";
$controller3 = new $controller_name(); // Fatal error: Class ''Index'' not found
Los 2 primeros casos funcionan bien. En la primera, ya que estoy usando "use Controller / Home;" al comienzo de mi script, puedo usar solo "nuevo Índice ();" sin problemas. Pero si en lugar de escribir "Índice", uso una variable de cadena como $ var = "Índice", NO funciona. No puedo entender por qué. Necesito que este script sea dinámico, por eso necesito una variable para esto.
¡Gracias!
Búsquedas adicionales de cola larga:
- php nombre completo de la variable
- php instanciar la clase del alias en variable
El espacio entre nombres significa que PHP no solo podrá encontrar el archivo con la ruta dada (más o menos lo mismo que require_once), sino que el nombre de la clase también coincide con la directiva de espacio de nombres. El único diff? Barras para guiones bajos (Ejemplo # 2 a continuación).
// This may be working because Symfony''s autoloader has found a class named Index
$controller = new Index();
// A name-space call so PHP knows where to actually find the file
// Chances are the class name here is Controller_Home_Index
$controller_name = "Controller//Home//Index";
$controller2 = new $controller_name();
// Symfony''s autloader should have picked this up, but didn''t
// It''s possible that with this construct Symfony cannot find the class and b/c
// it''s not namespaced, PHP has no choice but to fail
$controller_name = "Index";
$controller3 = new $controller_name();
Verifique su directorio de caché de proyectos de Symfony, hay algunos archivos planos de arreglos PHP que también pueden ayudarlo.
Has probado:
use Controller/Home/Index as Index;
y entonces
$controller3 = new Index();
Es lo mismo que me pasó con el servicio Amazon S3 de Zend. Lo resolví usando:
use Zend/Service/Amazon/S3/S3 as Zend_Service_Amazon_S3;
$s3 = new Zend_Service_Amazon_S3($key, $secret);
Por supuesto, después del espacio de nombres en el archivo de carga automática como:
''Zend'' => __DIR__.''/../vendor/Zend/library'',
Interesante pregunta. Por lo que parece, no hay manera de evitarlo. Los documentos php parecen indicar explícitamente esto:
Se debe usar el nombre completo (nombre de clase con prefijo de espacio de nombres).
Una posible solución alternativa en su caso sería definir un espacio de nombres base para sus controladores en la configuración y registrar los controladores por su espacio de nombres relativo.
Supongamos que el espacio de nombres base es MyApp/Controller/
y estaríamos manteniendo nuestros controladores en una matriz (por razones de brevedad):
$controllers = array(
''foo/bar'' => ''MyFooController'',
''baz'' => ''Foo//MyBarController''
);
// One way how the controllers could be instantiated:
// returns ''MyApp//Controller//'
$namespace = $cfg->get(''namespaces.controller'');
$controller = $namespace.$controllers[''baz''];
$controller = new $controller();