Select and call_user_func_array issue - php

I've this function:
private function db_bind_array($stmt, &$row) {
$md = $stmt->result_metadata();
$param = array();
while($field = $md->fetch_field()) { $param[] = &$row[$field->name];}
return call_user_func_array(array($stmt, 'bind_result'), $param);
}
private function db_query($sql, $bind_param, $param) {
if($stmt = $this->conn->prepare($sql)) {
if(!$bindRet = call_user_func_array(array($stmt,'bind_param'),
array_merge(array($bind_param), $param))) $this->Terminate();
if(!$stmt->execute()) $this->Terminate();
$res = array();
if($this->db_bind_array($stmt, $res)) return array($stmt, $res);
}
}
protected function Select($recs, $table, $where, $bind_param, $param, $order_by = '', $sort = '', $limit = 1) {
if($order_by != '') $order_by = 'ORDER BY '.$order_by;
$sql = "SELECT $recs FROM $table WHERE $where $order_by $sort LIMIT $limit";
return $this->ExeSelect($sql, $bind_param, $param);
}
private function ExeSelect($sql, $bind_param, $param) {
if($res = $this->db_query($sql, $bind_param, array(&$param))) {
$stmt = $res[0]; $row = $res[1];
while($stmt->fetch()) {$this->row = $row; return $row;}
$stmt->close();
}
}
And I use it:
$row = $this->Select('id, name, title, 'Articles', where id >, 'i', 10, 'DESC', '', 10)
The problem is that it returns only one record instead of 10.
What's the problem?
Thanks

The problem is this line: while($stmt->fetch()) {$this->row = $row; return $row;}. You immediately return that result. Build an array before you return it.
private function ExeSelect($sql, $bind_param, $param) {
$ret = array();
if($res = $this->db_query($sql, $bind_param, array(&$param))) {
$stmt = $res[0]; $row = $res[1];
while($stmt->fetch()) {$ret[] = $row; }
$stmt->close();
}
return $ret;
}

Related

Passing array through bind_param

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;
}

pdo and like query

I have a query and it looks like:
if (strlen($search->q)) {
$where[] = ' AND (`name` LIKE :q)';
$arr['q'] = "%" . $search->q . "%";
}
$sql = 'SELECT
*,
FROM
`shop_products`
WHERE
1=1
'.implode('', $where);
Not I'm trying to get products from DB:
$result->products = $db->query($sql, $arr, $search->limitstart, $search->limit)->fetchAll();
My query function:
public function query($sql, $params=array(), $offset = null, $limit = null){
if (!is_null($offset) && !is_null($limit)) {
$sql .= ' LIMIT :limit OFFSET :offset';
$params['limit'] = (int)$limit;
$params['offset'] = (int)$offset;
}
$stmt = $this->database->prepare($sql);
if (!empty($params)) {
foreach($params as $key => $value) {
if(is_int($value)) {
$param = PDO::PARAM_INT;
} elseif(is_bool($value)) {
$param = PDO::PARAM_BOOL;
} elseif(is_null($value)) {
$param = PDO::PARAM_NULL;
} elseif(is_string($value)) {
$param = PDO::PARAM_STR;
} else {
$param = false;
}
if($param) $stmt->bindValue(":$key", $value, $param);
}
}
$stmt->execute();
return $stmt;
}
My problem that LIKE instruction does not work. How can I solve this problem and fix my code?

when i run my program it keeps throwing these errors

