Calling stored procedures multiple times from a prepared statement - php

This seems to be a Windows specific issue a few people have had, without a satisfactory outcome. I haven't tried the code on my Linux server yet.
When using a prepared statement to call a stored procedure multiple times crashes Apache.
The stored procedure appears to be returning two results, even for a simple SELECT * FROM users making the next execute not work.
The workaround I'm using now is $mysqli->next_result(); between each execute.
My question, has anyone experienced this? And is there a fix, is this a bug or am I just doing something wrong?
Windows 7
wamp server
-Apache 2.4.2
-Mysql 5.5.24
-PHP 5.4.3
/* MySQL code */
DELIMITER $$
PROCEDURE `get_data`(IN var1 VARCHAR(45),IN var2 VARCHAR(45) )
BEGIN
SELECT *
FROM data_table
WHERE `data1` = var1 AND `data2` = var2;
END
/* End MySQL code */
<?php
if( !($stmt = $mysqli->prepare("CALL get_data(?,?)")) )
die("Prepare failed: (" . $stmt->errno . ") " . $stmt->error);
$var1 = "some_data_1";
$var2 = "some_data_2";
if( $stmt->bind_param("ss", $var1, $var2) )
{
if( $stmt->execute() )
{
echo "Execute one complete.";
}
else
echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}
else
echo "Bind failed: (" . $stmt->errno . ") " . $stmt->error;
/* Current fix to clear stray results sent from the stored procedure */
$stmt->next_result();
$var2 = "some_data_555";
if( $stmt->bind_param("ss", $var1, $var2) )
{
if( $stmt->execute() )
{
echo "Execute two complete.";
}
else
echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}
else
echo "Bind failed: (" . $stmt->errno . ") " . $stmt->error;
?>
The code is obviously modified for debugging and stackoverflow.
The exact code with a normal query, IE SELECT * FROM users works fine, until you call a stored procedure, IE CALL get_data(?,?)

Related

MySQL unwanted automatic replacing \n to linebreaks when storing data

I am using PHP to pass a query like this:
"UPDATE `prove750_mrdias`.`stringsMrDias`
SET `conteudo` = '$conteudo'
WHERE `stringsMrDias`.`ID` = $id;"
when I echo $conteudo I get Sobre\nmim as expected.
But after the query, I look at the database and the value stored is the formatted string:
'sobre
mim'
That's causing all sorts of problems when parsing the data back to my application.
If I go to phpMyAdmin and pass the value of $conteudo manually it maintains the expected behavior, only when querying the replace is happening without calling it.
Any ideas?
I suspect it's an issue of interpolation. You can kill two birds with one stone by using prepared statements. By using prepared statements
your data won't be corrupted or need to be manually handled by you,
your application will not be subject to security issues a la SQL injection.
This might look like:
$sql = "UPDATE `prove750_mrdias`.`stringsMrDias` SET `conteudo` = ? WHERE `stringsMrDias`.`ID` = ?";
$preparedStatement = $pdo_handle->prepare( $sql );
$preparedStatement->execute([$conteudo, $id]);
That is, you first tell the database the form of the query you want executed, and then -- in a separate call -- you send the arguments to that query.
Try http://php.net/manual/en/function.nl2br.php
Example,
$conteudo = nl2br($conteudo);
Then store into database.
Prepared statements was the right direction.
After looking at the mysqli documentation I ended up with a code like this:
`$sql = "UPDATE `prove750_mrdias`.`stringsMrDias` SET `conteudo` = (?) WHERE `stringsMrDias`.`ID` = (?)";
if (!($stmt = $con->prepare($sql))) {
echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}
if (!$stmt->bind_param('ss', $conteudo,$id)) {
echo "Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error;
}
if (!$stmt->execute()) {
echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}`
Had to use the bind_param() as execute() don't accept any parameters.

PHP code for inserting non-duplicate values into MySQL

