溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Deliverer1.0.8是否已經支持 PHP5

發(fā)布時間:2021-07-06 14:30:49 來源:億速云 閱讀:95 作者:小新 欄目:編程語言

小編給大家分享一下Deliverer1.0.8是否已經支持 PHP5,相信大部分人都還不怎么了解,因此分享這篇文章給大家參考一下,希望大家閱讀完這篇文章后大有收獲,下面讓我們一起去了解一下吧!

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

因為是為了解決祖?zhèn)鞔a的問題,也聽到群友的一些聲音,還是很有必要支持下 PHP5 的,所以這段時間一直在著力解決這個版本兼容問題,沒想到問題比較我預計的要難很多。

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

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

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

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

初次調用解決了,發(fā)現內嵌的調用,又不在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 做的更好了,點贊。

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

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

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

表示監(jiān)控foo函數3次調用后退出,并且打印出deliverer-request-id和其入參,可以再根據deliverer-request-id查看完整的調用棧。

以上是“Deliverer1.0.8是否已經支持 PHP5”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業(yè)資訊頻道!

向AI問一下細節(jié)

免責聲明:本站發(fā)布的內容(圖片、視頻和文字)以原創(chuàng)、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

php
AI