Best way to using mysqli object in class - php

This is my code in config.php file:
<?php
$db_username = 'name';
$db_password = 'my password';
$db_name = 'my db';
$db_host = 'localhost';
$mysqli = new mysqli($db_host, $db_username, $db_password, $db_name);
if ($mysqli->connect_error) {
throw new Exception("Error in Database Connection!");
}
?>
Now I have separate function.php with class commonFunctions
<?php
require_once '../config/config.php';
class commonFunctions {
function doLogin(){
global $mysqli;
$result = $mysqli->query("SELECT * FROM table WHERE itemcolor = 'red'") ;
$row_cnt = $result->num_rows;
return $row_cnt;
}
}
$common=new commonFunctions();
?>
Here I am using global $mysqli; to access $mysqli from config, which may not be a appropriate way to program and using global $mysqli; in every function to access $mysqli looks so bad.
Can you guys pls suggest better and clean way.
Thanks

It depends what programming paradigm you're comfortable with. Personally I like my PHP to be Object Orientated (OO), so i'd put the mysql in a new class called DB or something and then when I want to run the query i'd do $db->query('blabla').
class DB {
private $db;
function __construct() {
$dbConfig = Main::app()->config['db'];
$this->db = new \mysqli($dbConfig['host'], $dbConfig['user'], $dbConfig['pass'], $dbConfig['db']);
}
public function query($query, $where = false) {
if (!empty($where)) {
if (strpos(strtolower($where), 'where') > 0)
$query .= ' ' . $where;
else
$query .= ' WHERE ' . $where;
}
$result = $this->db->query($query);
if (!isset($result) || $result === false) {
dd([$query, $this->db->error, $where]);
}
/* will return true on INSERT / UPDATE queries */
if ($result !== true)
return $result->fetch_all(MYSQL_ASSOC);
}
}
Maybe you might just want to create a function in commonFunctions that handled all queries?
function query($query) {
global $mysqli;
return $mysqli->query($query);;
}

Related

OOP PHP Database results to Array

