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?
Related
I wrote a class for PDO and need to disconnect PDO => ( I don't know how to do it )
I don't know code wrote is structurally correct?!
use $this->returnconn(); for db connection
Please guide me...
Sample code:
class conn {
public $inner;
public function returnconn() {
$CONF = $TMPL = array();
// The MySQL credentials
$CONF['host'] = 'localhost';
$CONF['user'] = 'root';
$CONF['pass'] = '';
$CONF['name'] = 'cmss';
$dsn ="mysql:host=".$CONF['host'].";dbname=".$CONF['name']."";
try{
$conn = new PDO($dsn,$CONF['user'],$CONF['pass']);
$conn ->exec("SET CHARACTER SET UTF8");
}catch(PDOException $e){
die($e->getMessage());
}
return $conn;
}
public function select(){
switch ($this->inner->switch){
case "select":
$sql="SELECT ".$this->inner->todo." FROM ".$this->inner->table." WHERE ".$this->inner->sql."";
$result=$this->returnconn()->prepare($sql);
/*
* this->returnconn();
*/
$result->execute();
if($result->rowCount()<=0){
return '{"msg":"empty "}';
}else{
return $result->fetch(PDO::FETCH_ASSOC);
}
break;
}
}
}
/* receive data */
$obj = new conn;
$iner = array();
$iner['table'] = 'category';
$iner['switch'] ='select';
$iner['todo'] = '*';
$iner['sql'] = '`id` IS NOT NULL ORDER BY `id` ASC';
$in = json_decode(json_encode($iner));
$obj ->inner = $in;
echo json_encode($obj ->select());
Do need a function to disconnect?
I have 3 files: dbconnect (here's declaration of $pdo), core.php (file with class to manage) and test.php.
I want to receive data from DB, but I have error:
Notice: Undefined variable: pdo in C:\xampp\htdocs\project\core.php on line 24
In dbconnect $pdo is in try catch, but before this I put: $pdo=null(to make variable accessible) but it doesn't work.
dbconnect ---> core.php(error here) ---> test.php;
//dbconnect.php
<?php
$mysql_host = 'localhost';
$username = 'root';
$password = '';
$database = 'db';
$pdo = null;
try {
$pdo = new PDO('mysql:host='.$mysql_host.';dbname='.$database.';charset=utf8', $username, $password );
}
catch(PDOException $e) {
echo 'Połączenie nie mogło zostać utworzone.<br />';
}
?>
//core.php
require_once('cms/dbconnect.php');
class getCore{
public $link_allegro;
public $link_facebook;
function getLinks(){
$query= $pdo->query('SELECT `url` FROM `links` WHERE `title` = "facebook"');
$row = $query->fetch();
$this->link_facebook = $row["url"];
$query= $pdo->query('SELECT url FROM links WHERE title = "allegro"');
$row = $query->fetch();
$this->link_allegro = $row["url"];
$query->closeCursor();
}
}
//test.php
<?php
require_once('core.php');
$tmp = new getCore;
$tmp->getLinks();
echo $tmp->link_allegro;
echo $tmp->link_facebook;
?>
Anyone can solve this? Thanks.
This is a scoping problem. $pdo doesn't exists in your getCore class.
You can make a DatabaseConnect class to manage your db access.
You can use this basic class for your database connection :
<?php
class DatabaseConnect {
private $mysql_host = 'localhost';
private $username = 'root';
private $password = '';
private $database = 'db';
private $pdo = null;
public function getPdo(){
return $this->pdo;
}
public function __construct(){
try {
$this->pdo = new PDO('mysql:host='.$mysql_host.';dbname='.$database.';charset=utf8', $username, $password );
}
catch(PDOException $e) {
echo 'Połączenie nie mogło zostać utworzone.<br />';
}
}
}
?>
You can getting your PDO instance in an other class with calling DatabaseConnect object -> getPdo() :
- Instannciate a new DatabaseConnect.
- Get PDO instance with the methof of the class.
Like that :
$databaseConnect = new DatabaseConnect();
$pdo = $databaseConnect->getPdo();
You next code :
//core.php
require_once('cms/dbconnect.php');
class getCore{
public $link_allegro;
public $link_facebook;
function getLinks(){
$databaseConnect = new DatabaseConnect();
$pdo = $databaseConnect-getPdo();
$query= $pdo->query('SELECT `url` FROM `links` WHERE `title` = "facebook"');
$row = $query->fetch();
$this->link_facebook = $row["url"];
$query= $pdo->query('SELECT url FROM links WHERE title = "allegro"');
$row = $query->fetch();
$this->link_allegro = $row["url"];
$query->closeCursor();
}
}
//test.php
<?php
require_once('core.php');
$tmp = new getCore;
$tmp->getLinks();
echo $tmp->link_allegro;
echo $tmp->link_facebook;
You need to pass $pdo to the getLinks() function as an input to make it available for use. you could try getLinks($pdo)
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 trying to build my own little framework.
Now I am having problems calling class functions into another class function.
Users.php code
class User extends Connection{
public function __construct(Connection $conn, Log $log){
parent::__construct($log);
$this->conn = $conn;
}
public function generatePassword(){
$length = 12;
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$password = '';
for ($i = 0; $i < $length; $i++) {
$password .= $characters[rand(0, strlen($characters) - 1)];
}
return $password;
}
public function generateToken(){
$token = md5(uniqid(mt_rand(), true));
return $token;
}
public function checkUsername($prefix, $username){
echo "test";
}
}
$user = new User($conn, $log);
$conn = new Connection($log);
connection.php code
<?php
class Connection{
private $log;
private $db;
public function __construct(Log $log){
$this->log = $log;
$this->createConnection();
}
public function createConnection(){
$dataConnection = $this->getConnection();
$host = $dataConnection['localhost'];
$dbname = $dataConnection['dbname'];
$user = $dataConnection['user'];
$pass = $dataConnection['pass'];
try{
$this->db = new PDO('mysql:host='.$host.';dbname='.$dbname.'',$user,$pass, array(PDO::MYSQL_ATTR_INIT_COMMAND => "SET NAMES utf8"));
$this->db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->log->insertLog("installer","Trying to connect to database");
} catch(PDOException $e){
$this->errorHandling($e->getCode());
}
}
public function errorHandling($error){
switch ($error){
case 2002:
$this->log->insertLog("installer","Installer error code 2002: Host unknown");
return ('Host unkown');
break;
case 1049:
$this->log->insertLog("installer","Installer error code 1049: Database does not exist");
return ('Database does not exist');
break;
case 1045:
$this->log->insertLog("installer","Installer error code 1045: Could not connect to database");
return ('Could nog connect to database');
break;
}
}
public function getConnection(){
$xml = simplexml_load_file("config/config.xml");
$dataConnection = array();
$dataConnection['localhost'] = $xml->host;
$dataConnection['dbname'] = $xml->dbname;
$dataConnection['user'] = $xml->user;
$dataConnection['pass'] = $xml->pass;
return $dataConnection;
}
public function query($sql){
try {
$this->db->exec($sql);
} catch(PDOException $e) {
$this->errorHandling($e->getCode());
}
}
public function select($sql){
try{
$result = $this->db->prepare($sql);
$result->execute();
return $result->fetchAll();
} catch(PDOException $e){
$this->errorHandling($e->getCode());
}
}
}
$conn = new Connection($log);
$log = new Log();
Log.php code
<?php
class Log{
public function createLog($file){
$date = date("dmY");
$location = 'var/log/'.$file.'-'.$date.'.log';
if (!file_exists($location)){
$file = fopen($location, 'w');
$message = "/** LOG FILE CREATED **/\n";
file_put_contents($location,$message, FILE_APPEND);
fclose($file);
}
return $location;
}
public function insertLog($file,$message){
$date = date("d-m-Y H:i:s", time());
$location = $this->createLog($file);
$message = $date." - ".$message."\n";
file_put_contents($location, $message, FILE_APPEND);
}
}
$log = new Log();
Now when I am trying to call the function checkUsername on user.php (will be used to check if the username already exists in db) I get the error:
Notice: Undefined variable: log in
/opt/www/decocka2/web/www.anthonydecock.be/core/conn/connection.php on
line 77
Catchable fatal error: Argument 1 passed to Connection::__construct()
must be an instance of Log, null given, called in
/opt/www/decocka2/web/www.anthonydecock.be/core/conn/connection.php on
line 77 and defined in
/opt/www/decocka2/web/www.anthonydecock.be/core/conn/connection.php on
line 7
What am I doing wrong?
Try to create the connection and the log object before the user object.
I am trying to change the following code to use MySqli instead of MySql. I have removed some methods that seem unimportant to what I'm addressing here.
class db {
var $hostname,
$database,
$username,
$password,
$connection,
$last_query,
$last_i,
$last_resource,
$last_error;
function db($hostname=DB_HOSTNAME,$database=DB_DATABASE,$username=DB_USERNAME,$password=DB_PASSWORD) {
$this->hostname = $hostname;
$this->database = $database;
$this->username = $username;
$this->password = $password;
$this->connection = mysql_connect($this->hostname,$this->username,$this->password) or $this->choke("Can't connect to database");
if($this->database) $this->database($this->database);
}
function database($database) {
$this->database = $database;
mysql_select_db($this->database,$this->connection);
}
function query($query,$flag = DB_DEFAULT_FLAG) {
$this->last_query = $query;
$resource = mysql_query($query,$this->connection) or $this->choke();
list($command,$other) = preg_split("|\s+|", $query, 2);
// Load return according to query type...
switch(strtolower($command)) {
case("select"):
case("describe"):
case("desc"):
case("show"):
$return = array();
while($data = $this->resource_get($resource,$flag)) $return[] = $data;
//print_r($return);
break;
case("replace"):
case("insert"):
if($return = mysql_insert_id($this->connection))
$this->last_i = $return;
break;
default:
$return = mysql_affected_rows($this->connection);
}
return $return;
}
function resource_get($resource = NULL,$flag = DB_DEFAULT_FLAG) {
if(!$resource) $resource = $this->last_resource;
return mysql_fetch_array($resource,$flag);
}
}
This is what I've got so far:
class db {
var $hostname = DB_HOSTNAME,
$database = DB_DATABASE,
$username = DB_USERNAME,
$password = DB_PASSWORD,
$connection,
$last_query,
$last_i,
$last_resource,
$last_error;
function db($hostname, $database, $username, $password) {
$this->hostname = $hostname;
$this->database = $database;
$this->username = $username;
$this->password = $password;
$this->connection = new mysqli($this->hostname, $this->username, $this->password, $this->database) or $this->choke("Can't connect to database");
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
if($this->database)
$this->database($this->database);
}
function database($database) {
$this->database = $database;
mysqli_select_db($this->connection, $this->database );
}
function query($query, $flag = DB_DEFAULT_FLAG) {
$this->last_query = $query;
//print_r($query);
$result = mysqli_query($this->connection, $query) or $this->choke("problem connecting to DB");
while($row=mysqli_fetch_assoc($result)) {
$resource[]=$row;
}
//print($command);
//print_r($resource);print("<br>");
list($command, $other) = preg_split("|\s+|", $query, 2);
// Load return according to query type...
switch(strtolower($command)) {
case("select"):
case("describe"):
case("desc"):
case("show"):
$return = array();
while($data = $this->resource_get($resource, $flag))
$return[] = $data;
//print_r($return);
break;
case("replace"):
case("insert"):
if($return = mysqli_insert_id($this->connection))
$this->last_i = $return;
break;
default:
$return = mysqli_affected_rows($this->connection);
}
return $return;
}
function resource_get($resource = NULL, $flag = DB_DEFAULT_FLAG) {
if(!$resource)
$resource = $this->last_resource;
return mysqli_fetch_array($resource, $flag);
}
So here's the problem: I've checked the results with a print_r() and the $resource array is loading correctly, but the value of $return when checked with print_r() just ends up being "Array()". Therefore, as near as I can figure, something isn't being handled correctly in this part of the code, which is why I included the resource_get() function call:
$return = array();
while($data = $this->resource_get($resource, $flag))
$return[] = $data;
//print_r($return);
break;
If I use mysqli_fetch_row($resource, $flag) instead of mysqli_fetch_array($resource, $flag) I still get the same result, i.e. print_r($return) yields simply "Array()".
The variable $resource does not represent a mysqli_result resource object at the time you pass it into $this->resource_get(). Instead, it is already a 2D array of results since you previously ran a mysqli_fetch_assoc() loop.
To make this work with your current code, you may either remove the earlier fetch loop:
$result = mysqli_query($this->connection, $query) or $this->choke("problem connecting to DB");
// Remove this
//while($row=mysqli_fetch_assoc($result)) {
// $resource[]=$row;
//}
And later, pass $result instead of $resource into your resource_get() method since it is $result that is the resource object.
Or, you might just skip the resource_get() call entirely and return $resource directly since it already contains the result array.