class ActionWires{
public static function _checkExistDate($array){
try{
$sql = "SELECT id FROM wires WHERE fdate = ?";
$state = pdoConnect::_connect() ->prepare($sql);
$state->execute($array);
return $state->fetch()?true:false;
}catch(PDOException $e){
echo "database connection fail".$e->getMessage();
exit();
}
}
public static function _showWires($array){
try{
$sql = "SELECT id,wname,fdate,fname,fpath,caption,category FROM wires WHERE fdate = ?";
$state = pdoConnect::_connect() ->prepare($sql);
$state->execute($array);
return $state->fetchAll();
}catch(PDOException $e){
echo "database connection fail".$e->getMessage();
exit();
}
}
There are lot of codes are the same. The main difference is sql query and return value. Are there any suggestion to minimize the same codes.
It'll be hard to minimise this completely because of the different return types.
From a quick glance, I think about the best you can do is have a shared function which accepts the SQL string and parameter array, and runs the prepare and execute commands, and returns the result object. For example:
class ActionWires
{
public static function _checkExistDate($array){
try{
$sql = "SELECT id FROM wires WHERE fdate = ?";
$state = self::runSQL($sql, $array);
return $state->fetch()?true:false;
}catch(PDOException $e){
echo "database connection fail".$e->getMessage();
exit();
}
}
public static function _showWires($array){
try{
$sql = "SELECT id,wname,fdate,fname,fpath,caption,category FROM wires WHERE fdate = ?";
$state = self::runSQL($sql, $array);
return $state->fetchAll();
}catch(PDOException $e){
echo "database connection fail".$e->getMessage();
exit();
}
}
private static function runSQL($sql, $paramList)
{
$state = pdoConnect::_connect() ->prepare($sql);
$state->execute($paramList);
return $state;
}
}
But it only saves you a couple of lines.
Related
I created a function to grab data from my database. I want this function to be reusable just by placing correct arguments for different tables. Here's what I've done :
public function selectdata($table, $arguments='*', $where = null){
if($this->isconnect){
//check whether users put column names in the select clause
if(is_array($arguments)){
$new_args = implode(',', $arguments);
$sql = 'SELECT '.$new_args.' FROM '.$table;
} else {
$sql = 'SELECT '.$arguments.' FROM '.$table;
}
//check whether users use the where clause
if($where != null && is_array($where)){
$where = implode(' ', $where);
$sql .= ' WHERE '.$where ;
}
$query = $this->db->query($sql);
$query -> SetFetchMode(PDO::FETCH_NUM);
while($row = $query->fetch()){
print_r($row);
}
} else {
echo 'failed, moron';
}
}
And this is the way to run the function :
$columnname = array('bookname');
$where = array('bookid','=','2');
echo $database-> selectdata('buku', $columnname, $where);
The code worked quite decently so far, but I'm wondering how I want to use $where but without $columnname in the function. How do I pass the arguments in the function?
And could you point to me the better way to create a function to grab data using PDO?
Just use a PDO class which can look like this:
<?php
class DB_Connect{
var $dbh;
function __construct(){
$host = "xxx";
$db = "xxx";
$user = "xxx";
$password = "xxx";
$this -> dbh = $this -> db_connect($host, $db, $user, $password);
}
public function getDBConnection(){
return $this -> dbh;
}
protected function db_connect($host, $db, $user, $password){
//var_dump($host, $db, $user, $password);exit();
try {
$dbh = new PDO("mysql:host=$host;dbname=$db", $user, $password);
}
catch(PDOException $err) {
echo "Error: ".$err->getMessage()."<br/>";
die();
}
return $dbh;
}
public function query($statement){
$keyword = substr(strtoupper($statement), 0, strpos($statement, " "));
$dbh = $this->getDBConnection();
if($dbh){
try{
$sql = $dbh->prepare($statement);
$exe = $sql->execute();
}
catch(PDOException $err){
return $err->getMessage();
}
switch($keyword){
case "SELECT":
$result = array();
while($row = $sql->fetch(PDO::FETCH_ASSOC)){
$result[] = $row;
}
return $result;
break;
default:
return $exe;
break;
}
}
else{
return false;
}
}
}
?>
Now you can include that class and create an object with $dbh = new DB_Connect; and call every statement you want just with the reference on $dbh->query($statement)
This is my prefered way to do this.
EDIT: If you want to use a statement on another Database, just use the __construct($db) method to pass your database name on object creation
I am very new to php and this is my first attempt at using mysqli. I can't seem to figure out why I am getting this error? I have reviewed similar questions on it but I still don't understand what the problem is.
Here is my code:
<?php
require_once('abstractDAO.php');
class customerDAO extends abstractDAO {
function __construct() {
try{
parent::__construct();
} catch(mysqli_sql_exception $e){
throw $e;
}
}
public function getCustomers(){
//The query method returns a mysqli_result object
$result = $this->mysqli->query('SELECT * FROM customers');
$customers = Array();
if($result->num_rows >= 1){
while($row = $result->fetch_assoc()){
$customer = new Customer($row['customerName'], $row['phoneNumber'], $row['emailAddress']);
$customers[] = $customer;
}
$result->free();
return $customers;
}
$result->free();
return false;
}
/*
* This is an example of how to use a prepared statement
* with a select query.
*/
public function getCustomer($customerName){
$query = 'SELECT * FROM customers WHERE customerName = ?';
$stmt = $this->mysqli->prepare($query);
$stmt->bind_param('s', $customerName);
$stmt->execute();
$result = $stmt->get_result();
if($result->num_rows == 1){
$temp = $result->fetch_assoc();
$customer = new Customer($temp['customerName'], $temp['phoneNumber'], $temp['emailAddress']);
$result->free();
return $customer;
}
$result->free();
return false;
}
public function addCustomer($customer){
if(!$this->mysqli->connect_errno){
$query = 'INSERT INTO customers VALUES (?,?,?)';
$stmt = $this->mysqli->prepare($query);
$stmt->bind_param('sss',
$customer->getCustomerName(),
$customer->getPhoneNumber(),
$customer->getEmailAddress());
$stmt->execute();
if($stmt->error){
return $stmt->error;
} else {
return $customer->getCustomerName() . ' added successfully!';
}
} else {
return 'Could not connect to Database.';
}
}
}
?>
Let me know if you need any more code snippets.
Any suggestions would be very much appreciated!
mysqli::prepare returns false if there was an error.
false is not an object, thus you get the error:
call to method function on bind_param() on a non-object.
You can get the error message by examining the $mysqli->error property.
public function addCustomer($customer) {
if(!$this->mysqli->connect_errno) {
$query = 'INSERT INTO customers (customerName,phoneNumber,emailAddress)
VALUES (?,?,?)';
$stmt = $this->mysqli->prepare($query);
if (!$stmt) {
$err = $this->mysqli->error;
echo $err;
// do something with $err
return $err;
}
$stmt->bind_param('sss',
$customer->getCustomerName(),
$customer->getPhoneNumber(),
$customer->getEmailAddress());
if(!$stmt->execute()){
return $stmt->error;
} else {
return $customer->getCustomerName() . ' added successfully!';
}
} else {
return 'Could not connect to Database.';
}
}
The most typical reason why prepare fails is a malformed or invalid query, but without knowing the customer schema or constraints I can't be sure what your particular problem is.
I connected to the DB via this.
public static function connect() {
try {
self::$db_handle = new PDO("mysql:host=".SERVER.";dbname=".DBNAME,USER, PASSWORD);
self::$db_handle->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
echo "Successful connected to DB<br/>";
}
catch(PDOException $e) {
echo "Conncection failed: " . $e->getMessage();
exit();
}
}
It echoes Successful Connection. So am guessing, there is no issue with the connectivity.
Now I use the following code to query the DB.
$sql=func_get_arg(0);
$params=array_slice(func_get_args(), 1);
$statement=self::$db_handle->prepare($sql);
echo "<br/>Stat: ".$statement."</br>"; //Just for testing purposes
if($statement===false){
echo "False";
return false;
}
if(count($params)==0){
$results=$statement->execute();
}
else
$results=$statement->execute($params);
if($results===false)
return false;
else{
return $statement->fetchAll(PDO::FETCH_ASSOC);
}
I have no clue why it echoes False. The statement which I tried to echo is an empty string.
$sql =
"SELECT * FROM `users` where $key = ?"
and $params is the email address itself.
I am unable to detect my fault. Kindly help. Thanks :)
change it to this
public static function connect()
{
self::$db_handle = new PDO("mysql:host=".SERVER.";dbname=".DBNAME,USER, PASSWORD);
self::$db_handle->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
self::$db_handle->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
$PDO = <yourclass>::connect();
$statement = $PDO->prepare("SELECT * FROM users WHERE key=?");
$statement->execute(array(1));
echo $PDO->lastInsertId();
I'm tinkering with a class that 'should' allow me to easily execute a fetchall query and display the results within a foreach statement. I assume all is working correctly as I have no errors. As for the foreach - this must be the problem? How would I foreach the results gained from the $connect->query()? I'm new to using any database OOP framework in my functions so I could be along the wrong lines completely.
<?
error_reporting(1);
class dbconnect {
private $host;
private $database;
private $username;
private $password;
private $pdo;
private $error;
public function __construct() {
$this->host = "localhost"; // Host
$this->database = "images"; // Database Name
$this->username = "*"; // Username
$this->password = "*"; // Password
$options = array(
PDO::MYSQL_ATTR_INIT_COMMAND => 'SET NAMES utf8'
);
try {
$this->pdo = new PDO("mysql:host={$this->host};dbname={$this->dbname};charset=utf8", $this->username, $this->password, $options);
}
catch(PDOException $e) {
$this->error = $e->getMessage();
}
}
public function query($query) {
try {
$stmt = $this->pdo->prepare($query);
$stmt->execute();
} catch(PDOException $ex) {
die("Failed to run query: " . $ex->getMessage());
}
$rows = $stmt->fetchAll();
return $rows;
}
}
$connect = new dbconnect;
$rows = $connect->query("select * from photos");
foreach($rows as $row):
print $row['id'];
endforeach;
?>
The $rows variable you're declaring inside query is not accessible to the outside, it is local to that function. Most likely, you simply want to return those results to the caller:
$rows = $stmt->fetchAll();
return $rows; // return value from function...
and have the caller capture that return value in its own variable:
$rows = $connect->query("select * from images"); // ... is received by caller
foreach($rows as $row):
Also check out dougjore's answer, you're mixing $this->stmt and $stmt inside your query method.
Pretty sure you aren't ever actually executing the query:
$this->stmt = $this->pdo->prepare($query);
$stmt->execute();
I believe (I could be wrong, I'm rather new to PDO myself and I haven't built a class for it), that you need to say $this->stmt->execute();
You could do
//PDO::FETCH_ASSOC: returns an array indexed by column name as returned in your result set
$this->stmt = $this->pdo->prepare($query);
$this->stmt->execute();
while ($result = $this->stmt->fetch(PDO::FETCH_ASSOC))
{
//do something with the result
}
Have a look here for more options to fetch PDO query results:
http://php.net/manual/en/pdostatement.fetch.php
$connect = new dbconnect;
$sql="select * from photos";
$stmt=$connect->pdo->prepare($sql);
$stmt->execute();
$result=$stmt->fetch(PDO::FETCH_ASSOC);
foreach($result as $key => $value) {
echo $key . "-" . $value . "<br/>";
}
I want to know how to use named parameters in a prepared statement with pdo class, so the call to pdo look something like following.
$query = $bdd->prepare('SELECT * FROM table WHERE login = :login AND pww = :pww');
$query->execute(array('login' => $login, 'pww' => $pww));
And I want to integrate this on a class regardless of the number of parameters.
Currently, I have this code
require_once 'constants.php';
class Mysql extends PDO {
private $con;
public function __construct() {
try {
$this->con = parent::__construct(DB_DSN, DB_USER, DB_PASS);
if ($this->getAttribute(PDO::ATTR_DRIVER_NAME) == DB_TYPE)
$this->setAttribute(PDO::MYSQL_ATTR_USE_BUFFERED_QUERY, TRUE);
return $this->con;
} catch (PDOException $e) {
die('Error:' . $e->getMessage());
}
}
public function select($reqSelect) {
try {
$this->con = parent::beginTransaction();
$result = parent::prepare($reqSelect);
$result->execute();
//$this->con = parent::commit();
$this->con = parent::rollBack();
return $result;
$result->closeCursor();
} catch (Exception $e) {
die('Error:' . $e->getMessage());
}
}
public function selectAll($reqSelect) {
$result = parent::prepare($reqSelect);
$result->execute();
$resultat = $result->fetchAll();
return $resultat;
$result->closeCursor();
}
}
And for parameters, I use somethings like ( which is wrong and vulnerable to injection )
require_once 'classes/Mysql.class.php';
$mysql = new Mysql();
$sql = 'SELECT * FROM articles WHERE id = '.$_GET['id'].' LIMIT 1';
$data = $mysql->select($sql);
Thanks.
So it's seems that I have figured it out, the trick was adding an optional parameter to the function, you use it whenever you need to work with prepared statements (named parameters).
So the function is something like
public function selectAll($reqSelect, $param = null) {
$result = parent::prepare($reqSelect);
//Check whether the parameter was passed or not
if (is_null($param)) {
$result->execute();
$resultat = $result->fetchAll();
return $resultat;
} else {
//Binding the parameters
$result->execute($param);
$resultat = $result->fetchAll();
return $resultat;
}
$result->closeCursor();
}
And for applying it, it goes like
//First param, the SQL. Here we have named parameters, so we need them to get bind
$sql = 'SELECT * FROM articles WHERE publish = :number';
//Second param, the parameters that will get bind with the named ones
$param = array(':number' => 1);
$query = $mysql->selectAll($sql, $param);
foreach ($query as $row) {
extract($row);
echo $title . '<br />';
}
I don't know if this, is considered the best practice, secured or even correct. if I'm mistaken feel free to correct me.