I am new to the idea of oop php and i am trying to write an irc php.
What I'm trying to do:
I am trying to query my database, get results from my database and put it into an array inside my program.
I tried making a new function to carry out the task and called it in the __construct function.
I have shortened the code but it pretty much looks like this:
Any thoughts and ideas are much appreciated.
class IRCBot
{
public $array = array();
public $servername = "localhost";
public $username = "root";
public $password = "usbw";
public $dbname = "bot";
function __construct()
{
//create new instance of mysql connection
$conn = new mysqli($this->servername, $this->username, $this->password, $this->dbname);
if ($mysqli->connect_errno)
{
echo "Failed to connect to MySQL: (" . $mysqli->connect_errno . ") " . $mysqli->connect_error;
}
echo $mysqli->host_info . "\n";
$this->database_fetch();
}
function database_fetch()
{
$query = "SELECT word FROM timeoutwords";
$result = mysqli_query($query);
while($row = mysqli_fetch_assoc($result))
{
$array[] = $row();
}
}
function main()
{
print_r($array);
}
}
$bot = new IRCBot();
Changes
1) Change if ($mysqli->connect_errno) to if ($conn->connect_errno)
2) Change $array[] = $row(); to $array[] = $row;
3) Add return $array; in function database_fetch()
4) Call database_fetch() function inside main() function instead of constructor.
5) Add $this->conn in mysqli_query() (Thanks #devpro for pointing out.)
Updated Code
<?php
class IRCBot
{
public $array = array();
public $servername = "localhost";
public $username = "root";
public $password = "usbw";
public $dbname = "bot";
public $conn;
function __construct()
{
//create new instance of mysql connection
$this->conn = new mysqli($this->servername, $this->username, $this->password, $this->dbname);
if ($this->conn->connect_errno)
{
echo "Failed to connect to MySQL: (" . $this->conn->connect_errno . ") " . $this->conn->connect_error;
}
}
function database_fetch()
{
$query = "SELECT word FROM timeoutwords";
$result = mysqli_query($this->conn,$query);
while($row = mysqli_fetch_assoc($result)){
$array[] = $row;
}
return $array;
}
function main()
{
$data = $this->database_fetch();
print_r($data);
}
}
Quick Start
Object Oriented Programming in PHP
Classes and Objects
Principles Of Object Oriented Programming in PHP
First of all you need to fix error from your constructor, you can modify as:
function __construct()
{
//create new instance of mysql connection
$this->conn = new mysqli($this->servername, $this->username, $this->password, $this->dbname);
if ($this->conn->connect_errno)
{
echo "Failed to connect to MySQL: (" . $this->conn->connect_errno . ") " . $this->conn->connect_error;
}
echo $this->conn->host_info . "\n";
}
Here, you need to replace $mysqli with $conn because your link identifier is $conn not $mysqli
No need to call database_fetch() here.
You need to use $conn as a property.
Now you need to modify database_fetch() method as:
function database_fetch()
{
$query = "SELECT word FROM timeoutwords";
$result = mysqli_query($this->conn,$query);
$array = array();
while($row = mysqli_fetch_assoc($result))
{
$array[] = $row;
}
return $array;
}
Here, you need to pass add first param in mysqli_query() which should be link identifier / database connection.
Second, you need to use return for getting result from this function.
In last, you need to modify your main() method as:
function main()
{
$data = $this->database_fetch();
print_r($data);
}
Here, you need to call database_fetch() method here and than print the data where you need.

Passing arguments in function pdo php

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

Connect to DB with PHP Class isn't working when try to retrieve results

Good morning.
I'm trying to make a DB class to connect and retrieve results from my DB. So, I think with the class is everything good. But, the results won't appear.
Here is my DB class:
<?php class Conexao {
var $host = "localhost";
var $usuario = "root";
var $senha = "xxxxxx";
var $banco = 'restaurante';
private $mysqli;
public function Abrir()
{
$this->mysqli = new mysqli($this->host, $this->usuario, $this->senha, $this->banco);
}
public function Fechar()
{
$this->mysqli->close();
}
}
class Comando {
public function Executar($sql)
{
$con = new Conexao();
$con->Abrir();
$re = $con->mysqli->query($sql);
$con->Fechar();
return $re;
}
}
?>
And here is where I'm trying to retrieve the results:
<?php
$queryMesasAtivas = Comando::Executar('SELECT * FROM mesas WHERE status =1 AND numero !="'.$_SESSION["mesa"].'"');
if ($queryMesasAtivas->num_rows > 0) {
while ($rowMesasAtivas = $queryMesasAtivas->fetch_assoc()) {
echo "<option value='".$rowMesasAtivas['numero']."'>Mesa ".$rowMesasAtivas['numero']."</option>";
}
}
else {
echo '<option>Nenhuma mesa ativa</option>';
}
?>
I tried some modifications but, nothing changes. Everytime it's still not working. What's wrong?
As the Comando::Executar is not static, but rather declared as public function..., you will have to do something such as:
$comando = new Comando();
$queryMesasAtivas = $comando->Executar('SELECT * FROM mesas WHERE status =1 AND numero !="'.$_SESSION["mesa"].'"');
if ($queryMesasAtivas->num_rows > 0) {
while ($rowMesasAtivas = $queryMesasAtivas->fetch_assoc()) {
echo "<option value='".$rowMesasAtivas['numero']."'>Mesa ".$rowMesasAtivas['numero']."</option>";
}
}
else {
echo '<option>Nenhuma mesa ativa</option>';
}
Or declare the method as static, namely:
public static function Executar($sql)
{
$con = new Conexao();
$con->Abrir();
$re = $con->mysqli->query($sql);
$con->Fechar();
return $re;
}
And then you can use the double colon (::) syntax:
$queryMesasAtivas = Comando::Executar('SELECT * FROM mesas WHERE status =1 AND numero !="'.$_SESSION["mesa"].'"');
I would suggest not calling an open and close every time you run a query, but rather a class like this:
class Conexao
{
private $link;
public function __construct($host = null, $username = null, $password = null, $dbName = null)
{
$this->link = mysqli_init();
$this->link->real_connect($host, $username, $password, $dbName) or die("Failed to connect");
}
public function __destruct()
{
$this->link->close();
}
public function Query($sql)
{
return $this->link->query($sql);
}
}
This is then used as such:
$conexao = new Conexao("host", "username", "password", "db_name");
$result = $conexao->Query("SELECT * FROM `table` WHERE 1 ORDER BY `id` ASC;");
This is not only smaller, but more lightweight on the server because you aren't permanently opening and closing database connections, reducing CPU use and memory use.
Using static properties for the host etc. (keeps them in memory even after __destruct is used so you do not need to redeclare them every time):
class Conexao
{
private $link;
private static $host, $username, $password, $dbName;
public function __construct($host = null, $username = null, $password = null, $dbName = null)
{
static::$host = $host ? $host : static::$host;
static::$username = $username ? $username : static::$username;
static::$password = $password ? $password : sattic::$password;
static::$dbName = $dbName : $dbName : static::$dbName;
$this->link = mysqli_init();
$this->link->real_connect(static::$host, static::$username, static::$password, static::$dbName) or die("Failed to connect");
}
public function __destruct()
{
$this->link->close();
}
public function Query($sql)
{
return $this->link->query($sql);
}
}
$conexao = new Conexao("host", "username", "password", "db_name");
$result = $conexao->Query("SELECT * FROM `table` WHERE 1 ORDER BY `id` ASC;");
$conexao->__destruct(); // Destroy the class
$conexao = new Conexao(); // Reinitialise it
$result = $conexao->Query("SELECT * FROM `table` WHERE 1 ORDER BY `id` ASC;");
Using a config instance of the connection class:
config.php file:
<?php
require_once 'path/to/Conexao.php';
$conexao = new Conexao("host", "username", "password", "db_name");
?>
index.php file:
<?php
require_once 'config.php';
$result = $conexao->Query("SELECT * FROM `table` WHERE 1 ORDER BY `id` ASC;");
?>
The class now has a parent on my github!

DB class wont load

I'm trying to connect using a simle db class. For some reason it only print out
"Initiate DB class"
test.php
include 'db.class.php';
echo 'Initiate DB class';
$db = new DB();
echo 'DB class did load';
db.class.php
class DB extends mysqli {
private static $instance = null;
private function __construct () {
parent::init();
$host = 'localhost';
$user = 'root';
$pass = 'MY_PASS';
$dbse = 'MY_DB';
parent::real_connect($host, $user, $pass, $dbse);
if (0 !== $this->connect_errno):
die('MySQL Error: '. mysqli_connect_error());
//throw new Exception('MySQL Error: '. mysqli_connect_error());
endif;
}
public function fetch ($sql, $id = null, $one = false) {
$retval = array();
if ($res = $this->query($sql)):
$index = 0;
while ($rs = $res->fetch_assoc()):
if ($one):
$retval = $rs; break;
else:
$retval[$id ? $rs[$id] : $index++] = $rs;
endif;
endwhile;
$res->close();
endif;
return $retval;
}
}
I have tried to search my log files for error but they come out empty.
Ok got it,
In your call to db your calling new DB(); which mean you're trying to call the constructor of your DB class.
In your DB class it looks like you're trying to create a singleton, but something is missing normally there would be something to assign the instance the database connection, and something that asks the instance if it's empty create a new connection or if it's not use the same instance.
At the end of the day to make this work you can change your constructor to public.
Try this:
Db_class:
class Db_class{
/***********************CONNECT TO DB*********************/
public function db_connect(){
$user = '***';
$db = '***';
$password = '***';
$host = '***';
try {
$dbh = new PDO("mysql:host=$host;dbname=$db", $user, $password);
}
catch(PDOException $err) {
echo "Error: ".$err->getMessage()."<br/>";
die();
}
return $dbh;
}
/******************PREPARE AND EXECUTE SQL STATEMENTS*****/
public function query($statement){
$keyword = substr(strtoupper($statement), 0, strpos($statement, " "));
$dbh = $this->db_connect();
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;
}
}
Other PHP:
$db = new Db_class();
$sql = "SQL STATEMENT";
$result = $db->query($sql);
Your constructor is marked as private which means new DB will raise an error. I see you have a private property to store an instance, are you missing the singleton method to return a new object?

PHP MySQL database class not working with insertion

I've been using this class:
<?
class DbConnector {
var $theQuery;
var $link;
function DbConnector() {
$host = 'localhost';
$db = 'my_db';
$user = 'root';
$pass = 'password';
// connect to the db
$this->link = mysql_connect($host, $user, $pass);
mysql_select_db($db);
register_shutdown_function(array(&$this, 'close'));
}
function find($query) {
$ret = mysql_query($query, $this->link);
if (mysql_num_rows($ret) == 0)
return array();
$retArray = array();
while ($row = mysql_fetch_array($ret))
$retArray[] = $row;
return $retArray;
}
function insert($query) {
$ret = mysql_query($query, $this->link);
if (mysql_affected_rows() < 1)
return false;
return true;
}
function query($query) {
$this->theQuery = $query;
return mysql_query($query, $this->link);
}
// get some results
function fetchArray($result) {
return mysql_fetch_array($result);
}
function close() {
mysql_close($this->link);
}
function exists($query) {
$ret = mysql_query($query, $this->link);
if (mysql_num_rows($ret) == 0)
return false;
}
function last_id($query) {
return mysql_insert_id($query);
}
}
?>
Which I'm using for a lot of queries and it's working fine, although I'm trying to insert using this query:
global $db;
$query = $db->insert("INSERT INTO `submissions` (
`id` ,
`quote` ,
`filename` ,
`date_added` ,
`uploaded_ip`
)
VALUES (
NULL , '{$quote}', '{$filename}', NOW(), '{$_SERVER['REMOTE_ADDR']}')
");
And it's giving me this error:
Not Found
The requested URL /horh_new/id/<br /><b>Fatal error</b>: Call to a member function insert() on a non-object in <b>/Applications/MAMP/htdocs/horh_new/addit.php</b> on line <b>52</b><br /> was not found on this server.
Although when I don't use that class above, and use this instead:
$con = mysql_connect("localhost","root","password");
if (!$con) {
die('Could not connect: ' . mysql_error());
}
mysql_select_db("my_db", $con);
mysql_query("INSERT INTO `submissions` (
`id` ,
`quote` ,
`filename` ,
`date_added` ,
`uploaded_ip`
)
VALUES (
NULL , '{$quote}', '{$filename}', NOW(), '{$_SERVER['REMOTE_ADDR']}')
");
echo mysql_insert_id();
mysql_close($con);
It works fine. Can anyone tell me what is wrong with my class? I'd really appreciate it.
You should do like
global $db;
$db = new DbConnector();
Or the better way to use this is
add a static function of class DbConnector, which will create only single instance throughout a request
public static function getInstance(){
static $instance = null;
if($instance === null){
$instance = new DbConnector();
}
return $instance;
}
And use this class as
$db = DbConnector::getInstance();
$db->insert($query);
you need to instantiate the object before using it
$db = new DbConnetor();
now you can do an insert
although i suggest adding a __construct method to connect to the database first
class DbConnector {
public function __construct() {
// connect to db here
}
Are you sure $db contains an instance of your class? Maybe just do a var_dump() of $db just before your call to $db->insert() and see if it's set.

Categories