web-dev-qa-db-ja.com

キーワード「use」は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はどのように機能しますか?クラスをインポートするために使用できますか?

121
Green

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

クラスを自動ロードする場合- autoloading について読んでください

75
zerkms

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

useキーワードの目的:

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

現在、主要なフレームワークはincluderequireを介して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 を参照してください。

159
Rajan Rawal

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

17
BlocksByLukas

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

8
Samy Dindane

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

PHPの autoloading 機能に関するこの記事をご覧ください。フレームワークには、このタイプの機能の多くの実装がすでにあります。

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

4
Tyler Carter

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

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

名前空間Acme\DemoBundle\Controller;

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

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

3
Eric Draven

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

3
Abdul Mannan

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

上記の例以外では、このように実行することはできません。次のように、クラス内でキーワード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'
3
Thielicious

キーワード「use」を使用すると、名前空間リテラルを短縮できます。エイリアスを使用する場合と使用しない場合の両方を使用できます。エイリアシングを使用しない場合、完全な名前空間の最後の部分を使用する必要があります。

<?php
    use foo\bar\lastPart;
    $obj=new lastPart\AnyClass(); //If there's not the line above, a fatal error will be encountered.
?>
1

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

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
}

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

0
Dotun Peter