首頁  >  文章  >  後端開發  >  Deliverer 1.0.8已經支援 PHP5!

Deliverer 1.0.8已經支援 PHP5!

藏色散人
藏色散人轉載
2021-07-05 16:14:211280瀏覽

經歷了兩週的迭代,Deliverer 目前更新到了1.0.8 https://github.com/zhoumengka.. .

因為是為了解決祖傳程式碼的問題,也聽到群友的一些聲音,還是很有必要支持下PHP5 的,所以這段時間一直在著力解決這個版本相容問題,沒想到問題比較我預計的難很多。

記錄下開發中遇到的問題(主要是體力活)也想分享之後,有興趣的朋友可以fork一份之後,對程式碼不那麼陌生,更期待各位個PR

在PHP7 中,函數或方法在執行的時候都在zend_execute_data結構體中的execute_data->call->fbc中,而PHP5 中對應的字段拿到的卻是呼叫該函數的函數,二者差距比較大。

後來發現PHP5 zend_execute_dataopline中查到了當前執行的函數信息,但在PHP5.4 前後邏輯還有差異,需要區別對待(還好編譯器提示報錯的字段)

#if PHP_VERSION_ID < 50400
#define OP1_FUNCTION_PTR(n) (&(n)->op1.u.constant)
#else
#define OP1_FUNCTION_PTR(n) ((n)->op1.zv)
#endif

初次調用解決了,發現內嵌的調用,又不在opline裡面了,而且版本不一樣,取得地方也不一樣,並且和上面的opline 的判斷版本號碼還不一樣,這就只能靠體力測試了。

#if PHP_VERSION_ID < 50500
    if (execute_data->fbc != NULL)
    {
        fbc = execute_data->fbc;
    }
#else
    if (execute_data->call != NULL && execute_data->call->fbc != NULL)
    {
        fbc = execute_data->call->fbc;
    }
#endif

最終取得函數資訊就是多層判斷

    zend_function *fbc;

#if PHP_VERSION_ID < 70000
#if PHP_VERSION_ID < 50500
    if (execute_data->fbc != NULL)
    {
        fbc = execute_data->fbc;
    }
#else
    if (execute_data->call != NULL && execute_data->call->fbc != NULL)
    {
        fbc = execute_data->call->fbc;
    }
#endif
    if (fbc == NULL)
    {
        fbc = get_function_from_opline(execute_data->opline);
    }
#else
    if (execute_data->call != NULL && execute_data->call->func != NULL)
    {
        fbc = execute_data->call->fbc;
    }
#endif

在從opline 裡查詢到的只是函數的名字,需要再去全域函數表裡找到對應的函數指標

static zend_function *get_function_from_opline(zend_op *opline)
{
    zend_function *fbc;

    zval *function_name = OP1_FUNCTION_PTR(opline);

    if (Z_STRVAL_P(function_name) == NULL)
    {
        return NULL;
    }

    if (zend_hash_find(EG(function_table), Z_STRVAL_P(function_name), Z_STRLEN_P(function_name) + 1, (void **)&fbc) ==
        FAILURE)
    {
        return NULL;
    }

    return fbc;
}

整體來說PHP5 的處理比PHP7 複雜很多,這也說明PHP7 做的更好了,按讚。

這些就是這幾天的開發工作,可能還有很多實際的線上環境沒有遇到過,如果你有興趣,可以使用這個工具來解決問題,也可以一起來完善這個小工具。

下週或下下週我將加上 watch 功能,支援函數和方法的參數列印。主要是類比Java 的Arthas ,因為在其中trace 和watch 功能是我最常用的,雖然PHP 可以線上直接修改加日誌,但是這樣畢竟不規範,走發布流程又太慢,我想這個watch 功能還是很有必要的,大概是

$ ./bin/deliverer -w foo -n 3

表示監控foo函數3次呼叫後退出,並且印出deliverer-request-id和其入參,可以再根據deliverer-request-id查看完整的呼叫堆疊。

如果覺得有這興趣,就請給個星星吧,https://github.com/zhoumengkang/deliverer

安裝和使用上有任何問題,歡迎加​​我微信zhoumengkang 前來騷擾,暗號:deliverer

推薦學習:《PHP影片教學

以上是Deliverer 1.0.8已經支援 PHP5!的詳細內容。更多資訊請關注PHP中文網其他相關文章!

陳述:
本文轉載於:segmentfault.com。如有侵權,請聯絡admin@php.cn刪除