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

时间:2022-08-22 21:21:46

I have a file with a class Resp. The path is:

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

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

And I have an index.php file in this directory:

我有一个指数。本目录中的php文件:

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

In this index.php file I want to instantiate a class Resp.

在这个索引。我想实例化一个类Resp的php文件。

$a = new Resp();

I know I can use require or include keywords to include the file with a class:

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

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

But I want to import classes without using require or include. I'm trying to understand how use keyword works. I tried theses steps but nothing works:

但是,我想在不使用require或include的情况下导入类。我正在尝试理解使用关键字是如何工作的。我尝试了这些步骤,但没有成功:

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

It says:

它说:

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

How does the keyword use work? Can I use it to import classes?

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

8 个解决方案

#1


59  

use doesn't include anything. It just imports the specified namespace (or class) to the current scope

不包括任何使用。它只是将指定的名称空间(或类)导入到当前的范围。

If you want the classes to be autoloaded - read about autoloading

如果你想让这些课程都是自动的,那就读读自动阅读吧。

#2


128  

No, you can not import a class with the use keyword. You have to use include/require statement. Even if you use a PHP auto loader, still autoloader will have to use either include or require internally.

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

The Purpose of use keyword:

使用关键字的目的:

Consider a case where you have two classes with the same name; you'll find it strange, but when you are working with a big MVC structure, it happens. So if you have two classes with the same name, put them in different namespaces. Now consider when your auto loader is loading both classes (does by require), and you are about to use object of class. In this case, the compiler will get confused which class object to load among two. To help the compiler make a decision, you can use the use statement so that it can make a decision which one is going to be used on.

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

Nowadays major frameworks do use include or require via composer and psr

现在,主要的框架都是通过composer和psr来使用include或required

1) composer

1)作曲家

2) PSR-4 autoloader

2)PSR-4自动装卸机

Going through them may help you further. You can also use an alias to address an exact class. Suppose you've got two classes with the same name, say Mailer with two different namespaces:

通过它们可能会对你更有帮助。您还可以使用别名来寻址一个确切的类。假设您有两个名称相同的类,假设Mailer有两个不同的名称空间:

namespace SMTP;
class Mailer{}

and

namespace Mailgun;
class Mailer{}

And if you want to use both Mailer classes at the same time then you can use an alias.

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

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

Later in your code if you want to access those class objects then you can do the following:

在你的代码中,如果你想要访问这些类对象,你可以做如下操作:

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

It will reference the original class.

它将引用原始类。

Some may get confused that then of there are not Similar class names then there is no use of use keyword. Well, you can use __autoload($class) function which will be called automatically when use statement gets executed with the class to be used as an argument and this can help you to load the class at run-time on the fly as and when needed.

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

Refer this answer to know more about class autoloader.

参考这个答案来了解更多关于类自动阅读器的信息。

#3


8  

Don’t overthink what a Namespace is.

不要过度思考命名空间是什么。

Namespace is basically just a Class prefix (like directory in Operating System) to ensure the Class path uniqueness.

名称空间基本上只是一个类前缀(如操作系统中的目录),以确保类路径的惟一性。

Also just to make things clear, the use statement is not doing anything only aliasing your Namespaces so you can use shortcuts or include Classes with the same name but different Namespace in the same file.

同样,为了清楚地说明这一点,use语句并没有做任何事情,只是对名称空间进行混叠,以便您可以使用快捷方式,或者在同一个文件中包含名称相同但名称不同的类。

E.g:

例句:

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

If you want to know how PHP Namespaces and autoloading (the old way as well as the new way with Composer) works, you can read the blog post I just wrote on this topic: https://enterprise-level-php.com/2017/12/25/the-magic-behind-autoloading-php-files-using-composer.html

如果您想知道PHP名称空间和自动加载(旧的方式以及Composer的新方式)是如何工作的,您可以阅读我刚刚在这个主题上写的博客文章:https://企业级-php.com/2017/12/25/the magic-behind- autoloading-phps - files-composer.html

#4


7  

You'll have to include/require the class anyway, otherwise PHP won't know about the namespace.
You don't necessary have to do it in the same file though. You can do it in a bootstrap file for example. (or use an autoloader, but that's not the topic actually)

无论如何,您必须包含/要求类,否则PHP将不知道名称空间。你不必在同一个文件中做。例如,可以在引导文件中执行。(或者使用自动阅读器,但这不是主题)

#5


4  

The issue is most likely you will need to use an auto loader that will take the name of the class (break by '\' in this case) and map it to a directory structure.

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

You can check out this article on the autoloading functionality of PHP. There are many implementations of this type of functionality in frameworks already.

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

I've actually implemented one before. Here's a link.

我之前已经实现过一个了。这里有一个链接。

#6


3  

I agree with Green, Symfony needs namespace, so why not use them ?

我同意Green, Symfony需要命名空间,所以为什么不使用它们呢?

This is how an example controller class starts:

示例控制器类就是这样开始的:

namespace Acme\DemoBundle\Controller;

名称空间Acme \ DemoBundle \控制器;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

使用Symfony \包\ FrameworkBundle \ \控制器;

class WelcomeController extends Controller { ... }

类welcome econtroller扩展了控制器{…}

#7


3  

The use keyword is for aliasing in PHP and it does not import the classes. This really helps
1) When you have classes with same name in different namespaces
2) Avoid using really long class name over and over again.

