代码之家  ›  专栏  ›  技术社区  ›  sergtk

PHP+MYSQLI:使用准备好的语句进行变量参数/结果绑定

  •  7
  • sergtk  · 技术社区  · 17 年前

    在我即将结束的一个项目中,我为PHP编写并实现了一个对象关系映射解决方案。在怀疑者和梦想家喊出“到底是怎么回事?”之前,放松点——我还没有找到让后期静态绑定工作的方法——我只是在尽可能以最好的方式解决它。

    bind_params() bind_result()

    你会问,为什么我需要支持数量可变的参数?因为我的模型的超类(把我的解决方案想象成一个被黑客攻击的PHP ActiveRecord wannabe)是定义查询的地方,所以find()方法不知道需要绑定多少参数。

    现在,我已经考虑过构建一个参数列表并将字符串传递给eval(),但我不太喜欢这种解决方案——我宁愿实现自己的安全检查并传递语句。

    有人对如何做到这一点有什么建议(或成功案例)吗?如果您可以帮助我解决第一个问题,也许我们可以解决绑定结果集的问题(我认为这将更加困难,或者如果涉及确定表结构的初始查询,则至少会占用更多资源)。

    4 回复  |  直到 5 年前
        1
  •  12
  •   Jeff Atwood    17 年前

    在PHP中,您可以使用 call_user_func_array . 方法的一个例子是:

    call_user_func_array(array(&$stmt, 'bindparams'), $array_of_params);
    

    该函数将被调用,数组中的每个成员都作为自己的参数传递。

        2
  •  2
  •   mickmackusa Tom Green    5 年前

    ... ).

    • 您有一个非空的值数组要绑定到查询和
    • 数组值在查询上下文中被适当地处理为字符串类型的值,并且
    • 您的输入数组被调用 $values

    PHP5.6及更高版本的代码:

    $stmt->bind_param(str_repeat('s', count($values)), ...$values);
    

    bind_param() 如果愿意,可以使用splat/spread操作符解包——数据类型字符串只需要是数组的第一个元素。

    array_unshift($values, str_repeat('s', count($values)));
    $stmt->bind_param(...$values);
    
        3
  •  1
  •   zhikharev    14 年前

    您必须确保$array\u of_params是 ,而不是价值观本身。应该是:

    $array_of_params[0] = &$param_string; //link to variable that stores types
    

    然后。。。

    $param_string .= "i";
    $user_id_var = $_GET['user_id'];//
    $array_of_params[] = &$user_id_var; //link to variable that stores value
    

    否则(如果是值数组),您将得到:

    PHP警告:mysqli_stmt::bind_param()的参数2应为引用


    $bind_names[] = implode($types); //putting types of parameters in a string
    for ($i = 0; $i < count($params); $i++)
    {
       $bind_name = 'bind'.$i; //generate a name for variable bind1, bind2, bind3...
       $$bind_name = $params[$i]; //create a variable with this name and put value in it
       $bind_names[] = & $$bind_name; //put a link to this variable in array
    }
    

    call_user_func_array( array ($stmt, 'bind_param'), $bind_names); 
    
        4
  •  0
  •   Steven Oxley    17 年前

    我不允许编辑,但我相信代码

    call_user_func_array(array(&$stmt, 'bindparams'), $array_of_params);
    

    $stmt 是对象和 bindparams 是该对象中的方法,不需要引用。应该是:

    call_user_func_array(array($stmt, 'bindparams'), $array_of_params);
    

    Callback Functions ."

        5
  •  0
  •   jsleuth    16 年前
    call_user_func_array(array(&$stmt, 'bindparams'), $array_of_params);
    

    在我所处的环境中,这对我来说不起作用,但这个答案让我走上了正确的道路。实际起作用的是:

    $sitesql = '';
    $array_of_params = array();
    foreach($_POST['multiselect'] as $value){
        if($sitesql!=''){
            $sitesql .= "OR siteID=? ";
            $array_of_params[0] .= 'i';
            $array_of_params[] = $value;
        }else{
            $sitesql = " siteID=? ";
            $array_of_params[0] .= 'i';
            $array_of_params[] = $value;
        }
    }
    
    $stmt = $linki->prepare("SELECT IFNULL(SUM(hours),0) FROM table WHERE ".$sitesql." AND week!='0000-00-00'");
    call_user_func_array(array(&$stmt, 'bind_param'), $array_of_params);
    $stmt->execute();