wake-up-neo.net

Wie funktioniert das Keyword "use"? PHP und kann ich damit Klassen importieren?

Ich habe eine Datei mit einer Klasse Resp. Der Pfad ist:

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

Und ich habe eine index.php-Datei in diesem Verzeichnis:

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

In dieser index.php-Datei möchte ich eine Klasse Resp instanziieren.

$a = new Resp();

Ich weiß, dass ich require oder include Schlüsselwörter verwenden kann, um die Datei in eine Klasse aufzunehmen:

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

Ich möchte jedoch Klassen importieren, ohne require oder include zu verwenden. Ich versuche zu verstehen, wie das use-Keyword funktioniert. Ich habe diese Schritte ausprobiert, aber nichts funktioniert:

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

Es sagt:

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

Wie funktioniert das Keyword use? Kann ich damit Klassen importieren?

111
Green

use enthält nichts. Es importiert einfach den angegebenen Namespace (oder die Klasse) in den aktuellen Bereich

Wenn Sie möchten, dass die Klassen automatisch geladen werden - lesen Sie über autoloading

68
zerkms

Nein, Sie können keine Klasse mit dem Schlüsselwort use importieren. Sie müssen eine includerequire-Anweisung verwenden. Selbst wenn Sie einen Auto-Loader PHP verwenden, muss der Autoloader intern include oder require verwenden. 

Der Zweck von _/use Schlüsselwort:

Stellen Sie sich einen Fall vor, in dem Sie zwei Klassen mit demselben Namen haben. Sie werden es seltsam finden, aber wenn Sie mit einer großen MVC-Struktur arbeiten, passiert dies. Wenn Sie also zwei Klassen mit demselben Namen haben, platzieren Sie sie in verschiedenen Namespaces. Überlegen Sie sich nun, wann Ihr Auto Loader beide Klassen lädt (do von require), und Sie sind dabei, ein Objekt der Klasse zu verwenden. In diesem Fall wird der Compiler verwirrt, welches Klassenobjekt zwischen zwei geladen werden soll. Um dem Compiler zu helfen, eine Entscheidung zu treffen, können Sie die use-Anweisung verwenden, damit er entscheiden kann, für welche Anweisung sie verwendet wird.

Heutzutage verwenden wichtige Frameworks include oder require über composer und psr

1) Komponist

2) PSR-4 Autoloader

Sie durchzugehen, kann Ihnen weiterhelfen. Sie können auch einen Alias ​​verwenden, um eine genaue Klasse anzusprechen. Angenommen, Sie haben zwei Klassen mit demselben Namen, beispielsweise Mailer mit zwei unterschiedlichen Namespaces:

namespace SMTP;
class Mailer{}

und 

namespace Mailgun;
class Mailer{}

Wenn Sie beide Mailer-Klassen gleichzeitig verwenden möchten, können Sie einen Alias ​​verwenden. 

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

Wenn Sie später in Ihrem Code auf diese Klassenobjekte zugreifen möchten, können Sie Folgendes tun:

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

Es wird auf die ursprüngliche Klasse verweisen.

Einige können verwirrt sein, dass es dann keine ähnlichen Klassennamen gibt und dann das use-Schlüsselwort nicht verwendet wird. Sie können die Funktion __autoload($class) verwenden, die automatisch aufgerufen wird, wenn die use-Anweisung mit der Klasse ausgeführt wird, die als Argument verwendet werden soll. Dies kann Ihnen dabei helfen, die Klasse nach Bedarf zur Laufzeit zu laden. 

Lesen Sie diese Antwort , um mehr über den Autoloader zu erfahren. 

149
Rajan Rawal

Überlegen Sie nicht, was ein Namespace ist.

Namespace ist im Grunde nur ein Präfix Class (wie das Verzeichnis im Betriebssystem), um die Eindeutigkeit des Pfads Class sicherzustellen.

Um die Dinge klarer zu machen, bewirkt die Anweisung use nichts Aliasing für Ihre Namespaces, sodass Sie Verknüpfungen verwenden oder Classes mit demselben Namen, aber unterschiedlichen Namespace in einfügen können die gleiche Datei.

Z.B:

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

Wenn Sie wissen möchten, wie PHP Namespaces und Autoloading (der alte Weg sowie der neue Weg mit Composer) funktionieren, können Sie den Blogpost lesen, den ich gerade zu diesem Thema schrieb: https: // enterprise- level-php.com/2017/12/25/the-magic-behind-autoloading-php-files-using-composer.html

12
BlocksByLukas

Sie müssen die Klasse sowieso einschließen/fordern, andernfalls kennt PHP den Namespace nicht.
Sie müssen dies jedoch nicht unbedingt in der Datei same tun. Sie können dies beispielsweise in einer Bootstrap-Datei tun. (oder einen Autoloader verwenden, aber das ist eigentlich nicht das Thema)

8
Samy Dindane

Das Problem ist höchstwahrscheinlich, dass Sie einen Autoloader verwenden müssen, der den Namen der Klasse übernimmt (in diesem Fall break by '\') und einer Verzeichnisstruktur zuordnen.

Sie können diesen Artikel über die Autoloading - Funktionalität von PHP lesen. Es gibt bereits viele Implementierungen dieser Art von Funktionalität in Frameworks.

Ich habe eigentlich schon eins implementiert. Hier ist ein Link .

4
Tyler Carter

Ich stimme mit Green überein. Symfony benötigt einen Namespace. Warum also nicht?

So beginnt eine Beispiel-Controller-Klasse:

namensraum Acme\DemoBundle\Controller;

verwenden Sie Symfony\Bundle\FrameworkBundle\Controller\Controller.

klasse WelcomeController erweitert Controller {...}

3
Eric Draven

Das Schlüsselwort use dient zum Aliasing in PHP und importiert die Klassen nicht. Das hilft wirklich 
1) Wenn Sie Klassen mit gleichem Namen in verschiedenen Namespaces haben
2) Vermeiden Sie es, immer und immer wieder lange Klassennamen zu verwenden.

3
Abdul Mannan

Kann ich damit Klassen importieren?

Außer den obigen Beispielen kann man das nicht so machen. Sie können auch das Schlüsselwort use in Klassen verwenden, um traits wie folgt zu importieren:

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'
2
Thielicious

Mit dem Schlüsselwort "use" werden Namespace-Literale gekürzt. Sie können sowohl mit als auch ohne Aliasing arbeiten. Ohne Aliasing müssen Sie den letzten Teil des vollständigen Namespace verwenden.

<?php
    use foo\bar\lastPart;
    $obj=new lastPart\AnyClass(); //If there's not the line above, a fatal error will be encountered.
?>
1

Namensraum wird verwendet, um den Pfad zu einer bestimmten Datei zu definieren, die eine Klasse enthält, z.

namespace album/className; 

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

Sie können diese bestimmte Klasse dann in eine andere PHP-Datei einschließen, indem Sie das Schlüsselwort "use" wie folgt verwenden:

use album/className;

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

ANMERKUNG: Verwenden Sie nicht den Pfad zu der Datei, die die zu implementierende Klasse enthält. Er erweitert die Verwendung, um ein Objekt zu instanziieren, sondern verwendet nur den Namespace.