3分鐘短文|PHP獲取函數參數名,和類定義的常量,都要反射!

2020-12-07 程式設計師小助手

引言

本文我們分享兩個知識點,算是PHP編程中的稍微高階一點的用法,一般不會用到。可是有了這個思路之後,你對於自己的冗餘代碼,應該會有想法了。

反射

獲取函數形參列表

我們在寫程序的時候,不可能所有功能邏輯全堆到一個方法裡。總是要考慮設計方式,重用,以及功能拆分。會細分出許多的函數。

那麼對於一個聲明的函數,類似下面這樣:

function test($name, $age) {}

是否有這樣的函數,可以直接獲取到 test 函數的傳參名呢?

get_func_argNames('test');

輸出類似於:

Array['name','age']

能做到嗎?PHP有這樣的現成函數嗎?很遺憾,沒有!我們需要手動造出來,需要使用一個對象——函數反射 ReflectionFunction。

實現起來代碼如下:

該對象提供 getParameters 方法,返回一個形參列表。使用的之後直接用就是:

print_r(get_func_argNames('get_func_argNames'));

輸出參數數組:

Array( [0] => funcName)

注意,上述方法返回的是全局有效的函數的參數列表,而對於類方法,則需要 ReflectionClass 提供支持了。

驗證是否正確,我們獲取 preg_match 函數的參數列表,輸出如下:

array:5 [ 0 => "pattern" 1 => "subject" 2 => "subpatterns" 3 => "flags" 4 => "offset"]

結果無誤。

類的常量列表

對於一個類,可能源自於多重繼承。那麼對於該類和繼承來的所有常量,我們想要匯總為一個列表,有沒有辦法?

且父類有可能添加或刪除了定義的常量,這個數據是動態的變化的,手動寫死只能是死路一條。

還好,PHP 有反射這個高級語言特性的類,專門用於操作對象。

比如有下面的類:

能否獲取其常量列表,可以是下面三種方式的任意一種:

請問用什麼辦法?

許多優秀的框架在底層設計模式上,幾乎繞不開那個話題——反射。我們對類的操作,也需要反射參與。PHP 提供了 ReflectionClass 用於類操作。

你只需要這麼寫:

$refl = new ReflectionClass('Profile');print_r($refl->getConstants());

輸出的就是所有常量的列表,也就是這種格式:

array('Profile::LABEL_FIRST_NAME' => 'First Name', 'Profile::LABEL_LAST_NAME' => 'Last Name', 'Profile::LABEL_COMPANY_NAME' => 'Company', );

完美解決,幾乎不需要過多解釋。

寫在最後

本文提出的兩個問題,和解決方法,都用到了凌駕於函數和類本身的操作。用於操作函數的類,和操作類的類。為了重用,和壓縮代碼量,你肯定用的著。

Happy coding :-)

我是 @程式設計師小助手 ,持續分享編程知識,歡迎關注。

