キーワード「use」はPHPでどのように機能し、それを使用してクラスをインポートできますか?


136

クラスのあるファイルがあります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ますか?クラスをインポートするために使用できますか?


1
ファイルをインポートせずにはいられません。流れを変えないでください。また、名前空間は実際にはPHPでは使用されていません。VB.NETのように
Cole Johnson

13
@ cole-johnson、あなたに同意しないでください。symfonyはnamespacesを中心に構築されています。実際、名前空間を使用しない場合、Symfonyはありません
Green

回答:


80

use何も含まれていません。指定された名前空間(またはクラス)を現在のスコープにインポートするだけです

クラスを自動ロードしたい場合- 自動ロードについてお読みください


@ G-Manそれは尋ねられた質問そのものに答えます。
zerkms

188

いいえ、useキーワードを含むクラスをインポートすることはできません。include/ requireステートメントを使用する必要があります。PHPオートローダーを使用する場合でも、オートローダーはどちらか、includeまたはrequire内部で使用する必要があります。

使用目的キーワード:

同じ名前のクラスが2つある場合を考えます。奇妙なことに気づくでしょうが、大きなMVC構造で作業しているときに起こります。したがって、同じ名前のクラスが2つある場合は、それらを異なる名前空間に配置します。次に、オートローダーが両方のクラスをロードしているときに(によって実行require)、クラスのオブジェクトを使用しようとしている場合を考えます。この場合、コンパイラーは、2つのクラスのうち、どのクラスオブジェクトをロードするかを混乱させます。コンパイラーが決定を下すのを助けるために、useステートメントを使用して、どのステートメントを使用するかを決定できるようにすることができます。

今日では、主要なフレームワークは、使用を行うincluderequireを経由composerし、psr

1)作曲家

2)PSR-4オートローダー

それらを通過すると、さらに役立つ場合があります。エイリアスを使用して、正確なクラスをアドレス指定することもできます。同じ名前の2つのクラスがあり、Mailer2つの異なる名前空間があるとします。

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により、必要に応じて、実行時にその場でクラスをロードできます。

クラスオートローダーの詳細については、この回答を参照してください。


別のクラス名を使用しないのはなぜですか?
神聖な

15
@divine。クラスはサードパーティベンダーからのものである可能性があります
Dayo

3
@divine。衝突する両方のクラスがサードパーティからのものである場合はどうなりますか?
だよ

2
@divine慣例により、名前空間は<vendorName> / <packageName>になるため、すでに解決されています。慣例に従い、packagistが他の誰かから同じベンダー名を受け入れることは不可能です。また、packagist.orgは、パッケージのcomposerインストールに使用されるPHPリポジトリです。
Tpojka

1
@rootは重要ではありません。何が使用されるかをランタイムに伝えるだけです。あなたが車を運転していて、信号があなたに前に出て、あなたが壊れているuseと言っているように、ステートメントがコンパイラーにこれをロードするように指示するように、今のところ。わかりました!
Rajan Rawal

23

名前空間とは何かを考えすぎないでください。

名前空間は基本的に、クラスパスの一意性を確保するための単なるクラスプレフィックス(オペレーティングシステムのディレクトリのようなもの)です。

また、説明を明確にするために、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


8

とにかくクラスをインクルード/要求する必要があります。そうしないと、PHPは名前空間を認識しません。ただし
同じファイルで行う必要はありません。たとえば、ブートストラップファイルで行うことができます。(またはオートローダーを使用しますが、それは実際のトピックではありません)


4

この問題は、クラスの名前(この場合は「\」で区切る)を取得してそれをディレクトリ構造にマップするオートローダーを使用する必要がある可能性が高いです。

PHPのオートローディング機能に関するこの記事をチェックしてください。フレームワークには、このタイプの機能の実装がすでに多数あります。

実際に実装したことがあります。こちらがリンクです。


それでも問題があります。フルパスを構築できるようにするには、再帰モデルが必要です。現在、単一レベルの名前空間のみを処理します。
タイラーカーター

3

私はグリーンに同意します、symfonyには名前空間が必要なので、なぜそれらを使用しないのですか?

これは、サンプルのコントローラークラスの開始方法です。

名前空間Acme \ DemoBundle \ Controller;

Symfony \ Bundle \ FrameworkBundle \ Controller \ Controllerを使用します。

クラスWelcomeControllerはController {...}を拡張します


3

クラスをインポートするために使用できますか?

上記の例以外は、そのようにはできません。次のように、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'

3

このuseキーワードはPHPのエイリアス用であり、クラスをインポートしません。これは本当に役立ちます
1)異なる名前空間に同じ名前のクラスがある場合
2)本当に長いクラス名を何度も使用しないでください。


2

名前空間は、クラスを含む特定のファイルへのパスを定義するために使用されます。

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
}

注:実装するクラスを含むファイルへのパスを使用しないでください。オブジェクトのインスタンス化に拡張され、名前空間のみを使用します。


2

キーワード「use」の使用は、名前空間リテラルを短くするためです。エイリアスを使用しても使用しなくても使用できます。エイリアスを使用しない場合は、完全な名前空間の最後の部分を使用する必要があります。

<?php
    use foo\bar\lastPart;
    $obj=new lastPart\AnyClass(); //If there's not the line above, a fatal error will be encountered.
?>
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.