PHP 5.6.0 released

Usar espacios de nombres: Apodar/Importar

(PHP 5 >= 5.3.0)

La capacidad de referirse a un nombre completamente cualificado externo con un alias, o importar, es una característca importante de los espacios de nombres. Esto es similar a la capacidad de los sistemas de ficheros basados en Unix de crear enlaces simbólicos a un fichero o directorio.

Todas las versiones de PHP que tiene soporte para espacios de nombres admiten tres tipos de alias o importacion: apodar un nombre de clase, apodar un nombre de interfaz, y apodar un nombre de espacio de nombres. PHP 5.6+ también permite apodar o importar nombres de funciones y constantes.

En PHP, apodar se lleva a cabo con el operador use. Aquí hay un ejemplo que muestra los cinco tipos de importación:

Ejemplo #1 Importar/apodar con el operador use

<?php
namespace foo;
use 
Mi\Completo\NombreDeClase as Otro;

// esto es lo mismo que usar Mi\Completo\NombreEN as NombreEN
use Mi\Completo\NombreEN;

// importar una clase global
use ArrayObject;

// importar una función (PHP 5.6+)
use function Mi\Completo\nombreDeFunción;

// aposar una función (PHP 5.6+)
use function Mi\Completo\nombreDeFunción as func;

// importar una constante (PHP 5.6+)
use const Mi\Completa\CONSTANTE;

$obj = new namespace\Otra// instancia un objeto de la clase foo\Otra
$obj = new Otra// instancia un objeto de la clase class Mi\Completo\NombreDeClase
NombreEN\suben\func(); // llama a la función Mi\Completo\NombreEN\subes\func
$a = new ArrayObject(array(1)); // instancia un objeto de la clase ArrayObject
// sin el "use ArrayObject" instanciaríamos un objeto de la clase foo\ArrayObject
func(); // llama a la función Mi\Completo\nombreDeFunción
echo CONSTANT// imprime el valor de Mi\Completa\CONSTANTE;
?>
Observe que para los nombres de espacios de nombres (nombres de espacios de nombres completamente cualificados que contienen el separador de espacios de nombres, como Foo\Bar en oposición a los nombres globales que no lo contienen, como FooBar), no es necesaria y no está recomendada la barra invertida inicial, ya que los nombres importados deben ser completamente cualificados, y no son procesados en relación al espacio de nombres actual.

PHP soporta adicionalmente un atajo apropiado para poner múltiples sentencias use en la misma línea

Ejemplo #2 Importar/apodar con el operador use, múltiples sentencias use combinadas

<?php
use Mi\Completo\NombreDeClase as OtraMi\Completo\NombreEN;

$obj = new Otra// instancia un objeto de la clase Mi\Completo\NombreDeClase
NombreEN\suben\func(); // llama a la función Mi\Completo\NombreEN\suben\func
?>

La importación se realiza en tiempo de compilación, y al hacerlo no afecta a los nombres de clases, funciones o constantes.

Ejemplo #3 La importación y los nombres dinámicos

<?php
use Mi\Completo\NombreDeClase as OtraMi\Completo\NombreEN;

$obj = new Otra// instancia un objeto de la clase Mi\Completo\NombreDeClase
$a 'Otra';
$obj = new $a;      // instancia un objeto de la clase Otra
?>

Además, la importación sólo afecta a los nombres no cualificados y cualificados. Los nombres completamente cualificados son absolutos, y no son afectados por la importación.

Ejemplo #4 La importación y los nombres completamente cualificados

<?php
use Mi\Completo\NombreDeClase as OtraMi\Completo\NombreEN;

$obj = new Otra// instancia un objeto de la clase Mi\Completo\NombreDeClase
$obj = new \Otra// instancia un objeto de la clase Otra
$obj = new Otra\cosa// instancia un objeto de la clase Mi\Completo\NombreDeClase\cosa
$obj = new \Otra\cosa// instancia un objeto de la clase Otra\cosa
?>

Reglas de ámbito para la importación

La palabra clave use debe ser declarada en el ámbito exterior de un fichero (el ámbito global) o dentro de declaraciones de espacios de nombres. Esto es porque la importación se realiza en tiempo de compilación y no en tiempo de ejecución, por lo que no puede ser delimitada en bloque. El siguiente ejemplo mostrará un uso ilegal de la palabra clave use:

Ejemplo #5 Regla de importación ilegal

<?php
namespace Languages;

class 
Greenlandic
{
    use 
Languages\Danish;

 ...
}
?>

Nota:

Las reglas de importación tiene una base por fichero, lo que significa que los ficheros incluidos NO heredarán las reglas de importación del padre.

