PHP PDO workflow - php

I've been using PDO for quite some while now, but I'm wondering whether I'm checking for errors too much or not enough. This is how my stuff generally looks:
$STH = $DBH->prepare("SELECT something FROM table WHERE field=:field AND field2=:field2");
$STH->bindParam(":field",$field);
$STH->bindParam(":field2",$field2);
if($STH->execute()){
if($STH->rowCount() == 1){
echo "This is what is returned";
}else{
echo "Something went wrong.";
}
}else{
echo "Something went wrong.";
}
Of course the $STH->rowCount()-check depends on what I'm expecting. For example when a user logs in, only one result can be found with that username. Now of course this is already checked in the database, yet I double check it here again. Is this necesary?
Also the if(STH->execute())-check I'm not sure if it's really necessary. What are the best practices?

According to the documentation 'http://php.net/pdostatement.rowcount' it's a bad practice to use rowcount with SELECT statements because many databases can not return the number of rows affected by a SELECT statement. For checking user it's better to use:
Select count(*) ..... and PDOStatement:execute + PDOStatement:fetchColumn.
Also keep in mind (STH->execute() doesn't check anything it only says that your query is executed without errors.

Related

Issue with PHP and Mysql

Good evening everyone, I'm having issues with my below code, Variable $uname is declared from a http post but for some reason the print out the the err log stays blank where it should show the results of the MySQL query
Field in table is called firstname (no caps)
$da= mysqli_query($c,
"SELECT * FROM users WHERE username='".$uname."'") or die(mysqli_error($c));
while ($row = mysqli_fetch_assoc($da)) {
error_log("User $Uname: match.");
error_log("FN : ".$row['firstname']."");
}
Any ideas ?
Add a message to tell you if no results were found by the query.
Since there can be only one user with a given username (I assume), you don't need a while loop. Just fetch that one row.
$row = mysqli_fetch_assoc($da));
if ($row) {
error_log("User $uname: match.");
error_log("FN : ".$row['firstname']."");
} else {
error_log("User $uname: no match.");
}
You also had a typo in your echo statement, $Uname should have been $uname.
First of all use a prepared statement: for security reasons you should never trust user inputs, prepared statements do the escaping for you.
Other than that I only see two reasons why nothing is logged:
error reporting is turned off ( this seems unlikely since you expect to see something in there)
the query is returning an empty result set and the while loop is skipped
try to print $uname or the full query and execute it

Insert multiple checkbox answers into database