use关键字用于在PHP中别名,它不导入类。这真的很有帮助1)当你在不同的命名空间中有名称相同的类时2)避免重复使用很长的类名。

#8


1  

Can I use it to import classes?

我可以用它来导入类吗?

You can't do it like that besides the examples above. You can also use the keyword use inside classes to import traits, like this:

除了上面的例子,你不能那样做。您还可以在类中使用关键字来导入特性,比如:

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'

#1


59  

use doesn't include anything. It just imports the specified namespace (or class) to the current scope

不包括任何使用。它只是将指定的名称空间(或类)导入到当前的范围。

If you want the classes to be autoloaded - read about autoloading

如果你想让这些课程都是自动的,那就读读自动阅读吧。

#2


128  

No, you can not import a class with the use keyword. You have to use include/require statement. Even if you use a PHP auto loader, still autoloader will have to use either include or require internally.

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

The Purpose of use keyword:

使用关键字的目的:

Consider a case where you have two classes with the same name; you'll find it strange, but when you are working with a big MVC structure, it happens. So if you have two classes with the same name, put them in different namespaces. Now consider when your auto loader is loading both classes (does by require), and you are about to use object of class. In this case, the compiler will get confused which class object to load among two. To help the compiler make a decision, you can use the use statement so that it can make a decision which one is going to be used on.

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

Nowadays major frameworks do use include or require via composer and psr

现在,主要的框架都是通过composer和psr来使用include或required

1) composer

1)作曲家

2) PSR-4 autoloader

2)PSR-4自动装卸机

Going through them may help you further. You can also use an alias to address an exact class. Suppose you've got two classes with the same name, say Mailer with two different namespaces:

通过它们可能会对你更有帮助。您还可以使用别名来寻址一个确切的类。假设您有两个名称相同的类,假设Mailer有两个不同的名称空间:

namespace SMTP;
class Mailer{}

and

namespace Mailgun;
class Mailer{}

And if you want to use both Mailer classes at the same time then you can use an alias.

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

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

Later in your code if you want to access those class objects then you can do the following:

在你的代码中,如果你想要访问这些类对象,你可以做如下操作:

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

It will reference the original class.

它将引用原始类。

Some may get confused that then of there are not Similar class names then there is no use of use keyword. Well, you can use __autoload($class) function which will be called automatically when use statement gets executed with the class to be used as an argument and this can help you to load the class at run-time on the fly as and when needed.

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

Refer this answer to know more about class autoloader.

参考这个答案来了解更多关于类自动阅读器的信息。

#3


8  

Don’t overthink what a Namespace is.

不要过度思考命名空间是什么。

Namespace is basically just a Class prefix (like directory in Operating System) to ensure the Class path uniqueness.

名称空间基本上只是一个类前缀(如操作系统中的目录),以确保类路径的惟一性。

Also just to make things clear, the use statement is not doing anything only aliasing your Namespaces so you can use shortcuts or include Classes with the same name but different Namespace in the same file.

同样,为了清楚地说明这一点,use语句并没有做任何事情,只是对名称空间进行混叠,以便您可以使用快捷方式,或者在同一个文件中包含名称相同但名称不同的类。

E.g:

例句:

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

If you want to know how PHP Namespaces and autoloading (the old way as well as the new way with Composer) works, you can read the blog post I just wrote on this topic: https://enterprise-level-php.com/2017/12/25/the-magic-behind-autoloading-php-files-using-composer.html

如果您想知道PHP名称空间和自动加载(旧的方式以及Composer的新方式)是如何工作的,您可以阅读我刚刚在这个主题上写的博客文章:https://企业级-php.com/2017/12/25/the magic-behind- autoloading-phps - files-composer.html

#4


7  

You'll have to include/require the class anyway, otherwise PHP won't know about the namespace.
You don't necessary have to do it in the same file though. You can do it in a bootstrap file for example. (or use an autoloader, but that's not the topic actually)

无论如何,您必须包含/要求类,否则PHP将不知道名称空间。你不必在同一个文件中做。例如,可以在引导文件中执行。(或者使用自动阅读器,但这不是主题)

#5


4  

The issue is most likely you will need to use an auto loader that will take the name of the class (break by '\' in this case) and map it to a directory structure.

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

You can check out this article on the autoloading functionality of PHP. There are many implementations of this type of functionality in frameworks already.

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

I've actually implemented one before. Here's a link.

我之前已经实现过一个了。这里有一个链接。

#6


3  

I agree with Green, Symfony needs namespace, so why not use them ?

我同意Green, Symfony需要命名空间,所以为什么不使用它们呢?

This is how an example controller class starts:

示例控制器类就是这样开始的:

namespace Acme\DemoBundle\Controller;

名称空间Acme \ DemoBundle \控制器;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

使用Symfony \包\ FrameworkBundle \ \控制器;

class WelcomeController extends Controller { ... }

类welcome econtroller扩展了控制器{…}

#7


3  

The use keyword is for aliasing in PHP and it does not import the classes. This really helps
1) When you have classes with same name in different namespaces
2) Avoid using really long class name over and over again.

use关键字用于在PHP中别名,它不导入类。这真的很有帮助1)当你在不同的命名空间中有名称相同的类时2)避免重复使用很长的类名。

#8


1  

Can I use it to import classes?

我可以用它来导入类吗?

You can't do it like that besides the examples above. You can also use the keyword use inside classes to import traits, like this:

除了上面的例子,你不能那样做。您还可以在类中使用关键字来导入特性,比如:

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'