I have seen this function online to bring a basic support for named parameters for MySQli:
function parseNamedParams(&$queryStr, &$params)
{
$array = array();
if ($c = preg_match_all('/(:\w+)/is', $queryStr, $matches)) { // To match words starting with colon
$list = $matches[0]; // $matches is two-dimensional array, we only need first element
foreach($list as $value) { // We'll replace each parameter in the query string with a '?' (as to comply with mysqli), and make sure the value is in the correct order.
$queryStr = str_replace($value, '?', $queryStr);
$array[] = $params[$value];
}
$params = $array;
}
}
I've been trying to use it:
$DB = new mysqli("host","user","pass","db");
$Query = "SELECT uname FROM test WHERE uname = :user";
$Params = array (
":user" => "Sophie"
);
$Bind = parseNamedParams($Query, $Params);
$SQL = $DB->prepare($Bind);
$SQL->execute();
$SQL->bind_result($Username);
$SQL->fetch();
$SQL->close();
But alas, this does not work
Update
Forgot to include the error message:
Fatal error: Call to a member function execute() on a non-object in
C:\xampp\htdocs\index.php on line 25
If your looking for PDO Style prepared statements, then switch to PDO... But if you really insist on doing this, then I have the following solution:
function Named_Params ($Query, $Params,$DBLink){
$New_Param = array_values($Params);
$Count = 0;
if (preg_match_all('/(:\w+)/is',$Query,$Match)){
$List = $Match[0];
foreach ($List AS $Value){
$Secure_Var = $DBLink->real_escape_string($New_Param[$Count]);
$Query = str_replace($Value,$Secure_Var, $Query);
$Count++;
}
}
return $Query;
}
$DB = new mysqli("","","","");
$Query = "SELECT uname FROM test WHERE uname = ':user'";
$Params = array (
":user" => "Sophie"
);
$Input = Named_Params($Query,$Params,$DB);
$Query = $DB->prepare($Input);
$Query->execute();
$Query->bind_result($Username);
$Query->fetch();
$Query->close();
echo $Name;
Hopefully this is what your looking for
Related
I'm passing an array of values through a bind_param function, the way I do this is like this:
<?php
class Query{
private $_mysqli;
/*
* #param object $mysqli
*/
public function __construct($mysqli)
{
$this->_mysqli = $mysqli;
}
/*
* #param string query
* #param string $types
* #param array $values
*/
public function read($query = "", $type = "", $params = array())
{
$query = ($query === "") ? die("Read error: Query") : $query;
$type = ($type === "") ? die("Read error: Type") : array($type);
$params = (count($params) == 0) ? die("Read error: Params") : $params;
$values = array();
foreach($params as $key => $value) {
$values[$key] = &$params[$key];
}
if ($stmt = $this->_mysqli->prepare($query))
{
call_user_func_array(array($stmt, "bind_param"), array_merge($type, $values));
$stmt->execute();
$fields = array();
for($i=0; $i<count($params); $i++){
$fields[$i] = $params[$i];
}
call_user_func_array(array($stmt, "bind_result"), $fields);
$array = array();
while($data = $stmt->fetch())
{
$array[] = $data;
}
return $array;
}
}
}
This is the way I use my function
<?php
//$mysqli is the mysqli connection
$query = new Query($mysqli);
$query_str = "SELECT * FROM users WHERE voornaam = ? AND achternaam = ?";
$types = "ss";
$params = array("Firstname", "Lastname");
var_dump($query->read($query_str, $types, $params));
?>
The part where I get stucked is:
<?php
$fields = array();
for($i=0; $i<count($params); $i++){
$fields[$i] = $params[$i];
}
call_user_func_array(array($stmt, "bind_result"), $fields);
$array = array();
while($data = $stmt->fetch())
{
$array[] = $data;
}
?>
Im not sure where it goes wrong, I have a feeling at the while loop.
hope you guys can help me making this function working :)
you are binding results , so you don't need to assign your fetched data to new variable,
mysqli_stmt::bind_result -- mysqli_stmt_bind_result — Binds variables
to a prepared statement for result storage
while you are using call_user_func_array , and according to this comment, your loop :
while($data = $stmt->fetch())
{
$array[] = $data;
}
may be as follows:
while($stmt->fetch())
{
// params which you had bind it into bindParams
$array[] = $params;
}
I'm writing a function that takes three arguments, the first two arguments are strings but I want the third argument to comprise of multiple arguments.
Below is the block of code
function myFetch($query, $datatype, $variables){
include("models.php");
$stmt = $conn->prepare($query);
$stmt->bind_param($datatype, $variables);
$stmt->execute();
$result = $stmt->get_result();
return $result->fetch_assoc();
$stmt->close();
$conn->close();
}
From the above code, I'd like the third argument $variable to contain other arguments, example $variable = $one, $two, $three, $four of which these arguments have their own data to be passed to the bind_param function.
Example of the $query, $datatype and $variables:
$query = "SELECT * FROM table WHERE id = ? and visible = ?";
$datatype = "ii";
$id = 1,$visible = 1;
$variables = $id, $visible;
The solution would be like this:
Create an empty $param array and loop through your argument variable array $variables using a for loop.
In each iteration of the loop, push the elements to $variables array as a reference.
Use array_unshift() function to push $datatype to the beginning of $variables array.
Finally, use call_user_func_array() function to bind each of the parameters.
So your myFetch() function should be like this:
function myFetch($query, $datatype, $variables){
include("models.php");
$stmt = $conn->prepare($query);
$param = array();
$count = count($variables);
for($i = 0; $i < $count; ++$i){
$param[] = &$variables[$i];
}
array_unshift($param, $datatype);
call_user_func_array(array($stmt, 'bind_param'), $param);
$stmt->execute();
$result = $stmt->get_result();
$stmt->close();
$conn->close();
return $result;
}
Subsequently, you can call this function like this:
$query = "SELECT * FROM table WHERE id = ? and visible = ?";
$datatype = "ii";
$variables = array(1, 1);
$result = myFetch($query, $datatype, $variables);
while($row = $result->fetch_assoc()){
// display $row details
}
This should do everything you want in your function:
$query = "SELECT * FROM table WHERE id = ? and visible = ?";
$variables = array($id, $visible);
function myFetch($query, $variables){
include("models.php");
$stmt = $conn->prepare($query);
$stmt->execute($variables);
$result = $stmt->fetchAll(PDO::FETCH_ASSOC);
}
Just some thoughts:
Could you use include_once outside your function instead of include?
When you return a value before you close your connection, it will never get closed
Use Reflection to call mysqli::bind_param(), Example:
<?php
$resource = $db->prepare("SELECT * FROM table WHERE id = ? and visible = ?");
$reflectionArray = array(1,"yes");
$reflection = new ReflectionClass('mysqli_stmt');
$method = $reflection->getMethod("bind_param");
$method->invokeArgs($resource, $reflectionArray);
$resource->execute();
?>
Your function:
function myFetch($query, $datatype, $variablesArray){
include("models.php");
$stmt = $conn->prepare($query);
$reflection = new ReflectionClass('mysqli_stmt');
$method = $reflection->getMethod("bind_param");
$method->invokeArgs($stmt, $variablesArray);
$resource->execute();
$result = $stmt->get_result();
$stmt->close();
$conn->close();
return $result->fetch_assoc();
}
I have this script trying to put array into mysqli_stmt_bind_param, I googled around and found this solution, however, the code doesn't seems to be working properly. I received no results from database and a warning.
Warning: call_user_func_array() expects parameter 1 to be a valid callback, first array member is not a valid class name or object
Here is my code:-
$sql_param = array();
$params = array();
$query = "SELECT campname,url,views,leads,subs,country,affid FROM camp WHERE";
if (isset($_POST['fromdatetime']) && isset($_POST['todatetime'])) {
$datefrom = $_POST['fromdatetime'].":00";
$dateto = $_POST['todatetime'].":59";
$sql_param[] = $datefrom;
$sql_param[] = $dateto;
$bindparam = "ss";
$query .= "datevisit between (?) AND (?)";
}
if (isset($_POST['affidcode'])) {
$affidcode = $_POST['affidcode'];
$sql_param[] = $affidcode;
$bindparam .= "s";
$query .= " AND affid = (?)";
}
$sql_param_count = count($sql_param);
$params[] = &$bindparam;
for($i = 0; $i < $sql_param_count; $i++) {
$params[] = &$sql_param[$i];
}
/* create a prepared statement */
$stmt = mysqli_prepare($mysqli, $query);
call_user_func_array(array($stmt, 'mysqli_stmt_bind_param'), $params);
/* execute query */
$status = mysqli_stmt_execute($stmt);
Ensure that $stmt is valid mysqli_stmt object (not false) after this block:
/* create a prepared statement */
$stmt = mysqli_prepare($mysqli, $query);
Then try this:
array_unshift($params, $stmt);
call_user_func_array('mysqli_stmt_bind_param', $params);
i am using This code for showing user data record but this code is not work on my side
I want to echo out specific user data. I created a function where I insert multiple arguments (each argument represents a column in the database) and then echo whichever column I want with a simple line of code.
Index.php
include('function.php');
$conn = new MySQLi(localhost, root, password, database);
$user_id = $_SESSION['login_user']; // like 1
$user = user_data($conn, $user_id, 'login', 'pass', 'nikename', 'email');
if(empty($user)){
echo 'error'; // always showing this error
}else{
echo $user['nickename'];
}
Always Showing echo 'error';
function user_data($conn, $user_id){
$data = array();
$user_id = (int)$user_id;
$func_num_args = func_num_args();
$func_get_args = func_get_args();
if ($func_num_args > 1) {
unset($func_get_args[0]);
unset($func_get_args[1]);
$valid = array('login', 'pass', 'nikename', 'email');
$fields = array();
foreach($func_get_args as $arg) {
if(in_array($arg, $valid)) $fields[] = $arg;
}
$fields = '`' . implode ('`, `', $fields) . '`';
if($stmt = $conn->prepare("SELECT $fields FROM `users` WHERE `user_id` = ?")) {
$stmt->bind_param('si', $fields, $user_id);
$stmt->execute();
//here I am trying to convert the result into an array
$meta = $stmt->result_metadata();
while ($field = $meta->fetch_field()) {
$parameters[] = &$row[$field->name];
}
call_user_func_array(array($stmt, 'bind_result'), $parameters);
while ($stmt->fetch()) {
foreach($row as $key => $val) {
$x[$key] = $val;
}
$results[] = $x;
}
return $results;
$stmt->close();
}
}
}
Seeing and analyzing your code several times, I think the below will solve your issue.
Add this before your while/fetch loop
$row = array();
stmt_bind_assoc($stmt, $row);
so your code will look like this
$row = array();
stmt_bind_assoc($stmt, $row);
while ($stmt->fetch()) {
foreach($row as $key => $val) {
$x[$key] = $val;
}
$results[] = $x;
}
Also make sure you read the full documentation of bind_param on php.net here
Thanks and Best Regards
I guess, instead of
if($stmt = $conn->prepare("SELECT $fields FROM `users` WHERE `user_id` = ?")) {
$stmt->bind_param('si', $fields, $user_id);
you should go with
if($stmt = $conn->prepare("SELECT $fields FROM `users` WHERE `user_id` = ?")) {
$stmt->bind_param('i', $fields, $user_id);
Bind parameters. Types: s = string, i = integer, d = double, b = blob
As far as you have one argument with type INT you need to pass 'i' as a first parameters.
Try debugging over line by line in that function where you will get exact flaw by var_dump().
I would like to return all the results from my prepared query (mysqli) as objects in an array but i cant find a fetchall method or something similar. How do i go about this?
public function getImageResults ($search_term)
{
if (empty($search_term))
return false;
$image_query = $this->db_connection->stmt_init();
$image_query_sql =
"
SELECT
Images.url as url
FROM
Images, ImageSearch, ImageSearchResults
WHERE
ImageSearch.search_string = ? AND
ImageSearchResults.search_id = ImageSearch.id AND
ImageSearchResults.image_id = Images.id AND
Images.deleted = 0 AND
ImageSearch.deleted = 0 AND
ImageSearchResults.deleted = 0
";
if ($image_query->prepare($image_query_sql))
{
$image_query->bind_param('s', $search_term);
$image_query->execute();
$image_query->store_result();
$image_query->bind_result($url);
return //need to return the entire result set here... any ideas?
}
return false;
}
I found this code on the net which kinda works but i get this error when i use it
Notice: Use of undefined constant
mysqli_stmt_bind_result - assumed
'mysqli_stmt_bind_result'
private function getresult ($stmt)
{
$result = array();
$metadata = $stmt->result_metadata();
$fields = $metadata->fetch_fields();
for (;;)
{
$pointers = array();
$row = new stdClass();
$pointers[] = $stmt;
foreach ($fields as $field)
{
$fieldname = $field->name;
$pointers[] = &$row->$fieldname;
}
call_user_func_array(mysqli_stmt_bind_result, $pointers);
if (!$stmt->fetch())
break;
$result[] = $row;
}
$metadata->free();
return $result;
}
The mysqli_stmt_bind_result on this line:
call_user_func_array(mysqli_stmt_bind_result, $pointers);
should be quoted:
call_user_func_array('mysqli_stmt_bind_result', $pointers);
You could also use PDO, an untested example but it should work:
public function getImageResults ($search_term)
{
$sql =
"
SELECT
Images.url as url
FROM
Images, ImageSearch, ImageSearchResults
WHERE
ImageSearch.search_string = ? AND
ImageSearchResults.search_id = ImageSearch.id AND
ImageSearchResults.image_id = Images.id AND
Images.deleted = 0 AND
ImageSearch.deleted = 0 AND
ImageSearchResults.deleted = 0
";
$pdo = new PDO('mysql:dbname=testdb;host=127.0.0.1', 'username', 'password');
$sth = $pdo->prepare($sql);
$sth->execute(array($search_term));
$result = $sth->fetchAll(PDO::FETCH_CLASS, "ArrayObject");
//var_dump($result);//debug
return $result;
}
Hm, you could try something like this, if I remember correctly:
call_user_func_array(array($stmt, 'bind_result'), $pointers);