Importar clases y espacios de nombres en PHP: ¿Qué diferencia hace una barra inalcadora principal?

StackOverflow https://stackoverflow.com/questions/4849279

Pregunta

¿Cuál es la diferencia entre esos dos?

use Exception;
use \Exception;

O aquellos:

use Foo\Bar;
use \Foo\Bar;

los manual dice:

Tenga en cuenta que para los nombres con el espacio de nombres (nombres de espacio de nombres totalmente calificados que contienen separador de espacio de nombres, como Foo Bar en lugar de los nombres globales que no, como Foobar), la barra inalcadora principal es innecesaria y no permitida, ya que los nombres de importación deben estar completamente calificados, y no se procesan en relación con el espacio de nombres actual.

Pero realmente no entiendo esto, ya que todas las variantes anteriores funcionan, es decir, definitivamente no está "no permitida".

Una mirada a zend_do_use mostró que is_global (establecido, cuando hay una barra inalcadora principal) solo se usa para una advertencia en el siguiente caso:

namespace {
    use Exception;
}

Lo que me dice: "La declaración de uso con 'excepción' de nombre no compuesto no tiene efecto". (Aunque hacer lo mismo con use \Exception tendría un poco de poco efecto, pero no lanza una advertencia).

Entonces: ¿me estoy perdiendo algo? ¿Hay realmente alguna diferencia?

¿Fue útil?

Solución

El manual especifica la barra insegura como innecesario, que naturalmente significa que si todavía lo usas, el significado es equivalente. Sin embargo, como has señalado, el manual dice que supuestamente no está permitido, lo cual es falso.

Sin embargo, hay algo más preocupante con el manual. Anuncian esto:

// importing a global class
use \ArrayObject;

Si es cierto que los nombres de importación no se procesan en relación con el espacio de nombres actual, entonces use \ArrayObject y use ArrayObject Debe tener el mismo significado. Que más podría use ArrayObject ¿Consulte que no sea el global? En la práctica, el motor importará el global.

Además, con errores como este:http://bugs.php.net/bug.php?id=49143

Creo que hay confusión sobre cuál se supone que es el estándar.

Para responder a su pregunta: no hay diferencia. Sin embargo, si yo fuera el desarrollador de motores que también creía en el estándar de liderazgo, entonces no necesitaría considerar un caso en el que alguien escribiera use \Exception;. Creo que este fue probablemente el caso.

Otros consejos

De hecho, no hay diferencia en el uso de barras inalcanzadas principales en la importación de espacios de nombres en este momento y también información en Manual de PHP ha cambiado:

Tenga en cuenta que para los nombres con el espacio de nombres (nombres de espacio de nombres totalmente calificados que contienen separador de espacio de nombres, como Foo Bar en lugar de los nombres globales que no, como Foobar), la barra inalcadora principal es innecesaria y es no recomendado, ya que los nombres de importación deben estar completamente calificados y no se procesan en relación con el espacio de nombres actual.

Por lo tanto, ahora no hay información verdadera de que no se recomienda usar invertido de fondo principal, pero no hay información que no esté permitido en el pasado.

Entonces en este momento:

use Exception;
use \Exception;

Esas 2 líneas funcionan de la misma manera, pero deberías usar la primera.

Por lo general, la barra inalcadora principal define que el identificador es absoluto. Si falta, el intérprete supone que es un identificador relativo.

Este es un identificador absoluto:

$x = new \Name\Space\To\Class();

Este es un identificador relativo, debido a la barra de no liderazgo. Es relativo al espacio de nombres actual:

namespace Name\Space;
$x = new To\Class;

Este es también un identificador relativo. En este caso, está resuelto contra el use declaración, porque la última parte (alias) es la misma, que la primera de la clase:

namespace Other\Name\Space;
use Name\Space;
$x = new Space\To\Class;

Sin embargo, porque en namespace y use Declaraciones Solo se permiten identificadores absolutos (nombres totalmente calificados), está bien omitirlo aquí. En namespace, incluso no está permitido establecer la barra inesperada principal.

Para obtener más información sobre cómo PHP resuelve las diferentes declaraciones del espacio de nombres, consulte el Manual de reglas del espacio de nombres.

no decir que tenemos

namespace MyNamespace
use Exception;
use \Exception;

Luego, el primer uso realmente importa la clase MyNamesPace Exception y la segunda de la clase principal Excepción

Entonces puedes tener algo como

namespace MyNamespace;
class Exception extends \Exception{ }

Y luego puedo

throw new \Exception('Exception from global namespace');
throw new \MyNamespace\Exception('Exception from MyNamespace');

La barra inesperada principal significa el espacio de nombres global. Si está en el alcance de un espacio de nombres, debe usarlo para llegar al espacio de nombres global. Por ejemplo:

namespace A
{
    class A
    {
        public function __construct()
        {
            echo('namespace: A<br />');
        }
    }
}

namespace B\A
{
    class A
    {
        public function __construct()
        {
            echo('namespace: B\\A<br />');
        }
    }
}

namespace B
{
    class B
    {
        public function __construct()
        {
            new \A\A(); // namespace: A
            new A\A(); // namespace: B\A
        }
    }
    new B();
}

Con la barra inalcadora principal obtuviste el camino absoluto, y sin él obtuviste el camino relativo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top