add a note add a note

User Contributed Notes 10 notes

up
14
x at d dot a dot r dot k dot REMOVEDOTSANDTHIS dot gray dot org
1 year ago
You are allowed to "use" the same resource multiple times as long as it is imported under a different alias at each invocation.

For example:

<?php
use Lend;
use
Lend\l1;
use
Lend\l1 as l3;
use
Lend\l2;
use
Lend\l1\Keller;
use
Lend\l1\Keller as Stellar;
use
Lend\l1\Keller as Zellar;
use
Lend\l2\Keller as Dellar;

...

?>

In the above example, "Keller", "Stellar", and "Zellar" are all references to "\Lend\l1\Keller", as are "Lend\l1\Keller", "l1\Keller", and "l3\Keller".
up
11
k at webnfo dot com
1 year ago
Note that you can not alias global namespace:

use \ as test;

echo test\strlen('');

won't work.
up
11
c dot 1 at smithies dot org
3 years ago
If you are testing your code at the CLI, note that namespace aliases do not work!

(Before I go on, all the backslashes in this example are changed to percent signs because I cannot get sensible results to display in the posting preview otherwise. Please mentally translate all percent signs henceforth as backslashes.)

Suppose you have a class you want to test in myclass.php:

<?php
namespace my%space;
class
myclass {
// ...
}
?>

and you then go into the CLI to test it. You would like to think that this would work, as you type it line by line:

require 'myclass.php';
use my%space%myclass; // should set 'myclass' as alias for 'my%space%myclass'
$x = new myclass; // FATAL ERROR

I believe that this is because aliases are only resolved at compile time, whereas the CLI simply evaluates statements; so use statements are ineffective in the CLI.

If you put your test code into test.php:
<?php
require 'myclass.php';
use
my%space%myclass;
$x = new myclass;
//...
?>
it will work fine.

I hope this reduces the number of prematurely bald people.
up
6
samuel dot roze at gmail dot com
2 years ago
(All the backslashes in namespaces are slashes because I can't figure out how to post backslashes here.)

You can have the same "use" for a class and a namespace. For example, if you have these files:

<?php
// foo/bar.php
namespace foo;

class
bar
{
    public function
__toString ()
    {
        return
'foo\bar\__toString()';
    }
}
?>

<?php
// foo/bar/MyClass.php
namespace foo/bar;

class
MyClass
{
    public function
__toString ()
    {
        return
'foo\bar\MyClass\__toString()';
    }
}
?>

In another namespace, you can do:
<?php
namespace another;
require_once
'foo/bar.php';
require_once
'foo/bar/MyClass.php';

use
foo/bar;

$bar = new bar();
echo
$bar."\n";

$class = new bar/MyClass();
echo
$class."\n";
?>

And it will makes the following output:
foo\bar\__toString()
foo\bar\MyClass\__toString()
up
2
anon
6 months ago
The <?php use ?> statement does not load the class file. You have to do this with the <?php require ?> statement or by using an autoload function.
up
3
cl
1 year ago
Something that is not immediately obvious, particular with PHP 5.3, is that namespace resolutions within an import are not resolved recursively.  i.e.: if you alias an import and then use that alias in another import then this latter import will not be fully resolved with the former import.

For example:
use \Controllers as C;
use C\First;
use C\Last;

Both the First and Last namespaces are NOT resolved as \Controllers\First or \Controllers\Last as one might intend.
up
1
thinice at gmail.com
3 years ago
Because imports happen at compile time, there's no polymorphism potential by embedding the use keyword in a conditonal.

e.g.:

<?php
if ($objType == 'canine') {
  use
Animal\Canine as Beast;
}
if (
$objType == 'bovine') {
  use
Animal\Bovine as Beast;
}

$oBeast = new Beast;
$oBeast->feed();
?>
up
0
Anonymous
1 year ago
The last example on this page shows a possibly incorrect attempt of aliasing, but it is totally correct to import a trait \Languages\Languages\Danish.
up
-5
Jan Tvrdk
3 years ago
Importing and aliasing an interface name is also supported.
up
-6
nsdhami at live dot jp
4 years ago
The "use" keyword can not be declared inside the function or method. It should be declared as global, after the "namespace" as:

<?php

namespace mydir;

// works perfectly
use mydir/subdir/Class1 as Class1;

function
fun1()
{
   
// Parse error: syntax error, unexpected T_USE
   
use mydir/subdir/Class1 as Class1;
}

class
Class2
{
    public function
fun2()
    {
       
// Parse error: syntax error, unexpected T_USE
       
use mydir/subdir/Class1 as Class1;
    }
}
?>
To Top