主頁 > 知識庫 > PHP反射機制案例講解

PHP反射機制案例講解

熱門標簽:滄州電銷外呼系統(tǒng)價格 上海400客服電話怎么申請 凱立德地鐵站地圖標注 溫州外呼系統(tǒng)招商 天津電銷外呼系統(tǒng)違法嗎 銀行信貸電話機器人 手機外呼系統(tǒng)什么原理 400電話個人能不能辦理 合肥ai電銷機器人費用

簡介

就算是類成員定義為private也可以在外部訪問,不用創(chuàng)建類的實例也可以訪問類的成員和方法。

PHP自5.0版本以后添加了反射機制,它提供了一套強大的反射API,允許你在PHP運行環(huán)境中,訪問和使用類、方法、屬性、參數(shù)和注釋等,其功能十分強大,經(jīng)常用于高擴展的PHP框架,自動加載插件,自動生成文檔,甚至可以用來擴展PHP語言。由于它是PHP內(nèi)建的oop擴展,為語言本身自帶的特性,所以不需要額外添加擴展或者配置就可以使用。更多內(nèi)容見官方文檔。

反射類型

PHP反射API會基于類,方法,屬性,參數(shù)等維護相應的反射類,已提供相應的調(diào)用API。

類型 說明
Reflector Reflector 是一個接口,被所有可導出的反射類所實現(xiàn)(implement)
Reflection 反射(reflection)類
ReflectionClass 報告了一個類的有關(guān)信息
ReflectionZendExtension 報告Zend擴展的相關(guān)信息
ReflectionExtension 報告了PHP擴展的有關(guān)信息
ReflectionFunction 報告了一個函數(shù)的有關(guān)信息
ReflectionFunctionAbstract ReflectionFunction 的父類
ReflectionMethod 報告了一個方法的有關(guān)信息
ReflectionObject 報告了一個對象(object)的相關(guān)信息
ReflectionParameter 取回了函數(shù)或方法參數(shù)的相關(guān)信息
ReflectionProperty 報告了類的屬性的相關(guān)信息

訪問

假設定義了一個類 User,我們首先需要建立這個類的反射類實例,然后基于這個實例可以訪問 User 中的屬性或者方法。不管類中定義的成員權(quán)限聲明是否為public,都可以獲取到。

?php 
namespace Extend;

use ReflectionClass;
use Exception;

/**
 * 用戶相關(guān)類
 * Class User
 * @package Extend
 */
class User{
    const ROLE = 'Students';
    public $username = '';
    private $password = '';

    public function __construct($username, $password)
    {
        $this->username = $username;
        $this->password = $password;
    }

    /**
     * 獲取用戶名
     * @return string
     */
    public function getUsername()
    {
        return $this->username;
    }

    /**
     * 設置用戶名
     * @param string $username
     */
    public function setUsername($username)
    {
        $this->username = $username;
    }

    /**
     * 獲取密碼
     * @return string
     */
    private function getPassword()
    {
        return $this->password;
    }

    /**
     * 設置密碼
     * @param string $password
     */
    private function setPassowrd($password)
    {
        $this->password = $password;
    }
}

$class = new ReflectionClass('Extend\User');  // 將類名User作為參數(shù),即可建立User類的反射類
$properties = $class->getProperties();  // 獲取User類的所有屬性,返回ReflectionProperty的數(shù)組
$property = $class->getProperty('password'); // 獲取User類的password屬性ReflectionProperty
$methods = $class->getMethods();   // 獲取User類的所有方法,返回ReflectionMethod數(shù)組
$method = $class->getMethod('getUsername');  // 獲取User類的getUsername方法的ReflectionMethod
$constants = $class->getConstants();   // 獲取所有常量,返回常量定義數(shù)組
$constant = $class->getConstant('ROLE');   // 獲取ROLE常量
$namespace = $class->getNamespaceName();  // 獲取類的命名空間
$comment_class = $class->getDocComment();  // 獲取User類的注釋文檔,即定義在類之前的注釋
$comment_method = $class->getMethod('getUsername')->getDocComment();  // 獲取User類中g(shù)etUsername方法的注釋文檔

