Comment fonctionne le mot-clé «utiliser» en PHP et puis-je importer des classes avec?


136

J'ai un dossier avec une classe Resp. Le chemin est:

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

Et j'ai un index.phpfichier dans ce répertoire:

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

Dans ce index.phpfichier, je souhaite instancier une classe Resp.

$a = new Resp();

Je sais que je peux utiliser des mots require- includeclés ou pour inclure le fichier dans une classe:

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

Mais je veux importer des classes sans utiliser requireou include. J'essaie de comprendre comment usefonctionne le mot clé. J'ai essayé ces étapes mais rien ne fonctionne:

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();

Ça dit:

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

Comment fonctionne le mot-clé use? Puis-je l'utiliser pour importer des classes?


1
Vous ne pouvez pas sans importer les fichiers. Veuillez ne pas changer le flux. De plus, les espaces de noms ne sont pas vraiment utilisés en PHP. Tout comme VB.NET
Cole Johnson

14
@ cole-johnson, pas d'accord avec vous. Symfony est construit autour de namespaces. En fait il n'y a pas de Symfony si vous n'utilisez pas d'espaces de noms
Vert

Réponses:


80

usen'inclut rien. Il importe simplement l'espace de noms (ou la classe) spécifié dans la portée actuelle

Si vous souhaitez que les classes soient chargées automatiquement - lisez à propos du chargement automatique


@ G-Man il répond aux questions mêmes posées.
zerkms

188

Non, vous ne pouvez pas importer une classe avec le usemot - clé. Vous devez utiliser include/ requirestatement. Même si vous utilisez un chargeur automatique PHP, le chargeur automatique devra toujours utiliser soit includeou en requireinterne.

Le mot-clé Purpose of use :

Prenons un cas où vous avez deux classes avec le même nom; vous trouverez cela étrange, mais lorsque vous travaillez avec une grosse structure MVC, cela arrive. Donc, si vous avez deux classes avec le même nom, placez-les dans des espaces de noms différents. Considérez maintenant quand votre chargeur automatique charge les deux classes (fait par require) et que vous êtes sur le point d'utiliser un objet de classe. Dans ce cas, le compilateur ne sait pas quel objet de classe charger parmi deux. Pour aider le compilateur à prendre une décision, vous pouvez utiliser l' useinstruction afin qu'il puisse prendre une décision sur laquelle va être utilisée.

De nos jours, les principaux frameworks utilisent includeou requirevia composeretpsr

1) compositeur

2) chargeur automatique PSR-4

Les parcourir peut vous aider davantage. Vous pouvez également utiliser un alias pour adresser une classe exacte. Supposons que vous ayez deux classes avec le même nom, disons Maileravec deux espaces de noms différents:

namespace SMTP;
class Mailer{}

et

namespace Mailgun;
class Mailer{}

Et si vous souhaitez utiliser les deux classes Mailer en même temps, vous pouvez utiliser un alias.

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

Plus tard dans votre code, si vous souhaitez accéder à ces objets de classe, vous pouvez effectuer les opérations suivantes:

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

Il référencera la classe d'origine.

Certains peuvent être confus, car il n'y a pas de noms de classe similaires, alors il n'y a pas d'utilisation de usemot - clé. Eh bien, vous pouvez utiliser une __autoload($class)fonction qui sera appelée automatiquement lorsque l' useinstruction sera exécutée avec la classe à utiliser comme argument et cela peut vous aider à charger la classe à l'exécution à la volée en cas de besoin.

Reportez-vous à cette réponse pour en savoir plus sur le chargeur automatique de classe.


pourquoi ne pas simplement utiliser un nom de classe différent?
divin

15
@Divin. Les cours peuvent provenir de fournisseurs tiers
Dayo

3
@Divin. Que faire si les deux classes en collision proviennent de tiers?
Dayo

2
@divine Par convention, l'espace de noms sera <vendorName> / <packageName> de sorte qu'il a déjà été résolu. Conformément à la convention, il est impossible pour le packagiste d'accepter le même nom de fournisseur de quelqu'un d'autre. Et packagist.org est le référentiel PHP utilisé pour l'installation des packages par le compositeur.
Tpojka

