PDO connection / prep and execute in there own functions best practice - php

Hi all i have been playing with PDO's and am slowly converting some old code over to this.
Getting a little stuck with a few thing and struggling to find what i need.
What i am getting stuck on is:
Having the $db in a function or the sorts so its only open when i
call it, i only want to manage one instance of this
checking if
execute was successful and if not return a value etc.
Also any advice on the below code would be great full as i have gathered this from sources around the web.
Current Code:
//Database Array
$config['db'] = array(
'host' => 'localhost',
'username' => 'root',
'password' => 'root',
'dbname' => 'root');
//New PDO
$db = new PDO('mysql:host=' . $config['db']['host'] . ';dbname=' . $config['db']['dbname'], $config['db']['username'], $config['db']['password']);
//Check connection is ok
try {
$db->exec("SET CHARACTER SET utf8");
}
catch (PDOException $ex) {
print "Error!: " . $ex->getMessage() . "<br/>";
die();
}
//Update users function
function update($db, $fn, $ln, $email, $offers, $vlue, $responce) {
$stmt = $db->prepare("insert into kkt (fName_765, lName_765, email_765, signup_765, stamp_765) values (:fname, :lname, :email, :signup, NOW())");
$stmt->bindParam(':fname', $fn, PDO::PARAM_STR);
$stmt->bindParam(':lname', $ln, PDO::PARAM_STR);
$stmt->bindParam(':email', $email, PDO::PARAM_STR);
$stmt->bindParam(':signup', $offers, PDO::PARAM_STR);
$stmt->execute();
print $db->lastInsertId();
$stmt = null;
}
//Test Attributes
$fn = 'test';
$ln = 'test';
$email = 'tesst#test,com';
$offers = '1';
update($db, $fn, $ln, $email, $offers, $vlue, $responce);
thanks in advance for any help / tips
Edited Code:
//Database Array
$config['db'] = array(
'host' => 'localhost',
'username' => 'root',
'password' => 'root',
'dbname' => 'local');
//New PDO
$db = new PDO('mysql:host=' . $config['db']['host'] . ';dbname=' . $config['db']['dbname'], $config['db']['username'], $config['db']['password']);
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//Check connection is ok
try {
$db->exec("SET CHARACTER SET utf8");
}
catch (PDOException $ex) {
print "Error!: " . $ex->getMessage() . "<br/>";
die();
}
//Update users function
function update($db, $fn, $ln, $email, $offers, $vlue, $responce)
{
$stmt = $db->prepare("insert into local (fName_765, lName_765, email_765, signup_765) values (:fname, :lname, :email, :signup, NOW())");
$stmt->bindParam(':fname', $fn, PDO::PARAM_STR);
$stmt->bindParam(':lname', $ln, PDO::PARAM_STR);
$stmt->bindParam(':email', $email, PDO::PARAM_STR);
$stmt->bindParam(':signup', $offers, PDO::PARAM_STR);
try {
$stmt->execute();
print $db->lastInsertId(); //show ID
return true;
}
catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>"; // show error
return false;
}
}
//Test Attributes
$fn = 'test';
$ln = 'test';
$email = 'tesst#test,com';
$offers = '1';
if (!update($db, $fn, $ln, $email, $offers, $vlue, $responce)) {
echo "no update there is a slight problem";
} else {
echo "it seemed to work";
}
Seem to be getting there, the above works hows it looking

