I'm trying to use an existing class which has my DB connection in it to make a call within a new class. Here is my code to do this:
class ajaxHandler {
protected static $db;
function __construct() {
if (!class_exists('Db')) {
include "db_class.php";
$db = new Db();
}
}
function show_contest_details ($contest_id){
echo "The contest id is: ".$contest_id;
$event__conetest_details = $db->select("SELECT * FROM FF_CREATE_EVENT");
} // end of show_contest_details function
}
I am getting the following errors:
Notice: Undefined variable: db in /var/www/ajax_class.php on line 18
Fatal error: Call to a member function select() on a non-object in /var/www/ajax_class.php on line 18
How can I use my DB class within this class?
You've forgotten about self:::
class ajaxHandler {
protected static $db;
function __construct() {
if (!class_exists('Db')) {
include "db_class.php";
}
self::$db = new Db();
}
function show_contest_details ($contest_id){
echo "The contest id is: ".$contest_id;
$event__conetest_details = self::$db->select("SELECT * FROM FF_CREATE_EVENT");
} // end of show_contest_details function
}
Second thing, it is better to move code creating instance of Db outside the conditional block. You may accidentally include Db in other place, and then ajaxHandler will stop working, and you will not understand easily why.
You use class_exists() to test whether or not you have created the database. That is not correct. class_exists() checks if the class has been defined, which is true after PHP has loaded the file, not after it has created the first instatiation of the class. What you need is this:
class ajaxHandler {
protected static $db;
function __construct() {
if (is_null(self::$db)) {
include "db_class.php";
self::$db = new Db();
}
}
}
Related
I'm new to using namespaces. In this example I made class, which handles database connection and I'm trying to use it inside the other classes. Can you explain what is wrong?
Connection.php
namespace Database;
class Connection
{
private static $instance = null;
private $pdo;
private function __construct()
{
$this->pdo = new PDO("mysql:host=localhost;dbname=database;", "root", "pw");
}
public static function get()
{
if (is_null(self::$instance))
self::$instance = new Connection();
return self::$instance;
}
}
Auth.php
namespace PHPAuth;
use Database\Connection;
class Auth
{
protected $dbh;
public function __construct()
{
$this->dbh = Connection::get();
...
Thanks in advance.
Edit: Ok, now I included autoloader and including class is now working correctly. But now I'm getting error when using $dbh in Auth like $query = $this->dbh->query("SELECT * FROM...");
Fatal error: Call to undefined method Database\Connection::query()
in...
First issue with class not found
I'll add the answer (which worked for you) for the first issue for reference: "Namespaces doesn't automatically load the files. You need to add an autoloader for that."
Second issue with undefined method
Fatal error: Call to undefined method Database\Connection::query()
The answer is in the error message. You've made the class Database\Connection into a singleton where Database\Connection::get() returns an instance of itself (which doesn't have any ->query() method), and not the actual PDO instance.
If you want that method to return the PDO instance instead, I would do something like this:
namespace Database;
use PDO;
class Connection
{
private static $pdo;
private function __construct()
{
// Leave the constructor private so it still becomes
// a singleton and so we can't instantiate this class.
}
public static function get()
{
if (is_null(self::$pdo)) {
self::$pdo = new PDO("mysql:host=localhost;dbname=database;", "root", "pw");
}
return self::$pdo;
}
}
Now the Connection class have become a Factory for the PDO-connection.
Connection::get() will return the same PDO instance over and over and you should be able to call $this->dbh->query("...") from your Auth class.
I don't seem to be able to access the parent class constructor In PHP.
Here is the code
class Mysql
{
const SERVER, USER, PASSWORD, DB;
function Mysql()
{
return mysqli_connect(self::SERVER, ETC);
}
}
class Mysql_Select extends Mysql
{
function Mysql_Select()
{
$conn = new Mysql();
etc
}
}
I'm trying to keep the actual connection in the parent class, but I get the non-object error.
You're doing it wrong
First thing is that PHP4-style constructors are deprecated, use __construct method to define a costructor.
Second is that you must not return from constructor but rather keep the connection object inside class as instance property.
Third is that you must call parent methods using parent keyword.
class Mysql
{
const SERVER, USER, PASSWORD, DB;
protected $conn;
function __construct()
{
$this->conn = mysqli_connect(self::SERVER, ETC);
}
}
class Mysql_Select extends Mysql
{
function __construct()
{
parent::__construct();
// use $this->conn here from the parent class.
}
}
I've 3 class (Mysqliconn, Users and News).
Mysqliconn.class
Class Mysqliconn {
..connect to db
}
News.class
class News {
private $db;
public function __construct( Mysqliconn $db ) {
$this->db = $db;
}
public test() {
do something...
}
}
Users.class
class Users {
private $db;
public function __construct( Mysqliconn $db ) {
$this->db = $db;
}
public test2() {
do something...
}
}
In my php page
$db = new Mysqliconn();
$nw = new News( $db );
$us = new Users( $db )
$us->test2();
$nw->test();
My error
Catchable fatal error: Argument 1
passed to Users::__construct() must be an instance of Mysqliconn,
none given, called in ....\class\class.news.php
Now in my class Users I would like to to call a News class method,
but I get an error if I try to istantiate the class News inside class Users.
How can I do this?
Thanks.
Plz post what error you are getting. Otherwise it's difficult to capture the problem. But if you dont want to instantiate the news class in the user class you can access it like
class News
{
// news class
}
class Users
{
public function some_method(News $news){
// work with the $news object
}
}
$us = new Users();
$us->some_method(new News(/*$db*/));
This is just a basic code to give you an idea of how you can use it. In a production environment you have to take a lot of precautions.
i have the following code
class Application
{
protected $db;
public function getDBChange(database $db)
{
$this->db =& $db;
$this->update($db);
}
protected function update($db)
{
$this->db=& $db;
echo "\nServer - update- IN";
$SQL = "UPDATE `version` SET app_ver='1.0.6'";
if (!$this->db->query($SQL))
{
echo "\nDatabase Error.";
}
echo "\nServer - update- OUT";
}
}
it works properly but when I called this update function from a child class it gives error the child class as follow
class DemoApplication extends Application
{
callParent()
{
$this->update($this->db);
}
}
when i use this way it gives Error Fatal error: Call to a member function query() on a non-object in
That's because $db doesn't have a query() method. Is $this->db actually set and of an object that has a query() method?
Do some debugging:
var_dump($this->db);
Why are you passing $this->db to a method in a same $this context? Why not just set $this->db in a child class and then call $this->update? Since they are both defined in a parent class there should be no problem doing this. As for error itself: you try to set private member with address assignment of external variable, therefore it is possible to access a private member of an object later on via variable you want private member address to.
Im having problems extending a Class.
This is what I was trying to do:
class Core
{
protected $db;
public function __construct()
{
$this->set_db_class();
}
private function set_db_class ()
{
include_once ( './classes/Database.php' );
$this->db = new Database();
}
}
class Functions extends Core
{
public function __construct()
{
parent::__construct();
}
public static function create_user ()
{
$this->db->query ( "INSERT ..." );
}
}
So, that's the estructure, but my problem is that I'm getting the following error:
Fatal error: Using $this when not in object context in /Applications/XAMPP/xamppfiles/htdocs/own/newsite/classes/class.Functions.php on line 10
What can I do to solve this?
Declare create_user as non-static and call it from an instance, otherwise (as the error message says) you cannot access $this, since $this is always a reference to the current instance. In a static context, there isn't one.
$functions = new Functions();
$functions->create_user();
instead of
Functions::create_user();
If you want to bundle functions that are not logically related to each other, use a namespace and not a class. You can go with an all-static class (every tiny property and method is static so that you don't need an instance at any time), but that's a horrible solution and not what classes should be used for.