PHP 8.x compatibility error when using a closure for rowCssClassExpression
jjdunn opened this issue · 2 comments
What steps will reproduce the problem?
- create a widget of type CGridView.
- for the rowCssClassExpression, declare a PHP closure with the function signature ($row, $data, $grid) as defined in the documentation
What is the expected result?
closure is invoked when the grid runs. Code works fine in PHP 7.3.x
What do you get instead?
"Error: Cannot use positional argument after named argument in \framework\base\CComponent.php"
this is in evaluateExpression() when $expression is a closure
Additional info
problem is caused by PHP 8.x change. note the comment on this page:
https://www.php.net/manual/en/function.call-user-func-array.php
submitted by sebastian dot rapetti at tim dot it
who wrote:
Using PHP 8, call_user_func_array calls the callback function
using named arguments if an array with keys is passed to $args parameter.
if the array used has only values, arguments are passed positionally.
so in this case, the first two arguments are "row" and "data", but the third argument added in evaluateExpression() has the numeric key "0", which triggers the error.
WORKING SOLUTION
strip the array keys before passing $data to the closure:
in CComponent::evaluateExpression:
else
{
$_data_[]=$this;
// JJD 4/16/21 fix PHP 8.x error
//return call_user_func_array($_expression_, $_data_);
return call_user_func_array($_expression_, array_values($_data_));
}
same fix in yiilite.php
Q | A |
---|---|
Yii version | 1.1.23 |
PHP version | 8.0.3 |
Operating system | Windows 10 / Windows Server 2019 |
NB: there are 31 instances of call_user_func_array()
in 15 files in yii 1.1.x framework
they probably all need to be audited for the similar problem, in case the called function is a closure, and the caller adds a positional (rather than named) argument to the parameter-list