function db_execute($sql,$db,$array)
{
require(getcwd() . '/config/config.php');
if (empty($array))
{
$array = "";
print "Something wrong";
}
$connection = db_connect($db_host,$db_username,$db_password,$db);
$q = $connection->prepare($sql, array(PDO::ATTR_CURSOR => PDO::CURSOR_FWDONLY));
$q ->execute(array($array));
if(!$q)
{
die("Error! " . $connection->errorInfo());
}
$result = $q -> fetchAll();
return $result;
}
$sql = "SELECT VALUE FROM users WHERE :id = :idnum";
$array = array(':id' => 'USER_ID', ':idnum' => '2');
printFormattedArray($array);
printFormattedArray(db_execute($sql,"user_db",$array));
For some reason I can't get any results from this function to return any results. But when I substitute the query with
$sql = "SELECT VALUE FROM users WHERE USER_ID = 2";
It gives me the required results. What am I doing wrong?
Basically, you have 2 choices.
.1. Refrain from using dynamical identifiers in your queries.
So, go for your second query.
$sql = "SELECT VALUE FROM users WHERE USER_ID = :idnum";
$array = array(':idnum' => '2');
$data = db_execute($sql, $array);
.2. If you need dynamical identifiers, you need a distinct placeholder for them as well
So, your code would be like
$sql = "SELECT VALUE FROM users WHERE ?n = ?i";
$data = db_execute($sql, 'USER_ID', 2);
Also,
never connect in the query execution function. Connect once and then use opened connection
always set your PDO to report mysql errors
add this code after connect
$connection->setAttribute( PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION );
Related
I want to execute multiple MySQL queries. Where the next query depends on the status of the previous one. I need to check the status of the query and in some cases also rowCount(). If the first query returns what I want the next query will be executed and so on. If one of them fail the whole process will be stopped.
I usually nest my queries inside of a try/catch block. Is there a better way to do this? Here is my code. I do not want you to fix my code just see it and give me any suggestions. I'm using PDO with MySQL 5.6.26.
Thanks
$updated = false;
//#1
$query = "select username, forgot_code, time, valid from forgot_requests where forgot_code = :forgot_code";
try {
$run_query = $db->prepare($query);
$run_query->execute(array(':forgot_code' => $_POST['forgot_code']));
$data = $run_query->fetch(PDO::FETCH_OBJ);
//13min = 780s
if($run_query->rowCount() == 1 && (time() - $data->time < 7800000) && $data->valid) {
//#2
$query = "update users set password = :password where username = :username";
try {
$run_query = $db->prepare($query);
$run_query->execute(array(
':password' => password_hash($_POST['password'], PASSWORD_DEFAULT),
':username' => $data->username
));
//#3
$query = "update forgot_requests set valid = 0 where forgot_code = :forgot_code";
try {
$run_query = $db->prepare($query);
$run_query->execute(array(':forgot_code' => $_POST['forgot_code']));
//update
$updated = true;
} catch(PDOException $e) {}
} catch(PDOException $e) {}
}
} catch(PDOException $e) {}
I assume you want to enforce a valid database state with your pre cautions.
MySQL and PDO offer you the concept of transactions to ensure that a series of sql statements will only be executed all together.
Example
<?php
$db->beginTransaction();
// Query 2
$query = "update users set password = :password where username = :username";
$run_query = $db->prepare($query);
$run_query->execute(array(
':password' => password_hash($_POST['password'], PASSWORD_DEFAULT),
':username' => $data->username
));
// Query 3
$query = "update forgot_requests set valid = 0 where forgot_code = :forgot_code";
$run_query = $db->prepare($query);
$run_query->execute(array(':forgot_code' => $_POST['forgot_code']));
// All queries will be executed or no query will be executed
$db->commit();
?>
If you encounter any problems you can roll back a transaction:
<?php
$db->rollBack();
?>
Further information can be found in MySql manual: (http://dev.mysql.com/doc/refman/5.7/en/commit.html) and in php documentation (http://php.net/manual/de/pdo.begintransaction.php)
I've written this simple code to retrieve a value of a table which starts with a variable coming from a POST method: i know that in my table there is only that value, so i want to retrieve the unique value in a string variable:
...
$query = "SELECT * FROM news WHERE contenuto LIKE :contenuto%";
$query_params = array(
':contenuto' => $_POST['contenuto']
);
try {
$stmt = $db->prepare($query);
$result = $stmt->execute($query_params);
}catch (PDOException $ex){
}
$row = $stmt->fetch();
$this = $row['contenuto'];
echo $this;
...
But this code doesn't work because nothing in showed by echo.. any help?
The % wildcard should be in the bound variable and not the prepared statement
$query = "SELECT * FROM news WHERE contenuto LIKE :contenuto";
$query_params = array(
':contenuto' => $_POST['contenuto'] . '%'
);
You're mixing bind parameters with literals. Try this on for size:
$query = "SELECT * FROM news WHERE contenuto LIKE CONCAT(:contenuto, '%')";
I am creating a class for connecting to my database but I keep getting an message saying my sql syntax has an error, when echoing the query i get SELECT id, username from :table where :row = :value and it seems fine with no errors.
<?php
class db{
protected $datab;
public function __construct($username, $password, $host, $dbname, $options){
try {
$this->datab = new PDO("mysql:host={$host};dbname={$dbname};charset=utf8", $username, $password, $options);
}
catch(PDOException $ex) {
die("Failed to connect to the database: " . $ex->getMessage());
}
$this->datab->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->datab->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
}
public function select($array, $table, $row, $value){
$query = "SELECT";
foreach($array as $val) {
if ($val === end($array)){
$query.= " ".$val;
}else{
$query.= " ".$val.",";
}
}
$query.=" FROM :table WHERE :row = :value";
$query_params = array(
':table' => $table,
':row' => $row,
':value' => $value
);
echo $query; // SELECT id, username from :table where :row = :value
try{
$stmt = $this->datab->prepare($query);
$result = $stmt->execute($query_params);
}
catch(PDOException $ex) {
die("Failed to run query: " . $ex->getMessage());
}
$row = $stmt->fetch();
return $row;
}
}
$kit = new db("root", "", "localhost", "kit", array(PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'));
$kit->select(array("id", "username"), "user", "username", "yusaf");
?>
Error message:
Failed to run query: SQLSTATE[42000]: Syntax error or access violation: 1064 You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near ''user' where 'username' = 'yusaf'' at line 1
EDIT
I got a downvote please comment why you have given me this.
I guess I should have mentioned this is only for learning purposes I'm not actually going to use this class in an application it's pointless.
You cannot use :table or :row as a substitution value, you have to know the name of the tables and columns.
SELECT id, username from :table where :row = :value
Should be
SELECT id, username from tablename where columnname = :value
This select() function of yours is utterly useless.
Look, you are trying to save yourself TWO words, FROM and WHERE. In exchange you are losing both flexibility and readability of SQL. Too much a price for a questionable syntax sugar. What if you need order by? join? complex where? Not to mention you are actually obfuscating plain and readable SQL. Having such a unction is a mere nonsense.
What it have to be:
public function getRow($query, $params){
$stmt = $this->datab->prepare($query);
return $stmt->execute($params)->fetch();
}
So it can be used as
$row = $kit->getRow("SELECT id, username FROM user WHERE username =?", array("yusaf"));
The substitution replaces :table and :row with quoted values, resulting in :
SELECT id, username FROM 'user' WHERE 'username' = 'yusaf'
when it should be
SELECT id, username FROM user WHERE username = 'yusaf'
Change this line :
$query.=" FROM :table WHERE :row = :value";
to :
$query.=" FROM `$table` WHERE `$row` = :value";
So I have two functions:
function display_name1($s){
global $db;
$query1 = "SELECT Taken From Alcohol where P_Key = $s";
$r = $db->prepare($query1);
$r->execute();
$result = $r->fetchColumn();
return $result;
}
function write_Recipe($s){
global $db;
$query1 = "SELECT Taken From Alcohol where Name = $s";
$r = $db->prepare($query1);
$r->execute();
$result = $r->fetchColumn();
return $result;
}
The only difference is that I'm matching the input "$s" with "P_Key" in the first example, and "Name" in the latter. When I put in a number for the first function, I get the appropriate return. When I put in a string that matches at least one "Name", I get nothing back. It seems to not be matches the strings for some reason. Any ideas?
There is a syntax error in the SQL query. You are missing the table name in the second query:
"SELECT Taken From where Name = '$s'"
Should be something like:
"SELECT Taken FROM `tablename` WHERE `Name` = '$s'"
Further note, that if you already using prepared statements, you should bind variables to the query instead of building the query using string concatination. Also the usage of global isn't perfect for an OOP design. Here comes an example how it can be done better:
// extend a class from PDO
class CustomPDO extends PDO {
public function display_name($s){
// use placeholder :p_key in query
$query1 = "SELECT Taken FROM `Alcohol` WHERE `P_Key` = :p_key";
$r = $this->prepare($query1);
// bind value to prepared statement
$r->execute(array(
':p_key' => $s
));
$result = $r->fetchColumn();
return $result;
}
public function write_recipe($s){
// use placeholder :name in query
$query1 = "SELECT Taken FROM `tablename` WHERE `Name` = :name";
// use $this as we are extended from PDO
$r = $this->prepare($query1);
// bind value to prepared statement
$r->execute(array(
':name' => $s
));
$result = $r->fetchColumn();
return $result;
}
}
Then use the class like a regular PDO object:
$db = new CustomPDO($connection_string, $user, $password);
But having two additional methods:
$result = $db->display_name('foo');
$result = $db->write_recipe('foo');
When querying on strings, you should surround a variable with quotes, like so:
"SELECT Taken From where Name = '$s'"
Also your second query is missing a table name.
"SELECT Taken FromTableNamewhere Name = '$s'"
Strings need to be quoted (and probably escaped if you haven't already). You seem to be using PDO, why not add a placeholder ? and execute execute(array($s)); instead, making PDO do the work for you?
function display_name1($s){
global $db;
$query1 = "SELECT Taken From Alcohol where P_Key = ?";
$r = $db->prepare($query1);
$r->execute(array($s));
$result = $r->fetchColumn();
return $result;
}
function write_Recipe($s){
global $db;
$query1 = "SELECT Taken From Alcohol where Name = ?";
$r = $db->prepare($query1);
$r->execute(array($s));
$result = $r->fetchColumn();
return $result;
}
Can I do a WHERE clause inside an IF statement?
Like I want something like this:
$SQL = mysql_query("SELECT * FROM `table` ORDER BY `row` DESC");
$rows = mysql_fetch_array($SQL);
$email = $_SESSION['email_of_user'];
if($rows["row"] == "1" WHERE `row`='$email' : ?> (Pulls the logged in user's email)
Edit Server
<?php else : ?>
Add Server
<?php endif; ?>
Do I need (" where the WHERE statement is? Because I tried that and it didn't seem to work...
Or can I do it with an if condition inside of a where clause? Not sure of all these terms yet so correct me if I'm wrong...
You cannot mix up a query statement with PHP's statement. Instead write a query extracting desired results and check if there are any rows from that query.
I will show you an example:
$query = "SELECT * FROM `TABLE_NAME` WHERE `field` = '1' && `email`='$email'"; //Create similar query
$result = mysqli_query($query, $link); //Query the server
if(mysqli_num_rows($result)) { //Check if there are rows
$authenticated = true; //if there is, set a boolean variable to denote the authentication
}
//Then do what you want
if($authenticated) {
echo "Edit Server";
} else {
echo "Add Server";
}
Since Aaron has shown such a effort to encourage safe code in my example. Here is how you can do this securely. PDO Library provides options to bind params to the query statement in the safe way. So, here is how to do it.
$dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass); //Create the connection
//Create the Query Statemetn
$sth = $dbh->prepare('SELECT * FROM `TABLE_NAME` WHERE field = :field AND email = :email');
//Binds Parameters in the safe way
$sth -> bindParam(':field', 1, PDO::PARAM_INT);
$sth -> bindParam(':email', $email, PDO::PARAM_STRING);
//Then Execute the statement
$sth->execute();
$result = $sth->fetchAll(); //This returns the result set as an associative array