使用准备好的语句进行动态参数绑定

时间:2019-01-14 12:28:24

标签: php mysql prepared-statement eval bindparam

在为我的网站构建准备好的语句时,我发现可以迭代很多冗余代码。 mysqli::prepare是一个非常简单的迭代对象,但是当我进入mysqli::bind_parammysqli::bind_result时,遇到了以下问题组合:

1)我不知道mysqli::bind_param中有多少个参数
2)将extract(Array)用作mysqli::bind_param的参数将不起作用,因为mysqli::bind_param的参数是通过引用传递的。
3)鉴于传递的元素的值本身不能成为引用,因此EXTR_REF上的extract(Array)标志也无济于事。

在这一点上,我已经放弃,正在使用eval()

$statements[
    's_records_by_parent'=>[
        'sql'=>
            "select * from table where id=?",
        'params'=>[
                '"i"',
                '$id'
             ]
        ],
];
foreach($statements as $name=>$statement){
    if(!$name=$this->mysql->prepare(
        $statement['sql']
    ))
    {
        echo"Error preparing statement $name.";
        exit;
    }
    if(!eval("return \$name->bind_param(".implode(',',$statement['params']).");"))
    {
        echo"Error binding parameters for statement $name.";
        exit;
    }
}

上面的代码完全按照我想要的去做,除了有一个eval()语句,该语句最终将根据用户输入来准备与我有关的语句。

1 个答案:

答案 0 :(得分:0)

这是使用call_user_func_array()的代码:

$statements[
    's_records_by_parent'=>[
        'sql'=>
            "select * from table where id=?",
        'params'=>[
                'i',
                'id'
        ]
    ],
];
foreach($statements as $name=>&$statement){
    if(!$name=$this->mysql->prepare(
        $statement['sql']
    ))
    {
        echo"Error preparing statement $name.";
        exit;
    }
    foreach($statement['params']as$k=>$param)
         if($k)$statement['params'][$k]=&$$param;

    if(!call_user_func_array([$name,'bind_param'],$statement['params']))
    {
        echo"Error binding parameters for statement $name.";
        exit;
    }
}