beginTransaction in PDO - php

I've recently started learning about PDO.
My question is how can i execute more than 1 prepared statement.
In my example i'm trying to add a new student to the database.
The first part of the code i'm adding the student into the 'students' table.
The second part of the code i'm trying to add all of his classes (from array e.g an array(PHP,JAVA,ANGULAR)) into student_class table (which contain 2 columns - student_id and class_id).
Here's a snippet of what i've tried:
function addStudent($name, $phone, $email, $classes){
global $conn;
//first part
$stat = $conn->prepare("INSERT INTO students (sName, phone, email) VALUES(:name, :phone, :email)");
$stat->bindValue("name",$name,PDO::PARAM_STR);
$stat->bindValue("phone",$phone,PDO::PARAM_STR);
$stat->bindValue("email",$email,PDO::PARAM_STR);
$stat->execute();
//second part
//insert classes into student_class
$lastId = $conn->lastInsertId();
$conn->beginTransaction();
$len = count($classes);
for ($i=0; $i < $len; $i++) {
$cid = getClassByName($classes[$i]);//returns the class id
$cl = $conn->prepare("INSERT INTO student_class (student_id,class_id) VALUES(:sid, :cid)");
$cl->bindValue("sid",$lastId,PDO::PARAM_INT);
$cl->bindValue("cid",$cid,PDO::PARAM_INT);
$cl->execute();
}
$conn->commit();
}
try{
addStudent($params['name'], $params['phone'], $params['email'], $params['classes']);
}
catch(PDOException $e){
echo $e->getMessage();
$conn->rollback();
}
The result of this is: the user gets added to the 'students' table but the classes remain untouched (i'm getting no error), so i guess i'm doing something wrong with the second part.
I hope you can shed some light on this matter.

If these are prepared statements then you only "create" them once, and can execute them multiple times. Also edited your code to print error information, use it to debug.
function addStudent($name, $phone, $email, $classes){
global $conn;
//first part
$stat = $conn->prepare("INSERT INTO students (sName, phone, email) VALUES(:name, :phone, :email)");
$stat->bindValue("name",$name,PDO::PARAM_STR);
$stat->bindValue("phone",$phone,PDO::PARAM_STR);
$stat->bindValue("email",$email,PDO::PARAM_STR);
$stat->execute();
//second part
//insert classes into student_class
$lastId = $conn->lastInsertId();
$conn->beginTransaction();
$len = count($classes);
$cl = $conn->prepare("INSERT INTO student_class (student_id,class_id) VALUES(:sid, :cid)");
if (!$cl) {
echo "\nPDO::errorInfo():\n";
print_r($conn->errorInfo());
}
for ($i=0; $i < $len; $i++) {
$cid = getClassByName($classes[$i]);//returns the class id
$cl->bindValue("sid",$lastId,PDO::PARAM_INT);
$cl->bindValue("cid",$cid,PDO::PARAM_INT);
$cl->execute();
echo "\nPDOStatement::errorInfo():\n";
$arr = $cl->errorInfo();
print_r($arr);
}
$conn->commit();
}
try{
addStudent($params['name'], $params['phone'], $params['email'], $params['classes']);
}
catch(PDOException $e){
echo $e->getMessage();
$conn->rollback();
}

Related

Update one database table column with different values

I want to update table with max three value and minimum with two values.How it would be possible to update table. I Get values from form, there are three fields for three students. Now all of them having same value when i update them in the database. Now i am trying this why. Dont know it works or not
See my page
$s1_name=$_POST['s1_name'];
$s2_name=$_POST['s2_name'];
$s3_name=$_POST['s3_name'];
$query="update students SET Name=:Name
WHERE ProjectID='$id'
";
try
{
$stmt = $conn->prepare( $query );
$stmt->bindParam(':Name', $s1_name);
$stmt->bindParam(':Name', $s2_name);
$stmt->bindParam(':Name', $s3_name);
$result = $stmt->execute();
$msg = "Record updated";
}
catch(PDOException $ex)
{
$msg = $ex -> getMessage();
}
}
It does not work this way. The way you are doing it will result in the query only updating it for $s3_name.
You will have to do your try/catch statement for each query:
<?php
$names = [$_POST['s1_name'], $_POST['s2_name'], $_POST['s3_name']];
$query = "update students SET Name=:Name WHERE ProjectID='$id'";
foreach ($names as $name) {
try
{
$stmt = $conn->prepare($query);
$stmt->bindParam(':Name', $name);
$result = $stmt->execute();
$msg = "Record updated";
}
catch(PDOException $ex)
{
$msg = $ex -> getMessage();
}
}

