PHP 自動読み込みオートロードと名前空間のアプリケーション概要

不言
リリース: 2023-03-24 11:58:02
オリジナル
1604 人が閲覧しました

まず、名前空間とは何かについて説明します。

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

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

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

自動ロードの原理は、クラスをインスタンス化するときに、PHP がクラスを見つけられない場合、自動的に __autoload($class_name) メソッド、新しい class_name このメソッドのパラメータになります。したがって、必要に応じてこのメソッドで new を使用できます 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() を使用します。 基本的な自動ローディングを実現できます。ただし、プロジェクトが非常に大きい場合、または異なるパスのファイルをロードするために別の自動ロードが必要な場合、プロジェクト内で許可されるのは 1 つだけであるため、__autoload は役に立ちません。 __autoload() 関数。PHP では重複した名前を持つ関数が許可されていないため、2 つの __autoload() を宣言できません。 関数ファイルを使用しないと、致命的なエラーが報告されます。それではどうすればいいでしょうか?心配しないでください。あなたが何を考えても、PHP マスターはすでにそれを考えています。 したがって spl_autoload_register() このようにして、別の素晴らしい機能が誕生し、それに置き換わりました。より効率的に実行され、より柔軟になります。

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

りー

次のコードを LibDb.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();
ログイン後にコピー

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

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

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

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

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

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

DB.php

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

以上两个普通的类文件,添加了命名空间: 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 LibDb(); ,但是涉及到多个类互相调用的时候就会很棘手,所以我们还是在文件开头就使用 use 把路径处理好。

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

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

结束语

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

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


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

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