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.
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'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();
}
}
}
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.
}
}
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.
After looking at this question, I tried the chosen answer myself!
So basically what I wrote was `
abstract class person
{
function __construct()
{
// some code here
}
function myfunc()
{
$this->test();
}
abstract function test();
}
class employee extends person
{
function __construct()
{
parent::__construct();
}
function test()
{
echo "So you managed to call me !!";
}
}
$employee = new employee();
$employee->myfunc();`
When I run this script, I got an usual error
Fatal error: Using $this when not in object context on line 7.
So, how do I call an Abstract from the Parent Class?
EDIT
The real thing which I am trying to do is create a DatabaseObject class which holds all the common methods of different database objects and make classes extend it.
abstract class DatabaseObject {
abstract protected function getTableName();
public static function find_by_id($id = 0){
global $database;
$class = get_called_class();
$result_array = self::find_by_sql("SELECT * FROM ". $this->getTableName() ." WHERE _id = {$id} LIMIT 1");
echo $result_array . "<br />";
return !empty($result_array) ? array_shift($result_array) : false;
}
public static function find_by_sql($sql=""){
global $database;
$result_set = $database->query($sql);
$object_array = array();
while ($row = $database->fetch_array($result_set)){
$object_array[] = self::instantiate($row);
}
return $object_array;
}
}
}
So this is some part of my DatabaseObject Class. My User class is as follows
class User extends DatabaseObject {
protected static $table_name = "users";
protected function getTableName(){
global $table_name;
return $table_name;
}
}
Now, whenever I do
$user = new User();
$user->findById(1);
I get the error Fatal error: Using $this when not in object context
on the line which points to
$this->getTableName();
I hope this might help in clearing up some stuff. Is there any way I can achieve this?
Thanks!
Your code example works just fine, I don't understand your issue Demo.
So the code you've shared is not the code you talk about with the error .
You can not call the variable as if it were a member of the class, since you declared it static. Calls to static variables looks the same as when you call static functions, use the :: operator.
class User extends DatabaseObject {
protected static $table_name = "users";
protected function getTableName(){
return self::$table_name;
}
}
The first thing is you can not call the abstract function within the same class. You are calling test(); in side myfunc() which is not allowed by oops.
You cant access the abstract function inside the same abstract class.
What ever your needs are, you have to call that method in sub class only, abstract super class will not call the sub class function.
EDIT:
Because the function dosent exists in that class.