PHP + MySQLI:Связывание переменных параметров/результатов с подготовленными операторами

StackOverflow https://stackoverflow.com/questions/12656

  •  08-06-2019
  •  | 
  •  

Вопрос

В проекте, который я собираюсь завершить, я написал и реализовал решение объектно-реляционного сопоставления для PHP.Прежде чем сомневающиеся и мечтатели закричат: «Как же?», расслабьтесь — я не нашел способа заставить работать позднее статическое связывание — я просто работаю над этим наилучшим образом, насколько это возможно.

В любом случае, в настоящее время я не использую подготовленные операторы для запросов, потому что не смог придумать способ передать переменное количество аргументов в функцию. bind_params() или bind_result() методы.

Вы спросите, почему мне нужно поддерживать переменное количество аргументов?Потому что суперкласс моих моделей (подумайте о моем решении как о взломанном подражателе PHP ActiveRecord) определяет запрос, и поэтому метод find(), например, не знает, сколько параметров ему нужно будет связать .

Я уже думал о создании списка аргументов и передаче строки в eval(), но мне это решение не очень нравится — я бы предпочел просто реализовать свои собственные проверки безопасности и передавать инструкции.

Есть ли у кого-нибудь предложения (или истории успеха) о том, как это сделать?Если вы поможете мне решить эту первую проблему, возможно, мы сможем заняться связыванием набора результатов (что, я подозреваю, будет более сложным или, по крайней мере, более ресурсоемким, если оно включает первоначальный запрос для определения структуры таблицы).

Это было полезно?

Решение

В PHP вы можете передать переменное количество аргументов функции или методу, используя call_user_func_array.Примером метода может быть:

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

Функция будет вызываться с передачей каждого члена массива в качестве отдельного аргумента.

Другие советы

Вы должны убедиться, что $array_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:Ожидается, что параметр 2 для mysqli_stmt::bind_param() будет ссылкой


Еще один пример:

$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); 

Мне не разрешено редактировать, но я верю в код

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

Ссылка перед $stmt не обязательна.С $stmt это объект и bindparams это метод в этом объекте, ссылка не обязательна.Должен быть:

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

Для получения дополнительной информации см. руководство по PHP на Функции обратного вызова."

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();
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top