Fatal error: Call to a member function setErrorCallbackFunction() on a non-object
I can't seem to get this to work. I'm newer to oop and classes and such. I'm using a sql wrapper (yes I know some don't approve) because it's easier to query the database imo. Its class is "db" and extends PDO. I have a "page security" script here:
public function __construct() { //require necessary files require_once('config/dbconfig.php'); require_once('classes/class.mysqli.php');
//initiate connection $this->db = new db("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass); $this->db->setErrorCallbackFunction("errorHandler");
$this->getOnlineUsers(); }
private function getOnlineUsers() { //set up bind variables $bindemail = array( ":uemail" => $_SESSION['u_name'] );
// set up update values $updateVals = array( 'isonline' => 1, 'lastactive' => date('Y-m-d H:i:s') );
// set to update values for offline $updateOffline = array( 'isonline' => 0, 'lastactive' => date('Y-m-d H:i:s'), 'sessid' => null );
// update active user $this->db->update('users', $updateVals, 'email = :uemail', $bindemail);
// get list of active users $results = $this->db->select('users','isonline=1','','id, email, firstname, lastactive','','');
// catch all the users and output if (count($results) > 0) { foreach($results as $row) { // set up the date $date = $row['lastactive']; $currentDate = strtotime($date); $futureDate = $currentDate+(60*5); $formatDate = date("Y-m-d H:i:s", $futureDate);
// check the date on each record that says is online. If not, update that record to offline like logout if ($formatDate > date('Y-m-d H:i:s')) { echo '<li><a id="userid" href="userprofile.php?id=' .$row['id']. '" alt="Last Active: ' .$row['lastactive']. '">' .$row['firstname']. '</a></li>'; }else { //set up bind variables $getEmailBind = array( ":rowemail" => $row['email'] );
// update that field in database for inactive user $this->db->update('users', $updateOffline, 'email = :rowemail', $getEmailBind); } } } } public function __destruct() { //kill object connection unset($this->db); } }
But I get this error:
PHP Code:
Fatal error: Call to a member function setErrorCallbackFunction() on a non-object in /home/imengi86/public_html/fileshare/classes/class.whosonline.php on line 23
Both these classes are being "require" on the same page, but again, I'm going to need many queries to the database. I don't seem to understand why it's so. I know what it means, it's not an object, but I'm setting it as an object. I know it has something to do, most likely, with me setting another already, but there must be some way to make this work...? I also want to stay away from singleton. From what I've read and understand it's incredibly bad in the end...
Edit: It also doesn't matter if I use $connect instead of $db in the second class. Just to add...
Last edited by gkjr1; 02-10-2013 at 08:54 AM..
Reason: New Info
I've tried everything I can think of. The only way I can get it to work is NOT using it as an actual class, and just including this code as procedure style scripting.
I know I've gotta be doing something wrong with the class for it to be doing this, as plenty of classes I've seen include other objects in them and such, I just don't get it. Like I said, the first class works fine, it's just when I try to create another database object in a different class, where they both are included on the same page. Please someone help me out...
Never mind. I got it. If there's a better way please let me know.
I simply included the connection to the database in the config instead of a class and made an object. I then included that config in every single page I will need to access the database. From there, every class that needs to use the database (and each class being included on the page with the config included first) passes the global $db, which is the object, into a private function in the class.
If there is some sort of security issue in this aspect, or a more efficient way to do this please let me know. It's all I could get to work.
You are trying to replace the function for Handling Errors, and it seems to be invalid. Try to remove this line, and see if it works.
__________________ "Be formless... shapeless, like water. Now you put water into a cup, it becomes the cup. You pour water into a bottle; it becomes the bottle. You put water into a teapot; it becomes the teapot. Now water can flow, or creep or drip or crash! Be water, my friend..." by Bruce Lee
I briefly read over those. Is it basically just a code to load all or select classes on a page? And dependency injection is only putting in the classes needed? If someone could explain in layman terms please...
You are trying to replace the function for Handling Errors, and it seems to be invalid. Try to remove this line, and see if it works.
I believe I have tried this already and it just moved to the next call on the object, but I will try again when I get a chance. Just taking a break in between homework. Stupid college getting in the way of my website lol.
Many developers writing object-oriented applications create one PHP source file per class definition. One of the biggest annoyances is having to write a long list of needed includes at the beginning of each script (one for each class).
In PHP 5, this is no longer necessary. You may define an __autoload() function which is automatically called in case you are trying to use a class/interface which hasn't been defined yet. By calling this function the scripting engine is given a last chance to load the class before PHP fails with an error.
__autoload is a bit of an ol' school method already. spl_autoload_register is much easier to work with as it effectively constructs a stack of methods to check through until one returns a valid match. That does require 5.1.2 though.
An even easier method is if you use namespacing in PHP 5.3, suffix your extensions, and register that on the path. This is chained to the use keyword, so after an extension register and base path addition to the include path, you never need to issue a require/include for a class autoload again.
For this actual problem though, this error doesn't make any sense for what you have. new always returns a new instance of an object OR it throws an exception. I'm not aware of any way to nullify this within the constructor. I *believe* early 5.0 gen PHP had a bug that allowed you to destroy in a constructor by unsetting $this, but I also believe that's been fixed.
But from these lines here, you should always have an instance of the object:
PHP Code:
//initiate connection $this->db = new db("mysql:host=$db_host;dbname=$db_name", $db_user, $db_pass); $this->db->setErrorCallbackFunction("errorHandler");
The first line will assign $this->db with an instance of db, regardless of what that instance results in. If it cannot construct an instance (forced *new* construct singleton via exceptions for example), than that line would trigger an exception, which terminates the attempted construction of the WHOSONLINE object as well. When this happens, it would never attempt the setErrorCallbackFunction since it failed to construct the object properly. Here's an example of what I mean:
PHP Code:
class C { private $conn;
public function __construct() { $this->conn = new T(); print $this->conn->method(); } }
class T { private static $cnt = 0; public function __construct() { if (self::$cnt >= 1) { throw new RuntimeException('Can only have one of ' . __CLASS__); } self::$cnt++; } public function method() { return __METHOD__; } }
So here $c will exist, but $c2 will not. Since it fails on the second new C(), it is impossible to make it to echo '$c2 done.'; instruction.
Now, this all being said, they have had issues in the past with PDO not returning an object, nor throwing an exception if there were problems with connections to the databases. I wouldn't have expected that such bugs would still exist, but I do guess it depends on the version of PHP in use.
__________________
As of PHP 5.5, the MySQL library has been officially deprecated. It is recommended to move to either MySQLi or PDO libraries for your mysql connectivity. See here for help choosing which interface you prefer: http://php.net/manual/en/mysqlinfo.api.choosing.php