Inserting image into BLOB column MySQL using PHP

I Have Table Called XYZ
ID no no2 no3
1 465 Abc [BLOB - 15B]
2 465 Abc [BLOB - 18B]
3 465 Abc [BLOB - 80B]
4 456 Abc [BLOB - 50B]
i want to insert multiple images into "no3" using PDO
PHP
try {
$connection = new PDO($dsn, $username, $password, $options);
$sql = "INSERT INTO xyz (no, no2, no3) SELECT max(nos),nos2,:tmp from ASD;
for($i=0; $i<=count($data)-1; $i++)
{
$data = $_FILES['image']['tmp_name'];
$statement = $connection->prepare($sql);
$statement->bindParam(':tmp',addslashes(file_get_contents($data[$i])));
}
$statement->execute();
} catch(PDOException $error) {
echo $sql . "<br>" . $error->getMessage();
}
it insert only one image
As others have mentioned, you're missing a closing ", but it seems it is there in your actual code, because the behaviour you described doesn't match this syntax error.
So, looking further, you call execute only after the loop.
You will have to execute the statement over and over inside the for-loop as well.
Now you just overwrite the image in the bind parameter, call execute once, and thus only insert the last image in the database.
You should actually be able to prepare the statement once, and in the loop, for every iteration, bind a new value and execute the statement. So the code for the loop becomes this: (Assuming the details of loading the file, etc, is okay. I haven't investigated that).
$statement = $connection->prepare($sql);
for($i=0; $i<=count($data)-1; $i++)
{
$data = $_FILES['image']['tmp_name'];
$statement->bindParam(':tmp',addslashes(file_get_contents($data[$i])));
$statement->execute();
}
Correct PHP Code
$statement = $connection->prepare($sql);
$data = $_FILES['image']['tmp_name'];
for($i=0; $i<=count($data)-1; $i++)
{
$tmp = addslashes(file_get_contents($data[$i]));
$statement->bindParam(':tmp',$tmp);
$statement->execute();
}
Mate you forgot to add ending " at the of the query:
try {
$connection = new PDO($dsn, $username, $password, $options);
$sql = "INSERT INTO xyz (no, no2, no3) SELECT max(nos),nos2,:tmp from ASD";
for($i=0; $i<=count($data)-1; $i++)
{
$data = $_FILES['image']['tmp_name'];
$statement = $connection->prepare($sql);
$statement->bindParam(':tmp',addslashes(file_get_contents($data[$i])));
}
$statement->execute();
} catch(PDOException $error) {
echo $sql . "<br>" . $error->getMessage();
}

Unable to get results php mysqli select with bind

I am attempting to return a result set from mysql in php using mysqli. I have attempted several different ways, but they either end in errors, or empty arrays being returned. I know the query is good because I can run it in my db admin client replacing the question mark with the string needed and it returns as expected. Does anyone see something I have missed? Looks like it should be working to me, but obviously something has to be wrong. ¯_(ツ)_/¯
<?php
class db extends mysqli{
function __construct(){
parent::__construct(PUBP_HOST, PUBP_USER, PUBP_PASS, PUBP_DB);
}
/*
--------------------------------------------------------------------------*/
function read_agency_phones($agency_in){
$returnArray = array();
if($stmt = $this->prepare("SELECT firstname, lastname, agency, phonenumber FROM employees WHERE agency = ?")){
try{
$stmt->bind_param('s', $agency_in);
$stmt->execute();
$stmt->bind_result($first, $last, $agency, $phone);
while($stmt->fetch()){
$returnArray[] = array(
'first_name' => $first,
'last_name' => $last,
'agency' => $agency,
'phonenumber' => $phone
);
}
$stmt->free_result();
$stmt->close();
return $returnArray;
} catch (Exception $ex) {
return $ex->getMessage();
}
}
return 'failed001';
}
}
$db = new db();
$results = $db->read_agency_phones("SOME_STRING");
echo '<pre>';
echo var_export($results, true);
echo '</pre>';
die;
The agency field in the database is of type VARCHAR(10).
When running the following query in admin panel, results are returned as expected:
SELECT firstname, lastname, agency, phonenumber FROM employees WHERE agency = "THE-AGENCY"

Weird behaviour in PDO Statement with bindParam

I'm having some issues with inserting rows into a table using bindParam in a prepared statement.
Here my code.
$table = 'companies';
$fields = array('name', 'address', 'phone');
$values = array('Company Name', 'Company address', '555-9999999');
$sql = 'INSERT INTO '.$table.' ('.implode(', ', $fields).') VALUES ('
.substr(str_pad('', (count($fields) * 3), '?, '), 0, -2).')';
$statement = $db->prepare($sql);
for ($i = 1; $i <= count($fields); $i++) {
$statement->bindParam($i, $$fields[$i-1]);
}
for ($i = 0; $i < count($fields); $i++) {
${$fields[$i]} = $values[$i];
}
try {
$result = $statement->execute();
$this->rowCount = $result ? $statement->rowCount() : 0;
}
catch (Exception $ex) {
$this->error = $ex;
$result = false;
}
$sql becomes a string like "INSERT INTO companies (name, address, phone) VALUES (?, ?, ?)"
After binding params to some variables and giving value to those variables, I execute the clause but nothing happens, just $result is false but no error. That is, execution of the programa does not enter the catch block.
What it wrong with the code?. Any explanation?.
Thank you for your help.
I finally got to sort this out. The problem, in my case, was that I had a DateTime which I tried to store directly in the database since I had a DateTime field.
The solution: convert the DateTime field into a String doing
$dateTimeField->format('Y-m-d H:i:s')

skip stmt block

I am brand new to php and I ran into a problem that has already taken a few hours of poking around and researching and I could not find anything like it anywhere around the net.
Database:MyPHPAdmin winserver
Goal: Create a new row in table 'photo'. Take the last insert p_id for the current user and update the table accessible_to by creating a new row with that p_id.
I know I can create a trigger, and no it does not work either don't know why. Run out of ideas how.
What I found out by simply printing before-in-after the if statement
if ($stmt = $mysqli->prepare("insert into accessible_to values(?, ?, ?)"))
is that it just bypasses it.
Please post your suggestions.
P.S. The if statement above to which I am referring has been twisted in several ways and yet it does not work.
The connection is already imported.
Thank you a lot.
if(!isset($_SESSION["id"])) {
echo "You are not logged in. ";
echo "You will be returned to the homepage in 3 seconds or click here.\n";
header("refresh: 3; index.php");
}
else {
//if the user have uploaded a photo, insert it into database
if(isset($_POST["ext"])) {
//insert into database, note that p_id is auto_increment
if ($stmt = $mysqli->prepare("insert into photo (ext, owner_id) values (?,?)")) {
$stmt->bind_param("ss", $_POST["ext"], $_SESSION["id"]);
$stmt->execute();
$stmt->close();
$id = htmlspecialchars($_SESSION["id"]);
}
//The following function is fetching the last added p_id in PHOTO by the user with the current SESSION
//Do not simply get the last p_id in PHOTO because someone else might have just added another picture meanwhile
if ($stmt = $mysqli->prepare("select MAX(p_id) from photo where owner_id = ?")){
$stmt->bind_param("s", $id);
$stmt->execute();
$stmt->bind_result($p_id);
if ($stmt->fetch()){
$p_id = htmlspecialchars($p_id);
}
}
echo "BEFORE accessible_to insertion";
echo '<br />';
if ($stmt = $mysqli->prepare("insert into accessible_to values(?, ?, ?)")){
echo "Finally inside accessible_to insertion";
echo '<br />';
$stmt->bind_param("iss", $p_id, $id, 'T');
$stmt->execute();
$stmt->close();
}
echo "AFTER accessible_to insertion";
echo '<br />';
}
//if not then display the form for posting message
else {
echo "Something";
You can't boolean test an assignment and expect it to return a different result. What you want to test for is if $stmt->execute successfully executed or not.
$stmt = $mysql->prepare("insert into foo values (?,?)");
$stmt->bind_param(1,$f1);
$stmt->bind_param(2,$f2);
if ($stmt->execute()) {
... worked
} else {
... fubar
}
You have to start by calling mysqli::connect($server, $user, $pw, $db). The best way to do that is by constructing an object like:
$connection = new mysqli($server, $user, $password, $db);
if ($connection->errno)
{
echo "Connection failed";
echo $this->connection->error;
}
else
{
$stmt = $connection->prepare("insert into photo (ext, owner_id) values (?,?)")) {
$stmt->bind_param("ss", $_POST["ext"], $_SESSION["id"]);
$stmt->execute();
$stmt->close();
}

Categories