call_user_func_array将参数传递给构造函数

tue*_*tre 10 php mysql oop constructor

我搜索了很多页面的Google搜索结果以及此处的stackoverflow,但找不到适合我情况的解决方案.我似乎只在我试图构建的函数中有一个最后的障碍,它使用call_user_func_array来动态创建对象.

我得到的可捕获的致命错误是Object of class Product could not be converted to string.当错误发生时,在日志中我得到其中五个(每个参数一个):PHP Warning: Missing argument 1 for Product::__construct(),在可捕获的致命错误之前.

这是函数的代码:

public static function SelectAll($class, $table, $sort_field, $sort_order = "ASC")
{  
/* First, the function performs a MySQL query using the provided arguments. */

$query = "SELECT * FROM " .$table. " ORDER BY " .$sort_field. " " .$sort_order;
$result = mysql_query($query);

/* Next, the function dynamically gathers the appropriate number and names of properties. */

$num_fields = mysql_num_fields($result);
for($i=0; $i < ($num_fields); $i++)
{
  $fetch = mysql_fetch_field($result, $i);
  $properties[$i] = $fetch->name;
}

/* Finally, the function produces and returns an array of constructed objects.*/

while($row = mysql_fetch_assoc($result))
{
  for($i=0; $i < ($num_fields); $i++)
  {
    $args[$i] = $row[$properties[$i]];
  }
  $array[] = call_user_func_array (new $class, $args);
}

return $array;
}
Run Code Online (Sandbox Code Playgroud)

现在,如果我注释掉call_user_func_array行并将其替换为:

$array[] = new $class($args[0],$args[1],$args[2],$args[3],$args[4]);
Run Code Online (Sandbox Code Playgroud)

页面按原样加载,并填充我正在构建的表.所以在我尝试实际使用我的$args数组之前,一切都是绝对有效的call_user_func_array.

是否有一些关于调用我缺少的数组的细微细节?我读了一次call_user_func_array的PHP手册,然后是一些,该页面上的示例似乎向人们展示了构建一个数组并为第二个参数调用它.我能做错什么?

hak*_*kre 20

你不能$class像这样调用构造函数:

call_user_func_array (new $class, $args);
Run Code Online (Sandbox Code Playgroud)

这不是第一个参数的有效回调.让我们分开吧:

call_user_func_array (new $class, $args);
Run Code Online (Sandbox Code Playgroud)

是相同的

$obj = new $class;
call_user_func_array ($obj, $args);
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,构造函数$class已经在调用之前被调用call_user_func_array.由于它没有参数,您会看到以下错误消息:

Missing argument 1 for Product::__construct()
Run Code Online (Sandbox Code Playgroud)

接下来,$obj是object类型.一个有效的回调必须是一个字符串或一个数组(或者特别是一个非常特殊的对象:Closure但是这里没有讨论,我只是为了完整性而命名).

由于$obj是对象而不是有效的回调,因此您会看到PHP错误消息:

Object of class Product could not be converted to string.
Run Code Online (Sandbox Code Playgroud)

PHP尝试将对象转换为字符串,但它不允许.

正如您所看到的,您无法轻松地为构造函数创建回调,因为该对象尚不存在.也许这就是为什么你不能轻易地在手册中查找它.

构造函数需要一些特殊处理:如果需要将变量参数传递给not-yet initialize对象的类构造函数,可以使用它ReflectionClass来执行此操作:

  $ref = new ReflectionClass($class);
  $new = $ref->newInstanceArgs($args);
Run Code Online (Sandbox Code Playgroud)

看到 ReflectionClass::newInstanceArgs