Динамическая привязка параметров с использованием подготовленных операторов
Создавая подготовленные операторы для моего сайта, я обнаружил, что много избыточного кода можно перебирать. mysqli::prepare
был довольно простым, чтобы повторить, но когда я получил mysqli::bind_param
а также mysqli::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 ответ
Это код, использующий 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;
}
}