I am trying to achieve secure queries using prepared statements:
if (!($stmt = $db->prepare($q['query1']))) {
myException("Prepare failed: (" . $db->errno . ") " . $db->error);
} else if (!$stmt->bind_param("si", $variable1, $variable2)) {
myException("Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error);
} else if (!$stmt->execute() || !$stmt->store_result()) {
myException("Execute failed: (" . $stmt->errno . ") " . $stmt->error);
} else {
(...)
Is it the best way to do this? This code is unreadable. Can I use something like try catch block instead of if/else if? Will it work well?
As You suppose, this would be much clearer:
try {
$stmt = $db->prepare($q['query1']);
$stmt->bind_param("si", $variable1, $variable2);
$stmt->bind_param("is", $variable3, $variable4);
if($stmt->execute()) {
$stmt->store_result();
$stmt->bind_result($result);
$stmt->close();
} else {
throw new Exception("error");
}
} catch (\Exception $e) {
echo $e->getMessage();
}
[code has been edited due to OP request]
try {
$stmt = $db->prepare($q['query']);
$stmt->bind_param("s", $s);
$stmt->execute();
$stmt->store_result();
$stmt->bind_result($result);
if ($stmt->fetch()) {
$stmt->close();
return $result;
}
else
throw new Exception("error");
} catch (Exception $e) {
myExceptionHandler($e);
}
Will you accept that code? :)
Related
Having another PHP issue that's probably something simple, but I'd really appreciate any help!
My function does a mysqli count but the $count parameter it gets bound to is not changed, even though the sql runs fine and there are no errors.
The function:
function itemsCount ($conn, $list_id) {
$count = 0;
if (!($stmt = $conn->prepare("SELECT count(uid) FROM collection.user_list_item WHERE list_id = ?"))) {
echo "Prepare failed: " . $mysqli->error;
}
if (!($stmt->bind_param('i', $list_id))) {
echo "Bind failed: " . $stmt->error;
}
if (!($stmt->execute())) {
echo "Execute failed: " . $stmt->error;
}
if (!($stmt->bind_result($count))) {
echo "Bind failed: " . $stmt->error;
}
echo $count;
$stmt->close();
return $count;
}
And the call:
public function doAdd ($conn, $list_id, $item_id) {
if ($this->itemsCount($conn, $list_id) < 20) {
...do stuff ...
}
}
Sorry the code isn't very nice, but please help point me in the right direction!
var_dump the $list_id, the param bind i, expect a integer. I expect your var to be a string which you can see with the var_dump. Either cast the string to int, or use a different param bind.
EDITED CODEI have a mysqli line of code: $stmt->bind_param("ss", $_POST['skills'], $_POST['city']); in a working query.
I've found the need to change to PDO and have used:$stmt->bindValue(':skill', $skills, PDO::PARAM_STR);
$stmt->bindValue(':city', $city, PDO::PARAM_STR);
I get no results except the echoed "No result found. Did you enter a city?" nor error messages although there is a connection to the db as evidenced in the search form in which the select list of 'city' is loaded. The full query:
try {
global $pdo;
if(isset($_POST['search'])) {
$skills = htmlspecialchars($_POST['skills']);
$city = htmlspecialchars($_POST['city']);
$stmt = $pdo->prepare('SELECT skill.skill_name, team.city FROM skill JOIN team ON skill.skill_id=team.skill WHERE skill.skill_name LIKE :skills AND team.city LIKE :city');
$skills = "%".$skills."%";
$city = "%".$city."%";
$stmt->bindParam(':skills', $skills, PDO::PARAM_STR);
$stmt->bindParam(':city', $city, PDO::PARAM_STR);
$stmt->execute();
if ($stmt->rowCount() > 0){
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
foreach ($rows as $row) {
echo $row['skill'] . " is available in " . $row['city'];
}
}
else {
echo "No result found. Did you enter a city?";
}
}
}//try
catch(PDOException $e) {
echo "Error: " . $e->getMessage();
}
Thanks.
If you really need to use LIKE then you need a wildcard somewhere in the string. As a placeholder has to represent a complete data literal, and if you want to use LIKE you have to create the parameter with the wildcards included like this.
try {
global $pdo;
if(isset($_POST['search'])) {
$skills = '%' . htmlspecialchars($_POST['skills']) . '%';
$city = '%' . htmlspecialchars($_POST['city']) . '%';
$stmt = $pdo->prepare('SELECT skill.skill_name, team.city
FROM skill
JOIN team ON skill.skill_id=team.skill
WHERE skill.skill_name LIKE :skill
AND team.city LIKE :city');
$stmt->bindValue(':skill', $skills, PDO::PARAM_STR);
$stmt->bindValue(':city', $city, PDO::PARAM_STR);
$stmt->execute();
if ($stmt->rowCount() > 0){
$rows = $stmt->fetchAll();
foreach ($rows as $row) {
echo $row['skill_name'] . " is available in " . $row['city'];
}
}else{
echo "No result found. Did you enter a city?";
}
}
}
catch(PDOException $e) {
echo "Error: " . $e->getMessage();
}
A minor edit by ML: Corrected $row['skill'] to $row['skill_name']
I have the following scenario:
In my .db.inc.php file I'm connecting to a database:
try {
$dbh = new PDO('mysql:host=' . HOST . ';dbname=' . DATABASE , USER_DB, PASSWORD_DB);
}
catch (PDOException $e) {
die('Error!: ' . $e->getMessage() . '<br/>');
}
Then I run some functions before I need the connection, but I know that the connection is established as I don't have an error thrown.
Now I need to update my database:
include('.db.inc.php');
try {
/...
$sql = "UPDATE de_request_products SET report_id = :report_id WHERE request_id = :request_id";
$stmt = $dbh->prepare($sql);
$stmt->bindValue(':report_id', $report_number, PDO::PARAM_STR);
$stmt->bindValue(':request_id', $report_request_number, PDO::PARAM_STR);
$stmt->execute();
}
catch (PDOException $e){
die('Error!: ' . $e->getMessage() . '<br/>');
}
If above written try block fails, I want to have a try catch block in the Exception Handler to update the database:
// ....
catch (PDOException $e){
try {
//SEND EMAIL AND
$sql = "INSERT INTO de_failed_requests (datum, reason) VALUES (:datum, :reason)";
$stmt = $dbh->prepare($sql);
$stmt->bindValue(':datum', $date, PDO::PARAM_STR);
$stmt->bindValue(':reason', $e->getMessage(), PDO::PARAM_STR);
$stmt->execute();
} catch (PDOException $f) {
die('NOTHING WORKS AT ALL!'. $f->getMessage());
}
die('Error!: ' . $e->getMessage() . '<br/>');
}
Would this be the way to go or is there a more efficient way?
I got this query and it's not inserting into the database but it's not giving an error either.
try {
$sth = $Db->dbh->prepare("INSERT INTO users (username,password,email,phone,first_name) VALUES (:username,:password,:email,:phone,:firstname)");
$sth->execute(array(':username' => $username,':password' => $password, ':email' => $email,':phone' => $phone,':firstname'=>$firstname));
} catch(Exception $e) {
echo $e->getMessage();
exit();
}
I've tried inserting the query by command and it works fine. There are other insert queries on the site and those work fine too.. I'm not sure what I'm doing wrong here
Can you try something like this?
try
{
// Prepare Statement
if (!($stmt = $mysqli->prepare("INSERT INTO users (username,password,email,phone,first_name) VALUES (?,?,?,?,?)")))
throw new Exception("Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error);
// Bind Parms
if (!$stmt->bind_param("sssss", $username, $password, $email, $phone, $firstname))
throw new Exception("Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error);
// Execute Statement
if (!$stmt->execute())
throw new Exception("Execute failed: (" . $stmt->errno . ") " . $stmt->error);
}
catch (Exception $ex) {
exit('Error: '. $ex->getMessage());
}
P.S. As TiiJ7 suggestion on the comment to your question, are those two columns perm and rank - are they nullable columns? if not, you might have to specify a value at the time of row insertion.
More info here: http://php.net/manual/en/mysqli.quickstart.prepared-statements.php
The problem I am having is on occasion (1 of every 8 or so) insertions to the database, the string value of (fileLocation) will be incomplete. so for example..
what should be "filecomplete.mp4" will be inserted as "filecomple".
Has anyone experienced this before or have any ideas as to what the problem could be?
Here is my insert statement.
public function addNewGame($gameID, $receiverID, $senderID, $gameTrack, $fileLocation){
$this->gameid = $gameID;
$this->receiverid = $receiverID;
$this->senderid = $senderID;
$this->gameTrack = $gameTrack;
$this->filelocation = $fileLocation;
$SQUERY = "SELECT GameId FROM ActiveGames WHERE GameId = :gameid";
try{
$stamt = $this->connection->prepare($SQUERY);
if ($stamt === false) {
throw new Exception($this->connection->error);
}
$stamt->bindValue(':gameid', $this->gameid, PDO::PARAM_INT);
$stamt->execute();
$result = $stamt->fetchAll();
$resultCount = count($result);
if($resultCount > 0){
echo "existing record";
} else{
$QUERY = "INSERT INTO ActiveGames (GameId,
ReceiverId,
SenderId,
GameTrack,
FileLocation)
VALUES (
:gameid,
:receiverid,
:senderid,
:gametrack,
:filelocation)";
try{
$stmt = $this->connection->prepare($QUERY);
if ($stmt === false) {
throw new Exception($this->connection->error);
}
$stmt->bindValue(':gameid', $this->gameid, PDO::PARAM_INT);
$stmt->bindValue(':receiverid', $this->receiverid, PDO::PARAM_INT);
$stmt->bindValue(':senderid', $this->senderid, PDO::PARAM_INT);
$stmt->bindValue(':gametrack', $this->gameTrack, PDO::PARAM_STR);
$stmt->bindValue(':filelocation', $this->filelocation, PDO::PARAM_STR);
$stmt->execute();
}
catch(PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
}
}
catch(PDOException $e){
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
}