Using PDO to avoid SQL injections - newbie - php

I'm trying to use PDO to avoid sql injections and have been looking and searching around for examples and this is what I've come up with, but there are some kind of error somewhere. The database is not getting updated and I get and sql error, but it wont print the details.
elseif (isset($_POST["bilnr"])) {
$name = $_POST['name']; $mobil = $_POST['mobil']; $bilnr = $_POST['bilnr']; $regnr = $_POST['regnr']; $userid = $_COOKIE[userid]; $username = $_COOKIE[user];
$sql=$oDB->Prepare("UPDATE members SET name=:name, mobil=:mobil, bilnr=:bilnr, regnr=:regnr WHERE id=:userid AND username=:username");
$sql->execute(array(':userid' => $userid);
if (!$sql) {
echo "\nPDO::errorInfo():\n";
print_r($oDB->errorInfo());
}
echo "<p class=\"red\">Informasjonen er oppdatert!</p>";
mysqli_close($con); }
If or when I remove the mysqli_close string something crashes and the page just turns blank with no errors. Also with the code above the updates being made in the form dont get into the database.
and the PDO connection in a separate file which is being included
$oDB=new PDO("mysql:host=$host;dbname=$db_name", $username, $password);
Here is the updated code
elseif (isset($_POST["bilnr"])) {
$name = $_POST['name']; $mobil = $_POST['mobil']; $bilnr = $_POST['bilnr']; $regnr = $_POST['regnr']; $userid = $_COOKIE[userid]; $username = $_COOKIE[user];
$sql=$oDB->Prepare("UPDATE members SET name=:name, mobil=:mobil, bilnr=:bilnr, regnr=:regnr WHERE id=:userid AND username=:username");
$sql->execute(array(':userid' => $userid,
':name' => $name,
':mobile' => $mobile,
':bilnr' => $billnr,
':regnr' => $regnr,
':username' => $username));
if (!$sql) {
echo "\nPDO::errorInfo():\n";
print_r($oDB->errorInfo());
}
echo "<p class=\"red\">Update Done!</p>";
mysqli_close($con); }
The next problem is to get the values into the database, as it is now I don't receive any errors so I'm not sure whats wrong.
UPDATE
It works, was just some typo's in the array variables :)

First, you can't mix mysqli and PDO. Second, the problem with your query is that you have 6 placeholders, but you're only filling in one of them when you call execute(). It should be:
$sql->execute(array(':userid' => $userid,
':name' => $name,
':mobile' => $mobile,
':bilnr' => $billnr,
':regnr' => $regnr,
':username' => $username));

The first argument for mysqli_query must be a string (representation of an SQL query) but you are passing it a PDO prepared query.
Don't mix and match multiple database libraries.
Use PDO or mysqli_.

You don't need mysqli_* functions anymore, scrap 'em (only when you're using PDO) :) When you're using PDO, mysql_* and mysqli_* don't work when combining them. I recommend you to use PDO and not mysql functions anymore. PDO is now well established and is the preferred way.
$sql = "
INSERT INTO table (name)
VALUES (:name)
";
//Here you prepare the SQL (you already did that correctly).
$stmt = $db->prepare($sql);
//You can choose to use bindParam, bindValue or include it in the array (as you do it).
$stmt->bindParam(':name', $name, PDO::PARAM_STR);
$name = 'John';
$stmt->execute();
This is an example how to insert something into a MySQL database with PDO.

Related

How to use prepared statement for updating table instead of unprepared form

update1: I tried all of the suggestion (much appreciated btw) but the execution still isn't going through displaying "Updated 0 rows ‌". I have tried multiple ways of approaching this but nothing seems to work for me.
Here is the code I have at the moment:
if(isset($_POST['Done'])) {
$updateCD = "UPDATE users SET lgs=?, its=?, hbs=?, bios=?, pls=?, cts=? WHERE email=?";
$stmt = $con->prepare($updateCD);
$stmt->bind_param('sssssss', $_POST['lgs'], $_POST['its'], $_POST['hbs'], $_POST['bios'], $_POST['pls'], $_POST['cts'], $_GET['email']);
$stmt->execute();
if ($stmt->errno) {
echo "FAILURE!!! " . $stmt->error;
}
else {
echo "Updated {$stmt->affected_rows} rows";
$stmt->close();
}
}
I am wanting to increase the security of my code by replacing my basic sqli queries with prepared statements.
This UPDATE statement concerns updating the user's profile information in the database. Problem is, despite the models I followed, the update execution isn't getting through thus changing nothing in the database.
PHP code:
$email_login = mysqli_real_escape_string($con, $GET['email']);
$lg = mysqli_real_escape_string($con, $_POST['lgs']);
$it = mysqli_real_escape_string($con, $_POST['its']);
$hb = mysqli_real_escape_string($con, $_POST['hbs']);
$bio = mysqli_real_escape_string($con, $_POST['bios']);
$pl = mysqli_real_escape_string($con, $_POST['pls']);
$ct = mysqli_real_escape_string($con, $_POST['cts']);
if(isset($_POST['Done'])) {
$updateCD = "UPDATE users SET lgs=?, its=?, hbs=?, bios=?, pls=?, cts=? WHERE email=?";
$stmt = $con->prepare($updateCD);
$stmt->bind_param('sssssss', $lg, $it, $hb, $bio, $pl, $ct, $email_login);
$stmt->execute();
if ($stmt->errno) {
echo "FAILURE!!! " . $stmt->error;
}
else {
echo "Updated {$stmt->affected_rows} rows";
$stmt->close();
}
}
Note after closure: I understand why it may seem as if this question is similar to the other one, but by no means is it an exact duplicate. The referred question concerned updating a table in general whereas this question magnifies on using prepared statements to execute an update. I already know how to update a table without using prepared statements so I would like to improve my code syntax with a more reliable frameset. Although both questions are related, they have different scopes.
Your $email_login variable is empty; even if it's obtained via GET, you have to use $_GET, and not $GET.
As said in various comments, don't use mysqli_real_escape_string, since reliable escaping is done by MySQLi itself. Just pass in the $_POST variables directly as arguments for bind_param.
Some additional ideas:
Learn about prepared statements: http://php.net/manual/en/pdo.prepared-statements.php
Learn about the superglobals: http://www.w3schools.com/php/php_superglobals.asp
Consider using PDO instead of MySQLi: mysqli or PDO - what are the pros and cons?, http://www.quora.com/As-a-PHP-beginner-should-I-learn-MySQLI-or-PDO-first

Insert a lot of record using single arguments and using bindParam

I have some method to insert some data into a database like this:
public function register($username, $email, $hashedPassword, $activationCode)
{
try {
$conn = Database::getConnection();
// Connect and create the PDO object
$conn->exec('SET CHARACTER SET utf8'); // Sets encoding UTF-8
// Define and prepare an INSERT statement
$sql = 'INSERT INTO users (username, email, pass, reset_token, dateAdded )
VALUES (:username, :pass, :email, :token, now())';
$sqlprep = $conn->prepare($sql);
// Adds value with bindParam
$sqlprep->bindParam(':username', $username, PDO::PARAM_STR);
$sqlprep->bindParam(':email', $email, PDO::PARAM_STR);
$sqlprep->bindParam(':pass', $hashedPassword);
$sqlprep->bindParam(':token', $activationCode);
// If the query is successfully executed, output the value of the last insert id
if ($sqlprep->execute()) {
//echo 'Succesfully added the row with id='. $conn->lastInsertId();
$this->result = true;
}
$conn = null; // Disconnect
} catch (PDOException $e) {
include('../views/error.php');
include('../views/admin/includes/footer.php');
exit();
}
}
The problem is I think it's not a good method if I have so many arguments for my function to enter into a database. So is it any good way I can enter a lot of fields just by using 1 parameter but still using bindParam? Since I see a lot of examples is only using prepare without bindParam. I think I can use an array, but I don't know the proper way to do it. So I need some help how I can do it.
since you want keep your bindparam i suggest you use input like this:
$input = array('username' => $username, 'activationHash' => $activationHash);
and in your bindParam add a code like this:
public function register($input){
//code
$sqlprep->bindParam(':username', $input['username'], PDO::PARAM_STR);
//other
}
hope this will solve your problem
https://stackoverflow.com/a/10060755/1747411
Check second example, you have to repeat values with binds
e.g
VALUES (:username1, :pass1, :email1, :token1, now()), (:username2, :pass2, :email2, :token2, now())
and bindParam with loop
You can insert the params as an array into $sqlprep->execute($param_array)
Or, simply passing each param into an array inside execute, like this: $sqlprep->execute(array($param1, $param2))
Update:
Pass values into $input as an array:
$input = array('username' => $username, 'activationHash' => $activationHash); //and so on
Now on the model side,
You can bind these values to params using foreach loop like this:
foreach ($values as $key => $value) {
$sqlprep->bindParam(':' . $key, $value , PDO::PARAM_STR);
}

Empty Array when executing the SQL statement using PDO

I am am following a tutorial for MVC and I am stuck in a position where I can't go further.
The problem is that when I am executing the SQL Statement, I am trying to get the value and just print it/echo it.
I have a function where I am achieving it. Here's the code for it :
NOTE : I am using filter_input() method to get the $_POST(['login']) and $_POST(['password']). For some reason, I can't directly use $_POST() method because it giving me a warning for don't access superglobal $_POST directly.
I am not sure what exactly is the issue here. I am getting zero for this and I actually have one entry in the database.
public function run(){
$login = filter_input(INPUT_POST, 'login');
$password = filter_input(INPUT_POST, 'password');
$sth = $this->db->prepare("SELECT id FROM users WHERE
login = :login AND password = MD5(:password)");
$sth->execute(array(
':login' => $login,
':password' => $password
));
$data = $sth->fetchAll();
print_r($data);
/*$count = $sth->rowCount();
print_r($count);
if($count>0){
echo 'Have a record.';
}else{
echo 'No Record found.';
}*/
}
If someone can help me find the issue, I will really appreciate it.
Straight from manual,
PDOStatement::rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement executed by the corresponding PDOStatement object.
After update: Try below,
$sth = $this->db->prepare("SELECT id FROM users WHERE
login = :login AND password = :password");
$sth->execute(array(
':login' => $login,
':password' => md5($password)
));
$data = $sth->fetchAll();

PHP MySQL UPDATE statement not working

I have a MySQL database with a table (opendpu) that has multiple columns including columns titled "ECRNUM" and "PE_REQUIRED".
I'm simply trying to test this update statement by specifying some values. I get this error:
Array ( [0] => 42000 [1] => 1064 [2] => 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 'DOE WHERE ECRNUM = 81308' at
line 1 )
I cannot, for the life of me, figure out what is wrong here. Can anyone help?
<?php
require ('config.php');
$ecrno = '81308';
$pe_required = 'JOHN DOE';
while (true) {
try {
$db = new PDO($dsn, $uname, $pword);
$db->exec( "SET CHARACTER SET utf8" );
$db->setAttribute( PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC );
$db->setAttribute( PDO::ATTR_PERSISTENT, true );
break;
}
catch (Exception $e) {
$db = null;
$counter++;
if ($counter == $limit)
throw $e;
}
}
$stmt = $db->prepare("UPDATE opendpu SET PE_REQUIRED = $pe_required WHERE ECRNUM = $ecrno");
$stmt->execute() or die(print_r($stmt->errorInfo(), true));
?>
.
+1 for using prepared statements... but (and its a big BUT):
You should never use prepared statements without bind_param as this leaves you wide open to SQL injection and negates the benefits of prepared statements.
$stmt = $db->prepare("UPDATE opendpu SET PE_REQUIRED=? WHERE ECRNUM=?");
$stmt->bind_param('si', $pe_required, $ecrno);
$stmt->execute() or die(print_r($stmt->errorInfo(), true));
Change your syntax like this [Enclosed quotes around the variable]
$stmt = $db->prepare("UPDATE `opendpu` SET PE_REQUIRED = '$pe_required' WHERE ECRNUM = '$ecrno'");
Please check with below query
$stmt = $db->prepare("UPDATE opendpu SET PE_REQUIRED = '.$pe_required.' WHERE ECRNUM = '.$ecrno.'");

php - mysql avoid sql injections

I have many functions like
updateUser($id,$username,$email)
updateMusic($id, $music)
etc...
Is there a generic function to avoid SQL injections ?
I just want to avoid using mysql_real_escape_string for each parameter I have
$username = mysql_real_escape_string($username);
$email= mysql_real_escape_string($email);
$music= mysql_real_escape_string($music);
ALWAYS use prepared statements
Do NOT use mysql driver, use mysqli or PDO
You should use parameterization and let the database driver handle it for you, i.e. with PDO:
$dbh = new PDO('mysql:dbname=testdb;host=127.0.0.1', $user, $password);
$stmt = $dbh->prepare('INSERT INTO REGISTRY (name, value) VALUES (:name, :value)');
$stmt->bindParam(':name', $name);
$stmt->bindParam(':value', $value);
// insert one row
$name = 'one';
$value = 1;
$stmt->execute();
Code from Bobby-Tables.
you may use,
list($id,$music) = array_map('mysql_real_escape_string',array($id,$music))
but prepared statements rocks
No there isn't, but you can parse all your inputs ( eg. GET and POST ) at beggining of the script

Categories