相關焦點

  • php常量是什麼?它和變量有什麼區別?
    很多計算機語言都是互通的,學過一門之後,再學第二門就很輕鬆了。為了能讓更多的人學好php,小編結合自己的理解和自學時所做的筆記,整合了一些知識點,並藉助百家號這個大平臺分享給大家,希望對大家有所幫助!今天小編將分享的是php常量,以及它和變量的區別。二、php常量1、什麼是php常量?
  • 實例,PHP計算一個圓的面積
    實例說明常量是PHP編程基礎的重要組成部分,其作用是定義一個不會改變的值。本例通過計算圓的面積說明常量是如何定義和使用的,運行結果如下圖所示。實現過程創建腳本 index.php 文件,首先,通過 drfine()函數定義常量。
  • php知識大通關——常見函數功能
    mysql_connect() mysql_query() mysql_close() 以上都不對解析:PHP 提供 mysql_connect() 函數來打開資料庫連接,不過,新版本建議使用 MySQLi 或 PDO 來連接。2、在php中,下面哪個函數用於在 PHP 中獲取環境變量?
  • PHP如何獲取一周的第一天
    使用PHP strtotime()函數可以獲取一周的第一天。此函數返回默認時間變量timestamp,然後使用date()函數將時間戳日期轉換為可理解的日期。strtotime()函數: strtotime()函數通過解析時間字符串返回時間戳中的結果。
  • php中函數禁用繞過的原理與利用
    影響範圍在於bash 1.14 – 4.3關鍵在於:目前的bash腳本是以通過導出環境變量的方式支持自定義函數,也可將自定義的bash函數傳遞給子相關進程。一般函數體內的代碼是不會被執行,但此漏洞會錯誤的將「{}」花括號外的命令進行執行。
  • PHP實戰技巧(1)microtime 微秒函數的應用
    微秒函數的應用define('LARAVEL_START', microtime(true));這是 laravel 框架入口文件的第一行代碼,給大家分析一下它的具體意義。定義常量(與變量的區別是 值 不可改變)define(..)
  • Java反射初探 ——「當類也學會照鏡子」
    ;2.每個成員變量都對應有一個保存和該變量有關信息的Field對象,這個對象所屬的類是 java.lang.reflect.Field3.API分析類中構造器信息 分析構造函數的時候,其實思路大體上和分析方法時候一致,關鍵在於獲取參數所屬類的Class對象 區別在於: 1.
  • php基礎大通關——十分鐘了解php基礎知識點之二
    本節我們繼續通過練習題的方式來熟悉php的基礎知識點。1. echo 和 print 有什麼區別? 它們的作用是一樣的 print 可以接收多個參數,而 echo 不能 echo可以接收多個參數,而 print 不能 print 是一個函數,而 echo 不是解析:echo 可以輸出多個字符串,print 只能輸出一個字符串,它可以表現得像一個函數。所以本題選擇第三個答案。2. upload_max_filesize 中最大上傳默認設置是多少?
  • EffectiveJava-3-類和接口
    保證類不會被擴展:用final修飾或將所有構造方法私有化並提供公有的靜態工廠方法3. 使所有域都是final的(實際上只要沒有方法能夠對域產生外部可見的改變即可,如延遲初始化,懶漢單例等,都不能讓該域是final的)4. 使所有域都是私有的5.
  • Hyperf 發布 v1.1.0 版本,企業級的 PHP 微服務雲原生協程框架
    swoole_hook_flags 來獲取由常量 SWOOLE_HOOK_FLAGS 所定義的 Runtime Hook 等級,您可以在 bin/hyperf.php 通過 !defined('SWOOLE_HOOK_FLAGS') && define('SWOOLE_HOOK_FLAGS', SWOOLE_HOOK_ALL); 的方式來定義該常量,即 Runtime Hook 等級; #596 為@Inject 註解增加了  required 參數,當您定義 @Inject(required=false) 註解到一個成員屬性上,那麼當該依賴項不存在時也不會拋出
  • 怎麼理解php中的數組?php的數組創建和使用方法是什麼?
    php數組的定義數組就是值類型相同的變量的集合,在PHP中的一種常用的複合數據類型,數據可以存放很多的數據,可以存儲任何類型的數據。我們可以把變量當做一個包含值得盒子,那麼可以把數組當做當成一個帶有隔層的盒子,每一層都可以存放一個值。
  • 簡析:Java反射、Java反射定義、反射的基石
    Java反射定義在程序運行過程中,對於任意一個類,可以獲得該類的屬性和方法;對於任意一個對象,可以調用該對象的任意一個屬性和方法。在運行時動態獲取類的信息和動態調用對象的屬性和方法稱為Java反射機制。
  • php htmlspecialchars()函數將特殊字符轉換為HTML實體
    htmlspecialchars()函數定義及用法在php中,htmlspecialchars()函數是使用來把一些預定義的字符轉換為HTML實體,返迴轉換後的新字符串,原字符串不變。如果 string 包含無效的編碼,則返回一個空的字符串,除非設置了 ENT_IGNORE 或者 ENT_SUBSTITUTE 標誌;被轉換的預定義的字符有:&:轉換為&amp;":轉換為&quot;':轉換為成為 '<:轉換為&lt;>:轉換為&gt;htmlspecialchars()函數有四個參數,第一個參數規定了需要轉換的字符串
  • php如何使用array_merge()函數?(代碼示例)
    array_merge()函數array_merge()函數用逗號(',')分隔的數組列表作為需要合併的參數,然後將後一個數組的值附加在前一個數組的末尾,形成一個新數組並返回,這個數組中包含在參數中傳遞的數組的合併值。說明:我們可以在參數中傳遞任意數量的數組。
  • 高樓萬丈平地起,基礎要打牢!Python獲取類的層次結構和繼承順序
    上一篇內容我們詳細了解了Python使用inspect模塊獲取一個模塊、類、實例、函數的信息及幫助文檔的方法(參見新手入門到進階,你不可不知的模塊,用Python獲取對象的詳細信息)。在出現嵌套列表的地方,它包含從緊靠列表前面的類派生的類,返回的每個條目都是一個2元組,包含一個類及其基類的元組。這是講了返回值參數「unique」默認為False,如果為True,則給定列表中每個類的返回結構中只會出現一個條目。否則,使用多重繼承的類及其子代將多次出現。這裡講參數怎麼樣?
  • 一起學JAVA——數組和函數
    如果有一段代碼要使用多次,我們可以給它起個名字,每次使用時通過名字調用,這樣就不用每次都寫一大段代碼了。如果某個函數在執行的時候需要調用者傳入數據,那麼可以定義參數列表,用於接收數據。如果函數運行之後需要返回給調用者數據,那麼需要指定返回值類型,並且用關鍵字return返回。
  • TP6多應用模式下獲取不到當前控制器和方法名 - php中文網
    前言:最近使用TP6做了一套項目,發現多應用模式下使用 $this->request->controller()和 $this->request->action() 無法獲取到當前的控制器和方法名,自己研究了一下,找了個笨辦法
  • Java基礎入門之常量具體定義
    1.整型常量整型常量是整數類型的數據,有二進位、八進位、十進位和十六進位4種表示形式,具體說明如下:● 二進位:由數字0和1 組成的數字序列。在JDK 7以後,允許使用二進位字面值來表示整數,此時二進位數值前面要以0b或0B開頭,目的是為了和十進位進行區分,如:0b01101100、0B10110101。
  • 學Java反射,看這篇就夠了 | 原力計劃
    我們來一句話定義反射:反射就是把 Java 類中的各種成分映射成一個個的 Java 對象。不理解這句話什麼意思?沒關係,在我百度了幾分鐘後,找到三種解釋:解釋一:一個類有:成員變量、方法、構造方法、包等等信息,利用反射技術可以對一個類進行解剖,把各個組成部分映射成一個個對象。
  • 反射——Java高級開發必須懂得
    描述:在 main 函數中,有一個 String args[] 參數,這就表示在執行某 .class 文件時,可以對 main 函數傳字符串參數(例如:命令行中:java OfficeBetter Excel,傳給主函數的參數就是Excel,如果傳多個參數,參數用空格隔開),Office類中使用了兩個類(沒有提供這兩個類),並調用其相應的方法