Page 1 of 2
Call to a member function on a non-object (PHP 5)
Posted: Tue Aug 28, 2007 3:06 am
by Bon Bon
Basically, if I have the following code:
Code: Select all
class FirstClasss {
function DoSomething () {
return 1;
}
}
$x = new FirstClass;
Is there any way of using the $x variable in other classes like so:
Code: Select all
class SecondClass {
$MyVal = 1;
function Compare () {
if (strcmp($x->DoSomething(), $this->MyVal) == 0) return TRUE;
}
}
If not, what is the best way to get something like this to work, I have also tried doing FirstClass::DoSomething() but then I have the problem of $this belonging to SecondClass.
Cheers as this one has got me.
Posted: Tue Aug 28, 2007 3:23 am
by onion2k
Pass $x to the constructor of the second class?
Posted: Tue Aug 28, 2007 3:28 am
by Bon Bon
Cheers for the post, but how do I do that?
Sorry, never really got into OOP before but with PHP 4 going out I thought I better start learning.
Cheers.
Posted: Tue Aug 28, 2007 4:23 am
by xpgeek
First example delegate class FirstClass
Code: Select all
class SecondClass {
$MyVal = 1;
$x;
//first example delegate class FirstClass
function SecondClass()
{
$this->x = new FirstClasss ();
}
function Compare () {
if (strcmp($this->x->DoSomething(), $this->MyVal) == 0) return TRUE;
}
}
second example - $x is parameter of Compare function
Code: Select all
class SecondClass {
$MyVal = 1;
function Compare ($x) {
if (strcmp($x->DoSomething(), $this->MyVal) == 0) return TRUE;
}
}
Posted: Tue Aug 28, 2007 5:10 am
by Bon Bon
So what I have in theory is:
Code: Select all
<?php
/* database class file */
class Database {
function __construct () {
//db connection
}
function Query ($sql) {
return mysql_query($sql);
}
}
$database = new Database;
/* session class file */
class Session {
private $Database;
function UseDatabaseObject ($Database) {
$this->Database = $Database;
}
function CleanUp () {
$this->Database->Query("DELETE LOW_PRIORITY FROM `session` WHERE DATE_ADD(`touched`, INTERVAL 2 DAY) < NOW()");
}
}
$session = new Session;
$session->UseDatabaseObject($database);
$session->CleanUp();
?>
So is this the best way I should be doing this kind of thing, this example is a lot closer to what I am trying to achieve, the only problem is I want to use the __construct to clean sessions etc but it is not possible this way so I have to manually call Session::CleanUp.
Posted: Tue Aug 28, 2007 7:07 am
by xpgeek
You can use constructor to create the object and destructor to clean up objects.
Posted: Tue Aug 28, 2007 7:33 am
by Bon Bon
Are you saying the best way to do this is through the following:
Code: Select all
<?php
/* database class file */
class Database {
function __construct () {
// db connect + select
}
function Query ($sql) {
return mysql_query($sql);
}
}
$database = new Database;
/* session class file */
class Session {
private $Database;
function __construct () {
$this->Database = new Database;
}
function __destruct () {
$this->Database->Query("DELETE LOW_PRIORITY FROM `session` WHERE DATE_ADD(`touched`, INTERVAL 2 DAY) < NOW()");
}
}
$session = new Session;
?>
- or -
Code: Select all
<?php
/* database class file */
class Database {
function Query ($sql) {
return mysql_query($sql);
}
}
$database = new Database;
/* session class file */
class Session {
private $Database;
function __construct ($Database) {
$this->Database = $Database;
}
function __destruct () {
$this->Database->Query("DELETE LOW_PRIORITY FROM `session` WHERE DATE_ADD(`touched`, INTERVAL 2 DAY) < NOW()");
}
}
$session = new Session($database);
?>
Or is there another way, because what I want to do is the second but without having to pass the object when creating an instance of Session but rather have it included in the Session class itself like so:
Code: Select all
<?php
/* database class file */
class Database {
function Query ($sql) {
return mysql_query($sql);
}
}
$database = new Database;
/* session class file */
class Session {
private $Database;
function __construct () {
$this->Database = $database;
}
function __destruct () {
$this->Database->Query("DELETE LOW_PRIORITY FROM `session` WHERE DATE_ADD(`touched`, INTERVAL 2 DAY) < NOW()");
}
}
$session = new Session;
?>
Posted: Tue Aug 28, 2007 7:45 am
by Bon Bon
Put it simple, I do not want to initiate another class when 1 is already initiated because this is wasting resources, nor do I want to pass a variable by reference because this is messy when I will be passing about 5 to 10 at any 1 time, I do not want to extend the database class either because this means that I am duplicating functionality that is already there which I do not want.
I am basically trying to push a variable into the class without using globals, effectively a global without being global, if anyone knows how?
Posted: Tue Aug 28, 2007 7:58 am
by olog-hai
Do your database class a singleton.
Code: Select all
<?php
/* database class file */
class Database {
static $instance = null
function __construct () {
// db connect + select
}
function getInstance(){
if (self::$instance ===null){
self::$instance = new Database();
}
return self::$instance;
}
function Query ($sql) {
return mysql_query($sql);
}
}
$database = new Database;
/* session class file */
class Session {
private $Database;
function __construct () {
$this->Database = Database::getInstance();
}
function __destruct () {
$this->Database->Query("DELETE LOW_PRIORITY FROM `session` WHERE DATE_ADD(`touched`, INTERVAL 2 DAY) < NOW()");
}
}
Posted: Tue Aug 28, 2007 8:04 am
by Bon Bon
Spot on, I love you.
Posted: Tue Aug 28, 2007 9:30 am
by Zoxive
Modified Function i found on these forms a while ago..
Code: Select all
function &singleton($class,$Params=''){
static $Objects = array();
if(!isset($Objects[$class])){
if(!empty($Param)){
$Objects[$class] = new $class($Params);
}else{
$Objects[$class] = new $class;
}
}
return $Objects[$class];
}
Code: Select all
/**
* Example
*/
class class_ext{
protected $Q = NULL;
function __construct(){
$this->Q = &singleton('Mysql'); //Loads Class Mysql
}
}
Posted: Tue Aug 28, 2007 9:34 am
by olog-hai
The '&' is not necessary in PHP 5 as passing objects 'by reference' is now the default behaviour, which means that creating a 'clone' requires extra effort.
Posted: Tue Aug 28, 2007 9:41 am
by Zoxive
olog-hai wrote:The '&' is not necessary in PHP 5 as passing objects 'by reference' is now the default behaviour, which means that creating a 'clone' requires extra effort.
Doesn't hurt, and its easier on my brain to remember that i want it as a reference.
Posted: Tue Aug 28, 2007 9:49 am
by olog-hai
I like your singleton factory

Posted: Tue Aug 28, 2007 10:21 am
by Bon Bon
The original solution about the singleton is the what I was looking for and to be honest I feel it is the best solution. If you're wondering, this is what I have got:
database.php
Code: Select all
<?php
class Database {
static $instance = null;
function __construct () {
// db connect + select
}
final function GetInstance() {
if (self::$instance === null) self::$instance = new Database();
return self::$instance;
}
function Query ($sql) {
// run query etc
}
}
$database = Database::GetInstance();
?>
session.php
Code: Select all
<?php
class Session {
private $Database;
function __construct () {
$this->Database = Database::GetInstance();
// do session cleaning
}
function __destruct () {
// log things
}
}
$session = new Session;
?>