クラス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
には何も含まれません。指定された名前空間(またはクラス)を現在のスコープにインポートするだけです
クラスを自動ロードする場合- autoloading について読んでください
いいえ、use
キーワードを使用してクラスをインポートすることはできません。 include
/require
ステートメントを使用する必要があります。 PHPオートローダーを使用している場合でも、オートローダーはinclude
またはrequire
を内部で使用する必要があります。
useキーワードの目的:
同じ名前の2つのクラスがある場合を考えます。奇妙なことに気づくでしょうが、大きなMVC構造で作業しているときに起こります。したがって、同じ名前の2つのクラスがある場合は、異なる名前空間に配置します。ここで、オートローダーが両方のクラスをロードするとき(require
による)を考慮し、クラスのオブジェクトを使用しようとしています。この場合、コンパイラは2つの中でロードするクラスオブジェクトを混同します。コンパイラーが決定を下せるようにするために、use
ステートメントを使用して、どちらを使用するかを決定できます。
現在、主要なフレームワークはinclude
とrequire
を介してcomposer
またはpsr
を使用しています。
1) 作曲家
2) PSR-4 オートローダー
それらを通過すると、さらに役立つ場合があります。エイリアスを使用して、正確なクラスをアドレス指定することもできます。同じ名前の2つのクラス、たとえば2つの異なる名前空間を持つ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
キーワードが使用されていないことに混乱するかもしれません。さて、引数として使用するクラスでuse
ステートメントが実行されるときに自動的に呼び出される__autoload($class)
関数を使用できます。これにより、必要に応じて実行時にオンザフライでクラスをロードできます。
クラスオートローダーの詳細については、この answer を参照してください。
Namespaceが何であるかを考えすぎないでください。
Namespaceは基本的にClassパスの一意性を確保するためのClassプレフィックス(オペレーティングシステムのディレクトリなど)です。
また、わかりやすくするために、seステートメントはNamespacesのエイリアスのみを行うのではなく、ショートカットを使用したり、同じものでClassesを含めたりできます。同じファイル内で名前が異なるNamespace。
例えば:
// 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は名前空間を認識しません。
ただし、同じファイルで行う必要はありません。たとえば、bootstrapファイルで実行できます。 (またはオートローダーを使用しますが、それは実際にはトピックではありません)
この問題は、クラスの名前(この場合は「\」で区切る)を取得し、それをディレクトリ構造にマップするオートローダーを使用する必要がある可能性が高いです。
PHPの autoloading 機能に関するこの記事をご覧ください。フレームワークには、このタイプの機能の多くの実装がすでにあります。
実際に実装したことがあります。 リンク です。
私はグリーンに同意します、Symfonyには名前空間が必要なので、なぜそれらを使用しないのですか?
これは、コントローラクラスの例の開始方法です。
名前空間Acme\DemoBundle\Controller;
symfony\Bundle\FrameworkBundle\Controller\Controllerを使用します。
クラスWelcomeControllerはController {...}を拡張します
use
キーワードは、PHPのエイリアシング用であり、クラスをインポートしません。これは本当に役立ちます
1)異なる名前空間に同じ名前のクラスがある場合
2)本当に長いクラス名を繰り返し使用しないでください。
クラスをインポートするために使用できますか?
上記の例以外では、このように実行することはできません。次のように、クラス内でキーワードuse
を使用して traits をインポートすることもできます。
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
use foo\bar\lastPart;
$obj=new lastPart\AnyClass(); //If there's not the line above, a fatal error will be encountered.
?>
名前空間は、クラスを含む特定のファイルへのパスを定義するために使用されます。
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
}
注:実装するクラスを含むファイルへのパスを使用しないでください。オブジェクトのインスタンス化に使用範囲を拡張しますが、名前空間のみを使用します。