目次
まとめ
ターゲット クラスです
読み込みの問題
読み込みメカニズム
自动加载机制
怎么使用?
注意问题
反射
反射属性
使い方は?
注意事項
反射注释
反射实例化
PHPリフレクション技術の詳細なコード例(画像とテキスト)
反射Grade类
执行类的方法
总结
ホームページ バックエンド開発 PHPチュートリアル PHPリフレクション技術の詳細なコード例(画像とテキスト)

PHPリフレクション技術の詳細なコード例(画像とテキスト)

Mar 11, 2017 am 10:23 AM

まとめ

Java のリフレクションと比較すると、PHP のリフレクションはまさに良心の働きです。ただし、メンテナンスの観点からは Java の方が優れており、さらに利点があります。ただし、処理が煩雑であるため、Java のリフレクション メカニズムに一定の学習コストがかかります。

今日はPHPのリフレクション技術を使ってクラス情報を取得してみました。
コアの操作は PHP の公式ヘルプ ドキュメントで参照できます。ここで最も一般的に使用されるのは

getProperties
getMethods
ログイン後にコピー

PHPリフレクション技術の詳細なコード例(画像とテキスト)

ターゲット クラスです

リフレクションの結果とメンテナンスをより適切に示すために、クラスを作成してみましょう。
PHPリフレクション技術の詳細なコード例(画像とテキスト)

<?phpclass Person {
    private $name;    private $age;    private $address;    public function __construct($name, $age, $address) {
        $this->name = $name;        $this->age = $age;        $this->address = $address;
    }    public function setter($key, $value) {
        exec ( "{$this}->" . $key . "={$value}" );
    }    /**
     * 通配型的getter方法不好用。
     * <br />
     * 原因: Object Person can not be converted to string.
     * 
     * @param unknown $key         
     * @return string
     */
    public function getter($key) {
        return exec ( "$this" . "->{$key}" );
    }    /**
     * 模拟Java语言实现的getter方法。<br />
     *
     * 缺点: 需要为每一个private属性提供单独的getter方法,使得代码略显臃肿。
     */
    public function getName() {
        return $this->name;
    }
}class Grade {
    private $name;    public function __construct($name) {
        $this->name = $name;
    }    public function setName($name) {
        $this->name = $name;
    }    public function getName() {
        return $this->name;
    }
}
ログイン後にコピー

読み込みの問題

読み込みメカニズム

正式な反映操作の前に、まず __autoload の自動読み込みメカニズムについて説明します。名前が示すように、(クラスまたはその他の PHP ファイル) が自動的にロードされます。 __autoload自动加载机制。顾名思义,自动化的进行加载(类,也可以是其他php文件)呗。

对于更深层次而言,这就涉及到PHP解释器的工作原理了。也就是说,我们不可能一个项目只写一个php文件,相反,一个项目中可能会有数以百计的php文件,而且不可避免的会进行相互调用。

也就是说,我们在A文件中声明并实现了一个加法函数,而需要在B文件中进行调用。很明显B文件中根本没有实现这个加法,所以PHP解释器就没办法进行加法运算了。

这个时候就需要让PHP解释器知道这个加法怎么做,于是就需要require / include 包含了这个加法函数的A文件了。

这样,PHP解释器就知道如何解释并运行咱们的PHP文件了。


与PHP相似的是,在Java语言中我们只需要在源文件前面添加import语句,Java虚拟机就能自动的在相关的类信息了。而且强类型的Java可以在编译之前就发现这样的问题,所以代码维护起来比较方便一点。而PHP则需要进行手动的 include/require了。

但是应该清楚的是,这两者换汤不换药而已。

自动加载机制

但是如果对每一个要被引用的php文件进行手动的加载的话,可能就要写好多个这样的加载语句了。所以为了方便处理这种问题,PHP5之后引入了自动加载机制。

void __autoload ( string $class )
ログイン後にコピー

$class 就是要进行加载的类的名称,请注意是的名称。


怎么使用?

既然自动加载机制这么好,那么我们要怎么使用呢?

答案就是在需要加载其他类文件的php中,添加一个自定义的__autoload($class) 函数即可。 还是以刚才的文件AB来举例。

文件A中有一个写好的类Person,在文件B中要进行使用。这个时候在文件B中添加一个__aotoload函数即可。而且这个函数的写法也比较的简单(一切按照最简思路来设计的话)。

