PHP MYSQL runs the query twice - php

When i run the following script. The row is inserted twice ( the query runs twice ) .
require_once $_SERVER['DOCUMENT_ROOT'].'/functions/sanitize.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/main/config.php';
$response = textsanitize($_POST['r']);
$ticket = idssanitize($_POST['t']);
$stmt = $condb->prepare("INSERT INTO ticket_reponses (ticket_id,user_id,time,response) VALUES (:ticket_id,:user_id,:time,:response)");
$stmt->execute(
array(
"ticket_id" => $ticket,
"user_id" => $_SESSION['user_id'],
"time" => time(),
"response" => $response
)
);
if($stmt->execute()){
echo "SUCCESS";
}
When i remove if($stmt->execute()){echo "SUCCESSS";}. It runs in the right way. The row inserted once.
Why does if($stmt->execute()) execute the query again ? I thought that if($stmt->execute()) only returns TRUE || FALSE. I want to ensure that the query was executed successfully.

One of the good uses of prepared statements in any language is that you can prepare it once and then execute it as many times as needed.
So in your case you execute() the statement twice, but it's possible that you could insert a whole bunch of data with the same prepared statement in a loop. Each time you call execute() you can just pass a new set of values to run the prepared statement. In your case it is an INSERT, so this is run twice.
In your case you probably just need...
$stmt = $condb->prepare("INSERT INTO ticket_reponses (ticket_id,user_id,time,response) VALUES (:ticket_id,:user_id,:time,:response)");
if($stmt->execute(array(
"ticket_id" => $ticket,
"user_id" => $_SESSION['user_id'],
"time" => time(),
"response" => $response))) {
echo "SUCCESS";
}

It is because it is calling the $stmt->execute() function twice. Once before the if statement and once as the condition in the if statement.
So, you need to remove one instance of it.
I believe that you need to check if the statement has executed correctly (hence the if). So, the code can be like...
require_once $_SERVER['DOCUMENT_ROOT'].'/functions/sanitize.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/main/config.php';
$response = textsanitize($_POST['r']);
$ticket = idssanitize($_POST['t']);
$stmt = $condb->prepare("INSERT INTO ticket_reponses (ticket_id,user_id,time,response) VALUES (:ticket_id,:user_id,:time,:response)");
$values = array(
"ticket_id" => $ticket,
"user_id" => $_SESSION['user_id'],
"time" => time(),
"response" => $response
);
if($stmt->execute($values)){
echo "SUCCESS";
}

You are executing $stmt->execute() twice, so it's simply inserting two rows. no rocket science here.
if you want to check if the query ran successfully or not do it in the first statement itself.
require_once $_SERVER['DOCUMENT_ROOT'].'/functions/sanitize.php';
require_once $_SERVER['DOCUMENT_ROOT'].'/main/config.php';
$response = textsanitize($_POST['r']);
$ticket = idssanitize($_POST['t']);
$stmt = $condb->prepare("INSERT INTO ticket_reponses (ticket_id,user_id,time,response) VALUES (:ticket_id,:user_id,:time,:response)");
$isSuccessful = $stmt->execute(
array(
"ticket_id" => $ticket,
"user_id" => $_SESSION['user_id'],
"time" => time(),
"response" => $response
)
);
if($isSuccessful){
echo "SUCCESS";
}

Related

Why does this PDO prepared statement not update the record?