I have basic PHP/MySQL experience, having taken an introductory class. My knowledge is literally limited to the following PHP codes:
if(!($stmt = $mysqli->prepare...)
if(!($stmt->bind_param...)
if(!$stmt->execute...)
I'm currently trying to write a program that allows a user to enter a new password, and checks the password against existing passwords in the database.
Here is what I have:
<?php
foreach($Password){
$dupesql = "SELECT PasswordID Passwords WHERE (Password = '$Password')";
$duperaw = mysql_query($dupesql);
if(mysql_num_rows($duperaw){
echo nl2br("$Password has already been used \n");
}
else{
echo "Password added \n";
}
}
?>
I got the code from this post: Check for duplicates before inserting
I'm not sure if the code itself has problems or if I need to add anything else to my PHP code to get this working, as it's currently producing an "Error 500".
MySQL extension is deprecated and probably you have PHP 7.0 from where it is removed. Rewrite your code to MySQLi or PDO. Check this question on how to convert to MySQLi: How could I change this mysql to mysqli?
Also, your code just doesn't add a password (never). Probably you expect to add it before the "Password Added" message, but be aware: the solution you want to use is not ideal, because there is a risk of race condition between checking the password for existence and adding it. This means that it is possible to add a password twice.
To solve this problem, you might want to use transactions. More details are covered in this question: PHP + MySQL transactions examples
I decided to go an entirely different route, which is to set the Password column as unique.
Then I did a simple INSERT that would prompt an error if the user attempts to add a duplicate:
<?php
if(!($stmt = $mysqli->prepare("INSERT INTO Heroes(HeroName, FirstName, LastName, Age, HomeCountry, RoleID) VALUES (?,?,?,?,?,?)"))){
echo "Prepare failed: " . $stmt->errno . " " . $stmt->error;
}
if(!($stmt->bind_param("sssisi",$_POST['HeroName'],$_POST['FirstName'],$_POST['LastName'],$_POST['Age'],$_POST['HomeCountry'],$_POST['RoleID']))){
echo "Bind failed: " . $stmt->errno . " " . $stmt->error;
}
if(!$stmt->execute()){
echo "Execute failed: " . $stmt->errno . " " . $stmt->error;
} else {
echo "Added " . $stmt->affected_rows . " row to Heroes.";
}
?>

failed to insert multiple data in mysqli using loop

I want to store one's friends of facebook into a table. The result of below code shows only a single record is inserted. It wasn't the problem of my loop because I echo the name, it all appeared.
foreach($user_friends['data'] as $friend){
//echo $friend['name'] . "</br>";
$userImg = "https://graph.facebook.com/".$friend['id']."/picture?width=200&height=200";
$friendsName = $friend['name'];
$stmt3 = $db->prepare("INSERT INTO allfriend(`uId`,`name`,`img`,`friendOf`) VALUES (?,?,?,?)");
$stmt3->bind_param('ssss', $user_fbid, $friendsName, $userImg, $user_fbid);
$stmt3->execute();
}
You're misusing the prepare / bind feature slightly. You only need to prepare once, but you do need to reset the statement after each use.
Also, you should check for failure of your statements. If you do that you may find out why things might work differently from what you expect.
Is it possible your column friend.uID is in fact a primary key? The code you've shown tries to insert the same value into multiple rows. That could be your problem.
Try this:
$stmt3 = $db->prepare
("INSERT INTO allfriend(`uId`,`name`,`img`,`friendOf`) VALUES (?,?,?,?)")
|| die "prepare failed: ". $db->error;
foreach($user_friends['data'] as $friend) {
//echo $friend['name'] . "</br>";
$userImg = "https://graph.facebook.com/".$friend['id']."/picture?width=200&height=200";
$friendsName = $friend['name'];
$stmt3->bind_param('ssss', $user_fbid, $friendsName, $userImg, $user_fbid)
|| die "bind_param failed " . $db->error;
$stmt3->execute()
|| die "execute failed " . $db->error;
$stmt3->reset()
|| die "reset failed " . $db->error;
}

posting data with apostrophe

I'm a complete beginner at PHP but have managed a simple code to input data to a table.
The code is:
$query = "INSERT into $table (suggestion1) VALUES('$suggestion1')";
All works fine but if the data inserted contains an apostrophe (e.g. don't) the query fails.
I've searched for hours but the answers I get are beyond my knowledge.
Any help or pointers would be great!
Steven
What you should be looking are prepared statements, in which to write your queries with parameters, and the call that prepared statement passing in parameters values and let the driver make the replaces/escaping. Here's a good starting point using mysqli.
Here's a simplified code sample from PHP.net :
$mysqli = new mysqli("example.com", "user", "password", "database");
/* Prepared statement, stage 1: prepare */
if (!($stmt = $mysqli->prepare("INSERT INTO test(id) VALUES (?)"))) {
echo "Prepare failed: (" . $mysqli->errno . ") " . $mysqli->error;
}
/* Prepared statement, stage 2: bind and execute */
$id = 1;
if (!$stmt->bind_param("i", $id)) {
echo "Binding parameters failed: (" . $stmt->errno . ") " . $stmt->error;
}
if (!$stmt->execute()) {
echo "Execute failed: (" . $stmt->errno . ") " . $stmt->error;
}
You want to escape your input: check the documentation.
Basically, what happens is this: when you put that data in with quotes, you get this:
INSERT INTO $table (suggestion1) VALUES ('it's great');
and MySQL gets confused with the second quote. When you "escape" you get this:
INSERT INTO $table (suggestion1) VALUES ('it\'s great');
and MySQL knows that second quote is part of the data, not of the query.
Wikipedia has info on it as well (a little more extensive, but worth reading and understanding).

Why is PHP mysqli prepared statement working but inserting all NULL values?

What would cause this? Code follows:
$m = new mysqli($host,$user,$pass,$db);
if(mysqli_connect_errno()) die('Connect failed: ' . mysqli_connect_error());
$PrepSQL = "INSERT INTO Products (" . implode(',',$this->cols) . ") VALUES (";
$PrepSQL .= '?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?,?)";
$stmt = $m->prepare($PrepSQL);
if(!$stmt) die('Could not prepare: ' . $m->error . "\n$PrepSQL\n");
$ret = $stmt->bind_param('isissssddssssssssssssssssssssssssisssssss',
$contents[0], ... bunch of these here ... );
if(!$ret) die('bind_param failed: ' . $m->error);
Then in a loop I have:
$contents = explode('|',$NL); // NL is pipe delimited data
print_r($contents);
if(!$stmt->execute()) die("Statement failed: " . $m->error);
And the script doesn't halt but every value is null in MySQL. Most of the types are strings and I would assume they would at least fill in even if the numeric types are wrong. The print_r is printing values correctly.
Can you show the complete code from preparing the statement to executing it?
I suspect that $contents in the first part is not the same $contents as in the second part. They need to be references to the same array, since you're populating it after binding it by reference.

Categories