首頁 後端開發 php教程 巧妙的重載魔術方法__call()

巧妙的重載魔術方法__call()

Aug 08, 2016 am 09:31 AM
config function key

工作半年了,感覺這半年學到的東西比大學四年學到的還要多,主要原因是心靜下來了,目標也明確了,不會去整天的和遊戲糾纏在一起了。大學時候其實也意識到了玩遊戲會影響自己的正常學習和工作的,但是一直控制不了自己,還是忍不住經常去玩,沒日沒夜的玩(本來就是悶騷男,還宅著玩遊戲,這也是大學四年只有遊戲、左右手,沒有女朋友的原因了)。現在工作了,每天都有任務,看到旁邊的牛人們在專案中如魚得水,就有了趕超他們的想法,於是每天都會給自己一個額外的小任務去學習新的知識,到現在工作有半年了,對以前不熟悉的linux現在也可應熟悉的使用了,對不熟悉的js也有了新的認識,可以說現在我對工作可以勝任(如果分為新手、高級新手、勝任者、精通者、專家)了,開發過活動、介面、後台,也優化完善過系統的框架,只要是產品運作提出的合理需求都可以快速的支援到位。當然還確確實實的感受到一點:程式設計師真是個奇怪的群體,大多時候總是會覺得自己的點子是最好的。 當然這個算是自信但有時候討論的時候你的咄咄逼人不一定是好事,所以還要多聽聽其他人的想法,不但可以發現自己的不足,還會建立良好的:」友誼「。跟大家瞎扯了這麼多這半年的一點點感受,謝謝你可以堅持看完^_^。

下面步入真題,說說如何巧妙的運用php的魔術方法,我相信這個在大多數項目中會用到。

先說明一下,這個小技巧我在專案中已經有很好的應用了,給我們專案帶來了很大的方便,在這裡先賣賣關子,您不妨繼續往下看。

在專案中,可配的設定資訊一定大量存在,比如說一個遊戲的機器人開放時段、支付方式的開啟與否、商城顯示title的配置等等,這些配置資訊一般有一個特點就是沒有特定的規則,而且產品運作可以隨時的給據實際情況去修改,這些資訊怎麼保存呢,肯定不會每種類型都去建一張表,這樣做簡直就是費力不討好,你想下,也許一張表中就保存了一條信息,所以得想想其他的方法,雖然這些信息沒有規則,但是他們卻有一個特點就是不會有太多,而且一般情況下數組就可以保存所有需要配置的信息,因此用json字符字串儲存資訊是個不錯的選擇,當需要使用的時候直接取出json_decode這樣就可以直接使用了,下面看看具體怎麼巧妙的利用php的魔術方法實現的。

這裡你先要了解下php的一個魔術方法__call(),查下php官方的文檔,是這樣解釋這個函數的

<span>public</span> <span>mixed</span> __call ( <span>string</span> <span>$name</span> , <span>array</span> <span>$arguments</span><span> )

__call() is triggered when invoking inaccessible methods in an </span><span>object</span> context.
登入後複製

意思是說當在一個物件中呼叫一個不可存取的方法(沒有權限、不存在)時會觸發這個函數,函數的參數$name是呼叫的函名,$arguments是呼叫的函數參數陣列。看看下面這個範例:

<span>class</span><span> Test
{
    </span><span>public</span> <span>function</span> __call(<span>$name</span>, <span>$arguments</span><span>)
    {
        </span><span>echo</span> "你调用了一个不存在的方法:\r"<span>;
        </span><span>echo</span> "函数名:{<span>$name</span>}\r"<span>;
        </span><span>echo</span> "参数: \r"<span>;
        </span><span>print_r</span>(<span>$arguments</span><span>);
    }
}

</span><span>$T</span> = <span>new</span><span> Test();
</span><span>$T</span>->setrobottime("12", "18");
登入後複製

這個函數會輸出下面的結果

<span>你调用了一个不存在的方法:
函数名:setrobottime
参数: 
Array
(
    [</span>0] => 12<span>
    [</span>1] => 18<span>
)</span>
登入後複製

這樣,我們就可以不去直接定義函數,而是用這個特性去做一些事情了。下面看看程式碼的實作思路,主要是思路,其中有些我是假設的,就像資料庫連接,這裡不主要講這個。

