PHP の自動読み込みオートロードと名前空間の詳細な解釈

亚连
リリース: 2018-06-23 14:46:20
オリジナル
1872 人が閲覧しました

PHP の自動ロードとは、インスタンス化されたクラスをロードするときに、class.php ファイルをインポートするために手動で require を記述する必要がないことを意味します。この記事では、主に PHP の autoload とインポートについて説明します。名前空間。アプリケーション、それを必要とする友人がそれを参照できます

まず、名前空間とは何かを説明します。

「ネームスペースとは何ですか? 大まかに言えば、ネームスペースは物事をカプセル化する方法です。この抽象的な概念は多くの場所で見ることができます。たとえば、オペレーティング システムでは、ディレクトリは、ディレクトリ内のファイルの場合など、関連するファイルをグループ化するために使用されます。たとえば、ファイル foo.txt はディレクトリ /home/greg と /home/other に同時に存在できますが、両方を同じディレクトリに存在させることはできません。さらに、ディレクトリ /home/greg の外にある foo.txt ファイルにアクセスする場合、/home/greg/foo.txt を取得するには、ファイル名の前にディレクトリ名とディレクトリ区切り文字を置く必要があります。プログラミングの分野では、名前空間の概念が使用されます。 . "

PHP の自動ロードは、インスタンス化されたクラスをロードするときに、class.php ファイルをインポートするための require を手動で記述する必要がないことを意味します。プログラムが自動的にロードしてインポートします。名前空間の仕様を使用すると、複雑なシステムでのさまざまなクラスのロードと呼び出しを簡単に処理できます。

1. 自動ロードの原理と __autoload の使用

自動ロードの原理は、クラスをインスタンス化するときに、PHP がクラスを見つけられない場合、自動的にこのファイル __autoload($class_name) を呼び出すことです。 ) メソッドでは、新しい class_name がこのメソッドのパラメータになります。したがって、このメソッドでは、自動ロードを実現するために新しい class_name が必要になるさまざまな判断と分割に基づいて、対応するパス クラス ファイルを要求できます。

まず、__autoload() の自動呼び出しを見てみましょう。例:

index.php

<?php 
$db = new Db();
ログイン後にコピー

Db クラスを手動でインポートしない場合、プログラムは、このクラスが見つからないというエラーを報告する可能性があります。

致命的なエラー: キャッチされないエラー: クラス 'DB' が D:webhellowebademo2017autoloadindex.php:2 に見つかりません スタック トレース: #0 {main} が D:webhellowebademo2017autoloadindex.php の 2 行目でスローされました

そこで、__autoload( ) メソッド もう一度見てみましょう:

$db = new DB();
function __autoload($className) {
 echo $className;
 exit();
}
ログイン後にコピー

上記の自動ロードメカニズムの説明によると、出力は次のとおりです: Db、これは新しく必要なクラスのクラス名です。したがって、現時点では、必要に応じて __autoload() メソッドでクラス ライブラリ ファイルをロードできます。

2. spl_autoload_register は自動的にロードします

小規模なプロジェクトの場合は、__autoload() を使用して基本的な自動ロードを実現できます。ただし、プロジェクトが大きい場合、または異なるパスのファイルをロードするために別の自動ロードが必要な場合、現時点では __autoload は役に立ちません。プロジェクト内で許可される __autoload() 関数は 1 つだけであり、PHP では重複した名前を持つ関数が許可されないためです。これは、2 つの __autoload() 関数ファイルを宣言できないことを意味します。宣言しないと、致命的なエラーが報告されます。それではどうすればいいでしょうか?心配しないでください。あなたが何を考えても、PHP マスターはすでにそれを考えています。 そこで、spl_autoload_register() のような別の素晴らしい関数が誕生し、それを置き換えました。より効率的に実行され、より柔軟になります。

まず使い方を見てみましょう。index.phpに次のコードを追加します。

