关键字"use"如何在PHP中工作,我可以用它导入类吗?

Gre*_*een 126 php import include

我有一个类的文件Resp.路径是:

C:\xampp\htdocs\One\Classes\Resp.php
Run Code Online (Sandbox Code Playgroud)

index.php在这个目录中有一个文件:

C:\xampp\htdocs\Two\Http\index.php
Run Code Online (Sandbox Code Playgroud)

在这个index.php文件中,我想实例化一个类Resp.

$a = new Resp();
Run Code Online (Sandbox Code Playgroud)

我知道我可以使用requireinclude关键字包含一个类的文件:

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

但我想导入类而不使用requireinclude.我试图了解use关键字的工作原理.我尝试了这些步骤,但没有任何作用:

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();
Run Code Online (Sandbox Code Playgroud)

它说:

Fatal error: Class 'One\Classes\Resp' not found in C:\xampp\htdocs\Two\Http\index.php
Run Code Online (Sandbox Code Playgroud)

关键字如何use运作?我可以用它来导入课程吗?

Raj*_*wal 172

不,您无法使用use关键字导入类.你必须使用include/ requirestatement.即使你使用PHP自动加载器,仍然自动加载器必须使用includerequire内部.

目的使用关键字:

考虑一个你有两个同名的类的情况; 你会发现它很奇怪,但当你使用一个大的MVC结构时,它就会发生.因此,如果您有两个具有相同名称的类,请将它们放在不同的名称空间中.现在考虑你的自动加载器何时加载两个类(确实如此require),并且你将要使用类的对象.在这种情况下,编译器会混淆哪两个类对象加载.为了帮助编译器做出决定,您可以使用该use语句,以便它可以决定将使用哪个.

如今主要的框架确实使用includerequire通过composerpsr

1)作曲家

2)PSR-4自动加载器

通过它们可能会对您有所帮助.您还可以使用别名来解决确切的类.假设您有两个具有相同名称的类,比如Mailer两个不同的名称空间:

namespace SMTP;
class Mailer{}
Run Code Online (Sandbox Code Playgroud)

namespace Mailgun;
class Mailer{}
Run Code Online (Sandbox Code Playgroud)

如果你想同时使用两个Mailer类,那么你可以使用别名.

use SMTP\Mailer as SMTPMailer;
use Mailgun\Mailer as MailgunMailer;
Run Code Online (Sandbox Code Playgroud)

如果要访问这些类对象,稍后在代码中可以执行以下操作:

$smtp_mailer = new SMTPMailer;
$mailgun_mailer = new MailgunMailer;
Run Code Online (Sandbox Code Playgroud)

它将引用原始类.

有些人可能会感到困惑,因为没有类似的类名,那么就没有使用use关键字.好吧,您可以使用__autoload($class)use语句执行时自动调用的函数,该类将用作参数,这可以帮助您在需要时动态地在运行时加载类.

请参阅此答案以了解有关类自动加载器的更多信息.

  • @divine.这些课程可能来自第三方供应商 (15认同)
  • @divine.如果两个碰撞类都来自第三方怎么办? (3认同)
  • 为什么不直接使用不同的类名呢? (2认同)
  • @divine按照惯例,命名空间将是<vendorName>/<packageName>,这样它就已经解决了.遵循惯例,packagist无法接受来自其他人的相同供应商名称.Packagist.org是PHP存储库,用于编译器安装包. (2认同)

zer*_*kms 75

use不包括任何东西.它只是将指定的命名空间(或类)导入当前范围

如果您希望自动加载类 - 请阅读有关自动加载的内容


Blo*_*kas 20

不要过分思考命名空间.

Namespace基本上只是一个Class前缀(就像操作系统中的目录一样),以确保Class路径的唯一性.

另外,为了清楚起见,use语句不会对命名空间进行别名操作,因此您可以使用快捷方式或在同一文件中包含具有相同名称但名称空间不同的.

例如:

// 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();
}
Run Code Online (Sandbox Code Playgroud)

如果您想知道PHP命名空间和自动加载(旧方法以及Composer的新方法)如何工作,您可以阅读我刚刚撰写的关于此主题的博客文章:https://enterprise-level-php.com/十二分之二千零十七/ 25 /的魔法隐藏,自动加载的PHP-文件-使用- composer.html


Sam*_*ane 8

您无论如何都必须包含/要求该类,否则PHP将不知道该命名空间.
但是,您不必在同一个文件中执行此操作.例如,您可以在引导程序文件中执行此操作.(或使用自动加载器,但实际上这不是主题)


Müs*_*bər 5

使用关键字“use”是为了缩短命名空间文字。您可以使用带别名或不带别名的两种方式。如果没有别名,您必须使用完整名称空间的最后一部分。

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