PHP 7.0.0 RC 1 Released

Uso de los 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 tienen soporte para espacios de nombres admiten tres tipos de alias o importación: 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, la acción de 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 Otra;

// esto es lo mismo que utilizar 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;

// apodar 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, por lo que no son procesados en relación al espacio de nombres actual.

PHP admite además un atajo para poner varias sentencias use en la misma línea

Ejemplo #2 Importar/apodar con el operador use, varias 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 durante la compilación, por lo que 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 cualificados y no cualificados. Los nombres completamente cualificados son absolutos, por lo que no se ven 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 reservada use debe ser declarada en el ámbito exterior de un fichero (el ámbito global) o dentro de declaraciones de espacios de nombres. Esto es así debido a que la importación se realiza durante la compilación y no durante la ejecución, por lo que no puede ser utilizada en un ámbito de bloque. El siguiente ejemplo muestra un uso ilegal de la palabra reservada use:

Ejemplo #5 Regla de importación ilegal

<?php
namespace Idiomas;

class 
Groenlandés
{
    use 
Idiomas\Danés;

 ...
}
?>

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 13 notes

up
35
k at webnfo dot com
2 years ago
Note that you can not alias global namespace:

use \ as test;

echo test\strlen('');

won't work.
up
16
x at d dot a dot r dot k dot REMOVEDOTSANDTHIS dot gray dot org
2 years 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
17
c dot 1 at smithies dot org
4 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
11
cl
2 years 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
2
sernuzh at gmail dot com
3 months ago
You'll get here the
Fatal error: Cannot declare class others\name because the name is already in use
So you can't get two classes <name> inside one namespace
<?php
namespace my {
class
name {
public function
__construct(){
echo
'my_namespace_object';
}
}
}
namespace
others{
use
my\name;
class
name {
public function
__construct(){
echo
'others_namespace_object';
}
}
$newObject = new name();
}
?>
up
9
anon
1 year 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
1
kelerest123 at gmail dot com
5 months ago
For the fifth example (example #5):

When in block scope, it is not an illegal use of use keyword, because it is used for sharing things with traits.
up
2
Anonymous
2 years 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
1
thinice at gmail.com
4 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
samuel dot roze at gmail dot com
3 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
-4
nsdhami at live dot jp
5 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;
    }
}
?>
up
-13
Jan Tvrdk
4 years ago
Importing and aliasing an interface name is also supported.
up
-13
Dr. Gianluigi &#34;Zane&#34; Zanettini
6 months ago
I was attempting to use something like this:

<?php
use $my_variable_namespace
?>

This is not supported. I did this instead:

<?php
if(..)
    use
My\First\Namespace;
else
    use
My\Other\Namespace;
?>
To Top