PHP MYSQL PDO Database Connection - php

I am using PHP to establish a connection to a MYSQL database using PDO. I keep getting this error:
Uncaught Error: Call to a member function query() on null
I am pretty new to this approach but why am I getting a null from the query?
This is the code calling the classes:
<?php
$data = new Data;
echo $data->connect();
$view = new View;
echo $view->getData();
?>
This is the query class with the problem I suspect:
<?php
class View extends Data {
public function getData() {
$sql = 'SELECT * FROM equipment';
$stm = $this->connect()->query($sql);
while ($row = $stm->fetch()) {
echo $row['manuName'] . '<br>';
}
}
}
?>
This is the connection class:
<?php
class Data {
private $dbHost = DB_HOST;
private $dbUser = DB_USER;
private $dbPass = DB_PASS;
private $dbName = DB_NAME;
private $dbHandler;
private $error;
public function connect() {
$con = 'mysql:host=' . $this->dbHost . ';dbname=' . $this->dbName;
$options = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
try {
$this->dbHandler = new PDO($con, $this->dbUser, $this->dbPass, $options);
} catch (PDOException $e) {
$this->error = $e->getMessage();
echo $this->error;
}
}
}
I am not seeing my error. If anyone can see why I cannot pull the data.
Thank you

As u_mulder said in the comments,
your connect method will not return anything.
I updated it as below and made some change on your getData() method:
public function connect() {
$con = 'mysql:host=' . $this->dbHost . ';dbname=' . $this->dbName;
$options = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
try {
//$this->dbHandler = new PDO($con, $this->dbUser, $this->dbPass, $options);
return new PDO("mysql:host=".$this->dbHost.";dbname=".$this->dbName,$this->dbUser,$this->dbPass);
} catch (PDOException $e) {
$this->error = $e->getMessage();
echo $this->error;
}
}
}
class View extends Data {
public function getData($table){
try {
$sql="SELECT * FROM $table";
$q = $this->connect()->query($sql) or die("failed!");
while($r = $q->fetch(PDO::FETCH_ASSOC)){ $data[]=$r; }
return $data;
}
catch(PDOException $e)
{
echo 'Query failed'.$e->getMessage();
}
}
}
$view = new View;
$result = $view->getData('equipment');
print_r($result);
Although I prefer remove connect method and add a constructor in your Data class as below:
public $this->conn;
public function __construct(){
$this->conn = new PDO("mysql:host=".$this->dbHost.";dbname=".$this->dbName,$this->dbUser,$this->dbPass);
}
and then change my getData as below:
$q = $this->conn->query($sql) or die("failed!");
‌Because as ADyson said in the comments :
you shouldn't really be connecting again every time you run a query..

Thanks again Ali, ADyson & u_mulder,
If I understand what all comments are saying, this code should factor in your advice. Can you please tell me if this is a better approach if you have the time.
Data Class:
<?php
class Data {
private $dbHost = DB_HOST;
private $dbUser = DB_USER;
private $dbPass = DB_PASS;
private $dbName = DB_NAME;
private $error;
public $this->conn;
public function __construct(){
$this->conn = new PDO("mysql:host=".$this->dbHost.";dbname=".$this->dbName,$this->dbUser,$this->dbPass);
}
try {
return new PDO("mysql:host=".$this->dbHost.";dbname=".$this->dbName,$this->dbUser,$this->dbPass);
} catch (PDOException $e) {
$this->error = $e->getMessage();
echo $this->error;
}
}
}
View Class:
<?php
class View extends Data {
public function getData($table){
try {
$sql="SELECT * FROM $table";
$q = $this->conn->query($sql) or die("failed!");
while($r = $q->fetch(PDO::FETCH_ASSOC)){ $data[]=$r; }
return $data;
}
catch(PDOException $e)
{
echo 'Query failed'.$e->getMessage();
}
}
}
Output:
<?php
$view = new View;
$result = $view->getData('equipment');
print_r($result);
?>
This code is still giving errors:
unexpected '->' (T_OBJECT_OPERATOR), expecting ',' or ';'

Related

Passing db object to php class oop style does not work