function __autoload($class) {
    $filename = "$class.class.php";    
    if(!file_exists($filename)){        
    throw new RuntimeException("$filename 文件不存在!");
    }else {        require "$filename";
    }
}
ログイン後にコピー

PHP解释器在扫描到文件B的时候会先进行检查,如果未引入目标类Person,则会判断有没有实现__autoload,如果存在则使用自动加载函数进行加载,否则报错退出。

注意问题

虽然上面的自动加载函数比较简单,但是现实中却需要为此付出很多的“代价”,也就是被加载的类文件的名称要和类保持一致(无需区分大小写)。如:

要加载的类的名称为Person,
则该类所在的文件的名称需要为person.class.php,或者Person.class.php
ログイン後にコピー

而且,路径问题也是一个比较棘手的问题,在这个简易的自动加载函数中也不难看到,这里他们位于同级目录下,试想一下不满足这个条件的情形,就可以知道这个自动加载函数的代码量将会多么大了吧。

如此的话,也会违反了自动加载机制的设计的初衷。所以按照特定的目录结构存放相关的类文件是非常有必要的。

所谓:增加了冗余的特点,却带来了容易维护的好处。

个人觉得,不妨按照Java语言的目录结构来维护PHP程序,这样会有意想不到的收获的。

反射

下面正式进入反射的话题,在摘要部分已经提到。重点就在于ReflectionClass的使用。

反射属性

<?phprequire &#39;./bean/beans.php&#39;;
// Person 在beans.php文件中声明$protype = new ReflectionClass("Person");
// 可以添加一个参数,来进行过滤操作。如只获取public类型的属性
$properties = $protype->getProperties();
// 反射获取到类的属性信息
foreach ($properties as $property) {    
echo $property."<br />";
}
ログイン後にコピー

PHPリフレクション技術の詳細なコード例(画像とテキスト)

相比于Java,要获取 private

より深いレベルでは、これには PHP インタープリターの動作原理が関係します。言い換えれば、1 つのプロジェクトに 1 つの PHP ファイルしか作成することはできません。逆に、1 つのプロジェクトに数百の PHP ファイルが存在する可能性があり、それらは必然的に相互に呼び出しを行うことになります。

つまり、ファイルAで加算関数を宣言して実装しましたが、ファイルBで呼び出す必要があります。明らかに、この加算は B ファイルにはまったく実装されていないため、PHP インタープリタは加算操作を実行できません。

PHPリフレクション技術の詳細なコード例(画像とテキスト)現時点では、この追加の実行方法を PHP インタープリターに知らせる必要があるため、この追加関数を含む A ファイルを require / include する必要があります。

このようにして、PHP インタープリターは PHP ファイルを解釈して実行する方法を認識します。


🎜PHP と同様に、Java 言語でもソース ファイルの前に import ステートメントを追加するだけで、Java 仮想マシンが関連するクラス情報を自動的に追加できます。さらに、強く型付けされた Java はコンパイル前にそのような問題を検出できるため、コードのメンテナンスがより便利になります。 PHP では手動の include/require が必要です。 🎜
🎜しかし、二人が薬を変えずにスープを変えただけであることは明らかであるはずです。 🎜
🎜自動ロードメカニズム🎜🎜しかし、参照される各 php ファイルを手動でロードする場合は、そのようなロードステートメントを複数記述する必要がある場合があります。したがって、この問題への対処を容易にするために、PHP5 以降では自動ロード機構が導入されました。 🎜
<?php
require &#39;./bean/beans.php&#39;;
$protype = new ReflectionClass("Person");
$methods = $protype->getMethods();
foreach ($methods as $method) {    
echo $method->getName()."<br />";
}
ログイン後にコピー
🎜$class は、ロードされるクラスの名前です。class の名前であることに注意してください。 🎜

使い方は?

🎜自動ローディング機構は非常に優れているので、どのように使用すればよいでしょうか? 🎜🎜その答えは、他のクラス ファイルをロードする必要があるカスタム __autoload($class) 関数を PHP に追加することです。 先ほどのファイル AB を例に考えてみましょう。 🎜🎜ファイル A には person というクラスが記述されており、これはファイル B で使用する必要があります。このとき、ファイル B に __aotoload 関数を追加するだけです。さらに、この関数の記述方法は比較的単純です (すべてが最も単純なアイデアに従って設計されている場合)。 🎜
filter过滤结果为仅包含某些属性的方法。默认不过滤。 

