2017年3月29日 星期三

__call()的妙用

        php有個magic method叫__call(),寫法是這樣的:

class Demo
{
    public function __call($function , $args)
    {
        echo 'function: *' . $function . '* don\'t exist!';
    }
}

(new Demo)->target();



        __call的兩個參數可以任意取名,只要確定是兩個就好。

        當呼叫的target不存在,class Demo就會轉為呼叫__call(),讓開發者可以去設定如果function呼叫不到的時候做的事情,以上面的code執行下來,結果會是:

function: *target* don't exist!

        當沒有建立__call()的時候,會出現報錯:

Fatal error: Call to undefined method Demo::target() in /Users/Hong/php/test/test.php on line 11

        這裡有個今天讀code剛學到的小技巧:

class Animal
{
    public function __call($function , $args)
    {
        if ($function == 'dog') {
            $this->bark();
        } elseif ($function == 'cat') {
            $this->meow();
        }
    }

    private function bark()
    {
        echo 'bark!';
    }

    private function meow()
    {
        echo 'meow!';
    }
}

(new Animal)->dog();



        假設今天不確定動物的叫聲,這裡只需要呼叫動物的種類當作function name,然後因為Animal class找不到該function name,所以會呼叫__call(),__call()拿到之後就可以根據該function name去做對應的動作。

        注意到了嗎?本來應該是找不到function name做的預防措施,這邊卻反過來利用了這個特性,故意讓class找不到該function name,然後做統一分發。

        所以如果運用到API的溝通部分就是,先看看$_SERVER['REQUEST_METHOD']進來的是什麼,GET,POST,PUT?接著再從__call()統一分發到對應的function去呼叫後端API,達到整合的作用。

        寫code真的是一門永遠無法精通的學問,就算把單一語言的特性跟用法用得滾瓜爛熟,但永遠都會有更出其不意,或是更聰明的方式去完成任務,這次的__call()反其道而行的用法著實讓我大開了眼界。


參考資料:

http://php.net/manual/en/language.oop5.overloading.php#object.call





2017年3月28日 星期二

error_reporting 與 display_errors 區別

        當安裝好php,並開始coding的時候,有時候會看到頁面報錯:


        或是看到有warning,但頁面依然正常執行:


        身為開發人員,看著報錯上的提示去debug是很重要的,但有時候已經到了demo階段,頁面上有的報錯還來不及解決,在漂亮的UI上如果出現幾行Notice,會嚴重影響美觀以及客戶對系統的第一印象,這時候便需要對報錯的機制做一些調適。

        在mac安裝好php之後,會有一個php.ini的參數配置檔,php在server上運行就是靠這個配置檔,我是用brew安裝的,php.ini路徑在/usr/local/etc/php/x.x/php.ini,根據版本的不同再去更改x.x就好。

        預設的配置為:



        可以看到,php.ini在不同的環境下有不同的建議配置。

        display_errors在開發的時候,建議用On,但是正在線上運行的專案則是Off,開發的時候秀出錯誤,盡可能方便掌握系統的狀況,而在線上環境的時候,保持頁面的整潔,不出現抱錯or程式碼。

        error_reporting有很多種配置方式,在php.ini裡都有很好的說明,而~則是代表不包含,例如E_ALL & ~E_DEPRECATED & ~E_STRICT就是秀出所有error,但除了E_DEPRECATED以及E_STRICT,這點在php.ini裡也有解釋。

        但error_reporting以及display_errors到底差在哪?

        display_errors意思是要不要秀到頁面上,也就是一開始的兩張圖片,Notice和Parse error。

        error_reporting則是決定要秀什麼到頁面上,全秀?還是把一些訊息先排除?


        display_errors:要不要秀?

        error_reporting:要秀什麼?