What the difference between bindParam and execute(array)? - php

$stmt = $this->_db->prepare("SELECT userid FROM users WHERE login = ? AND md5pass = ?");
#$stmt->bindParam(1, $login, PDO::PARAM_INT);
#$stmt->bindParam(2, $pass, PDO::PARAM_STR);
$stmt->execute(array($login,$pass));
$res = $stmt->fetch(PDO::FETCH_NUM);
Which way is better to transfer variables to prepeared statment bindParam or execute(array)? Both working but what is differense? Only PDO::PARAM checking? For SELECT I think array would be enough and for INSERT I sould use the bindParam. Am I right? Thanks to all. Just learning =)

With bindParam you can add the datatype and also important with bind param you are binding the variables by reference.

Related

pdo update statement using variable as table name

the pdo update statement below doesn't work due the table name ties to a variable. Does anyone know how to make it work?
$stmt1 = $DB_CON_C->prepare('UPDATE `".$account_list."`
SET property_type=:property_type; property_address=:property_address, property_city=:property_city, property_state=:property_state, property_zip=:property_zip WHERE contract_number=:order_list');
$stmt1->bindParam(':account_list', $account_list, PDO::PARAM_STR);
$stmt1->bindParam(':order_list', $order_list, PDO::PARAM_STR);
$stmt1->bindParam(':property_class', $property_class, PDO::PARAM_STR);
$stmt1->bindParam(':property_type', $property_type, PDO::PARAM_STR);
$stmt1->bindParam(':property_address', $property_address, PDO::PARAM_STR);
$stmt1->bindParam(':property_city', $property_city, PDO::PARAM_STR);
$stmt1->bindParam(':property_state', $property_state, PDO::PARAM_STR);
$stmt1->bindParam(':property_zip', $property_zip, PDO::PARAM_STR);
$stmt1->execute();
You will have to user single quotes in stead of double:
$stmt1 = $DB_CON_C->prepare('UPDATE `' .$account_list. '`
SET property_type=:property_type; property_address=:property_address, property_city=:property_city, property_state=:property_state, property_zip=:property_zip WHERE contract_number=:order_list');
Or, just simplify, and do:
->prepare("UPDATE {$account_list} SET...
Ie, use double quotes. The {} isn't needed, but I prefer using them because I personally use this as a prefix to the actual table name (so ("SELECT * FROM {$dbprefix}tablename"))
This way you do not need to concoct strings inside the query, which you shouldn't need to do. Just wrap the query in double quotes instead.

Which is better and secure method of writing PDO statements?

Ok so I am in a confusion here. I have seen multiple queries like these.
Query 1
$stmt = "SELECT * FROM tablename WHERE user = :user";
$stmt = $pdo->prepare($stmt);
$stmt-> bindValue(':user', $user);
$stmt-> execute();
Query 2
$stmt = $pdo->prepare("SELECT * FROM tablename WHERE user = :user");
$stmt-> execute(['user' => $user]);
So, I want to know which of the above queries are most efficient and preferred while coding? Or is there any other better way than these to code in PDO?
It is not bindParam/bindValue that makes your query safe but :user thing that is called parameter or placeholder. As long as you have all variables in your query substituted with parameters, your query is 100% safe.
So you can tell that the second option is as safe as the fiirst one, though being more concise. Personally, I'd prefer positional placeholders that makes even more concise code:
$stmt = $pdo->prepare("SELECT * FROM tablename WHERE user = ?");
$stmt-> execute([$user]);
but all there variants are equally safe and only a matter of taste.

Which PDO bind approach should be used for greater security?

I know of two ways to use PDO in PHP to update a MySQL database record. Please could someone explain which one I should use for better security and the difference and I am a little confused.
Method One:
$user = "root";
$pass = "";
$dbh = new PDO('mysql:host=somehost;dbname=somedb', $user, $pass);
$sql = "UPDATE coupons SET
coupon_code = :coupon_code,
valid_from = :valid_from,
valid_to = :valid_to,
discount_percentage = :discount_percentage,
discount_amount = :discount_amount,
calculationType = :calculationType,
limit = :limit
WHERE coupon_code = :coupon";
$stmt = $dbh->prepare($sql);
$stmt->bindParam(':coupon_code', $_POST['coupon_code'], PDO::PARAM_STR);
$stmt->bindParam(':valid_from', $_POST['$valid_from'], PDO::PARAM_STR);
$stmt->bindParam(':valid_to', $_POST['valid_to'], PDO::PARAM_STR);
$stmt->bindParam(':discount_percentage', $_POST['discount_percentage'], PDO::PARAM_STR);
$stmt->bindParam(':discount_amount', $_POST['discount_amount'], PDO::PARAM_STR);
$stmt->bindParam(':calculationType', $_POST['calculationType'], PDO::PARAM_STR);
$stmt->bindParam(':limit', $_POST['limit'], PDO::PARAM_STR);
$stmt->bindParam(':coupon', $_POST['coupon_code'], PDO::PARAM_STR);
$stmt->execute();
Method Two:
$dbtype="somedbtype";
$dbhost="somehost";
$dbname="somedb";
$dbuser="someuser";
$dbpass= "somepass";
$conn = new PDO("mysql:host=$dbhost;dbname=$dbname",$dbuser,$dbpass);
$title = 'PHP Pattern';
$author = 'Imanda';
$id = 3;
$sql = "UPDATE books
SET title=?, author=?
WHERE id=?";
$q = $conn->prepare($sql);
$q->execute(array($title,$author,$id));
From what I can see, method two does not bind the data, rather insert it directly into the query as an array type. Does this make the script more susceptible to SQL injection or other security risks?
The only difference between the two is that if you pass the array in to the execute function rather than calling bindParam yourself, it treats all parameters as PDO::PARAM_STR automatically, whereas in calling bindParam yourself you could bind them as integers, etc.
From the docs:
input_parameters
An array of values with as many elements as there are bound parameters in the SQL statement being executed. All values are treated as PDO::PARAM_STR.
You can also see from the examples there that you can use named parameters (e.g. :limit) when passing the array into the execute function. You don't have to just put ?. In that case you give the array a key:
$sth->execute(array(':calories' => $calories, ':colour' => $colour));
It's mostly a matter of preference. Both protect you from injection.
Though I think it's much easier to force data type with bind(), where as using execute(array()) will be using strings.

PDO execute with array returns null

I'm trying to use good PDO as always and almost everything works but one query:
$primary = 'my_id';
$table = 'my_table';
// This or...
$statement = $this->conn->prepare("SELECT MAX(:id) AS id FROM :table");
$statement->bindParam(':id', $primary, PDO::PARAM_STR);
$statement->bindParam(':table', $table, PDO::PARAM_STR);
$statement->setFetchMode(PDO::FETCH_ASSOC);
$statement->execute();
// This one. Both doesn't work.
$statement = $this->conn->prepare("SELECT MAX(:id) AS id FROM :table");
$statement->setFetchMode(PDO::FETCH_ASSOC);
$arr = array(
':id' => 'my_id',
':table' => 'my_table',
);
$statement->execute($arr);
These just return a null array. I feel so confused. So I have tried that:
$statement = $this->conn->prepare("SELECT MAX(".$primary.") AS id FROM ".$table);
$statement->setFetchMode(PDO::FETCH_ASSOC);
$statement->execute();
And it works. I feel like I'm missing something but can't figure it out. So clearly there's a problem with binding I tried different variations such as writing one of the variable manually, but no luck so far.
Thanks in advance for any help...
You can't use parameters as table names in PDO, so you will have to change this to avoid that. This is not a limitation of PDO, but a limitation of MySQL directly. The manual states that
Parameter markers can be used only where data values should appear,
not for SQL keywords, identifiers, and so forth.
Table and column names are identifiers, so using placeholders for them is not supported. See this question for an alternative method.

PDO and alphanumeric strings?

The current error when running this from the command line is "Call to a member function bindParam() on a non-object" which I've worked out to being a problem with the variable $orderPO. Something does not like non-numeric characters which led me to the bindParam PARAM_STR business which does not work either. The database fields are both varchar 50.
My search skills are failing me. I know this must be posted somewhere about a million times but I can't seem to find it. I am completely open to doing this another way if someone has a better idea.
Current attempt code:
try
{
$orderNum = '123456';
$orderPO = '123456-A';
$dbh = new PDO("mysql:host=localhost;dbname=dbname", 'someuser', 'somepass');
$stm = $dbh->prepare("insert into some_table (order_number, order_po)");
$stm->bindParam(':order_number', $orderNum, PDO::PARAM_STR);
$stm->bindParam(':order_po', $orderPO, PDO::PARAM_STR);
$stm->execute();
print_r($stm);
print_r($dbh);
$arr = $stm->errorInfo();
print_r($arr);
$stm->closeCursor();
$dbh = null;
}
catch(PDOException $e)
{
echo $e->getMessage();
}
In order to bind parameters using PDO, you will need to use placeholders, like this:
$stm = $dbh->prepare("
INSERT INTO `some_table` SET
`order_number` = :order_number,
`order_po` = :order_po
");
$stm->bindParam(':order_number', $orderNum, PDO::PARAM_STR);
$stm->bindParam(':order_po', $orderPO, PDO::PARAM_STR);
Notice the inclusion of the : character before the named placeholder. I also added column names to your query.
Read further and see examples: PDO bindParam
The correct syntax is
$stm = $dbh->prepare("insert into some_table (order_number, order_po) VALUES (?, ?)");
$stm->bindParam(1,$orderNum);
$stm->bindParam(2,$orderPO);
include the questions marks, the numbers in the bindParam call refer to which question mark you're binding the parameter to
You are trying to use bindparam, but bind param matches ? not cursors :. You have not included any parameters or values.
Also, you are missing your VALUES statement within the query, which is causing the query to fail. This is why you get the "Call to a member function bindParam() on a non-object"
To use the :value syntax, use bindValue, not bindParam. to use bindParam, switch the :value to ? in your query and number them in order is your execute array.
try
{
$orderNum = '123456';
$orderPO = '123456-A';
$dbh = new PDO("mysql:host=localhost;dbname=dbname", 'someuser', 'somepass');
$stm = $dbh->prepare("insert into some_table (order_number, order_po) VALUES (:order_number, :order_po)");
$stm->bindvalue(':order_number', $orderNum, PDO::PARAM_STR);
$stm->bindvalue(':order_po', $orderPO, PDO::PARAM_STR);
$stm->execute();
print_r($stm);
print_r($dbh);
$arr = $stm->errorInfo();
print_r($arr);
$stm->closeCursor();
$dbh = null;
}
catch(PDOException $e)
{
echo $e->getMessage();
}

Categories