It seems the file system analogy only goes so far. One thing that's missing that would be very useful is relative navigation up the namespace chain, e.g.
<?php
namespace MyProject {
class Person {}
}
namespace MyProjectPeople {
class Adult extends ..Person {}
}
?>
That would be really nice, especially if you had really deep namespaces. It would save you having to type out the full namespace just to reference a resource one level up.
Usar espacios de nombres: Lo básico
(PHP 5 >= 5.3.0)
Antes de hablar del uso de los espacios de nombres es importante entender cómo sabe PHP qué elemento del código del espacio de nombre se requiere. Se puede hacer una simple analogía entre los espacios de nombres de PHP y el sistema de archivos. Existen tres maneras de acceder a un archivo en el sistema de archivos:
- Nombre de archivo relativo como foo.txt. Esto se resuelve con directorioactual/foo.txt donde directorioactual es el directorio actualmente ocupado. Por lo que si el directorio actual es /home/foo, el nombre se resuelve con /home/foo/foo.txt.
- Nombre de ruta relativa como subdirectorio/foo.txt. Esto se resuelve con directorioactual/subdirectorio/foo.txt.
- Nombre de ruta absoluto como /main/foo.txt. Esto se resuelve con /main/foo.txt.
- Nombre no cualificado, o nombre de clase sin prefijo como $a = new foo(); o foo::métodoestático();. Si el espacio de nombres actual es espaciodenombresactual, esto se resuelve con espaciodenombresactual\foo. Si el código es global, no es de espacio de nombres, esto se resuelve con foo. Una advertencia: los nombres no cualificados para funciones y constantes se resolverán con funciones y constantes globales si la función o la constante del espacio de nombres no está definida. Véase Usar espacios de nombres: una alternativa a funciones/constantes globales para más detalles.
- Nombre cualificado, o un nombre de clase con prefijo como $a = new subespaciodenombres\foo(); o subespaciodenombres\foo::métodoestático();. Si el espacio de nombres actual es espaciodenombresactual, esto se resuelve con espaciodenombresactual\subespaciodenombres\foo. Si el código es global, no es de espacio de nombres, esto se resuelve con subespaciodenombres\foo.
- Nombre completamente cualificado, o un nombre con prefijo con el operador de prefijo global como $a = new \espaciodenombresactual\foo(); o \espaciodenombresactual\foo::métodoestático();. Esto siempre se resuelve con nombre literal especificado en el código, espaciodenombresactual\foo.
Aquí hay un ejemplo de los tres tipos de sintaxis en código real:
archivo1.php
<?php
namespace Foo\Bar\subespaciodenombres;
const FOO = 1;
function foo() {}
class foo
{
static function métodoestático() {}
}
?>
archivo2.php
<?php
namespace Foo\Bar;
include 'archivo1.php';
const FOO = 2;
function foo() {}
class foo
{
static function métodoestático() {}
}
/* Nombre no cualificado */
foo(); // se resuelve con la función Foo\Bar\foo
foo::métodoestático(); // se resuelve con la clase Foo\Bar\foo, método métodoestático
echo FOO; // se resuelve con la constante Foo\Bar\FOO
/* Nombre cualificado */
subespaciodenombres\foo(); // se resuelve con la función Foo\Bar\subespaciodenombres\foo
subespaciodenombres\foo::métodoestático(); // se resuelve con la clase Foo\Bar\subespaciodenombres\foo,
// método métodoestático
echo subespaciodenombres\FOO; // se resuelve con la constante Foo\Bar\subespaciodenombres\FOO
/* Nombre conmpletamente cualificado */
\Foo\Bar\foo(); // se resuelve con la función Foo\Bar\foo
\Foo\Bar\foo::métodoestático(); // se resuelve con la clase Foo\Bar\foo, método métodoestático
echo \Foo\Bar\FOO; // se resuelve con la constante Foo\Bar\FOO
?>
Observe que para acceder a cualquier clase, función o constante globales, se puede usar un nombre completamente cualificado, como \strlen() o \Exception o \INI_ALL.
Ejemplo #1 Acceder a clases, funciones y constantes globales desde un espacio de nombres
<?php
namespace Foo;
function strlen() {}
const INI_ALL = 3;
class Exception {}
$a = \strlen('hola'); // llama a la función global strlen
$b = \INI_ALL; // accede a la constante global INI_ALL
$c = new \Exception('error'); // instancia a la clase global Exception
?>
tom at tomwardrop dot com
26-Feb-2012 10:06
Lukas Z
05-Dec-2011 03:25
Well variables inside namespaces do not override others since variables are never affected by namespace but always global:
"Although any valid PHP code can be contained within a namespace, only four types of code are affected by namespaces: classes, interfaces, functions and constants. "
Source: "Defining Namespaces"
http://www.php.net/manual/en/language.namespaces.definition.php
philip dot preisser at arcor dot de
14-Jun-2011 02:34
Working with variables can overwrite equal variables in other namespaces
<?php // php5 - package-version : 5.3.5-1ubuntu7.2
namespace
main
{}
namespace
mainsub1
{
$data = 1;
}
namespace
mainsub2
{
echo $data;// 1
$data = 2;
}
namespace
mainsub1
{
echo $data;// 2
$data = 1;
}
namespace
{
echo $data;// 1
}
?>
Franois Vespa
21-Dec-2010 05:42
It seems you cannot nest a constant declaration within a if statement
<?php
namespace FOO;
if(eval)
const BAR=true;
// will throw the following error:
// PHP Parse error: syntax error, unexpected T_CONST
// instead use:
if(eval)
define('FOO\BAR',true);
?>
thinice at gmail.com
01-Dec-2010 10:10
Unfortunately as of 5.3.3, it's not possible to do something like:
<?php
namespace Animal {
require 'Bovine.php';
require 'Canine.php';
}
?>
Which could be quite handy for a handful of reasons.
kukoman at pobox dot sk
17-Oct-2008 11:20
PHP 5.3.0alpha2 (cli)
<?php
// namespace MyProject\DB;
require 'db.php';
use MyProjectDB; // fine; same as DB\
use MyProjectDBConnection as DBC; // fine
use MyProjectDB as HM; // fine
use HMConnection as DBC2; // class call ends with FATAL!!!
$x = new DBC(); // fine
$y = new HMConnection(); // fine
$z = new DBC2(); // Fatal error: Class 'HM\Connection' not found
?>
richard at richard-sumilang dot com
27-Mar-2008 01:36
Syntax for extending classes in namespaces is still the same.
Lets call this Object.php:
<?php
namespace comrsumilangcommon;
class Object{
// ... code ...
}
?>
And now lets create a class called String that extends object in String.php:
<?php
class String extends comrsumilangcommonObject{
// ... code ...
}
?>
Now if you class String was defined in the same namespace as Object then you don't have to specify a full namespace path:
<?php
namespace comrsumilangcommon;
class String extends Object
{
// ... code ...
}
?>
Lastly, you can also alias a namespace name to use a shorter name for the class you are extending incase your class is in seperate namespace:
<?php
namespace comrsumilangutil;
use comrsumlangcommon as Common;
class String extends CommonObject
{
// ... code ...
}
?>
- Richard Sumilang
