I am trying to be as efficient with code as possible. Unfortunately, I can't seem to figure out a good way of doing this. I have tried using Sammitch's code which does look cleaner but unfortunately it doesn't seem to work.
I would like a way to stop having to use prepare, execute, every time and a function to me makes the most sense. Using Simmitch's suggestion, I removed the initial connection to database to stop unnecessary overheads but the code still does not work. Showing a "SQLSTATE[HY093]: Invalid parameter number: parameter was not defined" error.
My code at present (some parts omitted as not necessary):
/*Function to talk to database*/
function doQuery($myDB, $myQuery, $myValues)
{
try
{
$st = $myDB->prepare($myQuery);
$st->execute($myValues);
//echo $success;
}
catch (PDOException $e)
{
echo "Failed because: " . $e->getMessage();
}
}
$db = new PDO('mysql:host=localhost;dbname='dbanme';charset=utf8', 'dbuser', 'dbpass');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //Set error mode
$query = "INSERT INTO users(login,pass,email,county) VALUES(:username,:password,:email,:count)";
$values = array('username' => $_POST['username'],
'password' => $_POST['password1'],
'email' => $_POST['email'],
'county' => $_POST['county']
);
doQuery($db, $query, $values);
<?php
function doQuery($db, $query, $arguments) {
try {
//Prepare and execute an insert into DB
$st = $db->prepare($query);
$st->execute(array($values));
echo $success; // 4. use echo
// you should probably return something here...
} catch (PDOException $e) {
// 5. Fail ~descriptively~
echo "Failed because: " . $e->getMessage();
// you should probably return something here...
}
}
// 1. Don't create the database inside of the same function that does the queries,
// creation/destruction of the objects/connections will cause unnecessary overhead,
$myDb = new PDO('mysql:host=localhost;dbname=dbname;charset=utf8', 'dbuser', 'dbpassword');
$myDb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //Set error mode
$myQuery = "INSERT INTO users(login,pass,email,county) VALUES(:username,:password,:email,:count)";
// 2. You can't define an array like that.
// 3. You do not need to add colons to the array indexes.
$myValues = array(
'username' => $_POST['username'],
'password' => $_POST['password1'],
'email' => $_POST['email'],
'county' => $_POST['county']
);
doquery($myDb, $myQuery, $myValues)
Don't forget to include " : " in your parameters array ?
/*Function to talk to database*/
function doQuery($myDB, $myQuery, $myValues)
{
try
{
$st = $myDB->prepare($myQuery);
$st->execute(array($myValues));
//echo $success;
}
catch (PDOException $e)
{
echo "Failed because: " . $e->getMessage();
}
}
$db = new PDO('mysql:host=localhost;dbname='dbanme';charset=utf8', 'dbuser', 'dbpass');
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); //Set error mode
$query = "INSERT INTO users(login,pass,email,county) VALUES(:username,:password,:email,:count)";
$values = array(':username' => $_POST['username'],
':password' => $_POST['password1'],
':email' => $_POST['email'],
':county' => $_POST['county']
);
doQuery($db, $query, $values);
I hope this worked!
Related
I want to do a transaction with php and my sql with PDO, the thing is that when i use the commit() function, the code returns a "FALSE" echo, but insert the data anyway. Maybe im doing something wrong, my code is this:
In the Connection class
protected function getConexion()
{
try
{
$params = array(PDO::ATTR_PERSISTENT=>true,PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8");
$this->conexion = new PDO($this->motor.":host=".self::$servidor.";dbname=".$this->db_name,self::$usuario,self::$password,$params);
return $this->conexion;
}
catch (PDOException $ex)
{
echo "Error en la conexión : " . $ex->getMessage();
}
}
and into my register function
if($miembro == "S")
{
try
{
$this->getConexion()->beginTransaction();
$sqlInsertUsuario = "INSERT INTO Usuario (apodo, password, correo, nombre, apellido, "
. "fchNacimiento, sexo, fchCreacion, ultimaSesion, ip, llave, activo, "
. "imgPerfil, nivel)"
. " VALUES (:apodo, :password, :correo, :nombre, :apellido, "
. ":fchNacimiento, :sexo, NOW(), NOW(), 'Ip aqui', :llave, '1', "
. "'imagen aqui', 'I')";
$sqlInsertCandidato = "INSERT INTO Candidato (correo) VALUES (:correo)";
$sentencia = $this->getConexion()->prepare($sqlInsertUsuario);
$sentencia->execute(array(':apodo' => $apodo, ':password' => $clave, ':correo' => $correo,
':nombre' => $nombre, 'apellido' => $apellido, 'fchNacimiento' => date($fchNacimiento),
':sexo' => $sexo, ':llave' => $llave));
$sentencia = $this->getConexion()->prepare($sqlInsertCandidato);
$sentencia->execute(array(':correo' => $correo));
$this->getConexion()->commit();
echo 'TRUE';
}
catch (Exception $ex)
{
$this->getConexion()->rollBack();
echo 'FALSE';
}
}
the problem is that returns "FALSE" but the data is inserted in the table anyway.
I found the problem, the thing is that I was calling the connection too many times in this method: $this->getConexion()->beginTransaction();
so the solution was to create a variable "$pdo" that saves the connection and later will use it for all the transaction.
$pdo = $this->getConexion();
$pdo->beginTransaction();
instead of this:
$sentencia = $this->getConexion()->prepare($sqlInsertUsuario);
$sentencia = $this->getConexion()->prepare($sqlInsertCandidato);
$this->getConexion()->commit();
use this:
$sentencia = $pdo->prepare($sqlInsertUsuario);
$sentencia = $pdo->prepare($sqlInsertCandidato);
$pdo->commit();
i was trying to get parent_id which is the last_insert_id. I am using php PDO, i was trying to get lastinsertedId but it keeps gave me an error.
I am able to execute parentRegister but i cannot get the lastInsertId using PDO.
What's wrong on my code?
function connect() {
// connection template
// $pdo = new PDO('mysql:host=127.0.0.1;dbname=SocialNetwork;charset=utf8','root','');
global $host;
global $dbName;
global $dbusername;
global $dbpassword;
try {
$pdo = new PDO("mysql:host=".$host.";dbname=".$dbName."", $dbusername, $dbpassword);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); // fetch as associative
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); // fetch as object
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
return $pdo;
} catch (PDOException $e) {
// die('error message: '.$e->message().'<br>');
// die('Our system have some problems now. Please try again later');
return false;
}
}
function query($query, $params = array()) {
$stmt = connect()->prepare($query);
$stmt->execute($params);
if(explode(' ', $query)[0] == 'SELECT'){
$data = $stmt->fetchAll();
return $data;
}
}
// parents 7 column
$parentsData = array(
'role_id' => 2,
'email' => $submittedData['email'],
'parent_name' => $submittedData['parentName'],
'phone' => $submittedData['phone'],
'address' => $submittedData['address'],
'postcode' => $submittedData['postcode'],
'password' => $submittedData['password']
);
// swimmers 6 column
$swimmersData = array(
'role_id' => 3,
'username' => $submittedData['username'],
'password' => $submittedData['password'],
'fname' => $submittedData['fname'],
'lname' => $submittedData['lname'],
'dob' => $submittedData['dob']
);
$parentsRegister = query('INSERT INTO parents('.$parentsField.') VALUES ('.$parentsValue.')', $parentsData);
$swimmersRegister = query('INSERT INTO swimmers('.$swimmersField.',`parent_id`) VALUES ('.$swimmersValue.','.connect()->query("SELECT LAST_INSERT_ID()")->fetchColumn().')', $swimmersData);
I tried to use this code but keeps gave me 0
$stmt = connect()->lastInsertId();
echo $stmt;
just figured out $pdo need to be set as global variable.
// put pdo variable as global to handle last inserted id
$pdo;
function connect() {
global $host;
global $dbName;
global $dbusername;
global $dbpassword;
global $pdo;
try {
$pdo = new PDO("mysql:host=".$host.";dbname=".$dbName."", $dbusername, $dbpassword);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
// $pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC); // fetch as associative
$pdo->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_OBJ); // fetch as object
$pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
return $pdo;
} catch (PDOException $e) {
// die('error message: '.$e->message().'<br>');
// die('Our system have some problems now. Please try again later');
return false;
}
}
function query($query, $params = array()) {
$stmt = connect()->prepare($query);
$stmt->execute($params);
// if select
if(explode(' ', $query)[0] == 'SELECT'){
$data = $stmt->fetchAll();
return $data;
// otherwise (update, delete, insert)
} else {
return ($stmt) ? true : false;
}
}
// insert to database
$parentsRegister = query('INSERT INTO parents('.$parentsField.') VALUES ('.$parentsValue.')', $parentsData);
$swimmersRegister = query('INSERT INTO swimmers('.$swimmersField.',`parent_id`) VALUES ('.$swimmersValue.','.$pdo->lastInsertId().')', $swimmersData);
I want to insert data into CLOUD and IDC tables.
Cloudid is the foreign key of IDC table, so i want to use transaction.
Before $conn->beginTransaction(); and $conn->commit(); are added ,it works fine, but without them, it works fine.
Here is my code:
<?php
if($_GET["act"]=="add")
{
try
{
$conn=new PDO('mysql:host=localhost;port=3306;dbname=xxx' , 'root' , 'xxxx');
//$conn->beginTransaction();
$query="
insert into CLOUD (name,date) VALUES('".$_POST['customerName']."','".$_POST['firstDay']."');
insert into IDC (name,id,phone,cloudid) VALUES('".$_POST['engName3']."','".$_POST['engID3']."','".$_POST['engPhone3']."',LAST_INSERT_ID());
insert into IDC (name,id,phone,cloudid) VALUES('".$_POST['engName4']."','".$_POST['engID4']."','".$_POST['engPhone4']."',LAST_INSERT_ID());
";
$stmt=$conn->query($query);
//$conn->commit();
echo "success";
}
catch(PDOException $e)
{
$conn->rollBack();
echo "connect failed!".$e->getMesage();
exit;
}
}
?>
Transactions are only available when the database uses InnoDB as the storage engine. You are probably using MyISAM
Have a look here for more details on the difference between the storage engines https://dev.mysql.com/doc/refman/5.7/en/storage-engines.html
As a side note, your code is vulnerable to SQL injections because you use raw post data in non prepared queries. you should have a look there : How can I prevent SQL injection in PHP?
Try to initiate your connection and get last inserted id like below, also i would recommend you to use prepared statements (see http://php.net/manual/ru/pdo.prepare.php):
if($_GET["act"]=="add")
{
try {
$dbh = new PDO('mysql:host=localhost;port=3306;dbname=xxx', 'root', 'xxx',
array(PDO::ATTR_PERSISTENT => true));
echo "Connected\n";
} catch (Exception $e) {
die("Unable to connect: " . $e->getMessage());
}
try {
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
$dbh->beginTransaction();
$stmt = $dbh->prepare('insert into CLOUD (name,date) VALUES(:customerName,:firstDay)');
$stmt->execute([
'customerName' => $_POST['customerName'],
'firstDay' => $_POST['firstDay']
]);
$cloud_id = $dbh->lastInsertId();
$stmt = $dbh->prepare('insert into IDC (name,id,phone,cloudid) VALUES(:name,:id,:phone,:cloudid)');
$stmt->bindParam(':name', $name);
$stmt->bindParam(':id', $id);
$stmt->bindParam(':phone', $phone);
$stmt->bindParam(':cloudid', $cloud_id);
$name = $_POST['engName3'];
$id = $_POST['engID3'];
$phone = $_POST['engPhone3'];
$stmt->execute();
$name = $_POST['engName4'];
$id = $_POST['engID4'];
$phone = $_POST['engPhone4'];
$stmt->execute();
$dbh->commit();
} catch (PDOException $e) {
$dbh->rollBack();
echo "Failed: " . $e->getMessage();
}
}
I am building am app that should execute multiple queries that involve insert, delete and update commands. There is no syntax error but I discovered that the delete command did not delete entry but the insert command inserted row and the action did not rollback. If the delete action did not happen, insert and others should be cancelled is the desired result.
<?
try {
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$pdo->beginTransaction();
$D = 2;
$Dn = 3;
$dumpi = $pdo->prepare("INSERT INTO `dumpi` .... SELECT .... FROM .... ");
$dumpi->execute();
$matchi = $pdo->prepare("DELETE FROM `marchi` WHERE `id`=....");
$matchi->execute();
$usri = $pdo->prepare("UPDATE `users` SET `status`='0' WHERE `id`='$Dn' ");
$usri->execute();
$donati = $pdo->prepare("UPDATE `dnsn` SET `status`='d' WHERE `id`='$D' ");
$donati->execute();
$donatidel = $pdo->prepare("UPDATE `dnsn` SET `status`='d',`deleted_by`='m' WHERE `dn`='$Dn' AND `status`='1' ");
$donatidel->execute();
$navwal = $pdo->prepare("UPDATE `wlt` SET `status`='0' WHERE `user`='$Dn'");
$navwal->execute();
$navwalt = $pdo->prepare("UPDATE `wlt` SET `status`='0' WHERE `dn`='$Dn' ");
$navwalt->execute();
// dont let te $D and Dn confuse you, its not the one causing any error
$pdo->commit();
// echo 'it works';
} catch (PDOException $e) {
$pdo->rollBack();
echo "Failed: " . $e->getMessage();
}
?>
The code ended here...
my connection to Db is of this script here...(just added for ref. php7)
$pdoOptions = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_EMULATE_PREPARES => true);
try {
$pdo = new PDO(
"mysql:host=" . MYSQL_HOST . ";dbname=" . MYSQL_DATABASE, //DSN
MYSQL_USER, //Username
MYSQL_PASSWORD, //Password
$pdoOptions //Options
);} catch (Exception $e) {
// design this well to make sense
die(
// conmment out in launch
$e->getMessage())
);
}
Well, if a query do not find any data, it is not an error.
If it's important for you that the delete query should necessarily find the the record to delete, then you have to verify that manually and than throw an exception.
$stmt = $pdo->prepare("DELETE FROM `marchi` WHERE `id`=?");
$stmt->execute([....]);
if (!$stmt->rowCount())
{
throw new Exception("Delete didn't find a record")
}
And then catch Exception, not PDOException.
Note that for some reason you aren't using prepared statements while you should
Reccently I have been attempting to insert an array into a database, I keep getting the error message "Notice: Array to string conversion", I not really sure how to resolve this issue, any advice would be greatly appreciated
<?php
try{
$db = new PDO("mysql:host=localhost;dbname=test", 'root', '');
$db ->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e){
echo $e->getMessage();
die();
}
if ($_SERVER["REQUEST_METHOD"] == "POST"){
$sort = $_POST['sort'];
$count = $_POST["count"];
$error = $_POST["error"];
$audit = array( ':sort' => $sort,
':count' => $count,
':error' => $error
);
foreach($audit as $completeAudit => $display) {
//print_r($display);
$sql = implode("INSERT INTO `audits` (`sort`, `count`, `error`, `timeentered`) VALUES ('$sort','$count','$error', NOW())");
}
$query = $db->prepare($sql);
$query->execute(array(
':sort' => $sort,
':count' => $count,
':error' => $error
));
}
EDIT
$db = new PDO("mysql:host=localhost;dbname=test", 'root', '');
$db ->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if ($_SERVER["REQUEST_METHOD"] == "POST"){
$sql = "INSERT INTO `audits` (`sort`, `count`, `error`, `timeentered`) VALUES (?,?,?, NOW())";
$stmt = $db->prepare($sql);
$query->execute(array($_POST['sort'], $_POST["count"], $_POST["error"]));
}
This is how it looks now, I deleted everything and used code supplied below
The problem is probably with the implode() call. It requires an array as parameter but you're passing a string.
However, you're overriding the $sql variable in every iteration inside the loop so I'm not sure what it's supposed to do.
Last thing, your code is subject to SQL inejctions so have a look at using prepared statements.
this error has nothing to do with PDO - it's just basic PHP syntax.
However, your PDO is wrong as well. Here is the proper code:
$db = new PDO("mysql:host=localhost;dbname=test", 'root', '');
$db ->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
if ($_SERVER["REQUEST_METHOD"] == "POST"){
$sql = "INSERT INTO `audits` (`sort`, `count`, `error`, `timeentered`) VALUES (?,?,?, NOW())");
$stmt = $db->prepare($sql);
$stmt->execute(array($_POST['sort'], $_POST["count"], $_POST["error"]));
}