我有一个文件,其中包含一个类Resp
。路径为:
C:'xampp'htdocs'One'Classes'Resp.php
我在这个目录中有一个index.php
文件:
C:'xampp'htdocs'Two'Http'index.php
在这个index.php
文件中,我想实例化一个类Resp
。
$a = new Resp();
我知道我可以使用require
或include
关键字将文件包含在类中:
require("One'Classes'Resp.php"); // I've set the include_path correctly already ";C:'xampp'htdocs". It works.
$a = new Resp();
但是我想在不使用require
或include
的情况下导入类。我试图了解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
如何工作?我可以使用它来导入类吗?
不可以,不能使用 use
关键字导入类。您必须使用include
/require
语句。即使您使用 PHP 自动加载器,自动加载器仍然必须在内部使用 include
或require
。
使用目的关键字:
考虑一个情况,你有两个同名的类;你会发现这很奇怪,但是当你使用一个大的MVC结构时,它就会发生。因此,如果有两个同名的类,请将它们放在不同的命名空间中。现在考虑您的自动加载程序何时加载两个类(按require
加载),并且您将要使用类的对象。在这种情况下,编译器会混淆在两个类对象中加载哪个类对象。为了帮助编译器做出决定,您可以使用 use
语句,以便它可以决定将用于哪一个。
如今,主要框架确实通过composer
和psr
使用include
或require
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
该函数将自动调用,这可以帮助您在需要时在运行时动态加载类。
请参阅此答案以了解有关类自动加载器的更多信息。
use
不包含任何内容。它只是将指定的命名空间(或类)导入到当前范围
如果您希望自动加载类 - 阅读有关自动加载的信息
不要过度思考命名空间是什么。
命名空间基本上只是一个类前缀(如操作系统中的目录),以确保类路径的唯一性。
同样为了清楚起见,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();
}
如果你想知道PHP命名空间和自动加载(旧方式以及Composer的新方式)是如何工作的,你可以阅读我刚刚写的关于这个主题的博客文章:https://enterprise-level-php.com/2017/12/25/the-magic-behind-autoloading-php-files-using-composer.html
你都必须包含/要求该类,否则 PHP 将不知道命名空间。
不过,您不必在同一个文件中执行此操作。例如,您可以在引导程序中执行此操作。(或使用自动加载机,但这实际上不是主题)
问题很可能是您需要使用自动加载程序,该加载程序将采用类的名称(在本例中以"''"分隔)并将其映射到目录结构。
您可以查看有关 PHP 自动加载功能的文章。在框架中已经有许多此类功能的实现。
我以前实际上已经实现过一个。这里有一个链接。
我同意Green的观点,Symfony需要命名空间,那么为什么不使用它们呢?
下面是示例控制器类的开始方式:
命名空间 Acme''DemoBundle''Controller;
使用 Symfony''Bundle''FrameworkBundle''Controller''Controller;
类欢迎控制器扩展控制器 { ... }
我可以使用它来导入类吗?
除了上面的例子之外,你不能这样做。您还可以在类中使用关键字 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'
use
关键字用于 PHP 中的别名,它不导入类。这真的很有帮助
1) 当您在不同的命名空间
中具有相同名称的类时2)避免一遍又一遍地使用很长的类名。
使用关键字"use"用于缩短命名空间文本。您可以同时使用别名和不使用别名。如果没有别名,则必须使用完整命名空间的最后一部分。
<?php
use foo'bar'lastPart;
$obj=new lastPart'AnyClass(); //If there's not the line above, a fatal error will be encountered.
?>
<</div>
div class="answers">命名空间用于定义包含类的特定文件的路径,例如
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
}
注意:不要使用包含要实现的类的文件的路径,使用扩展来实例化对象,而只使用命名空间。