1
@root n'a pas d'importance, il indique simplement à l'exécution ce qui doit être utilisé. comme si vous conduisiez une voiture et que le signal vous disait de sauter en avant et que vous vous cassiez, comme la usedéclaration de manière indiquera au compilateur de charger cela pour moi maintenant. Je l'ai cher!
Rajan Rawal

23

Ne réfléchissez pas trop à ce qu'est un espace de noms .

L'espace de noms est essentiellement juste un préfixe de classe (comme le répertoire dans le système d'exploitation) pour garantir l' unicité du chemin de classe .

Aussi juste pour clarifier les choses, l' instruction use ne fait rien qui alias uniquement vos espaces de noms afin que vous puissiez utiliser des raccourcis ou inclure des classes avec le même nom mais des espaces de noms différents dans le même fichier.

Par exemple:

// 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 vous voulez savoir comment fonctionnent les espaces de noms PHP et le chargement automatique (l'ancienne méthode ainsi que la nouvelle méthode avec Composer), vous pouvez lire l'article de blog que je viens d'écrire sur ce sujet: https://enterprise-level-php.com/ 2017/12/25 / la-magie-derriere-autoloading-php-files-using-composer.html


8

Vous devrez de toute façon inclure / exiger la classe, sinon PHP ne connaîtra pas l'espace de noms. Cependant,
vous n'êtes pas obligé de le faire dans le même fichier. Vous pouvez le faire dans un fichier bootstrap par exemple. (ou utilisez un chargeur automatique, mais ce n'est pas le sujet en fait)


4

Le problème est très probablement que vous devrez utiliser un chargeur automatique qui prendra le nom de la classe (interrompre par «\» dans ce cas) et le mapper à une structure de répertoires.

Vous pouvez consulter cet article sur la fonctionnalité de chargement automatique de PHP. Il existe déjà de nombreuses implémentations de ce type de fonctionnalité dans les frameworks.

J'en ai déjà implémenté un auparavant. Voici un lien .


Il y a un problème avec cela. Il a besoin d'un modèle récursif pour lui permettre de créer un chemin complet. Pour le moment, il ne gère que les espaces de noms à un seul niveau.
Tyler Carter

3

Je suis d'accord avec Green, Symfony a besoin d'un espace de noms, alors pourquoi ne pas les utiliser?

Voici comment un exemple de classe de contrôleur démarre:

espace de noms Acme \ DemoBundle \ Controller;

utilisez Symfony \ Bundle \ FrameworkBundle \ Controller \ Controller;

La classe WelcomeController étend le contrôleur {...}


3

Puis-je l'utiliser pour importer des classes?

Vous ne pouvez pas le faire comme ça en dehors des exemples ci-dessus. Vous pouvez également utiliser le mot-clé à l' useintérieur des classes pour importer des traits , comme ceci:

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

Le usemot-clé est pour l'aliasing en PHP et il n'importe pas les classes. Cela aide vraiment
1) Lorsque vous avez des classes avec le même nom dans des espaces de noms différents
2) Évitez d'utiliser des noms de classe très longs encore et encore.


2

L'espace de noms est utilisé pour définir le chemin vers un fichier spécifique contenant une classe, par exemple

namespace album/className; 

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

Vous pouvez ensuite inclure cette classe spécifique dans un autre fichier php en utilisant le mot-clé "use" comme ceci:

use album/className;

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

REMARQUE: n'utilisez pas le chemin d'accès au fichier contenant la classe à implémenter, étend l'utilisation pour instancier un objet mais n'utilisez que l'espace de noms.


2

L'utilisation du mot-clé "use" sert à raccourcir les littéraux d'espace de noms. Vous pouvez utiliser les deux avec ou sans alias. Sans alias, vous devez utiliser la dernière partie de l'espace de noms complet.

<?php
    use foo\bar\lastPart;
    $obj=new lastPart\AnyClass(); //If there's not the line above, a fatal error will be encountered.
?>
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.