I have a login system and I am currently converting it to PDO, but I think there is something wrong with my code as whenever I run the original code it works and when I run the PDO it doesn't (there are no errors in the console).
This is my original code:
$update_otp = "UPDATE classadmin SET code = $code, status = $status WHERE code = $fetch_code";
$update_res = mysqli_query($con, $update_otp);
This is my PDO converted code:
$update_otp = $conn->prepare("UPDATE classadmin SET code = :code, status = :status WHERE code = :code");
$update_res = $update_otp->execute(['code' => $code, 'status' => $status, 'code' => $fetch_code]);
code occurs twice as a named argument in the given statement, with two different values. This won't work, unless $code === $fetch_code.
This might help you out, using distinct names for the named arguments (you are completely free to choose them, they don't need to match the column name):
$update_otp = $conn->prepare("UPDATE classadmin SET code = :newCode, status = :status WHERE code = :oldCode");
$update_res = $update_otp->execute(['newCode' => $code, 'status' => $status, 'oldCode' => $fetch_code]);
When using emulated prepared statements (this is the default with PDO), the same placeholder can appear multiple times in the SQL. You have :code twice in the SQL. The value that you provide for :code in the execute will be put in place of the two placeholders named :code.
In PHP, associative arrays cannot have the same value with the same key. The one that comes later will overwrite the value with the same key.
$update_otp = $conn->prepare("
UPDATE classadmin
SET
code = :code,
status = :status
WHERE code = :code
");
$update_res = $update_otp->execute([
'code' => $code,
'status' => $status,
'code' => $fetch_code // <-- This one will overwrite the first $code
]);
To fix the problem use distinctly named placeholders or use positional arguments instead.

Stored procedure within function failing because of missing values

I can't figure out where my error lies here, but I'm calling this function and sending the 3 required arguments but the procedure is failing at execute.
I added a dump and die statement and it prints all 4 parameters being used in the procedure. One thing I'm concerned about is making sure all 4 things are being properly sent in as strings, as they should all be strings in the procedure.
Maybe it's something else because when I add the 4 param values manually into my IDE they successfully enter into the database. Is there an issue with how I'm sending these values?
function createUser($out2,$email,$access){
$type = 'web';
$userStmt = \DB::connection('odbc')->getPdo()->prepare("call schema.insertUser(?,?,?,?)");
$userStmt->bindParam(1, $out2, PDO::PARAM_STR,20);
$userStmt->bindParam(2, $email, PDO::PARAM_STR,140);
$userStmt->bindParam(3, $access, PDO::PARAM_STR, 2500);
$userStmt->bindParam(4, $type, PDO::PARAM_STR, 20);
dd("Out" . $out2 . "Email" . $email . "Access" . $access . "Type" . $type);
$userStmt->execute();
}
Dumping $userStmt
PDOStatement {#845 ▼
+queryString: "call schema.insertuser(?,?,?,?)"
errorInfo: array:4 [▼
0 => ""
1 => 0
2 => " ((null)[0] at (null):0)"
3 => ""
]
}

sql statement not returning any results

Hi I am creating some dummy data in a sql statement and returning the data in a jso n format. I believe I am connecting to the mysql db ok through odbc. However the dataset appears to be empty when I run the same query in workbench it returns data ok.
This is how the data is returned to the webpage making the call
"[{"coords":{"lat":null,"lng":null},"iconImage":null,"content":null},{"coords":{"lat":null,"lng":null},"iconImage":null,"content":null}]
here is my code I have no error messages just empty json.
require("../PHP/phpsqlajax_dbinfo.php");
$connection=odbc_connect($database, $username, $password);
if (!$connection)echo 'Failed to connect';
//Select Test statement
$query="select 53.745 as lat,-0.338 as lng,'https://developers.google.com/maps/documentation/javascript/examples/full/images/beachflag.png' as iconImage, '<h1>Tony G</h1>' as content union all
select 53.745 as lat,-0.310 as lng,'https://maps.gstatic.com/mapfiles/ms2/micons/blue.png' as iconImage, '<h1>fred</h1>' as content ";
$result=odbc_exec($connection,$query);
//work through result and create JSON
while ($row = odbc_fetch_row($result)){
$json[] = [
'coords' => ['lat' => $row['lat'],'lng' => $row['lng']],
'iconImage' => $row['iconImage'],
'content' => $row['content'],
];
}
echo json_encode($json);
I am a little puzzled as to what I am doing wrong.
thanks
Though it's unclear from manual where does data go to in odbc_fetch_row, it's clear that result (true or false) of this function is not what you expect. So, you should use another function, which returns array, in this case it is odbc_fetch_array:
while ($row = odbc_fetch_array($result)){
$json[] = [
'coords' => ['lat' => $row['lat'],'lng' => $row['lng']],
'iconImage' => $row['iconImage'],
'content' => $row['content'],
];
}

Store stmt results in an array, inside of an array

So I am trying to create multiple "result" arrays and fill them with the results of my statement, inside a "main" array.
However it seems to be that the result arrays are getting overwritten each time the loop passes instead of creating an additional array.
My code:
function retrieve_clients() {
$coach_id = $_SESSION['user_details']['id'];
$connection = connection();
$statement = select($connection, '*', 'relations', 'coach_id', '=');
$statement->bind_param('i', $coach_id);
if ($statement->execute()) {
$statement->bind_result($id, $coach_id, $client_id, $relation_date);
while ($statement->fetch()) {
$_SESSION['clients'] = array(
array($id, $coach_id, $client_id, $relation_date)
);
}
}
$statement->close();
}
I can't figure it out anymore. Please spare me because I'm still new to programming.
You need to add another dimension to your clients, by adding [] to the end of the variable.
$_SESSION['clients'][] = array(
array($id, $coach_id, $client_id, $relation_date)
);
I think the other answers are on the right track, however they add an unnecessary and probably undesirable dimension. Try adding a dynamic dimension with [] but remove one of the array dimensions that overwrites:
$_SESSION['clients'][] = array($id, $coach_id, $client_id, $relation_date);
That's because you're replacing the value of clients in following line,
$_SESSION['clients'] = array(
array($id, $coach_id, $client_id, $relation_date)
);
What you need to do is create an array of clients first before loop and then append each array in the main array.
Like this,
$_SESSION['clients']=array();
while ($statement->fetch()) {
$_SESSION['clients'][] = array(
array($id, $coach_id, $client_id, $relation_date)
);
Do yourself a favor, stop using mysqli (as well as that home-brewed "select" function).
With PDO you'll have a code that is sane:
function retrieve_clients() {
$sql = "SELECT * FROM relation WHERE coach_id = ?";
$statement = connection()->prepare($sql); // here goes your SQL
$statement->execute([$_SESSION['user_details']['id']]); // here goes a parameter
$_SESSION['clients'] = $statement->fetchAll(); // and here you have your array
}

Using PDO to avoid SQL injections - newbie

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.

Categories