I have a checkbox list and I want to insert each item checked into the database. Since it is a checkbox, I only have one value to pass to the database, but I am also passing a variable (primary key) grabbed from a previous database insertion.
My problem is that I can't get it to post to the database. I have tried multiple ways to do this through posts here and nothing seems to work. I am at a loss. I am also fairly new to PHP and mysqli, so I am sure there are better ways to do what I am trying to do, so please help me out.
The table consists of three columns (school_id, graduate_id, schoolName). The school_id is the AI primary key and graduate_id will be populated with the variable $graduateID grabbed from the previous query.
Here is what I have:
if (isset($_POST['school'])) {
$school=$_POST['school'];
$schoolQuery="";
foreach($school as $value) {
if(!$schoolQuery) {
$schoolQuery="INSERT INTO schoolReunion (graduate_id, schoolName) VALUES ($graduateID, '$value')";
} else {
$schoolQuery .= ", ($graduateID, '$value')";
mysqli_store_result($schoolQuery);
}
}
$schoolQuery .=";";
if (mysqli_multi_query ($schoolQuery)) {
echo "Files have been updated successfully.";
} else {
echo "Error: " . $schoolQuery . "<br/>" . mysqli_error($dbc);
}
}
When the error code prints out, it looks fine, but it just won't post anything and gives me no errors. Can you help me?
#Maximus & #Eko Junaidi Salam, while you may be right, I don't see any evidence that there are issues with the front-end/form.
#jeroen, you are totally correct.
CarR is dealing with a single concatenated query, so mysqli_query is suitable.
I recommend wrapping the user-supplied variable in mysqli_real_escape_string() to cover the query vulnerability.
mysqli_store_result() is to be used on queries that return a result set; mysqli_affected_rows() is the function that yields a measure of success with INSERT/UPDATE/DELETE type queries.
Lastly, you are right to correct MrTechie. I don't think he realized the query concatenation.
Assuming the form is delivering the necessary values, I'll suggest a new query build section:
$schoolQuery="";
foreach($school as $value){
if(!$schoolQuery) {
$schoolQuery="INSERT INTO schoolReunion (graduate_id,schoolName) VALUES ";
}else{
$schoolQuery.=",";
}
$schoolQuery.="('$graduateID','".mysqli_real_escape_string($dbc,$value)."')";
}
$schoolQuery.=";";
$graduateID IS NOT escaped because I am assuming it comes from a safe place; $value IS escaped because it comes from user input.
Now to deliver the built query. Your code has syntax and logic errors, so try this:
if($schoolResult=mysqli_query($dbc,$schoolQuery)){
$total_rows=mysqli_affected_rows($dbc);
echo $total_rows," file",($total_rows!=1?"s have":" has")," been added.";
// if($total_rows<1){echo "Query Logic Error, # $schoolQuery";}
}else{
// echo "Query Syntax Error # $schoolQuery<br>".mysqli_error($dbc);
}
Uncomment the error lines while you are testing, then re-comment or delete for production.
This should sufficiently fix all the issues that are apparent in your snippet of code. Beyond that are the assumed issues...
Since you mention that you are employing a previous query to declare $graduateID, I will assume you have acquired the value via a SELECT query. Be sure to check that you have used
mysqli_free_result($graduateResult); // I assumed this variable name
to avoid any conflicts with subsequent queries. This is sometimes overlooked.
mysqli_multi_query() is best used when you are dealing with queries that are dependent on a prerequisite query. It seems your $schoolQuery is dependent on the success of what I will call "$graduateQuery". If you wish, you could use mysqli_multi_query() to run $graduateQuery then $schoolQuery. To help you with this implementation, I would need to see more of your code. If you wish to go down that road, it might be best to message me directly or start a new post (after you've had a try at it yourself.) Here is half of your job done: Strict Standards: mysqli_next_result() error with mysqli_multi_query

When to provide error control for mysqli queries (PHP)

Okay, so I have some code here:
<?php
$rt = 'abc'; $imdb = 'defg';
if ($con = mysqli_connect($a,$b,$c,$d)) {
if (mysqli_query($con,"DELETE FROM blah WHERE a = '{$imdb}'")){
echo 'Deleted!';
if (mysqli_query($con, "INSERT INTO foo (c,d) VALUES ('{$rt}','{$imdb}')")){
echo 'Inserted after deletion!'
if (mysqli_query(...)) {
if (mysqli_query(....)) {
}
}
}
}
}
Some of my programs have many queries in a row, each of which is dependent on the result of a previous query. However, creating error handling for every single query and making sure that the logic of the code stays the same (not to mention staying readable) throughout can be a somewhat tedious and error prone process.
I would like to know a bit more about what is going on behind the scenes when a query is sent, because it would help me a lot with some of my questions. Namely, is it really necessary to write if (mysqli_query()) all the time for correct error handling, or is simply checking if the so-called 'master' connection exists enough?
That is, after I check mysqli_connect(), do I have to check every subsequent query within that connection to see if it went through (connection-wise, not logic-wise), or is it simply enough to check mysqli_connect() once, at the beginning of the program? It would sure make things a lot easier.
Also, while I'm looking at mysqli_multi_query() for more practical query management, I would prefer not to use it until I can fully understand the simpler query functions.
Thanks for your help!
Only few things for you to get it right
You have to distinguish an error from a query result. If your query depends on the result of the another one - it's all right to check the result. But if you want to check for the error - there are better ways.
In a properly written application a query error is a highly exceptional event, and there shouldn't be code written to handle it in place. It have to be done somewhere else.
mysqli can throw an exception in case of error, which is actually a Holy Grail you are looking for.
So, if you want to stop your code if one of queries failed, just set mysqli in exception mode and then pile your queries one after another.
<?php
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
$con = mysqli_connect($a,$b,$c,$d);
$rt = 'abc'; $imdb = 'defg';
mysqli_query($con,"DELETE FROM ...");
mysqli_query($con, "INSERT INTO ...");
mysqli_query(...);
mysqli_query(...);
...
And two additional notes
if you want to undo a previous query if following one failed, then use transactions
you should NEVER write a query like you do, interpolating a variable directly into it. You ought to use prepared statements, substituting every variable with placeholder in the query.

Update query running but not updating table php

Here's the code i am using withing a for loop which run 10 times:
$query = "UPDATE fblikes SET likes = '$var[$i]' WHERE link = '$web[$i]'";
if(mysql_query($query))
{
echo $query;
}
else
{
echo mysql_error();
}
The code runs, I do get ok! printed 10 times but nothing happens in the table. I also checked the 2 arrays i.e. $var and $web, they contain the correct values.
The query looks okay to me. Here's what i got (one of the 10 outputs) : UPDATE fblikes SET likes = '5' WHERE link = 'xxxxxxx.com/xxxx/iet.php';
I don't know what the problem exactly is, and to figure out you should print the value of $query, and show us what you get. More, please tell us the value of mysql_affected_rows() after the call to mysql_query().
However, your code implements some wrong patterns.
First of all, you are not escaping $var[$i] and $web[$i] with two potential effects:
You can produce wrong queries
You don't sanitize the input to the database, thus exposing your application to security issues
Moreover, you perform several similar queries that differ only on the inputs provided.
The solution, for both issues, is the use of prepared statements that will give you more control, security and performance. Consider abandoning mysql_* functions and switching to mysqli_* or PDO, and read about prepared statements.

please check validation

i am inserting day value to database,i want validation like if the day already exist it should say day already exist else it should innsert..please can anyone check the following code... thanks in advance
$dexist=$_POST['ext'];
$res=mysql_query("select Day from mess where Day='".$dexist."' ");
while($row=mysql_fetch_array($res))
{
$dy=$row['Day'];
}
if($dy==$dexist)
{
echo "<script language=\"javascript\">";
echo "window.alert ('File already exist');";
echo "//--></script>";
}
else
{
mysql_query("insert into mess (Date,Day,Breakfast,StartTimeb,EndTimeb,Lunch,StartTimel,EndTimel,Dinner,StartTimed,EndTimed) values('".$date."','".$day."','".$bre."','".$bres."','".$bree."','".$lun."','".$luns."','".$lune."','".$dinn."','".$dins."','".$dine."')");
}
Your script screams "SQL INJECTION!" Please pwn my site!
Also: your code is vulnerable to synchronization issues. For example, a file might be created AFTER you ran a select statement, but BEFORE you ran the INSERT statement. This will cause weird failures. That's why you should do the "select and insert" as a single stored proc (read up on atomic operations - more specifically, this is an instance of a "compare and swap").
Firstly never, ever pass unchecked POST/GET data into a MySQL query, it's a massive security hole. Use mysql_real_escape_string instead:
$res=mysql_query("select Day from mess where Day='" . mysql_real_escape_string($dexist) . "' ");
And similar for the latter call.
Secondly, it's not clear what you're asking... please tell us if the code is not working somewhere, and any errors you're getting. I think you have a problem with this line:
if(file_exists($dy==$dexist))
That is passing a boolean value ($dy==$dexist will evaluate to true or false) into the file_exists function. You need to pass the filename in.
Don't do that in PHP, it's difficult (impossible?) to do safely. Do it in MySQL by adding a unique index on the Day column:
ALTER TABLE mess ADD UNIQUE (Day);
You can then catch failures of that kind by looking for ER_DUP_UNIQUE from MySQL.
Use PHP's mysql_errno to check for error 1169 to catch unique constraint failure.
$query_result = mysql_query("insert into mess (Date,Day,Breakfast,StartTimeb,EndTimeb,Lunch,StartTimel,EndTimel,Dinner,StartTimed,EndTimed) values('".$date."','".$day."','".$bre."','".$bres."','".$bree."','".$lun."','".$luns."','".$lune."','".$dinn."','".$dins."','".$dine."')");
// 1169 means a unique constraint failure
if (!$query_result && mysql_errno() == 1169) {
echo "Oh noes, you tried to insert a value twice!";
}
This is a repost of your question.
searching for the original..
found it..
Want to check day already exist

Categories