Home >Backend Development >PHP Problem >Deliverer 1.0.8 already supports PHP5!

Deliverer 1.0.8 already supports PHP5!

藏色散人
藏色散人forward
2021-07-05 16:14:211321browse

After two weeks of iteration, Deliverer is currently updated to 1.0.8 https://github.com/zhoumengka.. .

Because it is to solve the problem of ancestral code, and I have heard some voices from the group of friends, it is still necessary to support PHP5, so I have been working hard to solve this version during this period. Compatibility issues, I didn’t expect the problem to be much more difficult than I expected.

After recording the problems encountered during development (mainly physical work) and wanting to share them, Interested friends can fork After a copy, the code will become less unfamiliar. Looking forward to your PR.

In PHP7, functions or methods are executed in zend_execute_data in the execute_data->call->fbc structure, while in PHP5 The corresponding field gets the function that calls the function, and the difference between the two is relatively large.

Later I found that the currently executed function information was found in opline of PHP5 zend_execute_data, but there are differences in the logic before and after PHP5.4 and need to be treated differently (fortunately The field where the compiler prompted an error)

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

The initial call was solved, but it was found that the embedded call was not in opline, and the version was different, and the place where it was obtained was different, and it was the same as The judgment version numbers of the opline above are not the same, so we can only rely on physical strength to measure them.

#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

The final acquisition of function information is multi-layer judgment

    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

What is queried from the opline is only the name of the function, and you need to find the corresponding function pointer in the global function table

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;
}

Overall, the processing of PHP5 is much more complicated than that of PHP7, which also shows that PHP7 does a better job, thumbs up.

These are the development work in the past few days. There may be many actual online environments that I have not encountered. If you are interested, you can use this tool to solve the problem, or you can work together to improve this small tool. .

Next week or the next week I will add the watch function to support parameter printing of functions and methods. Mainly by analogy with Java's Arthas, because the trace and watch functions are what I use most. Although PHP can directly modify and add logs online, this is not standardized after all, and the release process is too slow. I think the watch function is still very If necessary, probably

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

means that the monitoring foo function will exit after three calls, and print out deliver-request-id and its input parameters, you can then View the complete call stack based on deliver-request-id.

If you are interested in this, please give it a star, https://github.com/zhoumengkang/deliverer

If you have any questions about installation and use, please add me on WeChat zhoumengkang before To harass, password: deliverer

Recommended study: "PHP Video Tutorial"

The above is the detailed content of Deliverer 1.0.8 already supports PHP5!. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:segmentfault.com. If there is any infringement, please contact admin@php.cn delete