注意:創(chuàng)建反射類時傳送的類名,必須包含完整的命名空間,即使使用了 use 關(guān)鍵字。否則找不到類名會拋出異常。

交互

一旦創(chuàng)建了反射類的實例,我們不僅可以通過反射類訪問原來類的方法和屬性,還能創(chuàng)建原來類的實例或則直接調(diào)用類里面的方法。

$class = new ReflectionClass('Extend\User');  // 將類名User作為參數(shù),即可建立User類的反射類
$instance = $class->newInstance('youyou', 1, '***');  // 創(chuàng)建User類的實例

$instance->setUsername('youyou_2');  // 調(diào)用User類的實例調(diào)用setUsername方法設置用戶名
$value = $instance->getUsername();   // 用過User類的實例調(diào)用getUsername方法獲取用戶名
echo $value;echo "\n";   // 輸出 youyou_2

$class->getProperty('username')->setValue($instance, 'youyou_3');  // 通過反射類ReflectionProperty設置指定實例的username屬性值
$value = $class->getProperty('username')->getValue($instance);  // 通過反射類ReflectionProperty獲取username的屬性值
echo $value;echo "\n";   // 輸出 youyou_3

$class->getMethod('setUsername')->invoke($instance, 'youyou_4'); // 通過反射類ReflectionMethod調(diào)用指定實例的方法,并且傳送參數(shù)
$value = $class->getMethod('getUsername')->invoke($instance);    // 通過反射類ReflectionMethod調(diào)用指定實例的方法
echo $value;echo "\n";   // 輸出 youyou_4

try {
    $property = $class->getProperty('password_1');
    $property->setAccessible(true);   // 修改 $property 對象的可訪問性
    $property->setValue($instance, 'password_2');  // 可以執(zhí)行
    $value = $property->getValue($instance);     // 可以執(zhí)行
    echo $value;echo "\n";   // 輸出 password_2
    $class->getProperty('password')->setAccessible(true);    // 修改臨時ReflectionProperty對象的可訪問性
    $class->getProperty('password')->setValue($instance, 'password');// 不能執(zhí)行,拋出不能訪問異常
    $value = $class->getProperty('password')->getValue($instance);   // 不能執(zhí)行,拋出不能訪問異常
    $value = $instance->password;   // 不能執(zhí)行,類本身的屬性沒有被修改,仍然是private
}catch(Exception $e){echo $e;}

注意事項

  1. 直接訪問 protected 或則 private 的熟悉或者方法會拋出異常
  2. 需要調(diào)用指定的 ReflectionProperty 或則 ReflectionMethod 對象 setAccessible(true)方法才能訪問非公有成員
  3. 修改非公有成員的訪問權(quán)限只作用于當前的反射類的實例
  4. 需要注意獲取靜態(tài)成員和非靜態(tài)成員所使用的方法不一樣
  5. 獲取父類成員的方法和一般的不一樣

有時間會整理出反射類的API表,詳細的API列表可以先查閱官方文檔。

到此這篇關(guān)于PHP反射機制案例講解的文章就介紹到這了,更多相關(guān)PHP反射機制內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • 解決Laravel5.x的php artisan migrate數(shù)據(jù)庫遷移創(chuàng)建操作報錯SQLSTATE[42000]
  • laravel執(zhí)行php artisan migrate報錯的解決方法
  • laravel 5.1下php artisan migrate的使用注意事項總結(jié)
  • PHP垃圾回收機制講解
  • php之性能優(yōu)化案例
  • php artisan命令信息列舉

標簽:七臺河 赤峰 溫州 金華 怒江 白城 酒泉 洛陽

巨人網(wǎng)絡通訊聲明:本文標題《PHP反射機制案例講解》,本文關(guān)鍵詞  PHP,反射,機制,案例,講解,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請?zhí)峁┫嚓P(guān)信息告之我們,我們將及時溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡,涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《PHP反射機制案例講解》相關(guān)的同類信息!
  • 本頁收集關(guān)于PHP反射機制案例講解的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章