PHP + MYSQLI: привязка параметра / результата к готовым операторам

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

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

Почему мне нужно поддерживать переменное количество аргументов, спросите вы? Поскольку суперкласс моих моделей (думаю, мое решение как взломанный PHP ActiveRecord wannabe) – это то, где определяется запрос, поэтому метод 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 } 

и BOOOOOM:

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