Warning: Missing argument 1 for MysqlDB::__construct(), called in C:\xampp\htdocs\ripplezsolution\index.php on line 9 and defined in C:\xampp\htdocs\ripplezsolution\phpinclude\include\MySqlDb.php on line 10
Warning: Missing argument 2 for MysqlDB::__construct(), called in C:\xampp\htdocs\ripplezsolution\index.php on line 9 and defined in C:\xampp\htdocs\ripplezsolution\phpinclude\include\MySqlDb.php on line 10
Warning: Missing argument 3 for MysqlDB::__construct(), called in C:\xampp\htdocs\ripplezsolution\index.php on line 9 and defined in C:\xampp\htdocs\ripplezsolution\phpinclude\include\MySqlDb.php on line 10
Warning: Missing argument 4 for MysqlDB::__construct(), called in C:\xampp\htdocs\ripplezsolution\index.php on line 9 and defined in C:\xampp\htdocs\ripplezsolution\phpinclude\include\MySqlDb.php on line 10
Notice: Undefined variable: host in C:\xampp\htdocs\ripplezsolution\phpinclude\include\MySqlDb.php on line 11
Notice: Undefined variable: username in C:\xampp\htdocs\ripplezsolution\phpinclude\include\MySqlDb.php on line 11
Notice: Undefined variable: password in C:\xampp\htdocs\ripplezsolution\phpinclude\include\MySqlDb.php on line 11
Notice: Undefined variable: db in C:\xampp\htdocs\ripplezsolution\phpinclude\include\MySqlDb.php on line 11
This is my MysqlDB.php code
<?php
class MysqlDB {
protected $_mysql;
protected $_where = array();
protected $_query;
protected $_paramTypeList;
public function __construct ($host, $username, $password, $db) {
$this->_mysql = new mysqli($host, $username, $password, $db)
or die('There was a problem connecting to the database');
}
public function query($query)
{
$this->_query = filter_var($query, FILTER_SANITIZE_STRING);
$stmt = $this->_prepareQuery();
$stmt->execute();
$results = $this->_dynamicBindResults($stmt);
return $results;
}
/**
* A convenient SELECT * function.
*
* #param string $tableName The name of the database table to work with.
* #param int $numRows The number of rows total to return.
* #return array Contains the returned rows from the select query.
*/
public function get($tableName, $numRows = NULL)
{
$this->_query = "SELECT * FROM $tableName";
$stmt = $this->_buildQuery($numRows);
$stmt->execute();
$results = $this->_dynamicBindResults($stmt);
return $results;
}
/**
*
* #param <string $tableName The name of the table.
* #param array $insertData Data containing information for inserting into the DB.
* #return boolean Boolean indicating whether the insert query was completed succesfully.
*/
public function insert($tableName, $insertData)
{
$this->_query = "INSERT into $tableName";
$stmt = $this->_buildQuery(NULL, $insertData);
$stmt->execute();
if ($stmt->affected_rows)
return true;
}
public function update($tableName, $tableData)
{
$this->_query = "UPDATE $tableName SET ";
$stmt = $this->_buildQuery(NULL, $tableData);
$stmt->execute();
if ($stmt->affected_rows)
return true;
}
public function delete($tableName) {
$this->_query = "DELETE FROM $tableName";
$stmt = $this->_buildQuery();
$stmt->execute();
if ($stmt->affected_rows)
return true;
}
public function where($whereProp, $whereValue)
{
$this->_where[$whereProp] = $whereValue;
}
protected function _determineType($item)
{
switch (gettype($item)) {
case 'string':
return 's';
break;
case 'integer':
return 'i';
break;
case 'blob':
return 'b';
break;
case 'double':
return 'd';
break;
}
}
protected function _buildQuery($numRows = NULL, $tableData = false)
{
$hasTableData = null;
if (gettype($tableData) === 'array') {
$hasTableData = true;
}
// Did the user call the "where" method?
if (!empty($this->_where)) {
$keys = array_keys($this->_where);
$where_prop = $keys[0];
$where_value = $this->_where[$where_prop];
// if update data was passed, filter through
// and create the SQL query, accordingly.
if ($hasTableData) {
$i = 1;
$pos = strpos($this->_query, 'UPDATE');
if ( $pos !== false) {
foreach ($tableData as $prop => $value) {
// determines what data type the item is, for binding purposes.
$this->_paramTypeList .= $this->_determineType($value);
// prepares the reset of the SQL query.
if ($i === count($tableData)) {
$this->_query .= $prop . " = ? WHERE " . $where_prop . "= " . $where_value;
} else {
$this->_query .= $prop . ' = ?, ';
}
$i++;
}
}
} else {
$this->_paramTypeList = $this->_determineType($where_value);
$this->_query .= " WHERE " . $where_prop . "= ?";
}
}
if ($hasTableData) {
$pos = strpos($this->_query, 'INSERT');
if ($pos !== false) {
$keys = array_keys($tableData);
$values = array_values($tableData);
$num = count($keys);
foreach ($values as $key => $val) {
$values[$key] = "'{$val}'";
$this->_paramTypeList .= $this->_determineType($val);
}
$this->_query .= '(' . implode($keys, ', ') . ')';
$this->_query .= ' VALUES(';
while ($num !== 0) {
($num !== 1) ? $this->_query .= '?, ' : $this->_query .= '?)';
$num--;
}
}
}
if (isset($numRows)) {
$this->_query .= " LIMIT " . (int) $numRows;
}
$stmt = $this->_prepareQuery();
if ($hasTableData) {
$args = array();
$args[] = $this->_paramTypeList;
foreach ($tableData as $prop => $val) {
$args[] = &$tableData[$prop];
}
call_user_func_array(array($stmt, 'bind_param'), $args);
} else {
if ($this->_where)
$stmt->bind_param($this->_paramTypeList, $where_value);
}
return $stmt;
}
protected function _dynamicBindResults($stmt)
{
$parameters = array();
$results = 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()) {
$x = array();
foreach ($row as $key => $val) {
$x[$key] = $val;
}
$results[] = $x;
}
return $results;
}
protected function _prepareQuery()
{
if (!$stmt = $this->_mysql->prepare($this->_query)) {
trigger_error("Problem preparing query", E_USER_ERROR);
}
return $stmt;
}
public function __destruct()
{
$this->_mysql->close();
}
}
?>
and i'm calling a function insert() through index.php
<?php
ob_start();
session_start();
require_once("phpinclude/include/membersite_config.php");
require_once("phpinclude/include/MySqlDB.php");
$DB = new MysqlDB('172.90.13.97','king','mi*****hhh','kxxxx_database');
if (isset($_GET['action'])){$action = htmlentities($_GET['action']);}
else{$action = NULL;}
$mysqldb = new MysqlDB();
?>
<?php if($action=='add_cart'){?>
<?php $data=array($arrival, $departure, $result, $roomID, $category_price); $table='tb_cart';?>
<?php $this->mysqldb->insert($table, $data); ?>
<?php }?>
Problem is in this line
$mysqldb = new MysqlDB();
The constructor requries arguments which are not passed. You need to pass $host, $username, $password, $db to constructor.
Your code acutally makes no sense. You could use $DB instead of creating new object. You also use $this->mysqldb in no object context. There are plenty of errors in your code.
To fix:
Remove this line $mysqldb = new MysqlDB();
Change <?php $this->mysqldb->insert($table, $data); ?> to $DB->insert($table, $data);
Script should +- look like:
<?php
ob_start();
session_start();
require_once("phpinclude/include/membersite_config.php");
require_once("phpinclude/include/MySqlDB.php");
$DB = new MysqlDB('172.90.13.97','king','mi*****hhh','kxxxx_database');
$action = !empty($_GET['action']) ? htmlentities($_GET['action']) : null;
if ($action == 'add_cart') {
$data = array(
'arrival' => $arrival,
'departure' => $departure,
'result' => $result,
'roomID' => $roomID,
'category_price' => $category_price
);
$DB->insert('tb_cart', $data);
}