<span>class</span><span> Config
{
    </span><span>/*</span><span>*
     * 这里假定下数据库表名为
     * config.config,
     * 字段为:
     * config_key varchar(50),
     * config_value text,
     * primary key(config_key)
     *
     * 数据库连接为$link
     * 插入方法封装为query
     * 获取一条信息方法封装为getOne
     </span><span>*/</span>
    <span>/*</span><span>*
     * 要进行的操作
     </span><span>*/</span>
    <span>private</span> <span>static</span> <span>$keys</span> = <span>array</span><span>(
        </span><span>//</span><span>'调用方法' => 'key',</span>
        'roboottime'    => 'ROBOOTTIME',
        'dailysignin'   => 'DAILYSIGNIN',<span>
    );

    </span><span>/*</span><span>*
     * 设置方法
     * @param string $config_key 配置项key
     * @param string $config_value 配置型内容(一般为json格式)
     * @returne boolen true/false 插入是否成功
     </span><span>*/</span>
    <span>private</span> <span>function</span> set(<span>$config_key</span>, <span>$config_value</span><span>){
        </span><span>$sql</span> = "insert into config.config (config_key,config_value) values ('{<span>$config_key</span>}','{<span>$config_value</span>}') on duplicate key update config_value='{<span>$config_value</span>}'"<span>;
        </span><span>return</span> <span>$link</span>->query(<span>$sql</span><span>);
    }

    </span><span>/*</span><span>*
     * 获取值的方法
     * @param $config_key 要获取的配置的key
     * @returne string/false json字符串/失败
     </span><span>*/</span>
    <span>private</span> <span>function</span> get(<span>$config_key</span><span>)
    {
        </span><span>$sql</span> = "select * from config.config where config_key='{<span>$config_key</span>}'"<span>;
        </span><span>if</span>(<span>$ret</span> = <span>$link</span>->getOne(<span>$sql</span>,<span> MYSQL_ASSOC)){
            </span><span>return</span> <span>$ret</span><span>;
        }
        </span><span>return</span> <span>false</span><span>;
    }

    </span><span>/*</span><span>*
     * 重载魔术方法
     * @param string $name 被调用的方法名
     * @param array $arguments 调用时传递的参数
     * @return mixed 返回结果
     </span><span>*/</span>
    <span>public</span> <span>function</span> __call(<span>$name</span>, <span>$arguments</span><span>)
    {
        </span><span>$act</span>    = <span>substr</span>(<span>$name</span>, 0, 3<span>);
        </span><span>$func</span>   = <span>substr</span>(<span>$name</span>, 3<span>);
        </span><span>if</span>(!<span>in_array</span>(<span>$func</span>, self::<span>$keys</span><span>)){
            </span><span>return</span> <span>false</span><span>;
        }
        </span><span>if</span>(<span>$act</span> == 'set'<span>)
        {
            </span><span>return</span> <span>$this</span>->set(self::[<span>$func</span>], <span>$arguments</span>[0<span>]);
        }
        </span><span>elseif</span>(<span>$act</span> == 'get'<span>)
        {
            </span><span>return</span> <span>$this</span>->get(self::[<span>$func</span><span>]);
        }
        </span><span>return</span> <span>false</span><span>;
    }
}</span>
登入後複製

這樣,我們的就可以透過一張表儲存多個資訊了,呼叫時也很方便,只需要擴充下Config::$keys數組中的資訊就可以了,這樣做只是為了規範,為了可以清晰的知道哪些配置存放在了這張表中。

使用的時候可以像這樣去存放和獲取

<span>$config</span> = <span>new</span><span> Config();

</span><span>$info</span> = <span>array</span>("12","20"<span>);

</span><span>//</span><span>设置</span>
<span>$config</span>->setroboottime(json_encode(<span>$info</span><span>));

</span><span>//</span><span>获取</span>
<span>$config</span>->getroboottime();
登入後複製

這裡再說一個要注意的點,這些配置信息一般會緩存到redis中,放在數據庫中只是為了防止redis掛掉之後從數據庫中去恢復,這裡的一般指的是那些經常去讀取的信息,為了減少和db的交互,直接放在快取中。

  本文版權歸作者iforever(luluyrt@163.com)所有,未經作者本人同意禁止任何形式的轉載,轉載文章之後必須在文章頁面明顯位置給出作者和原文連接,否則保留追究法律責任的權利。

posted @ 2015-01-10 12:23 奔跑的Man 閱讀(...) 評論(...) 編輯 收藏

刷新評論刷新頁面返回頂部

博客園首頁博問新聞閃存程式設計師招募知識庫

公告

Copyright ©2015 奔跑的Man

本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn

熱AI工具

Undresser.AI Undress

Undresser.AI Undress

人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover

AI Clothes Remover

用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool

Undress AI Tool

免費脫衣圖片

Clothoff.io

Clothoff.io

AI脫衣器

Video Face Swap

Video Face Swap

使用我們完全免費的人工智慧換臉工具,輕鬆在任何影片中換臉!

熱工具

記事本++7.3.1

記事本++7.3.1

好用且免費的程式碼編輯器

SublimeText3漢化版

SublimeText3漢化版

中文版,非常好用

禪工作室 13.0.1

禪工作室 13.0.1

強大的PHP整合開發環境

Dreamweaver CS6

Dreamweaver CS6

視覺化網頁開發工具

SublimeText3 Mac版

SublimeText3 Mac版

神級程式碼編輯軟體(SublimeText3)

