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

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

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

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

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

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

$a = new Resp();

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

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

但是我想不使用 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();

上面写着:

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

关键字 use是如何工作的? 我可以用它来导入类吗?

208763 次浏览

use不包含任何内容,它只是将指定的名称空间(或类)导入到当前作用域

如果希望自动加载这些类,请阅读有关 自动加载的内容

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

问题很可能是您需要使用一个自动加载程序,该程序将获取类的名称(在本例中为’以’分隔)并将其映射到一个目录结构。

您可以查看这篇关于 PHP 的 自动加载功能的文章。在框架中已经有许多此类功能的实现。

我以前实现过一个,这是 链接

不,您不能导入具有 use关键字的类。必须使用 include/require语句。即使您使用 PHP 自动加载程序,仍然自动加载程序必须在内部使用 includerequire

使用关键字的用途:

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

现在主流框架通过 composerpsr使用 includerequire

1) 作曲家

2) PSR-4自动装弹机

仔细阅读可能会对你有进一步的帮助。 您还可以使用别名来寻址确切的类。假设有两个具有相同名称的类,比如具有两个不同名称空间的 Mailer:

namespace SMTP;
class Mailer{}

还有

namespace Mailgun;
class Mailer{}

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

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

在代码的稍后部分,如果您想访问这些类对象,那么您可以执行以下操作:

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

它将引用原始类。

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

请参考此 回答以了解更多关于类自动加载程序的信息。

我同意 Green 的观点,Symfony 需要名称空间,那么为什么不使用它们呢?

下面是示例控制器类的开始方式:

名称空间 Acme DemoBundle 控制器;

使用 Symfony 束框架束控制器;

类 WelcomController 扩展 Controller { ... }

use关键字是用于在 PHP 中使用别名,它不导入类
1)当在不同的名称空间中具有相同名称的类时
2)避免一次又一次地使用很长的类名。

我可以用它来导入类吗?

除了上面的例子,你不能这样做。还可以在类中使用关键字 use导入 品质,如下所示:

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'

不要多想什么是 命名空间

命名空间 基本上只是一个 同学们前缀(类似于操作系统中的目录) ,以确保 同学们路径的唯一性。

同样只是为了让事情更清楚,使用语句不做任何事情只是别名你的 名称空间,所以你可以使用快捷方式或包括 课程与相同的名称,但在同一个文件不同的 命名空间

例如:

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

如果您想知道 PHP 命名空间和自动加载(Composer 的旧方法和新方法)是如何工作的,您可以阅读我刚才写的关于这个主题的博客文章: https://enterprise-level-php.com/2017/12/25/the-magic-behind-autoloading-php-files-using-composer.html

命名空间用于定义包含类的特定文件的路径。

namespace album/className;


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

然后,您可以像下面这样使用关键字“ use”将这个特定的类包含到另一个 php 文件中:

use album/className;


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

注意: 不要使用包含要实现的类的文件的路径,扩展用于实例化对象,但只使用名称空间。

使用关键字“ use”是为了缩短名称空间文字。可以同时使用别名和不使用别名。如果不使用别名,则必须使用完整名称空间的最后一部分。

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