【问题标题】:PHP Using call_user_func_array to bind_paramPHP 使用 call_user_func_array 到 bind_param
【发布时间】:2016-01-04 15:13:05
【问题描述】:

我在使用 PHP OOP 向 mysql 插入数据时遇到问题。

所以,这是我的代码:

public function insert($setType, $setTable, $setRow, $setValues) {

        $change = function($values) {
            return "?";
        };

        $row = join(",", $setRow);

        $done = join(",", array_map($change, $setValues));  

        $values[] = join(",", $setValues);

        function SqlArrayReferenceValues($arr){
         if (strnatcmp(phpversion(),'5.3') >= 0) {
            $refs = array();
            foreach($arr as $key => $value)
            $refs[$key] = &$arr[$key];
            return $refs;
            }
        return $arr;
        }

        $insert = $this->connect->prepare("INSERT INTO $setTable ($row) VALUES ($done)");

        $mergedValues = array_merge(array($setType), $values);
        call_user_func_array(array($insert, "bind_param"), SqlArrayReferenceValues($mergedValues));


        $insert->execute();
        $insert->close();

        return $insert;     
    }

if (empty($_SESSION['transaction'])) :

$idt = date("ymdhis");

$_SESSION['transaction'] = $idt;
endif;

$st = $_SESSION['transaction'];

if (isset($_SESSION['email'])) :

$se = $_SESSION['email'];

$user = $objMysql->query(array("*"), "user", "email = '$se'");
    $dataUser = $objMysql->fetch($user);

$ide = $dataUser['id_user'];
else :
$ide = 0;
endif;

$currentLink = "http://$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]";
$objMysql->insert("sis", "url", array("id_transaction", "id_user", "url"), array("$st", "$ide", "$currentLink"));

这是我的 mysql 表: id_transaction 行 - 类型 varchar。 id_user 行 - 类型 INT url 行 - 输入文本

我有 1 个错误,

  1. mysqli_stmt::bind_param(): 类型定义字符串中的元素数与中的绑定变量数不匹配

我的代码有什么问题?

马丁的最终解决方案

public function SqlArrayReferenceValues($arr){
    if (strnatcmp(phpversion(),'5.3') >= 0) {
        $refs = array();
        foreach($arr as $key => $value)
            $refs[$key] = &$arr[$key];
        return $refs;
    }
    return $arr;
}

    public function insert($setType, $setTable, $setRow, $setValues) {

        $change = function($values) {
            return "?";
        };

        $row = join(",", $setRow);

        $done = join(",", array_map($change, $setValues));          
        $insert = $this->connect->prepare("INSERT INTO $setTable ($row) VALUES ($done)");

        $params = $setValues;

        $ww = array_merge(array($setType), $params);
        call_user_func_array(array($insert, "bind_param"), $this->SqlArrayReferenceValues($ww));


        $insert->execute();
        $insert->close();

        return $insert;     
    }

【问题讨论】:

  • $values 不是一个数组......它是一个字符串......这就是 $values = join(",", $setValues); 所做的
  • 您正在尝试将字符串传递给 array_merge。了解您的错误消息。它说明了一切。
  • 而第二个错误是由第一个问题触发的
  • join() 产生string,当然,它不是array
  • 您能否在问题的底部显示您当前使用什么代码来获取passed by reference 错误。谢谢

标签: php mysql


【解决方案1】:

正如 Mark Ba​​ker 和 bub 在 cmets 中正确指出的那样,您传递的是 string 值来代替 array 值。

您拥有的是一个值数组,然后您将其转换为字符串,然后再尝试将它们用作数组。无需在 $values 变量上使用 join

//$values = join(",", $setValues); // comment out this line,

 call_user_func_array(array($insert, "bind_param"), array_unshift(array($setType), $setValues));

在这里,您使用array_unshift 在数组的开始 处插入您传递给函数的数组TYPES。这将为您提供一个正确的数组以插入到 bind_param:

array("sis", $st, $side, $currentLink);

参考预期的问题:

上面存在一个问题,即 MySQLi OOP 代码期望对象作为引用,以及上面的 - 值需要通过单独的进程运行以将其“真实”值提供给 call_user_func_array() 函数.

在你的类/脚本中添加:

 private function SqlArrayReferenceValues($arr){
        if (strnatcmp(phpversion(),'5.3') >= 0) {
            $refs = array();
            foreach($arr as $key => $value)
                $refs[$key] = &$arr[$key];
            return $refs;
        }
        return $arr;
    }

此函数获取值并将正确的值类型返回给 call_user_array_function。

所以:

$mergedValues = array_unshift($setValues, $setType);
call_user_func_array(array($insert, "bind_param"), $this->SqlArrayReferenceValues($mergedValues));

我从 Stack Overflow 上的某个地方获得了这段代码,多年来它一直非常有用!这是链接:https://stackoverflow.com/a/16120923/3536236

更新 3:

您的代码应该看起来如何:

private function SqlArrayReferenceValues($arr){
         if (strnatcmp(phpversion(),'5.3') >= 0) {
            $refs = array();
            foreach($arr as $key => $value)
            $refs[$key] = &$arr[$key];
            return $refs;
            }
        return $arr;
        }

public function insert($setType, $setTable, $setRow, $setValues) {

        $change = function($values) {
            return "?";
        };
        $row = join(",", $setRow);
        $setValuesCopy = $setValues;
        $done = join(",", array_map($change, $setValuesCopy));      
        $insert = $this->connect->prepare("INSERT INTO ".$setTable." (".$row.") VALUES (".$done.")");

        $mergedValues = array_unshift($setValues, $setType);
        //probably not needed but resetting array numerical indexing:
        $mergedValues = array_values($mergedValues); 
        call_user_func_array(array($insert, "bind_param"), $this->SqlArrayReferenceValues($mergedValues));
        $insert->execute();
        $insert->close();
        return $insert;     
    }

$currentLink = "http://".$_SERVER[HTTP_HOST].$_SERVER[REQUEST_URI]";
$objMysql->insert("sis", "url", array("id_transaction", "id_user", "url"), array($st, $ide, $currentLink));

【讨论】:

  • 出现此问题:mysqli_stmt::bind_param() 的参数 2 应作为参考,在中给出值
  • 非常感谢 Martin 先生回答我的问题,我不知道这个方法是否仍然存在问题,警告 mysqli_stmt::bind_param(): Number of elements in type definition string doesn't match number of在中绑定变量
  • 您可以尝试在call_user_func_array 之前插入$mergedValues = array_values($mergedValues); 以正确重新索引数组,也请您可以使用一些代码输出更新您的问题,print_r$insert?$mergedValues 的 var_dump ?
  • 我发现您的代码存在其他严重问题,@ChingChing 因此更新了我的答案。请使用我更新的答案。
  • 致命错误:在中只能通过引用传递变量
猜你喜欢
  • 1970-01-01
  • 2020-04-23
  • 1970-01-01
  • 2017-08-16
  • 2017-08-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多