ホームページ  >  記事  >  バックエンド開発  >  PHP 名前空間の読み込みの問題

PHP 名前空間の読み込みの問題

WBOY
WBOYオリジナル
2016-09-23 11:31:041202ブラウズ

現在のディレクトリ構造が次のようになっているとします:
PHP 名前空間の読み込みの問題

A.php のコードは次のとおりです:

名前空間 A;
クラス A{
パブリック関数 __construct()
{
echo 'AAAAAAAAAAAA';
}
}

B.php のコードは次のとおりです:
namespace B;
use AA;
new A();
?>

エラーレポート: 致命的なエラー: クラス 'AA' が に見つかりません。 。 。

私は PHP の名前空間の命名規則についていつも混乱しています:

  1. PHP は名前空間の名前に基づいてそのクラスを自動的にロードしますか?

  2. 名前空間が使用されている場合でも、あるファイルが別のファイルのクラスを呼び出すときは、インスタンス化して使用する前に、require、include などを使用して他のクラス ファイルを現在のファイルにロードする必要があります

  3. 上記の 2 番目の点が「はい」の場合、自動ロードまたは他の方法を使用してロードすることは可能ですか?名前空間と呼ばれるものはクラスを区別するための名前にすぎず、クラスを自動的にロードする機能はないというのは本当ですか?

返信内容:

現在のディレクトリ構造が次のようになっているとします:
PHP 名前空間の読み込みの問題

A.php のコードは次のとおりです:

名前空間 A;
クラス A{
パブリック関数 __construct()
{
echo 'AAAAAAAAAAAA';
}
}

B.php のコードは次のとおりです:
namespace B;
use AA;
new A();
?>

エラーレポート: 致命的なエラー: クラス 'AA' が に見つかりません。 。 。

私は PHP の名前空間の命名規則についていつも混乱しています:

  1. PHP は名前空間の名前に基づいてそのクラスを自動的にロードしますか?

  2. 名前空間が使用されている場合でも、あるファイルが別のファイルのクラスを呼び出すときは、インスタンス化して使用する前に、require、include などを使用して他のクラス ファイルを現在のファイルにロードする必要があります

  3. 上記の 2 番目の点が「はい」の場合、自動ロードまたは他の方法を使用してロードすることは可能ですか?名前空間と呼ばれるものはクラスを区別するための名前にすぎず、クラスを自動的にロードする機能はないというのは本当ですか?

まず第一に、名前空間が何をするのかを明確にする必要があります。名前空間は、その名前が示すように、自分自身を宣言するスペースの名前です (classestool: クラス スペースのツール スペースにいることを宣言するのと同じです)。つまり、use を使用して導入した名前空間は、最終的には「場所の名前」 を導入しただけで、自分自身を宣言する場所の名前です。 include または require で導入する PHP は include または require で実体を導入する必要があり、この 2 つから分離することは不可能です。

私たちが目にする __autoload と spl_autoload_register は、PHP の魔法の導入方法に属します (実際、この概念はオブジェクト指向における制御の反転に似ています (個人的な理解) 魔法の導入 - 平たく言えば、魔法の箱を作成することです)。この Magic Box は、include と require という面倒な作業の処理を支援します。名前空間を介して自動ロードを実装したい場合は、ルールに従う必要があります: psr-0 自動ロード仕様 ルールに従ってロケーション名が宣言されている場合、使用を通じて 「ロケーション名」 が導入されます。マジックボックスで解析できます。場所名を解析した後、画像に従って検索し、include または require を使用して対応するファイルをインポートします。

まとめると、次の 3 つのポイントです。

  1. use はスペース名のみを紹介し、実際の本体は紹介しません。

  2. phpでは、phpファイルを導入するときにrequireとincludeが必要です;
  3. 常に変化し、幻想に惑わされないでください
  4. 参考:

    Autoload 自動ロード
  1. composer は分析を自動的にロードします
  2. IDEツールを使用して、PHP関連フレームワーク(laravelなど)の自動解析ソースコードを確認できます

    設定しない限り、自動的に読み込まれることはありません
  1. .

    spl_autoload_register()

  2. はい、クラスファイルをロードするには
  3. のような関数を使用する必要があります。

    require_once或者include_onece

  4. 名前空間はディレクトリとみなすことができます。名前の競合を避けるために、異なるディレクトリに同じファイル名を付けることができます。
1. 自動的にロードされません

<code>自动加载:
    类库映射
    PSR-4自动加载检测
    PSR-0自动加载检测
</code>

2.在TP5,可以用use 关键字即可, 不需要做require这样繁琐的操作了
3.已经该用spl_autoload_register了替代autoload, composer的出现不就是为了解决这种加载问题么?所以一定要设置命名空间,命名空间不具有自动加载类的作用,他是为了避免命名冲突和可视化类的路径和真正的懒加载等。

使用spl_autoload_register注册了自动装载函数才能使用use,demo:

<code><?php
class Autoload
{
    /**
     * 类映射
     * @var array
     */
    // private static $_classMap = [];

    public function __construct()
    {
        # code...
    }
    
    public static function init()
    {
        spl_autoload_register('Autoload::autoload');
    }

    public static function autoload($class_name='')
    {
        // if (self::$_classMap[$class_name]) {
        //     require(self::$_classMap[$class_name]);
        // }
        require(str_replace('\\', '/', $class_name).'.php');
    }

}


/* register autoload funxtion|注册自动装载函数 */
require('./Autoload.php');
Autoload::init();</code>

  1. pho不会自动加载类。spl_autoload的加载是从include配置中找对应的 类名.inc或者 类名.php来加载。(具体查看 php文档)

  2. ThinkPHP和Laravel以及Composer之类的框架程序,都是通过spl_autoload_resigster来实现按照一定功能加载类。

  3. 命名空间设置的初衷是为了区分不同区的同名类,不一定是按照文件夹来命名,命名空间相当于对类进行分区,比如,你有个类叫 Router 我也有个类叫 Router,类名重复了,这时命名空间就可以起作用了。

  4. 我的回答是是,ThinkPHP的原理是通过 命名空间 来解析成 路径 ,再注册了autoload来加载, 如 abc,会在指定目录找a/bc.class.php (.class.php是tp指定的加载后缀,指定目录通常是library ),Zend 框架是通过 _ 来分割路径,如 a_b_c 类。会变成 /a/b/c.php来在指定目录找。

去了解下php面向对象设计模式 他们说的就是这些

声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。