Как ключевое слово "использовать" работает в PHP и могу ли я импортировать классы с его помощью?


У меня есть файл с классом 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? Могу ли я использовать его для импорта классов?

Author: Green, 2012-06-10

8 answers

use ничего не включает в себя. Он просто импортирует указанное пространство имен (или класс) в текущую область

Если вы хотите, чтобы классы загружались автоматически - прочитайте о автоматической загрузке

 63
Author: zerkms, 2012-06-10 00:00:14

Нет, вы не можете импортировать класс с ключевым словом use. Вы должны использовать include/require заявление. Даже если вы используете автоматический загрузчик PHP, все равно автозагрузчику придется использовать либо include, либо require внутренне.

Цель использовать ключевое слово:

Рассмотрим случай, когда у вас есть два класса с одинаковым именем; вам это покажется странным, но когда вы работаете с большой структурой MVC, это случается. Поэтому, если у вас есть два класса с одинаковым именем, поместите их в разные пространства имен. Теперь рассмотрим, когда ваш автопогрузчик загружает оба класса (делает это с помощью require), и вы собираетесь использовать объект класса. В этом случае компилятор запутается, какой объект класса загружать из двух. Чтобы помочь компилятору принять решение, вы можете использовать оператор use, чтобы он мог принять решение, какой из них будет использоваться.

В настоящее время основные фреймворки используют include или require через composer и psr

1) композитор

2) PSR-4 автозагрузчик

Просмотр их может помочь вам в дальнейшем. Вы также можете использовать псевдоним для обращения к точному классу. Предположим, у вас есть два класса с одинаковым именем, скажем Mailer с двумя разными пространствами имен:

namespace SMTP;
class Mailer{}

И

namespace Mailgun;
class Mailer{}

И если вы хотите использовать оба класса почтовой программы одновременно, вы можете использовать псевдоним.

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

Позже в вашем коде, если вы хотите получить доступ к этим объектам класса, вы можете сделать следующее:

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

Это будет ссылаться на исходный класс.

Некоторые могут запутаться в том, что тогда нет похожих имен классов, тогда ключевое слово use не используется. Ну, вы можете использовать функцию __autoload($class), которая будет вызываться автоматически, когда оператор use будет выполнен с классом, который будет использоваться в качестве аргумента, и это может помочь вам загружать класс во время выполнения на лету по мере необходимости.

Обратитесь к этому ответу , чтобы узнать больше о загрузчике классов.

 136
Author: Rajan Rawal, 2018-02-24 06:20:14

Не переоценивайте, что такое пространство имен .

Пространство имен в основном является просто префиксом класса (как каталог в операционной системе), обеспечивающим уникальность пути класса.

Также просто для того, чтобы прояснить ситуацию, оператор 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

 9
Author: EnchanterIO, 2017-12-26 15:43:51

Вам все равно придется включить/потребовать класс, иначе PHP не будет знать о пространстве имен.
Вам не обязательно делать это в том же файле, хотя. Вы можете сделать это, например, в файле начальной загрузки. (или используйте автозагрузчик, но на самом деле это не тема)

 8
Author: Samy Dindane, 2012-06-10 00:00:31

Проблема, скорее всего, вам потребуется использовать автоматический загрузчик, который возьмет имя класса (в данном случае разбивается на "\") и сопоставит его со структурой каталогов.

Вы можете ознакомиться с этой статьей о автоматической загрузке функциональности PHP. В фреймворках уже существует множество реализаций этого типа функциональности.

На самом деле я уже реализовывал один из них раньше. Вот ссылка .

 4
Author: Tyler Carter, 2012-06-10 00:00:39

Я согласен с Грином, Symfony нужно пространство имен, так почему бы не использовать их?

Вот как начинается пример класса контроллера:

Пространство имен Acme\DemoBundle\Контроллер;

Используйте Symfony\Bundle\FrameworkBundle\Контроллер\Контроллер;

Класс WelcomeController расширяет контроллер {... }

 3
Author: Eric Draven, 2014-12-01 21:49:30

Ключевое слово use предназначено для псевдонимов в PHP и не импортирует классы. Это действительно помогает
1) Когда у вас есть классы с одинаковыми именами в разных пространствах имен
2) Избегайте использования действительно длинного имени класса снова и снова.

 3
Author: Abdul Mannan, 2017-07-15 08:08:20

Могу ли я использовать его для импорта классов?

Вы не можете сделать это подобным образом, кроме приведенных выше примеров. Вы также можете использовать ключевое слово 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'
 2
Author: Thielicious, 2017-06-26 09:19:05