Heim > Backend-Entwicklung > PHP-Problem > Deliverer 1.0.8 unterstützt bereits PHP5!

Deliverer 1.0.8 unterstützt bereits PHP5!

藏色散人
Freigeben: 2023-03-11 08:58:02
nach vorne
1328 Leute haben es durchsucht

Nach zweiwöchiger Iteration wird Deliverer derzeit auf 1.0.8 aktualisiert https://github.com/zhoumengka...

Weil es darum geht, den Ahnencode zu lösen Ich habe auch einige Stimmen von Freunden gehört, dass es immer noch notwendig ist, PHP5 zu unterstützen, daher habe ich in dieser Zeit hart daran gearbeitet, dieses Problem mit der Versionskompatibilität zu lösen. Unerwarteterweise ist das Problem viel schwieriger als ich erwartet hatte.

Nachdem Sie die während der Entwicklung aufgetretenen Probleme (hauptsächlich körperliche Arbeit) aufgezeichnet haben und diese teilen möchten, Interessierte Freunde können eine Kopie forken und sich mit dem Code weniger auskennen, und ich freue mich auf Ihre PR 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
Nach dem Login kopieren

初次调用解决了,发现内嵌的调用,又不在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
Nach dem Login kopieren

最终获取函数信息就是多层判断

    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
Nach dem Login kopieren

在从 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;
}
Nach dem Login kopieren

整体来说 PHP5 的处理要比 PHP7 复杂很多,这也说明 PHP7 做的更好了,点赞。

这些就是这几天的开发工作,可能还有很多实际的线上环境没有遇到过,如果你有兴趣,可以使用这个工具来解决问题,也可以一起来完善这个小工具。

下周或者下下周我将加上 watch 功能,支持函数和方法的参数打印。主要是类比 Java 的 Arthas ,因为在其中 trace 和 watch 功能是我最常用的,虽然 PHP 可以线上直接修改加日志,但是这样毕竟不规范,走发布流程又太慢,我想这个 watch 功能还是很有必要的,大概是

$ ./bin/deliverer -w foo -n 3
Nach dem Login kopieren

表示监控foo函数3次调用后退出,并且打印出deliverer-request-id和其入参,可以再根据deliverer-request-id .

In PHP7 befinden sich Funktionen oder Methoden bei der Ausführung in execute_data->call->fbc in der Struktur zend_execute_data, während die entsprechenden in PHP5 das Feld erhalten ist die Funktion, die die Funktion aufruft, und der Unterschied zwischen den beiden ist relativ groß.

Später stellte ich fest, dass die Informationen zur aktuell ausgeführten Funktion in opline von PHP5 zend_execute_data gefunden wurden, es jedoch Unterschiede in der Logik vor und nach PHP5.4 gab und dies auch der Fall sein muss Anders behandelt (zum Glück der Compiler Das Feld, das den Fehler verursacht hat)

rrreee

Der erste Aufruf wurde gelöst und es wurde festgestellt, dass der eingebettete Aufruf nicht in opline war und die Version und der Ort unterschiedlich waren Wo es erhalten wurde, war anders und es stimmte mit dem Urteil der obigen Meinung überein. Die Versionsnummer ist immer noch unterschiedlich, daher können wir uns nur auf die körperliche Stärke verlassen, um es zu messen. rrreeeDie endgültige Erfassung von Funktionsinformationen ist eine mehrschichtige Beurteilung

rrreee
Was von der Opline abgefragt wird, ist nur der Name der Funktion, und Sie müssen den entsprechenden Funktionszeiger in der globalen Funktionstabelle finden🎜rrreee🎜Im Allgemeinen , PHP5 wird besser verarbeitet als PHP7. Es ist viel komplizierter, was auch zeigt, dass PHP7 besser abschneidet, Daumen hoch. 🎜🎜Dies sind die Entwicklungsarbeiten der letzten Tage. Es gibt möglicherweise viele tatsächliche Online-Umgebungen, auf die ich noch nicht gestoßen bin. Wenn Sie interessiert sind, können Sie dieses Tool verwenden, um das Problem zu lösen, oder Sie können gemeinsam an der Verbesserung dieses Gadgets arbeiten . 🎜🎜Nächste oder nächste Woche werde ich die Überwachungsfunktion hinzufügen, um das Parameterdrucken von Funktionen und Methoden zu unterstützen. Hauptsächlich in Analogie zu Arthas von Java, da ich die Trace- und Watch-Funktionen am häufigsten verwende. Obwohl PHP Protokolle direkt online ändern und hinzufügen kann, ist dies schließlich nicht standardisiert und der Release-Prozess ist meiner Meinung nach zu langsam immer noch sehr notwendig, wahrscheinlich bedeutet 🎜rrreee🎜, dass die foo-Funktion überwacht wird, um nach 3 Aufrufen beendet zu werden, und die deliver-request-id und ihre Eingabeparameter auszudrucken, und Dann basierend auf deliver-request-idSehen Sie sich den vollständigen Aufrufstapel an. 🎜🎜Wenn Sie glauben, dass Sie interessiert sind, geben Sie ihm bitte einen Stern, https://github.com/zhoumengkang/deliverer🎜🎜Wenn Sie Probleme bei der Installation und Verwendung haben, fügen Sie mich bitte auf WeChat zhoumengkang hinzu, um zu belästigen, Passwort : Zusteller🎜🎜 Empfohlenes Lernen: „🎜PHP-Video-Tutorial🎜“🎜🎜

Das obige ist der detaillierte Inhalt vonDeliverer 1.0.8 unterstützt bereits PHP5!. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Verwandte Etiketten:
php
Quelle:segmentfault.com
Erklärung dieser Website
Der Inhalt dieses Artikels wird freiwillig von Internetnutzern beigesteuert und das Urheberrecht liegt beim ursprünglichen Autor. Diese Website übernimmt keine entsprechende rechtliche Verantwortung. Wenn Sie Inhalte finden, bei denen der Verdacht eines Plagiats oder einer Rechtsverletzung besteht, wenden Sie sich bitte an admin@php.cn
Beliebte Tutorials
Mehr>
Neueste Downloads
Mehr>
Web-Effekte
Quellcode der Website
Website-Materialien
Frontend-Vorlage