smarty-php / smarty

Smarty is a template engine for PHP, facilitating the separation of presentation (HTML/CSS) from application logic.
Other
2.26k stars 710 forks source link

Qualify `call_user_func_array` #1074

Open j-applese3d opened 1 month ago

j-applese3d commented 1 month ago

This feels like a PHP bug, so feel free to close as off-topic/won't fix. :smiley:

Basically, the stack trace - as returned from debug_backtrace() - is messed up when calling call_user_func_array() from within a namespace.

Simple PHP example:

<?php

namespace SomeTest;

function printTrace()
{
    print_r(debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS));
}

call_user_func_array('\SomeTest\printTrace', []);

The output is:

Array
(
    [0] => Array
        (
            [function] => SomeTest\printTrace
        )

    [1] => Array
        (
            [file] => /var/www/***
            [line] => 10
            [function] => call_user_func_array
        )

)

But, if you Fully-Qualify the function used, then you'll find the trace is "normal". You can qualify the function by either prepending a \ like \call_user_func_array(..., or you can add a use function call_user_func_array; statement at the top

Either method will fix the trace, and will have the added [alleged] benefit of being faster (as it doesn't have to check for a namespaced function):

Array
(
    [0] => Array
        (
            [file] => /var/www/***
            [line] => 10
            [function] => SomeTest\printTrace
        )

)

How does this affect Smarty?

Smarty makes use of call_user_func_array. Ex: in Extension\CallbackWrapper.php. https://github.com/smarty-php/smarty/blob/a1b4c9c551d01ff63220f053966c7aaa9053f89d/src/Extension/CallbackWrapper.php#L29

This could be changed to either Fully Qualify the function (as explained above), or call_user_func_array could simply be dropped and use the splat operator like so:

return ($this->callback)(...$params);

But like I mentioned, the entire issue is somewhat beyond the scope of Smarty. Just figured it may be of some interest.

wisskid commented 16 hours ago

Sounds good. Just to be sure: you are saying it would be better to add a backslash before each time Smarty uses call_user_func_array from a namespaced file?

j-applese3d commented 15 hours ago

Yes, that is correct.

Either that (add \ in front of every call_user_func_array), Or add use function call_user_func_array; Or don't use call_user_func_array at all and simply execute the callable: ($this->callback)(...$params);

But again, it's not a "smarty problem" so if you do not wish to add \ everywhere, I can also understand and do not mind. :slightly_smiling_face: