Seven_Rings Posted April 20, 2009 Share Posted April 20, 2009 Hey. I have been having this problem with a lot of objects... for a very long time. I probably just don't understand the frustrating method of error reporting for objects. Here is the code that isn't working. <?php require_once 'constants.inc'; // Includes the constants here. They are all valid. error_reporting(E_ALL); // Does about no good in error reporting. $con = new PDO('mysql:host='.DB_HOST.';dbname='.DB_NAME, DB_USER, DB_PASSWORD); // Looks right to me. class PDOMySQL { // Various functions here including the class constructor... function query($stmt,$vals) { global $con; $sth = $con->prepare($stmt); if(!$vals) { $sth->execute(); } else { $sth->execute($vals); } return $sth; } }; $database = new PDOMySQL(); ?> Any help you can give me at all is greatly appreciated. Thanks, -Seven_Rings Quote Link to comment https://forums.phpfreaks.com/topic/154807-solved-problem-with-php-data-objects/ Share on other sites More sharing options...
alphanumetrix Posted April 20, 2009 Share Posted April 20, 2009 posting the error would be helpful. Quote Link to comment https://forums.phpfreaks.com/topic/154807-solved-problem-with-php-data-objects/#findComment-814163 Share on other sites More sharing options...
RichardRotterdam Posted April 20, 2009 Share Posted April 20, 2009 why did you create a PDOMySQL class? PDO supports mysql fine as it is. Quote Link to comment https://forums.phpfreaks.com/topic/154807-solved-problem-with-php-data-objects/#findComment-814294 Share on other sites More sharing options...
Seven_Rings Posted April 20, 2009 Author Share Posted April 20, 2009 Oops... I forgot to post "the problem". I cant find a way to edit the first post. I was punished on here before for double posting, but since I just read the rules, and they say nothing about it, I do not expect to be punished. The error I am getting is the following: Fatal error: Call to a member function prepare() on a non-object in C:\wamp\www\index.php Thanks again, -Seven_Rings EDIT: This class is full of database functions, this *is* my database script. It's not just a PDOMySQL class. Quote Link to comment https://forums.phpfreaks.com/topic/154807-solved-problem-with-php-data-objects/#findComment-814458 Share on other sites More sharing options...
Seven_Rings Posted April 20, 2009 Author Share Posted April 20, 2009 Just went through the code again... this one is killing me. -Seven_Rings Quote Link to comment https://forums.phpfreaks.com/topic/154807-solved-problem-with-php-data-objects/#findComment-815020 Share on other sites More sharing options...
soak Posted April 20, 2009 Share Posted April 20, 2009 Seems as though $con isn't being instantiated correctly. If it helps, this is what my PDO details look like although mine is in a class.: <?php try { db::$__db = new PDO('mysql:host='.DB_SERVER.';'.(DB_PORT ? 'port='.DB_PORT.';' : '').'dbname='.DB_DATABASE, DB_USER, DB_PASSWORD, array(PDO::ATTR_PERSISTENT => true)); db::$__db->setAttribute(PDO::ATTR_EMULATE_PREPARES, true); return db::$__db; } catch (PDOException $e) { trigger_error('Unable to connect to the database.', E_USER_ERROR); } It should be wrapped in a try catch as it triggers an exception if the connection fails. Can you var_dump($con); after you instantiate it please? @Dj Kat, so that you can extend the class with your own functions to make it even easier to access the data you need. Also to allow you to abstract yourself away from that particular implementation. My DB class uses PDO if available and mysqli if it is not and I only have to use 1 set of functions to access it. I could just as easily hook it into adodb and use it with Postgres. EDIT: Sorry, meant to say that yep, connection details look fine. For some reason $con either isn't being set or isn't making it into the function. Quote Link to comment https://forums.phpfreaks.com/topic/154807-solved-problem-with-php-data-objects/#findComment-815028 Share on other sites More sharing options...
premiso Posted April 20, 2009 Share Posted April 20, 2009 Your error message is pretty self explanatory. Your class does not have the method "prepare". Simple as that. I do not know why you are using globals with a class. If you are and think that is right you need to read more up on OOP. For the global $con to work I believe you also have to define it as global at the start of the script. <?php global $con; // rest of code below The better alternative is make the PDOMySQL class have a constructor and pass the DB info to that and establish a connection in that constructor and store it as a class variable and use $this->con instead. Quote Link to comment https://forums.phpfreaks.com/topic/154807-solved-problem-with-php-data-objects/#findComment-815031 Share on other sites More sharing options...
Seven_Rings Posted April 20, 2009 Author Share Posted April 20, 2009 @premiso: I made the var global because it was inside of a function... had nothing to do with OOP. Anyways, I ended up taking your advice, which was actually the way I used to have it setup. Not sure why I changed, or that I want to remind myself. It works for now. Anyways, there is a new problem now, and since it's of the same type, I figured I would post it here. database.inc <?php require_once 'constants.inc'; // Includes the constants here. They are all valid. error_reporting(E_ALL); // Does about no good in error reporting. class PDOMySQL { // Various functions here including the class constructor... /* This is the function that is having a problem. */ function add_active_guest($ip, $url, $time) { /* If we aren't tracking visitors, stop here and return. Else continue. */ if(!TRACK_GUESTS) return; /* If we are tracking guests, add the active guest into the database. */ $stmt = "REPLACE INTO ".TABLE_ACTIVE_GUESTS." VALUES (?, ?, ?)"; $vars = array($ip,$url,$time); $sth = $this->query($stmt,$vars); /* And lastly, we will update the number of active guests since we just changed it. */ $this->calc_num_active_guests(); } /* Fixed this function already, here for refrence. */ function query($stmt,$vals) { $sth = $this->con->prepare($stmt); if(!$vals) { $sth->execute(); } else { $sth->execute($vals); } return $sth; } }; $database = new PDOMySQL(); ?> And the code that is calling it... session.inc if(TRACK_GUESTS) { $database->add_active_guest($this->ip, $this->url, $this->time); } database.inc is properly included and all. The error is as follows... Fatal error: Call to a member function add_active_guest() on a non-object in C:\wamp\www\session.inc OOP sometimes just doesn't feel worth the trouble. But hopefully someone can shed some light on what I am missing here... Thanks! -Seven_Rings Quote Link to comment https://forums.phpfreaks.com/topic/154807-solved-problem-with-php-data-objects/#findComment-815053 Share on other sites More sharing options...
premiso Posted April 20, 2009 Share Posted April 20, 2009 Where is the code where you actually call add_active_guest. $database has not been defined as a class. Are you calling it in a function? If so I would have to referrer you to variables scope. As far as that being the way it "was" (the global comment), I am not a mind reader. I just see what you post. Quote Link to comment https://forums.phpfreaks.com/topic/154807-solved-problem-with-php-data-objects/#findComment-815094 Share on other sites More sharing options...
Seven_Rings Posted April 21, 2009 Author Share Posted April 21, 2009 I posted the code that was calling add_active_guest... I'll post it again with the rest of the function (which is also inside of a different class). <?php class Session { // Class constructor and other functions... function start_session() { global $database; session_start(); $this->logged_in = $this->check_login(); $this->url = $_SESSION['url'] = $_SERVER['PHP_SELF']; $this->ip = $_SERVER['REMOTE_ADDR']; if(!$this->logged_in) { $this->username = $_SESSION['username'] = GUEST_NAME; $this->userlevel = GUEST_LEVEL; if(TRACK_GUESTS) { $database->add_active_guest($this->ip, $this->url, $this->time); } } else { if(TRACK_USERS) { $database->add_active_user($this->username, $this->url, $this->time); } } /* Remove inactive visitors from database */ $database->remove_inactive_users(); $database->remove_inactive_guests(); } }; $session = new Session(); ?> database.inc is included in the same source as the code I posted, so $database should be an instance of the PDOMySQL class. And I am globalizing $database because I am calling it from within a function. I have been coding for quite a while now, and I am pretty sure that is the correct thing to do. Hopefully between this and the last post, the answer will be obvious. Thanks for your time, -Seven_Rings Quote Link to comment https://forums.phpfreaks.com/topic/154807-solved-problem-with-php-data-objects/#findComment-815645 Share on other sites More sharing options...
premiso Posted April 21, 2009 Share Posted April 21, 2009 I think we still get to the point of the variable scope. global $database; $database = new PDOMySQL(); ?> If you add that it should work for the session. As far as this being a good way to do it, it is not. I would look more into OOP Programming in PHP. Quote Link to comment https://forums.phpfreaks.com/topic/154807-solved-problem-with-php-data-objects/#findComment-815657 Share on other sites More sharing options...
soak Posted April 21, 2009 Share Posted April 21, 2009 Are you including the file that starts up $database before you call $session->start_session()? If so something is either un-setting $database or $database isn't getting set correctly. @premiso, pretty sure there's no need to do that (unless you're instantiating the object within a function). Quote Link to comment https://forums.phpfreaks.com/topic/154807-solved-problem-with-php-data-objects/#findComment-815659 Share on other sites More sharing options...
premiso Posted April 21, 2009 Share Posted April 21, 2009 @premiso, pretty sure there's no need to do that (unless you're instantiating the object within a function). Yep you are right. He must not be calling the database class first or unsets it. Quote Link to comment https://forums.phpfreaks.com/topic/154807-solved-problem-with-php-data-objects/#findComment-815662 Share on other sites More sharing options...
Seven_Rings Posted April 21, 2009 Author Share Posted April 21, 2009 Well, instantiating the class inside the function DID work. But I am including database.inc before I am trying to call it. I am including database.inc and session.inc on the same page. And I am not resetting $database anywhere. Database is included first. If instantiating the class inside the function isn't the way to do it, than what is? I have done a bit of reading on OOP, but if you know the answer, I would certainly like to hear it. Thanks, You guys are great. -Seven_Rings Quote Link to comment https://forums.phpfreaks.com/topic/154807-solved-problem-with-php-data-objects/#findComment-815675 Share on other sites More sharing options...
soak Posted April 21, 2009 Share Posted April 21, 2009 I'm pretty sure that in your code something is unsetting database. Try: var_dump($database); just after you set it and also just before you call $session->session_start() I'll bet you get two different values. Your code looks fine, from what you've posted it should work. As for how to do it "properly" there are a few ways. Your PDOMySQL class could be a base class that all other classes inherit from (if this is the case the connection link will need to be static). Or you could make your DB class entirely static. Or you could instantiate it each time inside whichever class you need it in but this is arguably not the most efficient way of doing it Quote Link to comment https://forums.phpfreaks.com/topic/154807-solved-problem-with-php-data-objects/#findComment-815685 Share on other sites More sharing options...
premiso Posted April 21, 2009 Share Posted April 21, 2009 Singleton is a good way to go with a DB class. This would ensure that only one copy of the class is ever instantiated. Then where you use it, you just "re"-instaitate the object. Although it does not actually re-instantiate it. Instead it gives you the already instantiated object. This way you do not have to use global for it. An example: <?php class testSingleton { private static $instance; public function __construct() { echo "Test Construct<br />"; } public function test() { echo "This is the test function<br />"; } // delivers the current instance of this class "singleton" public static function getSingleton() { if (!isset(self::$instance)) { $c = __CLASS__; self::$instance = new $c(); } return self::$instance; } } class testSingletonTwo { private $testOne; public function __construct() { $testOne = testSingleton::getSingleton(); $testOne->test(); } } function testThree() { $testOne = testSingleton::getSingleton(); $testOne->test(); } testThree(); $singletonTwo = new testSingletonTwo(); ?> There is a rough break down. Be cautious when using them and only use them for classes (such as a database class) that actually need it. Quote Link to comment https://forums.phpfreaks.com/topic/154807-solved-problem-with-php-data-objects/#findComment-815689 Share on other sites More sharing options...
Seven_Rings Posted April 21, 2009 Author Share Posted April 21, 2009 You where right. The var_dump after: $database = new PDOMySQL(); was great... but before I called start_session it was NULL. I have no idea how this could be happening. I like the extending ideas, but would it be better for me to use a singleton, or to make Session extend PDOMySQL? Asking expert advice on which is better in my case, since you guys probably have a decent idea of what my script is. *Mostly a login system right now* Thanks again, -Seven_Rings Quote Link to comment https://forums.phpfreaks.com/topic/154807-solved-problem-with-php-data-objects/#findComment-815714 Share on other sites More sharing options...
premiso Posted April 21, 2009 Share Posted April 21, 2009 You where right. The var_dump after: $database = new PDOMySQL(); was great... but before I called start_session it was NULL. I have no idea how this could be happening. I like the extending ideas, but would it be better for me to use a singleton, or to make Session extend PDOMySQL? Asking expert advice on which is better in my case, since you guys probably have a decent idea of what my script is. *Mostly a login system right now* Thanks again, -Seven_Rings It would be better for a singleton in this case vs extending. You really should only extend when you have a base class and the extended class does just that. Such as for an example you have an Address class. Then for the collection you have an Addresses class, which extends the address. As every address has the base essentials, street, city, zip etc. But then the addresses can add information, such as company name, contact name etc incase a person has more than one address (billing/shipping) but you do not want to have to re-create all the fields for the different class. Hopefully that is clear. I got interrupted halfway through and distracted. Quote Link to comment https://forums.phpfreaks.com/topic/154807-solved-problem-with-php-data-objects/#findComment-815740 Share on other sites More sharing options...
Recommended Posts
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.