¿Cómo funciona la palabra clave "use" en PHP y puedo importar clases con ella?


136

Tengo un archivo con una clase Resp. El camino es:

C:\xampp\htdocs\One\Classes\Resp.php

Y tengo un index.phparchivo en este directorio:

C:\xampp\htdocs\Two\Http\index.php

En este index.phparchivo quiero crear una instancia de una clase Resp.

$a = new Resp();

Sé que puedo usar requireo includepalabras clave para incluir el archivo con una clase:

require("One\Classes\Resp.php");       // I've set the include_path correctly already ";C:\xampp\htdocs". It works.
$a = new Resp();

Pero quiero importar clases sin usar requireo include. Estoy tratando de entender cómo usefunciona la palabra clave. Intenté estos pasos pero nada funciona:

use One\Classes\Resp;
use xampp\htdocs\One\Classes\Resp;
use htdocs\One\Classes\Resp;
use One\Classes;
use htdocs\One\Classes;    /* nothing works */

$a = new Resp();

Dice:

Fatal error: Class 'One\Classes\Resp' not found in C:\xampp\htdocs\Two\Http\index.php

¿Cómo funciona la palabra clave use? ¿Puedo usarlo para importar clases?


1
No puede sin importar los archivos. Por favor no cambie el flujo. También los espacios de nombres realmente no se usan en PHP. Al igual que VB.NET
Cole Johnson

14
@ Cole-Johnson, no estoy de acuerdo contigo. Symfony está construido alrededor del namespaces. De hecho, no hay ningún Symfony si no usa espacios de nombres
Verde

Respuestas:


80

useno incluye nada Solo importa el espacio de nombres (o clase) especificado al ámbito actual

Si desea que las clases se carguen automáticamente, lea sobre carga automática


@ G-Man responde las mismas preguntas que se hacen.
zerkms

188

No, no puede importar una clase con la usepalabra clave. Tienes que usar include/ requiredeclaración. Incluso si usa un cargador automático PHP, el cargador automático tendrá que usarlo de manera interna includeo requireinterna.

El propósito de la palabra clave de uso :

Considere un caso en el que tiene dos clases con el mismo nombre; Le resultará extraño, pero cuando trabaja con una gran estructura MVC, sucede. Entonces, si tiene dos clases con el mismo nombre, colóquelas en espacios de nombres diferentes. Ahora considere cuándo su cargador automático está cargando ambas clases (hace por require) y está a punto de usar el objeto de clase. En este caso, el compilador se confundirá qué objeto de clase cargar entre dos. Para ayudar al compilador a tomar una decisión, puede usar eluse declaración para que pueda tomar una decisión sobre cuál se va a usar.

Hoy en día los principales marcos hacen uso includeo requirevíacomposer ypsr

1) compositor

2) PSR-4 cargador automático

Revisarlos puede ayudarte más. También puede usar un alias para abordar una clase exacta. Supongamos que tiene dos clases con el mismo nombre, digamos Mailercon dos espacios de nombres diferentes:

namespace SMTP;
class Mailer{}

y

namespace Mailgun;
class Mailer{}

Y si desea usar ambas clases de Mailer al mismo tiempo, puede usar un alias.

use SMTP\Mailer as SMTPMailer;
use Mailgun\Mailer as MailgunMailer;

Más adelante en su código, si desea acceder a esos objetos de clase, puede hacer lo siguiente:

$smtp_mailer = new SMTPMailer;
$mailgun_mailer = new MailgunMailer;

Hará referencia a la clase original.

Algunos pueden confundirse porque entonces no hay nombres de clase similares, entonces no hay uso de usepalabras clave. Bueno, puedes usar la __autoload($class)función que se llamará automáticamente cuandouse instrucción se ejecute con la clase que se usará como argumento y esto puede ayudarlo a cargar la clase en tiempo de ejecución sobre la marcha cuando sea necesario.

Consulte esta respuesta para saber más sobre el autocargador de clases.


¿Por qué no usar un nombre de clase diferente?
divina

15
@adivinar. Las clases pueden ser de terceros
Dayo

3
@adivinar. ¿Qué pasa si ambas clases de colisión son de terceros?
Dayo

