濮阳杆衣贸易有限公司

主頁(yè) > 知識(shí)庫(kù) > PHP反射機(jī)制案例講解

PHP反射機(jī)制案例講解

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

簡(jiǎn)介

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

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

反射類型

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

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

訪問

假設(shè)定義了一個(gè)類 User,我們首先需要建立這個(gè)類的反射類實(shí)例,然后基于這個(gè)實(shí)例可以訪問 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;
    }

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

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

    /**
     * 設(shè)置密碼
     * @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)建反射類時(shí)傳送的類名,必須包含完整的命名空間,即使使用了 use 關(guān)鍵字。否則找不到類名會(huì)拋出異常。

交互

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

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

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

$class->getProperty('username')->setValue($instance, 'youyou_3');  // 通過反射類ReflectionProperty設(shè)置指定實(shí)例的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í)例的方法,并且傳送參數(shù)
$value = $class->getMethod('getUsername')->invoke($instance);    // 通過反射類ReflectionMethod調(diào)用指定實(shí)例的方法
echo $value;echo "\n";   // 輸出 youyou_4

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

注意事項(xiàng)

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

有時(shí)間會(huì)整理出反射類的API表,詳細(xì)的API列表可以先查閱官方文檔。

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

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

標(biāo)簽:七臺(tái)河 赤峰 溫州 金華 怒江 白城 酒泉 洛陽

巨人網(wǎng)絡(luò)通訊聲明:本文標(biāo)題《PHP反射機(jī)制案例講解》,本文關(guān)鍵詞  PHP,反射,機(jī)制,案例,講解,;如發(fā)現(xiàn)本文內(nèi)容存在版權(quán)問題,煩請(qǐng)?zhí)峁┫嚓P(guān)信息告之我們,我們將及時(shí)溝通與處理。本站內(nèi)容系統(tǒng)采集于網(wǎng)絡(luò),涉及言論、版權(quán)與本站無關(guān)。
  • 相關(guān)文章
  • 下面列出與本文章《PHP反射機(jī)制案例講解》相關(guān)的同類信息!
  • 本頁(yè)收集關(guān)于PHP反射機(jī)制案例講解的相關(guān)信息資訊供網(wǎng)民參考!
  • 推薦文章
    潞西市| 黔西县| 景德镇市| 石首市| 奉新县| 齐齐哈尔市| 湖南省| 宾阳县| 德安县| 安吉县| 富川| 武冈市| 洪洞县| 黄平县| 南澳县| 湾仔区| 沭阳县| 广州市| 佛坪县| 民丰县| 井冈山市| 镇江市| 岱山县| 余庆县| 高安市| 昆山市| 普洱| 措美县| 会同县| 临安市| 三河市| 太保市| 开远市| 石首市| 大城县| 浏阳市| 和林格尔县| 永宁县| 漾濞| 满洲里市| 宁陵县|