PDO PHP Stored Procedure (bindParam) - php

Everything worked for me with bindParam and PDO.
But the moment I add 3 bindParam, it doesn't work.
Example that work:
$stmt=$dbh->prepare("select * from SP_IMPORT_CRM_SELECTIE(?,?,'test','org naam','French','1','2','adres','adres1','city','city','state','state','postal','postal','country','country','po','po','phone','other','email','otheremail','fax','web','VAT')");
$stmt->bindParam(1, $firma, PDO::PARAM_INT);
$stmt->bindParam(2, $ACC, PDO::PARAM_STR,20);
The moment I add a third param, my browser gives me the message = Can't receive data:
$stmt=$dbh->prepare("select * from SP_IMPORT_CRM_SELECTIE(?,?,?,'org naam','French','1','2','adres','adres1','city','city','state','state','postal','postal','country','country','po','po','phone','other','email','otheremail','fax','web','VAT')");
$stmt->bindParam(1, $firma, PDO::PARAM_INT);
$stmt->bindParam(2, $ACC, PDO::PARAM_STR,20);
$stmt->bindParam(3, $org, PDO::PARAM_STR,50);
Is there a limit on bindParam?

I have 26 input parameters. When I return 26 values in my stored procedure, IT WORKS..
It that normal?
So you always have to have the same number of input as output parameter?

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.

PHP -> PDO -> Prepare -> Call Procedure -> Insert Into -> Bind Parameters

using this procedure
CREATE PROCEDURE `Insert_New_Return_Id`(IN Insert_Stmnt varchar(1000), OUT IDNum int)
BEGIN
SET #buffer = Insert_Stmnt;
PREPARE stmt FROM #buffer;
EXECUTE stmt;
SELECT LAST_INSERT_ID() INTO IDNum;
DEALLOCATE PREPARE stmt;
END
the following code works fine :
$statement=$con->prepare("CALL Insert_New_Return_Id (\"INSERT INTO users (first_name,last_name)VALUES('test','test')\",#ID)");
$statement->execute();
$statement=$con->query("SELECT #ID");
while ($row = $statement->fetch()){echo "Last ID Insert : " . $row['#ID'];}
but when i'm trying to bind parameters the values are ?
$first_name = "test";
$last_name = "test";
$statement=$con->prepare("CALL Insert_New_Return_Id (\"INSERT INTO users (first_name,last_name)VALUES('?','?')\",#ID)");
$statement->bindParam(1, $first_name, PDO::PARAM_STR);
$statement->bindParam(2, $last_name, PDO::PARAM_STR);
$statement->execute();
$statement=$con->query("SELECT #ID");
while ($row = $statement->fetch()){echo "Last ID Insert : " . $row['#ID'];}
If i try VALUES(?,?) returns an error.
How can i make this work? Call a procedure with prepare statement and binding parameters?
Thank you
$statement->bindParam(1, 'test', PDO::PARAM_STR);
$statement->bindParam(2, 'test', PDO::PARAM_STR);
You must use a variable instead of the string 'test'. PDOStatement::bindParam binds variables by reference. By definition, you cannot do this with a string.
Use a variable instead.
$statement->bindParam(1, $str1, PDO::PARAM_STR);
$statement->bindParam(2, $str2, PDO::PARAM_STR);
Also, when you want to use CALL to call a stored procedure, just call the stored procedure by name. Do not repeat the query. Of course, this assumes you've done the work of adding the stored procedure to MySQL.
$statement=$con->prepare('CALL Insert_New_Return_Id(?,?)');
If you need a third parameter, add it to the stored procedure in MySQL and call it like this.
$statement=$con->prepare('CALL Insert_New_Return_Id(?,?,?)');

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.

Fetching User Information from MySQL Error using PDO

I have designed an authorization system for a project I'm working on. I'm able to retrieve the user ID from the database, however, I am now trying to get the user name and email for the user. I am fairly new to PHP, by the way.
I'm getting this error:
SQLSTATE[HY093]: Invalid parameter number: parameter was not defined
I am confused because
$stmt->execute()
works just fine, however
$stmt2->execute()
is failing. I'm sure the problem is something simple, but I cannot figure this out. Here is the PHP code for fetching the info.
$stmt = $dbh->prepare("SELECT nuewavedb_user_id, nuewavedb_username, nuewavedb_password FROM nuewavedb_users
WHERE nuewavedb_username = :nuewavedb_username AND nuewavedb_password = :nuewavedb_password");
$stmt2 = $dbh->prepare("SELECT nuewavedb_fullname, nuewavedb_email FROM nuewavedb_users
WHERE nuewavedb_username = :nuewavedb_username AND nuewavedb_password = :nuewavedb_password");
/*** bind the parameters ***/
$stmt->bindParam(':nuewavedb_username', $nuewavedb_username, PDO::PARAM_STR);
$stmt->bindParam(':nuewavedb_password', $nuewavedb_password, PDO::PARAM_STR, 40);
$stmt2->bindParam(':nuewavedb_fullname', $nuewavedb_fullname, PDO::PARAM_STR);
$stmt2->bindParam(':nuewavedb_email', $nuewavedb_email, PDO::PARAM_STR);
/*** execute the prepared statement ***/
$stmt->execute();
$stmt2->execute();
/*** check for a result ***/
$user_id = $stmt->fetchColumn();
$nuewavedb_fullname = $stmt2->fetchColumn();
$nuewavedb_email = $stmt2->fetchColumn(1);
Thanks in advance for your help!
You should somehow combine this query especially if it is the same table no need to read twice
$stmt = $dbh->prepare("SELECT
nuewavedb_user_id
,nuewavedb_username
,nuewavedb_password
,nuewavedb_fullname
,nuewavedb_email
FROM nuewavedb_users
WHERE nuewavedb_username = :nuewavedb_username AND
nuewavedb_password = :nuewavedb_password"
);
Then execute and fetch properly:
/*** bind the parameters ***/
$stmt->bindParam(':nuewavedb_username', $nuewavedb_username, PDO::PARAM_STR);
$stmt->bindParam(':nuewavedb_password', $nuewavedb_password, PDO::PARAM_STR, 40);
/*** execute the prepared statement ***/
$stmt->execute();
/*** fetch **/
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$nuewavedb_fullname = $row['nuewavedb_fullname'];
$nuewavedb_email = $row['nuewavedb_email'];
In your statement stmt2 you define 2 parameters : :nuewavedb_username and :nuewavedb_password
But when you bind the parameters you use :nuewavedb_fullname and :nuewavedb_email
You have to use same parameters names

What the difference between bindParam and execute(array)?

$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.

Categories