如何修復 .NET 解析器傳回的錯誤 0xC00CE556 如何修復 .NET 解析器傳回的錯誤 0xC00CE556 Apr 25, 2023 am 08:34 AM

在安裝應用程式的新版本時,Windows可能會顯示此錯誤訊息「解析C:\\Windows\Microsoft.Net\Framework\v2.0.50727\Config\machine.configParser傳回錯誤0xC00CE556時發生錯誤」。當您的系統啟動時,這個問題也會出現。無論您在何種情況下遇到此問題,.NETFramework都是幕後真正的罪魁禍首。您可以使用一些非常簡單的修復程序來阻止此錯誤代碼再次出現。修復1–替換損壞的檔案您可以輕鬆地從原始目錄中替換損壞的ma

function是什麼意思 function是什麼意思 Aug 04, 2023 am 10:33 AM

function是函數的意思,是一段具有特定功能的可重複使用的程式碼區塊,是程式的基本組成單元之一,可以接受輸入參數,執行特定的操作,並傳回結果,其目的是封裝一段可重複使用的程式碼,提高程式碼的可重複使用性和可維護性。

SQL中的identity屬性是什麼意思? SQL中的identity屬性是什麼意思? Feb 19, 2024 am 11:24 AM

SQL中的Identity是什麼,需要具體程式碼範例在SQL中,Identity是一種用於產生自增數字的特殊資料類型,它常用於唯一識別表中的每一行資料。 Identity欄位通常與主鍵列搭配使用,可確保每筆記錄都有獨一無二的識別碼。本文將詳細介紹Identity的使用方式以及一些實際的程式碼範例。 Identity的基本使用方式在建立表格時,可以使用Identit

SpringBoot怎麼監聽redis Key變化事件 SpringBoot怎麼監聽redis Key變化事件 May 26, 2023 pm 01:55 PM

一、功能概覽鍵空間通知使得客戶端可以透過訂閱頻道或模式,來接收那些以某種方式改變了Rediskey變化的事件。所有修改key鍵的指令。所有接收到LPUSHkeyvalue[value…]指令的鍵。 db資料庫中所有已過期的鍵。活動透過Redis的訂閱與發布功能(pub/sub)來分發,因此所有支援訂閱與發布功能的用戶端都可以在無須做任何修改的情況下,直接使用按鍵空間通知功能。因為Redis目前的訂閱與發布功能採取的是發送即忘(fireandforget)策略,所以如果你的程

redis批量刪除key值的問題怎麼解決 redis批量刪除key值的問題怎麼解決 May 31, 2023 am 08:59 AM

遇到的問題:在開發過程中,會遇到要批量刪除某種規則的key,例如login_logID(ID為變數),現在需要刪除"login_log*"這一類的數據,但是redis本身只有批量查詢一類別key值的指令keys,但是沒有批次刪除某一個類別的指令。解決方法:先查詢,在刪除,使用xargs傳參(xargs可以將管道或標準輸入(stdin)資料轉換成命令列參數),先執行查詢語句,在將查詢出來的key值,當初del的參數去刪除。 redis-cliKEYSkey*(查找條件)|xargsr

不可修補的 Yubico 二因素驗證金鑰漏洞破壞了大多數 Yubikey 5、安全金鑰和 YubiHSM 2FA 設備的安全性 不可修補的 Yubico 二因素驗證金鑰漏洞破壞了大多數 Yubikey 5、安全金鑰和 YubiHSM 2FA 設備的安全性 Sep 04, 2024 pm 06:32 PM

無法修補的 Yubico 二因素驗證金鑰漏洞已經破壞了大多數 Yubikey 5、安全金鑰和 YubiHSM 2FA 設備的安全性。 Feitian A22 JavaCard和其他使用Infineon SLB96xx系列TPM的裝置也容易受到攻擊。

php如何使用ThinkPHP\Config進行組態管理? php如何使用ThinkPHP\Config進行組態管理? May 31, 2023 pm 02:31 PM

隨著PHP語言的不斷發展,做為PHP後端框架中廣泛使用的ThinkPHP也在不斷改進。隨著業務場景的逐漸複雜,ThinkPHP中對於組態管理的需求也越來越大。在這種背景下,ThinkPHP提供了豐富的組態管理功能,今天我們就來介紹如何透過ThinkPHPConfig實現組態管理。一、ThinkPHPConfig的介紹ThinkPHPConfig是Thin

php如何使用CodeIgniter\Config進行組態管理? php如何使用CodeIgniter\Config進行組態管理? Jun 02, 2023 pm 06:01 PM

一、CodeIgniter簡介CodeIgniter是一個輕量級且全面的PHP開發框架,旨在為Web開發人員提供快速且強大的工具來建立Web應用程式。它是一個開源的框架,使用MVC架構模式來實現快速開發和基礎功能,同時支援多種資料庫。二、Config庫簡介Config庫是CodeIgniter框架中的一個元件,用於對程式碼進行組態管理。 Config庫包含了很多

See all articles