CK9 Posted April 27, 2011 Share Posted April 27, 2011 Hello again! I've been trying out new things (well, new for me) in php again. This time I decided to try a real challenge and make a forum system. A friend suggested I use a class for all database functionalities. i was reluctant at first, but decided if I was going to try using classes for the first time, it might as well be with this. With some guiding help, I set up the files and gave it a visual once over to check for errors. Nothing seemed out of place, but when I loaded the page to try it out, I got this error: Fatal error: Call to a member function query() on a non-object in /home/ck9/public_html/planning/forumbuild/list.php on line 20 I didn't see anything out of line, so I consulted my friend about it. He made a few small adjustment suggestions, but nothing fixed the issue. I then bugged my host about it, and he couldn't find anything wrong either. Both people are highly experienced in php, so when they say it SHOULD be working I am left rather confused. Here is list.php: <?php include("db.class.php"); include("db.config.php"); $db = new databaseConnection($config['user'],$config['pass'],$config['database']); $g = $_GET['g']; $s = $_GET['s']; $t = $_GET['t']; function tablestart($a = '1') { global $db; echo "<table border='" . $a . "' cellpadding='10' cellspacing='0' align='center' width='80%' style='color: #C0C0C0'>\n"; } function contents($table, $a, $b = '1', $c = '1') { global $db; $db->query("SELECT * FROM $table"); while($row = $db->fetch_array()) { if($row['level'] <= $_SESSION['ulevel']) { echo "<tr><td width='5%'><!--indicator--></td><td width='80%'><a href='index.php?pg=h&g='" . $row['g']; if(($a > '1') && ($row['g'] == $b)) { echo "&s=" . $row['s']; if(($a > '2') && ($row['s'] == $c)) { echo "&t=" . $row['t']; } } } echo "' style='color: #C0C0C0 ; text-decoration: none'><font size='4'>" . $row['name'] . "</font><br /><fpnt size='3'>" . $row['desc'] . "</td><td width='15%'><!--last update--></td></tr>\n"; } } if(empty($_SESSION['ulevel'])) { $_SESSION['ulevel'] = '0'; echo "<font color='#CC0000'><center>You need to register to post in these forums.</center></font><br />\n"; } if(empty($g)) { tablestart(); contents('group', '1'); echo "</table>\n"; } elseif(empty($s)) { tablestart(); contents('section', '2', $g); echo "</table>\n"; } elseif(empty($t)) { tablestart('0'); echo "<tr><td width='80%'></td><td><!--new topic--></td></tr>\n</table>\n"; tablestart(); contents('topic', '3', $g, $s); echo "</table>\n"; } elseif(!empty($t)) { tablestart('0'); echo "<tr><td width='80%'></td><td><!--new topic and reply--></td></tr>\n</table>\n"; $data = file_get_contents('topics/g' . $g . 's' . $s . 't' . $t . '.txt'); $post = explode("<!--p-->", $data); $length = count($post); tablestart('1'); for($z = '0'; $z < $length; $z ++) { $i = '0'; $cont = explode("<!--e-->", $post[$pos]); echo "<tr><td><b>" . $cont[$i] . "</b><br /><!--future additions--></td><td>\n<table width='100%' style='font-size: xx-small'>\n<tr><td height='3' width='75%'>"; $i ++; echo "Posted on" . $cont[$i] . "</td><td height='3' width='25%'><!--future additions--></td></tr><tr><td width='100%'>"; $i ++; echo $cont[$i] . "</td></tr></table></td></tr>\n"; } echo "</table>\n"; } ?> My aim here was to have a single page to display the groups, sections, topics, and posts in order to keep database calls where I could find them easily. and here is the class file: <?php class databaseConnection { protected $link; protected $lastResult; function databaseConnection($user,$pass,$database) { $this->link = mysql_connect("localhost",$user,$pass); if( !$this->link ) { die('Vital information missing.'); } else { mysql_select_db($database,$this->link) or die('could not find database: ' . mysql_error()); } } function query($query) { $this->lastresult = mysql_query($query) or die('MySQL error: ' . mysql_error()); return $this->lastresult; } function fetch_array($result = false) { if(!$result) { return mysql_fetch_array($this->lastresult); } else { return mysql_fetch_array($result); } } } ?> I have tried everything from adjusting the php tags to putting the class directly in the page. The config file just provides the user, pass, and which database to connect to. I've checked it's formatting a few times just in case. Quote Link to comment Share on other sites More sharing options...
btherl Posted April 27, 2011 Share Posted April 27, 2011 PHP is saying $db is not an object - what is it then? I would use var_dump() to show what is in $db before it is assigned, after it is assigned (after line 5 of list.php), and just before it is used in contents(). Once you've confirmed that it is correct after it is created but incorrect when used in contents(), start checking its value in between the points where you have already checked it, to find where it changes. Quote Link to comment Share on other sites More sharing options...
CK9 Posted April 27, 2011 Author Share Posted April 27, 2011 Okay, I did that and because of my lack of formal education in PHP, I'm left scratching my head a bit further NULL object(databaseConnection)#1 (2) { ["link:protected"]=> resource(7) of type (mysql link) ["lastResult:protected"]=> NULL } NULL I'm assuming that one of the class functions is causing it to revert back to a NULL variable. Looking through my class file, my attention is drawn to the followig lines: protected $link; protected $lastResult; and function query($query) { $this->lastresult = mysql_query($query) or die('MySQL error: ' . mysql_error()); return $this->lastresult; } function fetch_array($result = false) { if(!$result) { return mysql_fetch_array($this->lastresult); } else { return mysql_fetch_array($result); } } So, the function cannot execute because the protected status is preventing the list.php code from making a new entry (for lack of a better term) using the class. Am I at least close to correct? Quote Link to comment Share on other sites More sharing options...
btherl Posted April 27, 2011 Share Posted April 27, 2011 I'm assuming that one of the class functions is causing it to revert back to a NULL variable Ok this is the key finding - $db was an object after it got instantiated, but later it's not an object anymore, it's null. I don't think protected has anything to do with it, because protected class members may be accessed from within the class itself. And, if that were the issue, you would get an error instead of $db being set to null. If you want to eliminate this as a cause, just declare them both public instead. Another probably minor issue - $lastResult is not the same as $lastresult. What I would do is start displaying the contents of $db in more locations, so you can pinpoint exactly where it changes from an object to null. You might want to tag each location as well, eg: print "<pre> Before checking SESSION[ulevel]: " ; var_dump($db) ; print "</pre>"; The "pre" tags will make the output more readable. Eventually you will narrow it down to a single line. Before that line, $db is an object. After that line, $db is null. And that's the line you need to fix. Quote Link to comment Share on other sites More sharing options...
CK9 Posted April 27, 2011 Author Share Posted April 27, 2011 Okay, after adding it in several places, it would seem the second I'm inside the first function on list.php (tablestart), it's null...even before the "global $db;" line I see no reason for a function to cause this... Quote Link to comment Share on other sites More sharing options...
btherl Posted April 27, 2011 Share Posted April 27, 2011 It SHOULD be null before the global $db line. After global $db, it should be an object. The line "global $db;" is where $db is brought from global scope (ie outside all the functions) into local scope (ie inside the function). Is it still null after that line? Quote Link to comment Share on other sites More sharing options...
CK9 Posted April 27, 2011 Author Share Posted April 27, 2011 yes: Before first global: NULL After first global: NULL Before second global[ulevel]: NULL After secondglobal, before query: NULL and it errors at the query Quote Link to comment Share on other sites More sharing options...
btherl Posted April 27, 2011 Share Posted April 27, 2011 Well, that is strange. What happens if you pass $db as an argument to the function instead of using it as a global? Quote Link to comment Share on other sites More sharing options...
CK9 Posted April 27, 2011 Author Share Posted April 27, 2011 It doesn't work because it then ignores the inclusion of the config file Warning: mysql_connect() [function.mysql-connect]: Access denied for user 'nobody'@'localhost' (using password: NO) in /home/ck9/public_html/planning/forumbuild/db.class.php on line 8 Vital information missing. Quote Link to comment Share on other sites More sharing options...
btherl Posted April 27, 2011 Share Posted April 27, 2011 Can you please post the code that gave you that error. Also please post the third file, the one you haven't posted yet. You can edit the username and password first, but please leave everything else identical. Quote Link to comment Share on other sites More sharing options...
CK9 Posted April 27, 2011 Author Share Posted April 27, 2011 Line 8 of class file: $this->link = mysql_connect("localhost",$user,$pass); code for config file (info replaced with blank space): <?php $config = array( "user" => " ", "pass" => " ", "database" => " "); ?> Quote Link to comment Share on other sites More sharing options...
DavidAM Posted April 27, 2011 Share Posted April 27, 2011 Try your var_dump tests inside the functions again but DO NOT put the var_dump BEFORE the global command. I suspect that calling var_dump($db) BEFORE global, defines a new variable called $db because you have referenced it. Since you are "defining" it without assigning a value it is NULL. Leave the var_dump AFTER the global, and see what it tells us. Quote Link to comment Share on other sites More sharing options...
CK9 Posted April 27, 2011 Author Share Posted April 27, 2011 I did that the first time around with the vardump, it's getting nulled regardless of the dump. Quote Link to comment Share on other sites More sharing options...
btherl Posted April 27, 2011 Share Posted April 27, 2011 CK9, can you please post the full code. Snippets are not useful, because the important thing here is the order in which code is executed. Can you please post the full code of any file modified since you originally posted, along with the errors that code currently gives. The db config file looks innocent enough. Quote Link to comment Share on other sites More sharing options...
CK9 Posted April 27, 2011 Author Share Posted April 27, 2011 Currently, all the page codes are the same as posted in the first post (and whichever number the config code is in). I haven't done anything to permanantly modify the code. After running the test with the value dump lines, I removed them in order to keep the code the same as what is seen in this topic so that suggestions could be more quickly tested. Quote Link to comment Share on other sites More sharing options...
btherl Posted April 27, 2011 Share Posted April 27, 2011 Ok, can you please make the following changes function tablestart($a = '1') { global $db; to function tablestart($db, $a = '1') { And also change every call to tablestart() as follows: tablestart() replace with tablestart($db) tablestart('0') replace with tablestart($db, '0') I don't know what you did when I asked you to make $db an argument to those functions, but this is what I was wanting you to do. It's got nothing to do the db config file or where $db is set to a new class instance. Quote Link to comment Share on other sites More sharing options...
CK9 Posted April 27, 2011 Author Share Posted April 27, 2011 I had added the "$db->..." into the second function rather than adding $db as an argument.... After reviewing the code again, I realized the first itteration of the global variable (inside the tablestart function) was a placement error that I only partially corrected, so that gets removed entirely... Here's what I have now: <?php include("db.class.php"); include("db.config.php"); $db = new databaseConnection($config['user'],$config['pass'],$config['database']); $g = $_GET['g']; $s = $_GET['s']; $t = $_GET['t']; function tablestart($a = '1') { echo "<table border='" . $a . "' cellpadding='10' cellspacing='0' align='center' width='80%' style='color: #C0C0C0'>\n"; } function contents($db, $table, $a, $b = '1', $c = '1') { // global $db; $db->query("SELECT * FROM $table"); while($row = $db->fetch_array()) { if($row['level'] <= $_SESSION['ulevel']) { echo "<tr><td width='5%'><!--indicator--></td><td width='80%'><a href='index.php?pg=h&g='" . $row['g']; if(($a > '1') && ($row['g'] == $b)) { echo "&s=" . $row['s']; if(($a > '2') && ($row['s'] == $c)) { echo "&t=" . $row['t']; } } } echo "' style='color: #C0C0C0 ; text-decoration: none'><font size='4'>" . $row['name'] . "</font><br /><fpnt size='3'>" . $row['desc'] . "</td><td width='15%'><!--last update--></td></tr>\n"; } } if(empty($_SESSION['ulevel'])) { $_SESSION['ulevel'] = '0'; echo "<font color='#CC0000'><center>You need to register to post in these forums.</center></font><br />\n"; } if(empty($g)) { tablestart(); contents($db, 'group', '1'); echo "</table>\n"; } elseif(empty($s)) { tablestart(); contents($db, 'section', '2', $g); echo "</table>\n"; } elseif(empty($t)) { tablestart('0'); echo "<tr><td width='80%'></td><td><!--new topic--></td></tr>\n</table>\n"; tablestart(); contents($db, 'topic', '3', $g, $s); echo "</table>\n"; } elseif(!empty($t)) { tablestart('0'); echo "<tr><td width='80%'></td><td><!--new topic and reply--></td></tr>\n</table>\n"; $data = file_get_contents('topics/g' . $g . 's' . $s . 't' . $t . '.txt'); $post = explode("<!--p-->", $data); $length = count($post); tablestart('1'); for($z = '0'; $z < $length; $z ++) { $i = '0'; $cont = explode("<!--e-->", $post[$pos]); echo "<tr><td><b>" . $cont[$i] . "</b><br /><!--future additions--></td><td>\n<table width='100%' style='font-size: xx-small'>\n<tr><td height='3' width='75%'>"; $i ++; echo "Posted on" . $cont[$i] . "</td><td height='3' width='25%'><!--future additions--></td></tr><tr><td width='100%'>"; $i ++; echo $cont[$i] . "</td></tr></table></td></tr>\n"; } echo "</table>\n"; } ?> which now brings up MySQL error: You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near 'group' at line 1 which points me to either the class file or the database itself...the class file doesn't have the word 'group' anywhere in it, so it has to be something with the database...looking at that I find a spelling error in the table name...correcting the error doesn't clear the error...I use phpmyadmin for everything related to the database itself, so I'm not sure what the error is pointing at. Quote Link to comment Share on other sites More sharing options...
btherl Posted April 27, 2011 Share Posted April 27, 2011 Yay, you have now fixed the first error Previously the error was that $db was not available inside contents(). But now $db is available, and you are getting a new error from a query going through $db. "group" appears in list.php as an argument to contents(). The problem is that "group" is a reserved word for MySQL. If you really are using "group" as a table name, you will need to put it in backticks I believe. So your query should be: $db->query("SELECT * FROM `$table`"); I'm not a regular MySQL user so I could be wrong there. If that doesn't work, try this: $db->query("SELECT * FROM \"$table\""); Quote Link to comment Share on other sites More sharing options...
CK9 Posted April 27, 2011 Author Share Posted April 27, 2011 So, if I change it to, say, fgroup it should clear up? Apparently so =) Thanks for all the help and sorry for any frustrations, heh. Quote Link to comment Share on other sites More sharing options...
btherl Posted April 27, 2011 Share Posted April 27, 2011 Yep, fgroup will be fine. Congratulations on getting it working I still have no idea why the original code didn't work.. I agree with your php friends, the original code you posted should have worked. Quote Link to comment Share on other sites More sharing options...
CK9 Posted April 27, 2011 Author Share Posted April 27, 2011 Maybe there is a server setting that has an unforseen effect. Unfortunately, now that that part is fixed, I'm having issues with my login system that I didn't have without using a class for database connection. I'm sure it's just a simple thing though, probably didn't properly set up the username and password comparison (again, heh). Quote Link to comment 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.