Simple classes using oop php, trying to pass db object (from db class) to another class ( category class ) so i can get the content from db .
db class db.php
class db {
//put your code here
private $hostname = "127.0.0.1";
private $dbname = "php_oop_crud";
private $username = "root";
private $password = "";
public $conn;
public $status = 0;
public function getConnection() {
$this->conn = null;
try {
$this->conn = new PDO("mysql:host:$this->hostname;dbname=$this->dbname", $this->username, $this->password);
// this return null if unsccessfull
$this->status = $this->conn->getAttribute(PDO::ATTR_CONNECTION_STATUS);
if ($this->status) {
echo "connected to db : " . $this->status;
return $this->conn;
}
} catch (PDOException $ex) {
echo "Can't connect to db " . $this->status;
error_log("Ayman :: {{$ex->getMessage()}} - {{$ex->getFile()}} - {{$ex->getLine()}}");
return $this->conn;
}
}
}
pass db object to category class in index.php
// Create db connection pass it to product and category objects
$databaseConn = new db();
$db = $databaseConn->getConnection();
// create object and send database object to class
// now we need to call the function who crearte tha actual connection getConnection();
$category= new category($db);
$category->read();
category class category.php
<?php
class category {
//put your code here
private $databaseConn;
private $tabel_name = 'categories';
public $id;
public $name;
public function __construct($db) {
$this->databaseConn = $db;
}
public function read() {
$sql = 'SELECT * FROM categories';
$query = $this->databaseConn->prepare($sql);
$isok = $query->execute();
$row= $query->rowCount();
echo "row : " . $row;
var_dump($row);
echo "isok : " . $isok;
var_dump($isok);
if ($isok) {
echo "the red process is done and ok <br/> category table";
} else {
echo "Cant get category ";
var_dump($isok);
}
}
}
Now the var_dump($row) and var_dump($isok); are always false , mean while I can connect successfully to db
Credit for #ishegg , be careful when you construct your PDO .
// this will NOT work
$this->conn = new PDO("mysql:host:$this->hostname;dbname=$this->dbname", $this->username, $this->password);
// this will Work
$this->conn = new PDO("mysql:host=".$this->hostname.";dbname=".$this->dbname, $this->username, $this->password);

PHP oop how to call another class method in a easier way?