ReflectionMethod::IS_STATIC、 
ReflectionMethod::IS_PUBLIC、 
ReflectionMethod::IS_PROTECTED、 
ReflectionMethod::IS_PRIVATE、 
ReflectionMethod::IS_ABSTRACT、 
ReflectionMethod::IS_FINAL 的任意组合。
ログイン後にコピー
ログイン後にコピー
🎜PHP インタープリターは、ファイル B をスキャンするときに最初にチェックします。ターゲット クラス Person が導入されていない場合は、__autoload が実装されているかどうかを判断し、存在する場合は、自動ロード機能を使用します。それ以外の場合は、エラーで終了します。 🎜

注意事項

🎜上記の自動ロード機能は比較的単純ですが、実際には多くの「価格」が必要です。つまり、ロードされたクラス ファイルの名前がクラスと一致している必要があります (いいえ)大文字と小文字を区別する必要があります)。例: 🎜
<?phprequire &#39;./bean/beans.php&#39;;
$protype = new ReflectionClass ( "Person" );
$properties = $protype->getProperties ();
// 反射获取到类的属性信息
foreach ( $properties as $property ) {    
echo $property . ":";    
$doc = $property->getDocComment ();    
echo "   " . $doc . "<br />";    e
cho "--------------------------------------------------------" . "<br />";
}$methods = $protype->getMethods();
foreach ($methods as $method) {    
echo $method->getName()."<br />";   
 $doc = $method->getDocComment ();    
 echo "   " . $doc . "<br />";    
 echo "--------------------------------------------------------" . "<br />";
}
ログイン後にコピー
ログイン後にコピー
🎜 さらに、この単純な自動ロード機能では、パスの問題も比較的難しい問題ではありません。この条件が満たされない場合の状況を想像してみてください。と、これを知ることができます 自動読み込み機能のコード量は膨大になります。 🎜🎜この場合、自動ローディング機構の本来の目的にも反することになります。したがって、関連するクラス ファイルを特定のディレクトリ構造に従って保存することが非常に必要です。 🎜
🎜いわゆる: 冗長な機能が追加されますが、メンテナンスが容易になるという利点があります。 🎜
🎜個人的には、Java 言語のディレクトリ構造に従って PHP プログラムを保守する方が良いと思います。そうすることで、予期せぬ利益が得られるでしょう。 🎜🎜振り返り🎜🎜 ここで、概要セクションで言及した振り返りのトピックに正式に入ります。重要な点は、ReflectionClass の使用にあります。 🎜🎜リフレクション属性🎜
<?phprequire &#39;./bean/beans.php&#39;;
$protype = new ReflectionClass ( "Person" );// 模拟数据库中获取到的值,以关联数组的形式抛出
$values = array(    "name"=>"郭璞",    "age"=> 21,    "address"=>"辽宁省大连市");// 开始实例化
$instance = $protype->newInstanceArgs($values);    
print_r($instance);// 
var_dump($instance);
echo $instance->getName();
ログイン後にコピー
ログイン後にコピー
🎜PHPリフレクション技術の詳細なコード例(画像とテキスト)🎜🎜Java と比較して、PHP は private 属性を取得するのが簡単です。 🎜🎜反映方法🎜
<?phprequire &#39;./bean/beans.php&#39;;$classprotype = new ReflectionClass("Grade");$class = $classprotype->newInstanceArgs(array("name"=>"大三"));
var_dump($class);echo $class->getName();
ログイン後にコピー
ログイン後にコピー
🎜🎜🎜🎜さらに、フィルター条件を追加することもできます。 getMethods メソッド Tianji にフィルター パラメーターを与えるだけです。 🎜
filter过滤结果为仅包含某些属性的方法。默认不过滤。 

ReflectionMethod::IS_STATIC、 
ReflectionMethod::IS_PUBLIC、 
ReflectionMethod::IS_PROTECTED、 
ReflectionMethod::IS_PRIVATE、 
ReflectionMethod::IS_ABSTRACT、 
ReflectionMethod::IS_FINAL 的任意组合。
ログイン後にコピー
ログイン後にコピー

