PHP の自動ロードとは、インスタンス化されたクラスをロードするときに、class.php ファイルをインポートするために手動で require を記述する必要がなく、プログラムが自動的にロードしてインポートすることを意味します。この記事では主に PHP 自動ロードのアプリケーションを紹介します。 autoload と namespace 、困っている友人がそれを参照できるように、すべての人に役立つことを願っています。
「ネームスペースとは何ですか? 大まかに言えば、ネームスペースは物事をカプセル化する方法です。この抽象的な概念は多くの場所で見ることができます。たとえば、オペレーティング システムでは、ディレクトリは、ディレクトリ内のファイルの場合など、関連するファイルをグループ化するために使用されます。たとえば、ファイル 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('./Lib/' . $className . '.php')) { require './Lib/' . $className . '.php'; } }); $db = new Db(); $db::test();
次のコードを LibDb.php ファイルに追加します。
<?php class Db { public static function test() { echo 'Test'; } }
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 'Hello Db'; } public static function test() { echo 'Test'; } } Say.php <?php namespace Lib; class Say { public function __construct() { //echo 'Hello'; } public function hello() { echo 'say hello'; } }
上記 2 つの通常のクラス ファイルには名前空間が追加されています: namespace Lib; もちろん、このクラス ファイルが Lib ディレクトリの名前に属することを意味します。 1 プロジェクト名を表す別の名前。
次に、autoload.php を見てみましょう:
<?php spl_autoload_register(function ($class) { $prefix = 'Lib\\'; $base_dir = __DIR__ . '/Lib/'; // 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('\\', '/', $relative_class) . '.php'; if (file_exists($file)) { require $file; } });
以上代码使用函数 spl_autoload_register() 首先判断是否使用了命名空间,然后验证要调用的类文件是否存在,如果存在就 require 类文件。
好了,现在我们在首页index.php这样调用:
<?php use Lib\Db; use Lib\Say; require './autoload.php'; $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实现自动加载,所以还是一个“懒”字给我们带来了极好的开发效率。
相关推荐:
以上がPHP の自動読み込みオートロードと名前空間メソッドの概要の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。