I am creating a class "DBQuery" that contains all the database query functions such as insert, select, delete, ...
Everything is working fine when I create database connection inside the INSERT function. But i want separate the configuration so that i can include it in any other files and pages.
configuration.php
define("HOSTNAME", "localhost");
define("USERNAME", "root");
define("PASSWORD", "");
define("DATABASE", "edubits");
try {
$conn = new PDO("mysql:host=" . HOSTNAME . ";dbname=" . DATABASE . ";", USERNAME, PASSWORD);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$conn->setAttribute(PDO::ATTR_DEFAULT_FETCH_MODE, PDO::FETCH_ASSOC);
} catch (PDOException $e) {
echo $e;
}
class.php
/**
* Created by PhpStorm.
* User: Sunusi Mohd Inuwa
* Date: 11/18/2018
* Time: 11:02 AM
*/
class QUERY
{
function INSERT($table, $data, $conn)
{
include_once('../configuration.php');
// variable declaration
$columns = "";
$valueset = "";
$values = "";
//loop
foreach ($data as $column => $value) {
$columns = $columns . ', ' . $column;
$valueset = $valueset . ', ?';
$values = $values . ', ' . $value;
}
//trimming the first comma from the result above
$columns = ltrim($columns, ',');
$valueset = ltrim($valueset, ',');
$values = ltrim($values, ',');
//statement
$sql = "INSERT INTO " . $table . "(" . $columns . ") VALUES(" . $valueset . ")";
//convert values to array
$values = explode(',', $values);
//query
$query = $conn->prepare($sql)->execute($values);
//$query = $conn->prepare($sql)->execute([$values]);;
}
}
Use include, not include_once. If you use include_once, then it won't execute the code in the file the second time you call the method.
But it would probably be better to include the file in the class's constructor, so you only need to execute it once, rather than create a new connection every time you perform a query. Make $conn a class property instead of an ordinary variable.
The class below give the ability to get a connection object from getInstance() funtion, so you just include the Config class where you wanna communicate with database (model)
getInstance() : is singleton, which means that you have a single instance
class Config{
private $HOSTNAME = "localhost";
private $USERNAME = "root";
private $PASSWORD = "";
private $DATABASE = "edubits";
private static $pdo = null;
public static function getInstance($data = null){
if(self::$pdo == null){
self::PDOConnect($data = null);
}
return self::$pdo;
}
private static function PDOConnect(){
try{
$info = new DBInfo($data);
self::$pdo = new PDO("mysql:host=" . $this->HOSTNAME . ";dbname=" . $this->DATABASE . ";", $this->USERNAME, $this->PASSWORD);
self::$pdo->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
self::$pdo->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
} catch (PDOException $e) {
echo new PDOCustomException($e->getMessage(), null, $e);
}
}
public function close(){
return null;
}
}
Here i've choice to use config directly from your INSERT function to get connection object, or get connexion object in constructor one time and use it many time in QUERY class
So connection instance is stored on $cn
include_once('../configuration.php');
class QUERY
{
private $cn = null;
private $DBAction = null;
public function __construct(){
try {
$cn = new DBAction();
$this->cn = $cn::getInstance();
} catch (\PDOException $ex) {
throw new PDOCustomException($ex->getMessage(), null, $ex);
} catch (\Exception $ex) {
throw new CustomException($ex->getMessage(), null, $ex);
}
}
public function INSERT($table, $data, $conn) {
$config = new Config();
// variable declaration
$columns = "";
$valueset = "";
$values = "";
//loop
foreach ($data as $column => $value) {
$columns = $columns . ', ' . $column;
$valueset = $valueset . ', ?';
$values = $values . ', ' . $value;
}
//trimming the first comma from the result above
$columns = ltrim($columns, ',');
$valueset = ltrim($valueset, ',');
$values = ltrim($values, ',');
//statement
$sql = "INSERT INTO " . $table . "(" . $columns . ") VALUES(" . $valueset . ")";
//convert values to array
$values = explode(',', $values);
//query
$query = $this->cn->prepare($sql)->execute($values);
}
}
Related
This code from my PHP Project.
and create oracle connection class.
modified from mysql connection class(work fine).
class databaseOracle
{
public $oci;
public $connected = false;
public $parameters;
public $result;
function __construct($host, $dbPort, $dbName, $userDB, $passwordDB)
{
try {
$ociDB = "(DESCRIPTION=(ADDRESS_LIST = (ADDRESS = (PROTOCOL = TCP)(HOST = " . $host . ")(PORT = " . $dbPort . ")))(CONNECT_DATA=(SID=" . $dbName . ")))";
$this->oci = oci_connect($userDB, $passwordDB, $ociDB, 'AL32UTF8');
if (!$this->oci) {
$e = oci_error();
trigger_error(htmlentities($e['message'], ENT_QUOTES), E_USER_ERROR);
echo "Database oracle connection Failed.</br>";
exit();
} else {
echo "Database oracle connection success.</br>";
}
} catch (EngineExcpetion $e) {
echo "Error : " . $e->getMessage() . "</br>";
}
// exit();
}
public function bind($para, $value)
{
$this->parameters[count($this->parameters)] = ":" . $para . "\x7F" . $value;
}
public function bindParams($parray)
{
if (empty($this->parameters) && is_array($parray)) {
$columns = array_keys($parray);
foreach ($columns as $i => &$column) {
$this->bind($column, $parray[$column]);
}
}
}
public function queryString($showQuery = 0, $query = "", $parameters = "")
{
$this->result = null;
if ($showQuery == 1) {
require_once('SQLFormatter.php');
echo SqlFormatter::format($query);
var_dump($parameters);
}
$this->result = oci_parse($this->oci, $query);
# Add parameters to the parameter array
$this->bindParams($parameters);
# Bind parameters
if (!empty($this->parameters)) {
foreach ($this->parameters as $param) {
$parameters = explode("\x7F", $param);
oci_bind_by_name($this->result, $parameters[0], $parameters[1]);
}
}
oci_execute($this->result);
$r = oci_fetch_array($this->result, OCI_ASSOC + OCI_RETURN_LOBS + OCI_RETURN_NULLS);
$this->parameters = array();
return $r;
}
}
$oracleDB = new databaseOracle($ociHost, $ociPort, $ociDB, $ociUsername, $ociPassword);
$query = $oracleDB->queryString(0,"SELECT * from SOME_TABLE where CREATED_BY = :created FETCH NEXT 50 ROWS ONLY",array("created" => "2"));
print_r($query);
my problem
i'm create class of oracle connection. modify from mysql connection class.
it's can query and read record from oracle database. example 50 record
but array result of query show first row only.
Before Marking my question as duplicate please give any example or link where i can understand, i am learning PHP. hope you understand.
I am Trying to insert data using database_class and insert function.
Here's my database class.
//db_class.php
class database {
var $_sql = '';
var $_resource = '';
var $_result = '';
var $_insertId = '';
function connect() {
global $glob;
$host = $glob['localhost'];
$user = $glob['root'];
$pass = $glob[''];
$db = $glob['crestdb'];
try {
$this->_resource = new PDO('mysql:host='.$host.';port=3306;dbname='.$db.'', $user, $pass);
$this->_resource->query("SET SQL_BIG_SELECTS=1");
} catch (PDOException $e) {
print "Error!: " . $e->getMessage() . "<br/>";
die();
}
}
function insert($table, $dbFields) {
$field = array();
$value = array();
foreach ( $dbFields as $k => $v) {
//$v = addslashes(stripslashes($v));
$v = (stripslashes($v));
$field[] = $k;
$qmark[] =":".$k;
$value[":".$k] = $v;
}
$f = implode('`,`',$field);
$val = implode("','",$value);
$q = implode(",",$qmark);
$insertSql = "INSERT INTO `$table` (`$f`) VALUES ($q)";
$stmt = $this->_resource->prepare($insertSql);
$stmt->execute($value);
$_result=$this->_resource->lastInsertId();
$this->_insertId=$_result;
return $_result;
}
and am using it as
addcat.php
include( "db_class.php");
$obj = new database();
if(isset($_POST['submit'])){
$dbFields = array(
'cname' => $_POST['cname'],
'priority' =>$_POST['priority'],
'status' => $_POST['status'],
);
$obj->insert("category",$dbFields);
}
using this i am getting error as per my TITLE suggest.
i think i am making mistake in addcat.php am i calling this function wrongly?
this is the error:- Uncaught Error: Call to a member function prepare() on string in C:\xampp\htdocs\def\database.class.php:82 Stack trace: #0 C:\xampp\htdocs\def\addcat.php(42): database->insert('category', Array) #1 {main} thrown in C:\xampp\htdocs\def\database.class.php on line
By searching lot in google i tried to make different class for connection.
and #Felippe and #Aynber you both were right i have made an class using your suggestion.
class database{
var $_resource ;
var $_result = '';
var $_sql = '';
var $_insertId = '';
var $host = 'localhost';
var $user = 'root' ;
var $pass = '';
var $dbname = 'crestdb';
var $error;
public function __construct(){
// Set DSN
$dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
// Set options
$options = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
// Create a new PDO instanace
try{
$this->_resource = new PDO($dsn, $this->user, $this->pass, $options);
}
// Catch any errors
catch(PDOException $e){
$this->error = $e->getMessage();
}
}
maybe it still needs improvement but it works for me now !!.
I have a function with 2 arguments. Here it is
function listBoats($con,$table){
//get record set for all boats sort them by their "sort" number
$queryBoat = "SELECT * FROM " .$table. " WHERE `id` <> 'mainPage' ORDER BY `sort` LIMIT 0, 1000";
$result = mysqli_query($con,$queryBoat);
return $result;
}
here is how I'm calling it
$result = listBoats($con,"CSINSTOCK"); //run query to list all the boats in the CSINSTOCK table
I can't get it to work. But If I add the variable $table = "CSINSTOCK" inside the function it does work. Why wont the function pass the "CSINSTOCK" variable through?
I would suggest that you use PDO. Here is an example
EXAMPLE.
This is your dbc class (dbc.php)
<?php
class dbc {
public $dbserver = 'server';
public $dbusername = 'user';
public $dbpassword = 'pass';
public $dbname = 'db';
function openDb() {
try {
$db = new PDO('mysql:host=' . $this->dbserver . ';dbname=' . $this->dbname . ';charset=utf8', '' . $this->dbusername . '', '' . $this->dbpassword . '');
} catch (PDOException $e) {
die("error, please try again");
}
return $db;
}
function getAllData($qty) {
//prepared query to prevent SQL injections
$query = "select * from TABLE where qty = ?";
$stmt = $this->openDb()->prepare($query);
$stmt->bindValue(1, $qty, PDO::PARAM_INT);
$stmt->execute();
$rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
return $rows;
}
?>
your PHP page:
<?php
require "dbc.php";
$getList = $db->getAllData(25);
foreach ($getList as $key=> $row) {
echo $row['columnName'] .' key: '. $key;
}
If you have the access to your database you should be able to perform your required operations.
so i have been trying to debug this issue myself for a few days now and i can't seem to figure out why i'm not getting the results I expect.
My code is rather complex and for a DB connection to be establish it spans across 3 Classes and one config file.
but basically my end usage ends up being
$this->db('test')->query('SELECT * FROM test1');
this establishes a connection to my database by the alias of test the query returns results so i'm good so far.
now my issue is when i try to make a new PDO object.
$this->db('test2')->query('SELECT * FROM test2');
this returns nothing because there is not table called test2 in my test1 object.
but if I do this
$this->db('test2')->query('SELECT * FROM test1');
now this returns the same results from the first PDO object.
I have traced and tracked down every line of code to make sure that the correct parameters are being passed to my database class and that each connection is properly established to the corresponding databases.
now my question is, can you have more than one datbase pdo connection? if so is there a special flag that needs to be set in the PDO options? are my connections being cached somewhere and causing this confusion?
this is my PDO declaration in each new class object stored in my array of connections
try
{
$this->_con = new PDO(
"mysql:host=" . $host . ";
port=" . $port . ";
dbname=" . $name, $user, $pass
);
$this->_con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
// TODO: push all $e methods to the developer debugger
echo "Database Error: ". $e->getMessage();
}
edit my code that uses the connection
step 1: a call to the parent class
public function __call($name, $params)
{
$class = $name . '_system_helper';
$hash = md5($class . $params);
if (class_exists($class))
{
if (!array_key_exists($hash, $this->_sys_helper))
{
if (method_exists($class, 'init'))
{
$this->_sys_helper[$hash] = call_user_func_array(array($class, 'init'), $params);
} else {
$this->_sys_helper[$hash] = call_user_func_array($class, $params);
}
}
return $this->_sys_helper[$hash];
}
return null;
}
step 2: called from the parent class
class DB_System_Helper extends Jinxup
{
private $_con = null;
public function __construct($end = null)
{
$mode = null;
$host = null;
$name = null;
$user = null;
$pass = null;
$port = null;
if (isset($this->config['database']['mode']))
{
$mode = $this->config['database']['mode'] == 'production' ? 'production' : 'development';
if (count($this->config['database'][$mode]) > 1)
{
foreach ($this->config['database'][$mode] as $key => $database)
{
if ($database['#attr']['alias'] == $end)
{
$host = $this->config['database'][$mode][$key]['host'];
$name = $this->config['database'][$mode][$key]['name'];
$user = $this->config['database'][$mode][$key]['user'];
$pass = $this->config['database'][$mode][$key]['pass'];
$port = $this->config['database'][$mode][$key]['port'];
}
}
} else {
$host = $this->config['database'][$mode]['host'];
$name = $this->config['database'][$mode]['name'];
$user = $this->config['database'][$mode]['user'];
$pass = $this->config['database'][$mode]['pass'];
$port = $this->config['database'][$mode]['port'];
}
$this->_con = new PDO_Database_Helper($host, $name, $user, $pass, $port);
} else {
echo 'No database mode specified';
}
}
public function __call($name, $param)
{
return call_user_func_array(array($this->_con, $name), $param);
}
}
step 3: called from DB_System_Helper
class PDO_Database_Helper extends Jinxup
{
private $_con = null;
private $_id = 0;
public function __construct($host, $name, $user, $pass, $port = 3306)
{
try
{
$this->_con = new PDO(
"mysql:host=" . $host . ";
port=" . $port . ";
dbname=" . $name, $user, $pass
);
$this->_con->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
} catch(PDOException $e) {
// TODO: push all $e methods to the developer debugger
echo "Database Error: ". $e->getMessage();
}
}
[...]
}
Are you sure that the hashing you're doing is enough to "namespace" each connection in the $this->_sys_helper array?
I suspect the problem lies in the first stage.
public function __call($name, $params)
{
$class = $name . '_system_helper';
$hash = md5($class . $params);
if (class_exists($class))
{
if (!array_key_exists($hash, $this->_sys_helper))
{
if (method_exists($class, 'init'))
{
$this->_sys_helper[$hash] = call_user_func_array(array($class, 'init'), $params);
} else {
$this->_sys_helper[$hash] = call_user_func_array($class, $params);
}
}
>>>>>>>>>>>>>> are you sure this is not returning the wrong
>>>>>>>>>>>>>> connection because of how the hashing is working?
return $this->_sys_helper[$hash];
}
return null;
}
I have downloaded follwing code from one of Google Codes but problem is in getting Last Insert ID.
Please see in run() function
This method is used to run free-form SQL statements that can't be handled by the included delete, insert, select, or update methods. If no SQL errors are produced, this method will return the number of affected rows for DELETE, INSERT, and UPDATE statements, or an associate array of results for SELECT, DESCRIBE, and PRAGMA statements.
<?php
class db extends PDO {
private $error;
private $sql;
private $bind;
private $errorCallbackFunction;
private $errorMsgFormat;
public $lastid;
public function __construct($dsn, $user = "", $passwd = "") {
$options = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
try {
parent::__construct($dsn, $user, $passwd, $options);
} catch (PDOException $e) {
$this->error = $e->getMessage();
}
}
private function filter($table, $info) {
$driver = $this->getAttribute(PDO::ATTR_DRIVER_NAME);
if ($driver == 'sqlite') {
$sql = "PRAGMA table_info('" . $table . "');";
$key = "name";
} elseif ($driver == 'mysql') {
$sql = "DESCRIBE " . $table . ";";
$key = "Field";
} else {
$sql = "SELECT column_name FROM information_schema.columns WHERE table_name = '" . $table . "';";
$key = "column_name";
}
if (false !== ($list = $this->run($sql))) {
$fields = array();
foreach ($list as $record)
$fields[] = $record[$key];
return array_values(array_intersect($fields, array_keys($info)));
}
return array();
}
private function cleanup($bind) {
if (!is_array($bind)) {
if (!empty($bind))
$bind = array($bind);
else
$bind = array();
}
return $bind;
}
public function insert($table, $info) {
$fields = $this->filter($table, $info);
$sql = "INSERT INTO " . $table . " (" . implode($fields, ", ") . ") VALUES (:" . implode($fields, ", :") . ");";
$bind = array();
foreach ($fields as $field)
$bind[":$field"] = $info[$field];
return $this->run($sql, $bind);
}
public function run($sql, $bind = "") {
$this->sql = trim($sql);
$this->bind = $this->cleanup($bind);
$this->error = "";
try {
$pdostmt = $this->prepare($this->sql);
if ($pdostmt->execute($this->bind) !== false) {
if (preg_match("/^(" . implode("|", array("select", "describe", "pragma")) . ") /i", $this->sql))
return $pdostmt->fetchAll(PDO::FETCH_ASSOC);
elseif (preg_match("/^(" . implode("|", array("delete", "insert", "update")) . ") /i", $this->sql)) {
echo $this->lastInsertId();
return $pdostmt->rowCount();
}
}
} catch (PDOException $e) {
$this->error = $e->getMessage();
return false;
}
}
}
?>
Code i use to Insert Record
$insert = array(
"userid" => 12345,
"first_name" => "Bhavik",
"last_name" => "Patel",
"email" => "bhavik#sjmtechs.com",
"password" => "202cb962ac59075b964b07152d234b70"
$db->insert("users",$insert);
echo $db->lastid;
In the insert() function, you've never set $lastid, so it never has the correct value. You'll need something like this:
Change this line in the insert() function:
return $this->run($sql, $bind);
To this:
$rows = $this->run($sql, $bind);
$this->lastid = $this->lastInsertId();
return $rows;
You should also be able to access the lastInsertId() from outside of the class, even without the above modifications, like so:
$db->insert("users",$insert);
echo $db->lastInsertId();