反射注释

注释信息,这里就以文档信息为例。

<?phprequire &#39;./bean/beans.php&#39;;
$protype = new ReflectionClass ( "Person" );
$properties = $protype->getProperties ();
// 反射获取到类的属性信息
foreach ( $properties as $property ) {    
echo $property . ":";    
$doc = $property->getDocComment ();    
echo "   " . $doc . "<br />";    e
cho "--------------------------------------------------------" . "<br />";
}$methods = $protype->getMethods();
foreach ($methods as $method) {    
echo $method->getName()."<br />";   
 $doc = $method->getDocComment ();    
 echo "   " . $doc . "<br />";    
 echo "--------------------------------------------------------" . "<br />";
}
ログイン後にコピー
ログイン後にコピー

PHPリフレクション技術の詳細なコード例(画像とテキスト)

反射实例化

PHPリフレクション技術の詳細なコード例(画像とテキスト)

<?phprequire &#39;./bean/beans.php&#39;;
$protype = new ReflectionClass ( "Person" );// 模拟数据库中获取到的值,以关联数组的形式抛出
$values = array(    "name"=>"郭璞",    "age"=> 21,    "address"=>"辽宁省大连市");// 开始实例化
$instance = $protype->newInstanceArgs($values);    
print_r($instance);// 
var_dump($instance);
echo $instance->getName();
ログイン後にコピー
ログイン後にコピー

PHPリフレクション技術の詳細なコード例(画像とテキスト)

反射Grade类

<?phprequire &#39;./bean/beans.php&#39;;$classprotype = new ReflectionClass("Grade");$class = $classprotype->newInstanceArgs(array("name"=>"大三"));
var_dump($class);echo $class->getName();
ログイン後にコピー
ログイン後にコピー

PHPリフレクション技術の詳細なコード例(画像とテキスト)

执行类的方法