I am new to php OOP. I have a question regarding my situation.
db.php
class db{
protected $db_host;
protected $db_name;
protected $db_user_name;
protected $db_pass;
public function __construct() {
$this->db_host="localhost";
$this->db_name="bs";
$this->db_user_name="root";
$this->db_pass="";
}
public function conn(){
try {
$conn = new PDO("mysql:host=$this->db_host;dbname=$this->db_name", $this->db_user_name="root", $this->db_pass);
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
return $conn;
}
catch(PDOException $e)
{
echo $sql . "<br>" . $e->getMessage();
}
}
}
item.php
require "../../includes/db.php";
class item{
public $user_uid;
public $last_id;
public $display_item;
public $iid;
protected $item_id;
protected $item_name;
protected $item_price;
protected $item_quantity;
public function add_item($uid,$item_id,$item_n,$item_p,$item_q){
$db = new db();
$conn=$db->conn();
$this->user_uid=$uid;
$this->item_id=$item_id;
$this->item_name=$item_n;
$this->item_price=$item_p;
$this->item_quantity=$item_q;
try {
$sql = "INSERT item(uid,item_id,item_name,item_price,item_quantity)
VALUES('$this->user_uid','$this->item_id','$this->item_name','$this->item_price','$this->item_quantity')";
$conn->exec($sql);
$this->last_id=$conn->lastInsertId();
}
catch(PDOException $e){
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
}
public function display_item($uid){
$db = new db();
$conn=$db->conn();
$this->user_uid=$uid;
try{
$sql="SELECT * FROM item where uid='$this->user_uid'";
$statement=$conn->query($sql);
while($row=$statement->fetch()){
$this->iid[]=$row['iid'];
$this->display_item[]=[$row['item_id'],$row['item_name'],$row['item_price'],$row['item_quantity']];
}
}
catch(PDOException $e){
echo $sql . "<br>" . $e->getMessage();
}
$conn = null;
}
}
as you can see from item.php , i have to call
$db = new db();
$conn=$db->conn();
in add_item() and display_item() .
So that means every method that I have to access to database connection, i have to do that. Is there a easier way to do that by not creating $db = new db() in other class by modifying my codes?
OR
Did i miss out some functions that PHP can do that?
My desired way of doing it
require "../../includes/db.php";
$db = new db();
$conn=$db->conn();
class item{
...
...
public function add_item($uid,$item_id,$item_n,$item_p,$item_q){
try {
$sql = "INSERT item(uid,item_id,item_name,item_price,item_quantity)
VALUES('$this->user_uid','$this->item_id','$this->item_name','$this->item_price','$this->item_quantity')";
$conn->exec($sql);
}
public function display_item($uid){
....
try{
$sql="SELECT * FROM item where uid='$this->user_uid'";
$statement=$conn->query($sql);
so that i only declare 1 time()
$db = new db();
$conn=$db->conn();
in class item() and use it for the rest of methods.
Just add the connection in the constructor. Add the necessary property as well:
class db
{
protected $db_host;
protected $db_name;
protected $db_user_name;
protected $db_pass;
protected $db_conn; // add me here
Then inside the constructor, use the credentials there to connect. So that when you create the object, its already connected, you'll just use the property connection for your executing queries and stuff:
public function __construct()
{
$this->db_host = "localhost";
$this->db_name = "bs";
$this->db_user_name = "root";
$this->db_pass = "";
// connect
try {
$this->db_conn = new PDO("mysql:host=$this->db_host;dbname=$this->db_name", $this->db_user_name="root", $this->db_pass);
$this->db_conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->db_conn->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
}
catch(PDOException $e) {
echo $sql . "<br>" . $e->getMessage();
exit;
}
}
Then, extend the db class in item. You can now use db's db_conn property inside item class.
class item extends db
{
public $user_uid;
public $last_id;
public $display_item;
public $iid;
protected $item_id;
protected $item_name;
protected $item_price;
protected $item_quantity;
public function display_item($uid)
{
try {
$stmt = $this->db_conn->prepare('SELECT * FROM item WHERE uid = :uid');
$stmt->bindValue(':uid', $uid);
$stmt->execute();
foreach($stmt->fetchAll(PDO::FETCH_ASSOC) as $row) {
$this->iid[] = $row['iid'];
$this->display_item[] = [$row['item_id'], $row['item_name'], $row['item_price'], $row['item_quantity']];
}
} catch(PDOException $e) {
echo $e->getMessage();
exit;
}
}
}
Sidenote: I've added prepared statements on top

PDO class - fetching results after initial fetch

this is my PDO class
<?php
class Database
{
protected $dbh;
protected $query;
public $rows;
public function __construct($host,$user,$pass,$dbname)
{
// Set DSN
$dsn = 'mysql:host=' . $host . ';dbname=' . $dbname;
// Set options
$options = array( PDO::ATTR_PERSISTENT=> true,
PDO::ATTR_ERRMODE=> PDO::ERRMODE_EXCEPTION);
// Create a new PDO instanace
try
{
$this->dbh = new PDO($dsn, $user, $pass, $options);
}
catch(PDOException $e)
{
echo $this->error = $e->getMessage();
die();
}
}
public function query($query)
{
$this->query = $this->dbh->query($query);
}
public function execute($array=null)
{
$this->stmt->execute($array);
}
public function fetchAllQuery()//--------------------(1)
{
$resultQuery = $this->query->fetchAll(PDO::FETCH_ASSOC);
$this->rows = count($resultQuery);
return $resultQuery;
}
public function fetchQuery()//------------(2)
{
return $this->query->fetch(PDO::FETCH_ASSOC);
}
public function rowCountQuery()///////////////
{
return $this->rows;
}
}
$database = new Database('localhost','root','','speed');
$query = $database->query("SELECT * FROM tbl_deliverygrid");
$result = $database->fetchAllQuery();//--------------calling method (1)
echo '<pre>',print_r($result),'</pre><br>';
while($result2 = $database->fetchQuery())//----------calling method (2)
{
echo $result2['area'];
echo '<br>';
}
after calling (1) method i'm not able to get results calling (2) method
and also after calling (2) method i'm not able to get results calling (1) method
how to use both (1) and (2) methods simultaneously for getting results ?

PDO wont connect to the database

I've made a simple Database class to handle my database connections. But it's somehow not working? At first it wasn't working with MySQLi, so i tried PDO – which ain't working either.
I am however eager to make PDO work. I've already googled and searched here at StackOverflow, but without luck.
Here's my class:
class Database
{
// Local
protected $_host = "localhost";
protected $_user = "root";
protected $_pass = "root";
protected $_database = "hs";
protected $_connection;
// Construct
private function __construct()
{
try
{
$this->_connection = new PDO('mysql:host=localhost;dbname=hs', $this->_user, $this->_pass);
$this->_connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e)
{
echo 'ERROR: ' . $e->getMessage();
}
}
public function login($usr, $pwd)
{
echo "hi";
}
}
And here's the execution:
if(isset($_POST['hs_login']))
{
$db = new Database;
$db->login($_POST['hs_username'], $_POST['hs_password']);
}
Thanks in advance! :)
Constructors are always public so change that like so:
class Database
{
// Local
protected $_host = "localhost";
protected $_user = "root";
protected $_pass = "root";
protected $_database = "hs";
protected $_connection;
// Construct
public function __construct()
{
try
{
$this->_connection = new PDO('mysql:host=localhost;dbname=hs', $this->_user, $this->_pass);
$this->_connection->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
catch(PDOException $e)
{
echo 'ERROR: ' . $e->getMessage();
}
}
public function login($usr, $pwd)
{
echo "hi";
}
}
Also, new Database is a method call so change that like so:
if(isset($_POST['hs_login']))
{
$db = new Database;
$db->login($_POST['hs_username'], $_POST['hs_password']);
}
Just wanted to point out, that there are some cases, when you can use private constructors. One of the practical use of them is with Databases, so it's relevant in your case as well. This design pattern is called Singleton pattern, and it relies on static method calls. You don't have to instantiate the class, as instantiation is handled by the class itself. I've put together an example:
<?php
class Database {
private static $instance = null;
private $db;
private static $last_result;
private function __construct() {
try {
$pdo_param = array(
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC
);
$this->db = new PDO("mysql:host=YOUR_HOSTNAME;dbname=YOUR_DBNAME", "YOUR_USERNAME", "YOUR_PASSWORD", $pdo_param);
}
catch (PDOException $e) {
die($e->getMessage());
}
}
private static function getInstance() {
if (self::$instance == null) {
self::$instance = new self();
}
return self::$instance;
}
public static function query($sql) {
try {
$instance = self::getInstance();
$stmt = $instance->db->prepare($sql);
$stmt->execute();
self::$last_result = $stmt->fetchAll();
return self::$last_result;
}
catch (PDOException $e) {
die($e->getMessage());
}
}
public static function prepare($sql, $params) {
try {
$instance = self::getInstance();
$stmt = $instance->db->prepare($sql);
$stmt->execute($params);
self::$last_result = $stmt->fetchAll();
return self::$last_result;
}
catch (PDOException $e) {
die($e->getMessage());
}
}
}
$users = Database::query("SELECT * FROM users");
$filtered_users = Database::prepare("SELECT * FROM users WHERE username = :username", array(":username" => "john_doe"));
?>
<pre><?php
print_r($users);
print_r($filtered_users);
?></pre>
Singleton design pattern is really useful when you want to make sure, that there's ONLY ONE instance of a class in any given time.

Objects with db connection

I have a:
class Person
{
public $data;
public function __construct($name) {
$database = new Database;
$database->prepare('SELECT * FROM persons where name = :name');
$database->bindParam(':name', $name);
$database->execute();
$this->data = $database->fetch();
}
}
and i´m creating persons like this:
$jim = new Person('Jim');
$mike = new Person('Mike');
and this is my database class
class Database
{
private $host = 'localhost';
private $user = 'test';
private $pass = '123';
private $dbname = 'test';
private $dbh;
private $error;
private $stmt;
public function __construct()
{
$dsn = 'mysql:host=' . $this->host . ';dbname=' . $this->dbname;
$options = array(
PDO::ATTR_PERSISTENT => true,
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION
);
try{
$this->dbh = new PDO($dsn, $this->user, $this->pass, $options);
}
catch(PDOException $e){
$this->error = $e->getMessage();
echo $this->error;
}
}
public function prepare($query)
{
$this->stmt = $this->dbh->prepare($query);
}
public function bindParam($key, $val)
{
$this->stmt->bindParam($key, $val);
}
public function execute()
{
$this->stmt->execute();
}
public function fetch()
{
return $this->stmt->fetch(PDO::FETCH_ASSOC);
}
}
I´m getting this message very often
Warning: PDO::__construct(): MySQL server has gone away
I want to confirm if this approach is correct. calling the database in the constructor?
How can i know if the created person exists (i mean exist in the database)
should i do something like this?
$jim = new Person('Jim');
if($jim->data) {
echo 'person exists in the db';
}
thank you

Categories