checking if execute was successful and if not return a value etc.
Personally I prefer Exceptions, and PDO can be configured to raise Exceptions on errors. Exceptions are nice because the code that comes after the failed statement is not executed. This comes handy if you've a parent row, and then write some child rows which depend on the inserted parent. You don't want to write the child rows when the parent could not be created.
One can turn this on by doing this:
<?php
$pdo = new PDO(/* DSN */);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ATTR_ERRMODE_EXCEPTION);
Then you would do:
<?php
try {
$stmt->execute();
return true;
} catch (\PDOException $e) {
return false;
}
You can find more about this here: http://www.php.net/manual/en/pdo.error-handling.php
Having the $db in a function or the sorts so its only open when i call it, i only want to manage one instance of this
I'm usually managing a database connection by using a service container. The simplest existing option is Pimple. You then pass this service container around, and the service container is responsible for only creating one database connection.
<?php
$config = new \Pimple;
$config['db.options'] = array(
'host' => 'localhost',
'username' => 'root',
'password' => 'root',
'dbname' => 'root');
# Calling the "share" method makes sure that the function is only called when
# 'db' is retrieved the first time.
$config['db'] = $config->share(function() use ($config) {
return new PDO('mysql:host=' . $config['db.options']['host'] . ';dbname=' . $config['db.options'']['dbname'], $config['db.options'']['username'], $config['db.options'']['password']);
});
function update() {
global $config;
# Connection is only made the first time the 'db' key is accessed.
$db = $config['db'];
/* Do queries */
}

Having the $db in a function or the sorts so its only open when i call
it, i only want to manage one instance of this.
Open it at the start of your script and then pass it into the functions that need it. Opening a new database connection inside a function can lead to problems further down the line. For example, what if your function is used multiple times throughout the same script? You don't really want to open a new database connection every time that same function gets called.
checking if execute was successful and if not return a value etc.
As for checking if PDOStatement::execute was successful:
$result = $stmt->execute();
If you look at the manual, the return types are listed as:
Returns TRUE on success or FALSE on failure.
$result = $stmt->execute();
return $result;
or
return $stmt->execute();
Personally, I'd go with:
function update($db, $fn, $ln, $email, $offers, $vlue, $responce) {
$stmt = $db->prepare("insert into kkt (fName_765, lName_765, email_765, signup_765, stamp_765) values (:fname, :lname, :email, :signup, NOW())");
$stmt->bindParam(':fname', $fn, PDO::PARAM_STR);
$stmt->bindParam(':lname', $ln, PDO::PARAM_STR);
$stmt->bindParam(':email', $email, PDO::PARAM_STR);
$stmt->bindParam(':signup', $offers, PDO::PARAM_STR);
return $stmt->execute();
}
By the way, when you pass an object into a function, it is automatically passed by reference, which means that you can do something like:
$result = update($db, $fn, $ln, $email, $offers, $vlue, $responce);
if($result){
echo $db->lastInsertId();
}

Related

How can I provide conditions in SQL query?

I'm trying to update the database table. How can I prevent the password ("MemberPassword", $ pass) coming from the form from being updated with sql codes by providing a condition if it is empty? Is it possible?
//database connection
$SQL = "mysql:host=" . $this->MYSQL_HOST . ";dbname=" . $this->MYSQL_DB;
try {
$this->pdo = new \PDO($SQL, $this->MYSQL_USER, $this->MYSQL_PASS);
$this->pdo->exec("SET NAMES'" . $this->CHARSET . "'COLLATE'" . $this->COLLATION . "'");
$this->pdo->exec("SET CHARACTER SET'" . $this->CHARSET . "'");
$this->pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
$this->pdo->setAttribute(\PDO::ATTR_DEFAULT_FETCH_MODE, \PDO::FETCH_OBJ);
} catch (PDOException $e) {
die( $e->getMessage());
}
}
//Connect DB END
private function myQuery($query, $params = null)
{
if (is_null($params)) {
$this->stmt = $this->pdo->query($query);
} else {
$this->stmt = $this->pdo->prepare($query);
$this->stmt->execute($params);
}
return $this->stmt;
}
public function Update($query, $params = null)
{
try {
return $this->myQuery($query, $params)->rowCount();
} catch (PDOException $e) {
die($e->getMessage());
}
}
$update = $db->Update("UPDATE members SET
MemberUsername=?,
MemberPassword=?,
MemberEmail=?,
MemberName=?,
MemberLastName=?,
MemberBirthday=?,
MemberAge=?,
MemberGender=?,
CityID=?
WHERE MemberID=?
", array($username, $pass, $email, $name, $lastname, $birthday, $age, $gender, $city, $memberID));
You can easy use IFNULL(expr1,expr2) like:
IFNULL returns expr1 if they is not null else expr2
$update = $db->Update("UPDATE members SET
MemberUsername=?,
MemberPassword=IFNULL(?,MemberPassword),
MemberEmail=?,
MemberName=?,
MemberLastName=?,
MemberBirthday=?,
MemberAge=?,
MemberGender=?,
CityID=?
WHERE MemberID=?
", array($username, $pass, $email, $name, $lastname, $birthday, $age, $gender, $city, $memberID));
Use something like this in your php code:
$param = array($username, $email, $name, $lastname, $birthday, $age, $gender, $city);
$sqlUpdate = "UPDATE members SET
MemberUsername=?,
MemberEmail=?,
MemberName=?,
MemberLastName=?,
MemberBirthday=?,
MemberAge=?,
MemberGender=?,
CityID=?"
if(!is_null(pass)) {
$sqlUpdate = $sqlUpdate . ", MemberPassword = ?";
array_push($param , $pass);
}
$sqlUpdate = $sqlUpdate . " WHERE MemberID=?";
array_push($param , $memberID);
$update = $db->Update($sqlUpdate, $param);
You can use this pattern for all other fields.
I didn't understand what your question exactly is but I think this is what you want :
User submits a form and if Password that sent from this form was not empty then update everything including password, otherwise update everything except password!
For do this you can use if statement in your SQL Query
$update = $db->Update("UPDATE members SET
MemberUsername=?,
MemberPassword=IF(? IS NOT NULL AND LENGTH(?) > 0, ?, MembersPassword),
MemberEmail=?,
MemberName=?,
MemberLastName=?,
MemberBirthday=?,
MemberAge=?,
MemberGender=?,
CityID=?
WHERE MemberID=?
", array($username, $pass, $pass, $pass, $email, $name, $lastname, $birthday, $age, $gender, $city, $memberID));

PDO Exception : Tried to bind parameter number 65536. SQL Server supports a maximum of 2100 parameters

I want to read user data. But the result showing like
Tried to bind parameter number 65536. SQL Server supports a maximum
of 2100 parameters.
and here is my code of login.php (test with hard code first)
<?php
header("Content-type: application/json");
include_once 'Database.php';
include_once 'master.php';
//$username = $_GET['username'];
//$password = $_GET['password'];
$username = "angela123";
$password = "admin123";
// get database connection
$database = new Database();
$db = $database->getConnection();
$login = new Master($db);
$stmt = $login->Login($username, $password);
?>
and here is function of Login with parameter username and password
public function Login($username,$password)
{
// select all query
try {
$sqlsrvquery = ("
EXEC [dbo].[GetAllAdmin2]
#username = ':username',
#password = ':password',
");
// prepare query statement
$stmt = $this->conn->prepare($sqlsrvquery);
$stmt->bindParam(':username', $username, PDO::PARAM_STR);
$stmt->bindParam(':password', $password, PDO::PARAM_STR);
$stmt->execute();
while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
$admin_arr = array(
"username" => $row['username'],
"password" => $row['password'],
);
}
if ($row = 0) {
$admin_arr = array(
"status" => false,
"message" => "Invalid Get Data Admin!",
);
}
} catch (Exception $e) {
print_r($e->getMessage());
}
print_r(json_encode($admin_arr));
}
What's going on in this code? actually the result is working properly on SQL Server with SP
Here is the Login SP
ALTER Procedure [dbo].[GetAllAdmin2]
(
#username varchar(55),
#password varchar(55)
)
as
begin
SELECT username, password
FROM Admin
WHERE username = #username and password = #password
and status = 'Active';
END
When execute the SP, the output should be showing username and password
username password
angela123 admin123
And here is database.php
<?php
class Database
{
// specify your own database credentials
private $host = "DESKTOP-N550JK\SQLEXPRESS";
private $user = "sa";
private $database = "Library";
private $password = "sqlserver123";
public $conn;
// get the database connection
public function getConnection(){
try {
$this->conn = new PDO("sqlsrv:Server=" .$this->host . ";database=" . $this->database, $this->user, $this->password);
$this->conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $exception) {
echo "Connection error: " . $exception->getMessage();
die("Database Connection Error");
}
return $this->conn;
}
}
?>
any solution of this? thanks
You are using parameter binding in a wrong way and you need to remove the quotes around the placeholders (:username and :password). As is explained in the documetation, the statement template can contain zero or more named (:name) or question mark (?) parameter markers for which real values will be substituted when the statement is executed.
<?php
...
// Statement
$sqlsrvquery = "
EXEC [dbo].[GetAllAdmin2]
#username = :username,
#password = :password
";
$stmt = $this->conn->prepare($sqlsrvquery);
// Parameter bindings
$stmt->bindParam(':username', $username, PDO::PARAM_STR);
$stmt->bindParam(':password', $password, PDO::PARAM_STR);
// Statement execution
$stmt->execute();
...
?>
An additional example, using the ? parameter marker:
<?php
...
// Statement
$sqlsrvquery = "
EXEC [dbo].[GetAllAdmin2]
#username = ?,
#password = ?
";
$stmt = $this->conn->prepare($sqlsrvquery);
// Parameter bindings
$stmt->bindParam(1, $username, PDO::PARAM_STR);
$stmt->bindParam(2, $password, PDO::PARAM_STR);
// Statement execution
$stmt->execute();
...
?>

php: PDO exception handling

I have two PHP files DBConnector.php
<?php
class DBConnector {
const DB_STRING = 'mysql:host=localhost;dbname=test';
const DB_USER = 'test';
const DB_PASSWORD = 'qwerty';
private $connection;
function __construct() {
$this->connection = new PDO(self::DB_STRING, self::DB_USER, self::DB_PASSWORD);
$this->connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
function register_user($user_type, $login, $password, $email, $phone) {
$insert_user_sql = "insert into users (login, password, email, rating, phones, user_type)
values (:login, password(:password), :email, 0, :phone, :user_type)";
$sth = $this->connection->prepare($insert_user_sql);
$sth->execute(array(':login' => $login,
':password' => $password,
':email' => $email,
':phone' => $phone,
':user_type' => $user_type));
}
}
?>
and application.php
<?php
require "DBConnector.php";
require "UserType.php";
try {
$db = new DBConnector();
$db->register_user(UserType::OWNER, "test", "test", "test#gmail.com", "+111111111111");
} catch (Exception $e) {
echo "Error occured " + $e->getMessage();
}
?>
If the "insert into users" in DBConnector->register_user generates PDO exception, I can't catch it in my application.php.
Please, help me, what I'm doing wrong.
I found the problem.
The problem was in "plus" symbol, besides "." in echo command.
So "0" was printed, instead "Error occured..."

php PDO prepare(" INSERT ..(variables ) VALUES(?,?,) produces an error need assistance

$query = $this->link->prepare("INSERT INTO surveys (`username`,`inspected`,
`comments`,`ip_address`,`date`,`time`)
VALUES '(?,?,?,?,?,?)';);
$values = array ($username,$inspected,$comments,$ip_address,$date,$time);
var_dump($query);$rowCount = $query->rowCount();
$return $rowCount;
You can base yourself on the following which I've prepared for you.
Sidenote: I'm not entirely sure as to why you want to use rowCount() for, so I left it out for now.
If you're looking to check if a record exists using rowCount(), let me know.
The following method works to insert data into a database, which is based on a method I use.
<?php
$dbname = 'xxx';
$username = 'xxx';
$password = 'xxx';
try {
$pdo = new PDO("mysql:host=localhost;dbname=$dbname", $username, $password);
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch (PDOException $e) {
exit( $e->getMessage() );
}
$sql = "INSERT INTO surveys (
username,
inspected,
comments,
ip_address,
date,
time
) VALUES (
:username,
:inspected,
:comments,
:ip_address,
:date,
:time)";
$stmt = $pdo->prepare($sql);
$stmt->bindParam(':username', $_POST['username'], PDO::PARAM_STR);
$stmt->bindParam(':inspected', $_POST['inspected'], PDO::PARAM_STR);
$stmt->bindParam(':comments', $_POST['comments'], PDO::PARAM_STR);
$stmt->bindParam(':ip_address', $_POST['ip_address'], PDO::PARAM_STR);
$stmt->bindParam(':date', $_POST['date'], PDO::PARAM_STR);
$stmt->bindParam(':time', $_POST['time'], PDO::PARAM_STR);
// $stmt->execute();
$stmt->execute(array(':username' => $_POST['username'],':inspected' => $_POST['inspected'],':comments' => $_POST['comments'],
':ip_address' => $_POST['ip_address'],':date' => $_POST['date'],':time' => $_POST['time']));
if($stmt != false) {
echo "success!";
} else {
echo "an error occured saving your data!";
}

Data insert into mysql db table using PDO - Doesn't Insert Data

I'm 'Connected to database'. There is no data in the table, and $result doesn't echo anything. Even though I'm 'Connected to database', the error is as follows:
SQLSTATE[3D000]: Invalid catalog name: 1046 No database selected
I've read the relevant postings, with no luck.
<?php
include("/directory outside of html/db.php");
try {
$dbh = new PDO("mysql:host=$host;database=$database", $username, $password);
/*** echo a message saying we have connected ***/
echo 'Connected to database';
$dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
//try to insert data
$fname = 'BOB';
$lname = 'JONES';
$email = 'me#mymail.com';
$phone = '410-310-3456';
$resident = TRUE;
$age = '25=30';
$zip = '23456';
$result = FALSE;
$stmt = $dbh->prepare('INSERT INTO volunteers
(
lname,
fname,
email,
)
VALUES
(
:lname,
:fname,
:email,
)');
$result = $stmt->execute(array(
':lname' => $lname,
':fname' => $fname,
':email' => $email,
));
echo $result;
//catch any errors from try()
}
catch(PDOException $e)
{
echo $e->getMessage();
}
?>
Use dbname= instead of database= , like this:
$dbh = new PDO("mysql:host=$host;dbname=$database", $username, $password);
Alternatively, you can select later a different database with USE, like this:
$dbh->query("use newdatabase");

Categories