Как связать аргументы mysqli bind_param динамически в PHP?
Я учился использовать подготовленные и привязанные выражения для своих запросов sql, и до сих пор я пришел к этому, он работает нормально, но он не является динамическим вообще, когда приходит к нескольким параметрам или когда нет необходимости в параметрах,
public function get_result($sql,$parameter)
{
# create a prepared statement
$stmt = $this->mysqli->prepare($sql);
# bind parameters for markers
# but this is not dynamic enough...
$stmt->bind_param("s", $parameter);
# execute query
$stmt->execute();
# these lines of code below return one dimentional array, similar to mysqli::fetch_assoc()
$meta = $stmt->result_metadata();
while ($field = $meta->fetch_field()) {
$var = $field->name;
$$var = null;
$parameters[$field->name] = &$$var;
}
call_user_func_array(array($stmt, 'bind_result'), $parameters);
while($stmt->fetch())
{
return $parameters;
//print_r($parameters);
}
# close statement
$stmt->close();
}
Так я называю классы объектов,
$mysqli = new database(DB_HOST,DB_USER,DB_PASS,DB_NAME);
$output = new search($mysqli);
Иногда мне не нужно передавать какие-либо параметры,
$sql = "
SELECT *
FROM root_contacts_cfm
";
print_r($output->get_result($sql));
Иногда мне нужны только одни параметры,
$sql = "
SELECT *
FROM root_contacts_cfm
WHERE root_contacts_cfm.cnt_id = ?
ORDER BY cnt_id DESC
";
print_r($output->get_result($sql,'1'));
Иногда мне нужно только несколько параметров,
$sql = "
SELECT *
FROM root_contacts_cfm
WHERE root_contacts_cfm.cnt_id = ?
AND root_contacts_cfm.cnt_firstname = ?
ORDER BY cnt_id DESC
";
print_r($output->get_result($sql,'1','Tk'));
Итак, я считаю, что эта строка недостаточно динамична для динамических задач выше,
$stmt->bind_param("s", $parameter);
Чтобы построить динамическое bind_param, я нашел это в других сообщениях в Интернете.
call_user_func_array(array(&$stmt, 'bind_params'), $array_of_params);
И я попытался изменить код из php.net, но я никуда не ухожу,
if (strnatcmp(phpversion(),'5.3') >= 0) //Reference is required for PHP 5.3+
{
$refs = array();
foreach($arr as $key => $value)
$array_of_param[$key] = &$arr[$key];
call_user_func_array(array(&$stmt, 'bind_params'), $array_of_params);
}
Почему? Любые идеи, как я могу заставить его работать?
Или, может быть, есть лучшие решения?
Ответы
Ответ 1
нашел ответ для mysqli:
public function get_result($sql,$types = null,$params = null)
{
# create a prepared statement
$stmt = $this->mysqli->prepare($sql);
# bind parameters for markers
# but this is not dynamic enough...
//$stmt->bind_param("s", $parameter);
if($types&&$params)
{
$bind_names[] = $types;
for ($i=0; $i<count($params);$i++)
{
$bind_name = 'bind' . $i;
$$bind_name = $params[$i];
$bind_names[] = &$$bind_name;
}
$return = call_user_func_array(array($stmt,'bind_param'),$bind_names);
}
# execute query
$stmt->execute();
# these lines of code below return one dimentional array, similar to mysqli::fetch_assoc()
$meta = $stmt->result_metadata();
while ($field = $meta->fetch_field()) {
$var = $field->name;
$$var = null;
$parameters[$field->name] = &$$var;
}
call_user_func_array(array($stmt, 'bind_result'), $parameters);
while($stmt->fetch())
{
return $parameters;
//print_r($parameters);
}
# the commented lines below will return values but not arrays
# bind result variables
//$stmt->bind_result($id);
# fetch value
//$stmt->fetch();
# return the value
//return $id;
# close statement
$stmt->close();
}
то
$mysqli = new database(DB_HOST,DB_USER,DB_PASS,DB_NAME);
$output = new search($mysqli);
$sql = "
SELECT *
FROM root_contacts_cfm
ORDER BY cnt_id DESC
";
print_r($output->get_result($sql));
$sql = "
SELECT *
FROM root_contacts_cfm
WHERE root_contacts_cfm.cnt_id = ?
ORDER BY cnt_id DESC
";
print_r($output->get_result($sql,'s',array('1')));
$sql = "
SELECT *
FROM root_contacts_cfm
WHERE root_contacts_cfm.cnt_id = ?
AND root_contacts_cfm.cnt_firstname = ?
ORDER BY cnt_id DESC
";
print_r($output->get_result($sql, 'ss',array('1','Tk')));
mysqli настолько хромает, когда приходит к этому. Я думаю, что я должен перейти на PDO!
Ответ 2
Используя PHP 5.6, вы можете сделать это легко с помощью распаковать оператор (...$var
) и использовать get_result() insted bind_result()
public function get_result($sql,$types = null,$params = null) {
$stmt = $this->mysqli->prepare($sql);
$stmt->bind_param($types, ...$params);
if(!$stmt->execute()) return false;
return $stmt->get_result();
}
Пример:
$mysqli = new database(DB_HOST,DB_USER,DB_PASS,DB_NAME);
$output = new search($mysqli);
$sql = "SELECT * FROM root_contacts_cfm WHERE root_contacts_cfm.cnt_id = ?
AND root_contacts_cfm.cnt_firstname = ?
ORDER BY cnt_id DESC";
$res = $output->get_result($sql, 'ss',array('1','Tk'));
while($row = res->fetch_assoc()){
echo $row['fieldName'] .'<br>';
}
Ответ 3
Или, может быть, есть лучшие решения?
Этот ответ вам не очень помогает, но вы должны серьезно подумать о переходе на PDO из mysqli.
Основная причина этого заключается в том, что PDO делает то, что вы пытаетесь сделать в mysqli со встроенными функциями. В дополнение к ручному привязке к параметрам метод может вместо этого возьмем массив аргументов.
PDO легко расширяется, и добавление удобных методов для извлечения-все-и-возвращения вместо выполнения танца ready-execute очень просто.
Ответ 4
Я нашел хороший класс mysqli, он может обрабатывать динамические параметры и прост в использовании
https://github.com/ajillion/PHP-MySQLi-Database-Class
Вы можете ссылаться на исходный код, как он динамически создает запрос
https://github.com/ajillion/PHP-MySQLi-Database-Class/blob/master/MysqliDb.php