2
@divine Por convención, el espacio de nombres será <vendorName> / <packageName>, de modo que ya esté resuelto. Después de la convención, es imposible para el empaquetador aceptar el mismo nombre de proveedor de otra persona. Y packagist.org es un repositorio PHP que se utiliza para la instalación de paquetes por parte del compositor.
Tpojka

1
@root no importa, solo le dice al tiempo de ejecución lo que se debe usar. como si estuvieras conduciendo un automóvil y la señal te indica que te adelantes y te rompas, como la usedeclaración indicará que el compilador carga esto para mí ahora. Lo tengo querido!
Rajan Rawal

23

No pienses demasiado en qué es un espacio de nombres .

El espacio de nombres es básicamente un prefijo de clase (como el directorio en el sistema operativo) para garantizar la clase unicidad de la ruta de .

También solo para aclarar las cosas, el uso declaración de no hace nada solo alias sus espacios de nombres para que pueda usar accesos directos o incluir clases con el mismo nombre pero diferentes espacios de nombres en el mismo archivo.

P.ej:

// You can do this at the top of your Class
use Symfony\Component\Debug\Debug;

if ($_SERVER['APP_DEBUG']) {
    // So you can utilize the Debug class it in an elegant way
    Debug::enable();
    // Instead of this ugly one
    // \Symfony\Component\Debug\Debug::enable();
}

Si desea saber cómo funcionan los espacios de nombres PHP y la carga automática (la manera antigua y la nueva con Composer), puede leer la publicación del blog que acabo de escribir sobre este tema: https://enterprise-level-php.com/ 2017/12/25 / the-magic-behind-autoloading-php-files-using-composer.html


8

Tendrá que incluir / requerir la clase de todos modos, de lo contrario, PHP no sabrá sobre el espacio de nombres.
Sin embargo , no es necesario que lo haga en el mismo archivo. Puede hacerlo en un archivo de arranque, por ejemplo. (o use un cargador automático, pero ese no es el tema en realidad)


4

El problema es más probable que necesite usar un cargador automático que tomará el nombre de la clase (separe por '\' en este caso) y lo asigne a una estructura de directorio.

Puedes consultar este artículo sobre carga automática funcionalidad de de PHP. Ya hay muchas implementaciones de este tipo de funcionalidad en frameworks.

De hecho, he implementado uno antes. Aquí hay un enlace .


Sin embargo, hay un problema con eso. Necesita un modelo recursivo que le permita construir una ruta completa. En este momento solo maneja espacios de nombres de un solo nivel.
Tyler Carter

3

Estoy de acuerdo con Green, Symfony necesita un espacio de nombres, ¿por qué no usarlos?

Así es como comienza una clase de controlador de ejemplo:

espacio de nombres Acme \ DemoBundle \ Controller;

use Symfony \ Bundle \ FrameworkBundle \ Controller \ Controller;

clase WelcomeController extiende el controlador {...}


3

¿Puedo usarlo para importar clases?

No puedes hacerlo así además de los ejemplos anteriores. También puede usar la palabra clave usedentro de las clases para importar rasgos , como este:

trait Stuff {
    private $baz = 'baz';
    public function bar() {
        return $this->baz;
    }
}

class Cls {
    use Stuff;  // import traits like this
}

$foo = new Cls;
echo $foo->bar(); // spits out 'baz'

3

La usepalabra clave es para crear alias en PHP y no importa las clases. Esto realmente ayuda
1) Cuando tienes clases con el mismo nombre en diferentes espacios
de nombres 2) Evita usar el nombre de clase realmente largo una y otra vez.


2

El espacio de nombres se utiliza para definir la ruta a un archivo específico que contiene una clase, por ejemplo

namespace album/className; 

class className{
//enter class properties and methods here
}

Luego puede incluir esta clase específica en otro archivo php utilizando la palabra clave "use" de esta manera:

use album/className;

class album extends classname {
//enter class properties and methods
}

NOTA: No use la ruta al archivo que contiene la clase que se implementará, extiende el uso para crear una instancia de un objeto, sino solo use el espacio de nombres.


2

Usar la palabra clave "use" es para acortar literales de espacios de nombres. Puede usar ambos con alias y sin él. Sin alias, debe usar la última parte del espacio de nombres completo.

<?php
    use foo\bar\lastPart;
    $obj=new lastPart\AnyClass(); //If there's not the line above, a fatal error will be encountered.
?>
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.