SELECT * FROM `ware_house_indents` WHERE `has_cancel` = ? AND `eid`= ?
i need to get result above query in mysqli. but i cant use get_result() function because it is not working in server.i have found this below function and it is working fine.but that function not possible to pass multiple parameters.please help me to solve this problem.
function db_bind_array($stmt, &$row)
{
$md = $stmt->result_metadata();
$params = array();
while($field = $md->fetch_field()) {
$params[] = &$row[$field->name];
}
return call_user_func_array(array($stmt, 'bind_result'), $params);
}
function db_query($db, $query, $types, $params)
{
$stmt = $db->prepare($query);
$bindRet = call_user_func_array(array($stmt,'bind_param'),
array_merge(array($types), $params));
$stmt->execute();
$result = array();
if (db_bind_array($stmt, $result) !== FALSE) {
return array($stmt, $result);
}
$stmt->close();
return FALSE;
}
if (($qryRes = db_query($mysqli, $sql, 'i', array(&$var))) !== FALSE) {
$stmt = $qryRes[0];
$row = $qryRes[1];
while ($stmt->fetch()) {
print_r($row);
}
$stmt->close();
}
Let me suggest you a quite indirect solution.
You'd do yourself a huge favor if start using PDO instead of mysqli
It has no mysqli disadvantages when dealing with prepared statements as it has a way better implementation of above functions out of the box. So, it will let you to get your data in a few lines:
$sql = "SELECT * FROM ware_house_indents WHERE has_cancel = ? AND eid= ?";
$stm = $pdo->prepare($sql);
$stm->execute(array($cancel,$eid));
$data = $stm->fetchAll(); // or fetch() if you need only one row
that's all
Related
Ok, so I am having a lot of trouble with Prepared statements. I've done hours of research and still can't seem to fully understand everything...
I really feel like I need to understand Prepared statements because I was just about to release a few new free APIs on my website (which require API Key to execute API) but I recently realized how insecure everything is.... I can simply use SQL injection to bypass API Key check, e.g. 'OR'1'='1
Here is how I validate API Key:
$apikey = $_GET['key'];
$sql = "SELECT * FROM `table` WHERE `key` = '$apikey'";
$query = mysqli_query($con, $sql);
if($query)
{
$fetchrow = mysqli_fetch_row($query);
if(isset($fetchrow[0]))
{
echo "API Key is valid!";
}
else
{
echo "API KEY is invalid";
}
}
And like mentioned above this can easily be bypassed by executing my API like this
http://website.com/api.php?key='OR'1'='1
This really scared me at first, but then I did some research and learned a good way to prevent any form of SQL injection is to use prepared statement, so I did a lot of research and it just seems quite complicated to me :/
So I guess my question is, how can I take my above code, and make it function the same way using prepared statements?
Probably everything you need:
class Database {
private static $mysqli;
Connect to the DB:
public static function connect(){
if (isset(self::$mysqli)){
return self::$mysqli;
}
self::$mysqli = new mysqli("DB_HOST", "DB_USER", "DB_PASS", "DB_NAME");
if (mysqli_connect_errno()) {
/*Log error here, return 500 code (db connection error) or something... Details in $mysqli->error*/
}
self::$mysqli->query("SET NAMES utf8");
return self::$mysqli;
}
Execute statement and get results:
public static function execute($stmt){
$stmt->execute();
if ($mysqli->error) {
/*Log it or throw 500 code (sql error)*/
}
return self::getResults($stmt);
}
Bind results to the pure array:
private static function getResults($stmt){
$stmt->store_result();
$meta = $stmt->result_metadata();
if (is_object($meta)){
$variables = array();
$data = array();
while($field = $meta->fetch_field()) {
$variables[] = &$data[$field->name];
}
call_user_func_array(array($stmt, "bind_result"), $variables);
$i = 0;
while($stmt->fetch()) {
$array[$i] = array();
foreach($data as $k=>$v)
$array[$i][$k] = $v;
$i++;
}
$stmt->close();
return $array;
} else {
return $meta;
}
}
Class end :)
}
Example of usage:
public function getSomething($something, $somethingOther){
$mysqli = Database::connect();
$stmt = $mysqli->prepare("SELECT * FROM table WHERE something = ? AND somethingOther = ?");
$stmt->bind_param("si", $something, $somethingOther); // s means string, i means number
$resultsArray = Database::execute($stmt);
$someData = $resultsArray[0]["someColumn"];
}
Resolving your problem:
public function isKeyValid($key){
$mysqli = Database::connect();
$stmt = $mysqli->prepare("SELECT * FROM table WHERE key = ? LIMIT 1");
$stmt->bind_param("s", $key);
$results = Database::execute($stmt);
return count($results > 0);
}
PHP automatically closes DB connection so no worries about it.
$sql = "SELECT * FROM `table` WHERE `key` = ?";
if(stmt = $mysqli->prepare($sql)) {
$stmt->bind_param("i", $apikey);
$stmt->execute();
$stmt->bind_result($res);
$stmt->fetch();
$stmt->close();
}
See more - http://php.net/manual/en/mysqli.prepare.php
I'm attempting to write a parameterized query with PDO that accepts a number of inputs and acts as a search on a specific table.
There are a number of columns I wish to search on but each of which could be optional. The query simplified might look like:
SELECT * FROM item
WHERE name LIKE '%?%'
AND col2 IN (?, ?, .......)
AND col3 IN (?, ?, .......)
...
and with the IN clause, there could be any number (0 or more) of terms for each column.
Since the IN clause won't work with 0 values, and in PDO I'd have to iterate over each array passed in for each IN clause - I'm wondering if there's a better way to structure this as it seems like a big mess.
You can use "call_user_func_array" to make it dynamic. This is what I use:
public function selectMSData($handlename, $sql, $type='', $params = array())
{
if ( ! is_string($sql) || ! is_array($params) ) {
die('wrong param types');
}
$this->dbconnect($handlename); //connect to db and save connection with handle-name
$result = array();
$aRows = 0;
if(sizeof($params)==0) {
//simple query without runtime parameters
$msres = $this->dbhandle[$handlename]->query($sql);
if($msres === false) {
//log error
} else {
while($mres = $msres->fetch_array(MYSQLI_ASSOC)) {
$aRows++;
$result[] = $mres;
}
}
} else {
//prepared statement using runtime parameters
$stmt = $this->dbhandle[$handlename]->prepare($sql);
if(!$stmt) {
//log error
}
$valArr = array();
$valArr[] = $type;
foreach($params as $pkey => $pval) {
$valArr[] = &$params[$pkey];
}
call_user_func_array(array(&$stmt, 'bind_param'), $valArr);
if(!$stmt->execute()) {
//log error
};
$stmt->store_result(); //fetch is super-slow for text-fields if you don't buffer the result!!
$meta = $stmt->result_metadata();
while ($field = $meta->fetch_field()) {
$resfields[] = &$row[$field->name];
}
call_user_func_array(array($stmt, 'bind_result'), $resfields);
while ($stmt->fetch()) {
foreach($row as $key => $val) {
$c[$key] = $val;
}
$result[] = $c;
$aRows++;
}
$stmt->close();
}
$this->result = $result;
return $aRows;
}
and you call it like this:
$db->selectMSData('my_db_name', 'SELECT * FROM example WHERE a=? AND b=? LIMIT 1', 'ss', array($a, $b));
I am new to PHP prepare method, I need some help to use while loop in the following code.
Here is the query function
function query($query, $bindings, $conn) {
$stmt = $conn->prepare($query);
$stmt-> execute($bindings);
$result = $stmt->fetchAll();
return $result ? $result : false;
}
and the query
$home_team = query('SELECT home_team FROM premier_league
WHERE match_date >= :current_date
AND pre_selected = :pre_selected
ORDER BY match_date LIMIT 5',
array('current_date' => $current_date,
'pre_selected' =>$pre_selected),
$conn);
if (empty($home_team)){
echo "No Match Selected for Today.";
} else {
print_r($home_team);
}
How and where I use while loop for this query?
you don't need no while here
function query($query, $bindings, $conn) {
$stmt = $conn->prepare($query);
$stmt-> execute($bindings);
return $stmt->fetchAll();
}
$sql = 'SELECT home_team FROM premier_league WHERE match_date >= ?
AND pre_selected = ? ORDER BY match_date LIMIT 5';
$home_team = query($sql,array($current_date, $pre_selected), $conn);
foreach ($home_team as $row) {
echo $row['home_team']."<br>\n";
}
In else block
else {
print_r($home_team);
/* here
foreach ($home_team as $team) {
echo $team->home_team . '<br>';
}*/
}
PDOStatement implements Traversable so using fetchAll would be a overhead.
function query($query, $bindings, $conn) {
$stmt = $conn->prepare($query);
$stmt->execute($bindings);
$stmt->setFetchMode(PDO::FETCH_ASSOC);
return $stmt;
}
$home_team = query...;
foreach ($home_team as $row) {
echo $row['home_team']."<br>\n";
}
The idea of using a prepared query is to have the server parse the query once and create a query plan once. This is useful for queries that you execute repeatedly, only changing the parameter values.
Accordingly:
- the prepare should be done once.
- the execute should be done inside the loop.
If you are executing a query once in a while, then the prepare overhead is not worth it.
My query class isn't working on a clients new server because their server is missing the mysqlnd driver. How would I convert the method to not use mysqlnd and also not screw up all their classes?
function query($query, $params=NULL) {
if($params!=NULL) {
$stmt = $this->mysqli->prepare($query);
//must turn $params into reference array to bind
$ref = array();
foreach ($params as $key => $value) {
$ref[$key] = &$params[$key];
}
call_user_func_array(array($stmt,'bind_param'),$ref);
$stmt->execute();
$result = $stmt->get_result();
} else {
$result = $this->mysqli->query($query);
}
if($result){
$rowArray = array();
while ($myrow = $result->fetch_object()) {
$rowArray[] = $myrow;
}
return $rowArray;
}
return false;
}
A quite similar approach using call_user_func_array()
You can find some solutions in the Comments section on the manual page
I have no idea why mysqli require all this unnecessary toilsome stuff while PDO does it out of the box. Compare your soon-will-be code with this one:
function query($query, $params=NULL) {
$stmt = $this->pdo->prepare($query);
$stmt->execute($params);
return $stmt->fetchAll();
}
I have created a class to handle all database operations for my application. So far I have gathered and displayed the data in foreach statements within my view. What I wish to be able to do is get and set individual elements from a function from my database class.
Here is my database function for displaying data within a foreach:
public function test($sql, $type, $param)
{
$variables = array();
$results = array();
// Mysqli
if($stmt = $this->AC->Mysqli->prepare($sql))
{
$params = array_merge($type, $param);
call_user_func_array(array($stmt, 'bind_param'), $this->make_values_referenced($params));
$stmt->execute();
$stmt->store_result();
// Existance
if($stmt->num_rows > 0)
{
$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())
{
$elemet = array();
foreach($row as $key => $val)
{
$element[$key] = $val;
}
$results[] = $element;
}
return $results;
}
else
{
$results = FALSE;
return $results;
}
}
else
{
die("ERROR: We could not connect.");
}
}
The function below is called from my model:
public function profile_information($account_name)
{
// Mysqli Variables
$sql = "SELECT $this->account_details.bio
FROM account_details
WHERE $this->account_details.account_name = ? LIMIT 10";
$type = array("s");
$param = array($account_name);
$results = $this->AC->Database->prepared_select_loop($sql, $type, $param);
$this->AC->Template->set_data('profile_information', $results, FALSE);
}
Once set within my model, I call the function within my controller and access it within my view with a foreach for displaying data:
$profile_information = $this->get_data('profile_information');
foreach ($profile_information as $row) :
//Displaying data here
endforeach;
The above works fine for displaying a large amount of data, but what I'm wanting to do is call the a database function that will allow me set individual data elements. Therefore not having to use a foreach if im only getting a limited amount of data (i.e. one row of Name, age, address)
A non dynamic way I have tackled this problem is to write the database for every function that only desires one row from the database:
function name($variable)
{
$sql = 'statement here';
$stmt = $this->AC->Mysqli->prepare($sql);
$stmt->bind_param("i", $id);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result(bind results);
$stmt->fetch();
$this->AC->Template->set_data('id', $id);
$this->AC->Template->set_data('account_name', $account_name);
}
So in basically I want to make the above statement refactored into my database class and thus making it more dynamic.
I dont know how I would be able to tackle this problem, I don't want to use PDO, as I wish to find a solution within Mysqli. Any help would be appreciated.
Would you recommend just switching over to PDO?
Definitely.
Whole your function test() could be rewritten into three lines (assuming $param contains an array with parameters for the prepared statement):
public function test($sql, $param)
{
$stmt = $this->AC->pdo->prepare($sql);
$stmt->execute($param);
return $stmt->fetchAll();
}