<?php 
spl_autoload_register(function($className){
 if (is_file(&#39;./Lib/&#39; . $className . &#39;.php&#39;)) {
 require &#39;./Lib/&#39; . $className . &#39;.php&#39;;
 }
});
$db = new Db();
$db::test();
ログイン後にコピー

次のコードを LibDb.php ファイルに追加します。

<?php 
class Db
{
 public static function test()
 {
 echo &#39;Test&#39;;
 }
}
ログイン後にコピー

index.php を実行した後、new Db() が呼び出されると、spl_autoload_register は自動的に lib/ ディレクトリに移動し、対応する Db.php ファイルを見つけます。成功すると、$db::test(); を実行できます。同様に、Lib ディレクトリに複数の php クラス ファイルがある場合、複数のファイルを必要とせずに、index.php で直接呼び出すことができます。

つまり、spl_autoload_register は複数回再利用でき、ページに複数の spl_autoload_register がある場合、実行順序は 1 つずつ停止されます。

3. spl_autoload_register 自動読み込みと名前空間名前空間

非常に複雑なシステムの場合、ディレクトリ構造も非常に複雑になります。標準化された名前空間は、重複する多数のファイル、関数、クラスの問題を解決します。複雑なパスの下の名前。オートロードは現在、最新の PHP フレームワークの基礎となっており、基本的に spl_autoload_register は自動ロードの実装に使用されます。そのため、spl_autoload_register + 名前空間が主流になりました。

PSRシリーズの仕様に従って、名前空間の命名は非常に標準化されているため、名前空間に基づいて詳細なパスを見つけてクラスファイルを見つけることができます。

最も単純な例を使用して、複雑なシステムがクラス ファイルを自動的にロードする方法を説明します。

まず、システム ディレクトリ構造を準備します:

----/Lib  // 类目录
 --Db.php
 --Say.php
----autoload.php // 自动加载函数
----index.php // 首页
ログイン後にコピー

上記は基本的なシステム ディレクトリです。私たちが実現したいのは、名前空間と自動読み込みを使用して、ホームページのindex.phpのLibディレクトリ内の複数のクラスを直接呼び出すことです。

2つの列ファイルを用意します:

Db.php

<?php 
namespace Lib;
class Db
{
 public function __construct()
 {
 //echo &#39;Hello Db&#39;;
 }
 public static function test()
 {
 echo &#39;Test&#39;;
 }
}
Say.php
<?php
namespace Lib;
class Say 
{
 public function __construct()
 {
 //echo &#39;Hello&#39;;
 }
 public function hello()
 {
 echo &#39;say hello&#39;;
 }
}
ログイン後にコピー

以上两个普通的类文件,添加了命名空间: namespace Lib; 表示该类文件属于Lib\目录名称下的,当然你可以随便取个不一样的名字来表示你的项目名称。

现在我们来看autoload.php:

<?php 
spl_autoload_register(function ($class) {
 $prefix = &#39;Lib\\&#39;;
 $base_dir = __DIR__ . &#39;/Lib/&#39;;
 // does the class use the namespace prefix?
 $len = strlen($prefix);
 if (strncmp($prefix, $class, $len) !== 0) {
 // no, move to the next registered autoloader
 return;
 }
 $relative_class = substr($class, $len);
 // 兼容Linux文件找。Windows 下(/ 和 \)是通用的
 $file = $base_dir . str_replace(&#39;\\&#39;, &#39;/&#39;, $relative_class) . &#39;.php&#39;;
 if (file_exists($file)) {
 require $file;
 }
});
ログイン後にコピー

以上代码使用函数 spl_autoload_register() 首先判断是否使用了命名空间,然后验证要调用的类文件是否存在,如果存在就 require 类文件。

好了,现在我们在首页index.php这样调用:

<?php 
use Lib\Db;
use Lib\Say;
require &#39;./autoload.php&#39;;
$db = new Db();
$db::test();
$say = new Say;
$say->hello();
ログイン後にコピー

我们只需使用一个require将autoload.php加载进来,使用 use 关键字将类文件路径变成绝对路径了,当然你也可以在调用类的时候把路径都写上,如: new Lib\Db(); ,但是涉及到多个类互相调用的时候就会很棘手,所以我们还是在文件开头就使用 use 把路径处理好。

接下来就直接调用Lib/目录下的各种类文件了,你可以在Lib/目录下放置多个类文件尝试下。

运行index.php看看是不是如您所愿。

结束语

该文简单介绍了自动加载以及命名空间的使用,实际开发中,我们很少去关注autoload自动加载的问题,因为大多数现代PHP框架都已经处理好了文件自动加载的问题。开发者只需关注业务代码,使用规范的命名空间就可以了。当然,如果你想自己开发个项目不依赖大型框架亦或者自己开发php框架,那你就得熟悉下autoload自动加载这个好东西了,毕竟它可以让我们“偷懒”,省事多了。

现代php里,我们经常使用 Composer 方式安装的组件,都可以通过autoload实现自动加载,所以还是一个“懒”字给我们带来了极好的开发效率。

上面是我整理给大家的,希望今后会对大家有帮助。

相关文章:

有关JsonObject中的key-value数据解析排序(详细教程)

在Thinkjs3中如何使用静态资源目录

如何实现单层json按照key字母顺序排序(详细教程)

以上がPHP の自動読み込みオートロードと名前空間の詳細な解釈の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

関連ラベル:
php
ソース:php.cn
このウェブサイトの声明
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。
最新の問題
人気のチュートリアル
詳細>
最新のダウンロード
詳細>
ウェブエフェクト
公式サイト
サイト素材
フロントエンドテンプレート