Insert MySql data from array [duplicate]

This question already has an answer here:
Mysqli prepared statements build INSERT query dynamically from array
(1 answer)
Closed 6 months ago.
<?php
$files=array(name1,name2,name3,);
$conn = new mysqli($host, $user, $pass, $name);
if ($conn->connect_error) {
die("Connection failed: " . $conn->connect_error);
}
$sql = "INSERT INTO parmi_files (name)
VALUES ('$files')"; ///// -problem is here
if ($conn->query($sql) === TRUE) {
echo "New record created successfully";
} else {
echo "Error: " . $sql . "<br>" . $conn->error;
}
?>
I want to insert each value from array to MySql row, please solve it out.
Iterate through the items in the array and add them individually:
foreach ($arrayWithValues as $key=>$value) {
$sql = "INSERT INTO parmi_files (name) VALUES ('$value')";
mysqli_query($conn, $sql);
}
Something like this to insert multiple records at once:
$files = array('name1', 'name2', 'name3');
// ...
$filesMap = implode(',', array_map(function($value) {
return "('" . $conn->real_escape_string($value) . "')";
}, $files));
$sql = "INSERT INTO parmi_files (name) VALUES $filesMap";
You could use a PDO abstraction layer for this
I have made a class for this in the past
It uses: PDO, bound parameters, prepared statements
and it inserts everything in one sql query and the insert looks like this:
$db->insertRows('test_table', $default_row, $rows);
The full code
(which might seem a bit long, but makes sense if you read it) including the code for the connection would look like:
<?php
// Establish connection (on demand)
$db = new PdoHelper(function(){
$db_server = 'localhost';
$db_port= '3306';
$db_name = 'your_database';
$db_user = 'your_username';
$db_pass = 'your_password';
$dsn = 'mysql:host='.$db_server.';dbname='.$db_name.';port='.$db_port;
$driver_options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES 'utf8'",
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
);
$dbh = new PDO( $dsn, $db_user, $db_pass, $driver_options );
return $dbh;
});
// Make a blank sample to have default values for row keys
$default_row = array(
'a'=>null,
'b'=>null,
'c'=>null,
);
// The rows that we want to insert, with columns in the wrong order and nonsense
$rows = array(
array(
'b'=>'a2',
'c'=>'a3',
),
array(
'c'=>'b3',
'b'=>'b2',
),
array(
'b'=>'c2',
'c'=>'c3',
'nonsense'=>'boo',
),
);
// The actual insert query
// INSERT INTO `test_table` (`a`,`b`,`c`) VALUES (null,'a2','a3'), (null,'b2','b3'), (null,'c2','c3')
$db->insertRows('test_table', $default_row, $rows);
// The class that does it all
class PdoHelper {
private $db, $factory;
public function __construct($factory)
{
$this->factory = $factory;
}
public function connect()
{
$cb = $this->factory;
$this->db = $cb();
}
public function release()
{
$this->db = null;
}
public function implyConnect()
{
if(!$this->db){
$this->connect();
}
}
public function begin()
{
$this->implyConnect();
if($this->db instanceof PDO){
$this->db->beginTransaction();
}
}
public function commit()
{
$this->implyConnect();
if($this->db instanceof PDO){
$this->db->commit();
}
}
public function prepare($sql, $data=null, $callback=null)
{
$err = null;
$flat_data = array();
if($data){
$flat_data = self::flatten($data);
$sql = preg_replace_callback('/\?/isu', function($v) use (&$data) {
$val = array_shift($data);
if(is_array($val)){
return self::arrayToPlaceholder($val);
}
return '?';
}, $sql);
}
$this->implyConnect();
if($this->db instanceof PDO){
$stmt = $this->db->prepare($sql);
if($stmt instanceof PDOStatement){
$i = 1;
foreach($flat_data as $v) {
if(is_int($v)){
// workaround for a PDO bug with LIMIT ?,?
$stmt->bindValue($i++, $v, PDO::PARAM_INT);
}else{
$stmt->bindValue($i++, $v, PDO::PARAM_STR);
}
}
}
}
if($callback){
return call_user_func_array($callback, array($stmt));
}
return $stmt;
}
public function query($sql)
{
$res = false;
$args = func_get_args();
$data = array();
$callback = null;
if(isset($args[2])){
$data = $args[1];
$callback = $args[2];
}else
if(isset($args[1])){
if(is_callable($args[1])){
$callback = $args[1];
}else{
$data = $args[1];
}
}
$this->implyConnect();
$stmt = $this->prepare($sql, $data);
$res = $stmt->execute();
if($res && $callback && is_callable($callback)){
return call_user_func_array($callback, array($stmt, $this->db));
}
return $stmt;
}
// Helper functions
public function insertRows($table, $default, $rows=array(), $flag=null, $chunk_size=500)
{
if(empty($rows)){
return null;
}
$chunks = array_chunk($rows, $chunk_size);
foreach($chunks as $rows){
$data = array();
$data[] = $this->extend($default, $rows);
// http://stackoverflow.com/questions/1542627/escaping-column-names-in-pdo-statements
$flag = strtolower($flag);
$flags = array(
'ignore'=>'INSERT IGNORE INTO ',
'replace'=>'REPLACE INTO ',
);
$cols = array();
foreach($default as $k=>$v){
$k = str_replace('`', '``', $k);
$cols[] = '`'.$k.'`';
}
$sql = (isset($flags[$flag])?$flags[$flag]:'INSERT INTO ').$table.' ('.implode(',', $cols).') VALUES ?';
if($flag==='update'){
$cols = array();
foreach($default as $k=>$v){
$k = str_replace('`', '``', $k);
$cols[] = '`'.$k.'`=VALUE('.$k.')';
}
$sql .= ' ON DUPLICATE KEY UPDATE '.implode(', ', $cols);
}
$res = $this->query($sql, $data);
if(!$res){
return $res;
}
}
return $res;
}
public function insertRow($table, $default, $row, $flag=null)
{
$rows = array($row);
return $this->insertRows($table, $default, $rows, $flag);
}
// Helper functions
public static function extend($set, $rows)
{
foreach($rows as $k=>$v){
$v = array_intersect_key($v, $set);
$rows[$k] = array_replace($set, $v);
}
return $rows;
}
public static function flatten($x)
{
$d = array();
if(is_array($x)){
foreach($x as $k=>$v){
$d = array_merge($d, self::flatten($v));
}
}else{
$d[] = $x;
}
return $d;
}
public static function arrayToPlaceholder($array, $timeZone=null) {
return implode(',', array_map(function($v) use($timeZone){
if(is_array($v)){
return '('.self::arrayToPlaceholder($v, $timeZone).')';
}
return '?';
}, $array));
}
public function arrayToList($array, $timeZone=null) {
return implode(',',array_map(function($v) use($timeZone){
if(is_array($v)){
return '('.self::arrayToList($v, $timeZone).')';
}
$this->implyConnect();
return $this->escape($v);
},$array));
}
public function escape($val, $stringifyObjects=false, $timeZone=false) {
if(is_null($val)) return 'NULL';
if(is_bool($val)) return ($val) ? 'true' : 'false';
if(is_int($val)) return (string)$val;
if(is_float($val)) return (string)$val;
if (is_array($val)) {
return $this->arrayToList($val, $timeZone);
}
if(is_callable($val)){ return null; } // TODO
$val = preg_replace_callback('/[\0\n\r\b\t\\\'\"\x1a]/um', function($s) {
switch($s) {
case "\0": return "\\0";
case "\n": return "\\n";
case "\r": return "\\r";
case "\b": return "\\b";
case "\t": return "\\t";
case "\x1a": return "\\Z";
default: return "\\".$s;
}
}, $val);
return $this->db->Quote($val);
}
// Debug functions
public function getSQL($sql, $data){
foreach($data as $k=>$v){
if(is_array($v)){
$data[$k] = self::arrayToList($v);
}else{
$this->implyConnect();
$data[$k] = $this->escape($v);
}
}
$sql = preg_replace_callback('/\?/', function($match) use(&$data)
{
return array_shift($data);
}, $sql);
return $sql;
}
}

