Как ключевое слово "использовать" работает в 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
? Могу ли я использовать его для импорта классов?
8 answers
use
ничего не включает в себя. Он просто импортирует указанное пространство имен (или класс) в текущую область
Если вы хотите, чтобы классы загружались автоматически - прочитайте о автоматической загрузке
Нет, вы не можете импортировать класс с ключевым словом 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
будет выполнен с классом, который будет использоваться в качестве аргумента, и это может помочь вам загружать класс во время выполнения на лету по мере необходимости.
Обратитесь к этому ответу , чтобы узнать больше о загрузчике классов.
Не переоценивайте, что такое пространство имен .
Пространство имен в основном является просто префиксом класса (как каталог в операционной системе), обеспечивающим уникальность пути класса.
Также просто для того, чтобы прояснить ситуацию, оператор 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. В фреймворках уже существует множество реализаций этого типа функциональности.
На самом деле я уже реализовывал один из них раньше. Вот ссылка .
Я согласен с Грином, Symfony нужно пространство имен, так почему бы не использовать их?
Вот как начинается пример класса контроллера:
Пространство имен Acme\DemoBundle\Контроллер;
Используйте Symfony\Bundle\FrameworkBundle\Контроллер\Контроллер;
Класс WelcomeController расширяет контроллер {... }
Ключевое слово 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'