$instance->getName(); 
// 执行Person 里的方法getName// 或者:
$method = $class->getmethod(&#39;getName&#39;); 
// 获取Person 类中的getName方法$method->invoke($instance);    
// 执行getName 方法// 或者:$method = $class->getmethod(&#39;setName&#39;); 
// 获取Person 类中的setName方法$method->invokeArgs($instance, array(&#39;snsgou.com&#39;));
ログイン後にコピー

总结

回顾一下,本次试验演示了PHP中的反射技术,对比分析了Java语言的反射技术的实现。也只能说各有利弊吧。

在Java中,反射技术是编写框架的基础。虽然在PHP中反射技术不是特别的重要,而且用的时候约束也比较多,稍显鸡肋。但是比葫芦画瓢的话,还是可以做出一些有用的小工具的。


以上がPHPリフレクション技術の詳細なコード例(画像とテキスト)の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

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

ホットAIツール

Undresser.AI Undress

Undresser.AI Undress

リアルなヌード写真を作成する AI 搭載アプリ

AI Clothes Remover

AI Clothes Remover

写真から衣服を削除するオンライン AI ツール。

Undress AI Tool

Undress AI Tool

脱衣画像を無料で

Clothoff.io

Clothoff.io

AI衣類リムーバー

AI Hentai Generator

AI Hentai Generator

AIヘンタイを無料で生成します。

ホットツール

メモ帳++7.3.1

メモ帳++7.3.1

使いやすく無料のコードエディター

SublimeText3 中国語版

SublimeText3 中国語版

中国語版、とても使いやすい

ゼンドスタジオ 13.0.1

ゼンドスタジオ 13.0.1

強力な PHP 統合開発環境

ドリームウィーバー CS6

ドリームウィーバー CS6

ビジュアル Web 開発ツール

SublimeText3 Mac版

SublimeText3 Mac版

神レベルのコード編集ソフト(SublimeText3)

Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Ubuntu および Debian 用の PHP 8.4 インストールおよびアップグレード ガイド Dec 24, 2024 pm 04:42 PM

PHP 8.4 では、いくつかの新機能、セキュリティの改善、パフォーマンスの改善が行われ、かなりの量の機能の非推奨と削除が行われています。 このガイドでは、Ubuntu、Debian、またはその派生版に PHP 8.4 をインストールする方法、または PHP 8.4 にアップグレードする方法について説明します。

PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 PHP 開発用に Visual Studio Code (VS Code) をセットアップする方法 Dec 20, 2024 am 11:31 AM

Visual Studio Code (VS Code とも呼ばれる) は、すべての主要なオペレーティング システムで利用できる無料のソース コード エディター (統合開発環境 (IDE)) です。 多くのプログラミング言語の拡張機能の大規模なコレクションを備えた VS Code は、

今まで知らなかったことを後悔している 7 つの PHP 関数 今まで知らなかったことを後悔している 7 つの PHP 関数 Nov 13, 2024 am 09:42 AM

あなたが経験豊富な PHP 開発者であれば、すでにそこにいて、すでにそれを行っていると感じているかもしれません。あなたは、運用を達成するために、かなりの数のアプリケーションを開発し、数百万行のコードをデバッグし、大量のスクリプトを微調整してきました。

PHPでHTML/XMLを解析および処理するにはどうすればよいですか? PHPでHTML/XMLを解析および処理するにはどうすればよいですか? Feb 07, 2025 am 11:57 AM

このチュートリアルでは、PHPを使用してXMLドキュメントを効率的に処理する方法を示しています。 XML(拡張可能なマークアップ言語)は、人間の読みやすさとマシン解析の両方に合わせて設計された多用途のテキストベースのマークアップ言語です。一般的にデータストレージに使用されます

JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 JSON Web Tokens(JWT)とPHP APIでのユースケースを説明してください。 Apr 05, 2025 am 12:04 AM

JWTは、JSONに基づくオープン標準であり、主にアイデンティティ認証と情報交換のために、当事者間で情報を安全に送信するために使用されます。 1。JWTは、ヘッダー、ペイロード、署名の3つの部分で構成されています。 2。JWTの実用的な原則には、JWTの生成、JWTの検証、ペイロードの解析という3つのステップが含まれます。 3. PHPでの認証にJWTを使用する場合、JWTを生成および検証でき、ユーザーの役割と許可情報を高度な使用に含めることができます。 4.一般的なエラーには、署名検証障害、トークンの有効期限、およびペイロードが大きくなります。デバッグスキルには、デバッグツールの使用とロギングが含まれます。 5.パフォーマンスの最適化とベストプラクティスには、適切な署名アルゴリズムの使用、有効期間を合理的に設定することが含まれます。

母音を文字列にカウントするPHPプログラム 母音を文字列にカウントするPHPプログラム Feb 07, 2025 pm 12:12 PM

文字列は、文字、数字、シンボルを含む一連の文字です。このチュートリアルでは、さまざまな方法を使用してPHPの特定の文字列内の母音の数を計算する方法を学びます。英語の母音は、a、e、i、o、u、そしてそれらは大文字または小文字である可能性があります。 母音とは何ですか? 母音は、特定の発音を表すアルファベットのある文字です。大文字と小文字など、英語には5つの母音があります。 a、e、i、o、u 例1 入力:string = "tutorialspoint" 出力:6 説明する 文字列「TutorialSpoint」の母音は、u、o、i、a、o、iです。合計で6元があります

PHPでの後期静的結合を説明します(静的::)。 PHPでの後期静的結合を説明します(静的::)。 Apr 03, 2025 am 12:04 AM

静的結合(静的::) PHPで後期静的結合(LSB)を実装し、クラスを定義するのではなく、静的コンテキストで呼び出しクラスを参照できるようにします。 1)解析プロセスは実行時に実行されます。2)継承関係のコールクラスを検索します。3)パフォーマンスオーバーヘッドをもたらす可能性があります。

PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? PHPマジックメソッド(__construct、__destruct、__call、__get、__setなど)とは何ですか? Apr 03, 2025 am 12:03 AM

PHPの魔法の方法は何ですか? PHPの魔法の方法には次のものが含まれます。1。\ _ \ _コンストラクト、オブジェクトの初期化に使用されます。 2。\ _ \ _リソースのクリーンアップに使用される破壊。 3。\ _ \ _呼び出し、存在しないメソッド呼び出しを処理します。 4。\ _ \ _ get、dynamic属性アクセスを実装します。 5。\ _ \ _セット、動的属性設定を実装します。これらの方法は、特定の状況で自動的に呼び出され、コードの柔軟性と効率を向上させます。

See all articles