Problem with mysqli num rows

I have a function i use for selecting from the database
function selectquery ($sql, $types, $params)
{
$connection = getConnect ();
$result = $connection->prepare("$sql");
$result->bind_param($types, $params);
$status = $result->execute();
$result->store_result();
$return=array('obj'=>$result, 'status' => $status, 'data'=>array());
$meta = $result->result_metadata();
while ( $field = $meta->fetch_field() )
{
$parameters[] = &$row[$field->name];
}
call_user_func_array(array($result, 'bind_result'), $parameters);
while ( $result->fetch())
{
$x = array();
foreach( $row as $key => $val )
{
$x[$key] = $val;
}
$return['data'][] = $x;
}
$result->close();
return $return;
}
When i run my query:
$resultobj=selectquery ("select id from employers where subdomain = ? ", "s", $reg_subdomain);
if ($resultobj['obj']->num_rows()>0 || in_array($reg_subdomain, $locked_subdomains)) { $error .="Subdomain already exist, please choose another <br>"; }
I get this error message:
Warning: mysqli_stmt::num_rows() [mysqli-stmt.num-rows]: Couldn't fetch mysqli_stmt in /home/drac/public_html/dracxyz.com/functions.php on line 174
Please what am i not doing right?
Thanks
Use it like
$resultobj->num_rows()
http://php.net/manual/en/mysqli-result.num-rows.php

Categories