Sanjib Sinha Posted December 29, 2012 Share Posted December 29, 2012 I have a simple category table in which 5 or 6 names are there. Now I want to retrieve them. When I connect to mysql database in procedural way, the while loop is working great, giving nice output. But when I go through a class and trying to retrieve the data, it stops after giving the first table name. My procedural code is here: mysql_connect("localhost", "root", ""); mysql_selectdb("12reach"); $cat = mysql_query("SELECT * FROM `category` LIMIT 0 , 30"); if (!$cat){ die ('Error'); } while ($row = mysql_fetch_array($cat)) { extract($row); echo $row['name'].'<br>'; } It works fine. Giving six category name. But problem begins with the following code: I have two classes and a php file where I created an instance of category class and trying to get the category table names one by one. class ConnectClass { private $_connection; public function getConnect() { $this->_connection = mysql_connect("localhost", "root", ""); if (mysql_errno()) { throw new RuntimeException('Cannot access database: '.mysql_error()); } else { mysql_selectdb("12reach", $this->_connection); } } include 'ConnectClass.php'; class CatClass extends ConnectClass{ public function getcat() { $cat = mysql_query("SELECT * FROM `category` LIMIT 0 , 30"); if (!$cat){ die ('Error'); } while ($row = mysql_fetch_array($cat)) { extract($row); return $row['name'].'<br>'; } } } include 'CatClass.php'; $obj=new CatClass(); $obj->getConnect(); echo $obj->getcat(); Probably while loop is working inside the class. As I want to return the last name of the category table, I can get it placing it outside the loop. But if I want the full name list, it does not work in object oriented format. Any idea, where is my fault? Quote Link to comment https://forums.phpfreaks.com/topic/272473-why-while-loop-is-not-working-inside-a-class/ Share on other sites More sharing options...
Jessica Posted December 29, 2012 Share Posted December 29, 2012 Return exits the function. In your function create an array of the names and return that when done. Quote Link to comment https://forums.phpfreaks.com/topic/272473-why-while-loop-is-not-working-inside-a-class/#findComment-1401961 Share on other sites More sharing options...
Sanjib Sinha Posted December 29, 2012 Author Share Posted December 29, 2012 Many thanks for giving the clue. But I have a question. If I want to return rows as an array, the same thing happens. It returns an output 'Array'. Like this, include 'ConnectClass.php'; class CatClass extends ConnectClass{ public function getcat() { $cat = mysql_query("SELECT * FROM `category` LIMIT 0 , 30"); if (!$cat){ die ('Error'); } while ($row = mysql_fetch_array($cat)) { extract($row); $result = array($row['name']);// or $result=array($row); return $result; } } } in my php file connect.php, I tried to echo like this: include 'CatClass.php'; $obj=new CatClass(); $obj->getConnect(); //print_r($obj->getcat()); echo $obj->getcat(); But the output is Array. Quite normal. If I use print_r function I can see that while loop stops after the first row. But if I don't use return, and instaed use echo inside CatClass.php, it works fine. Like this: include 'ConnectClass.php'; class CatClass extends ConnectClass{ public function getcat() { $cat = mysql_query("SELECT * FROM `category` LIMIT 0 , 30"); if (!$cat){ die ('Error'); } while ($row = mysql_fetch_array($cat)) { extract($row); echo $row['name'].'<br>'; } } } In this case in my connect.php file I only call the function like this: include 'CatClass.php'; $obj=new CatClass(); $obj->getConnect(); $obj->getcat(); Now it gives nice output of all the rows of table names. So, return is simply not working inside a class while loop. It exits and do not enter again into that loop. But if I echo it, it produces perfect output inside that function. Now, my question is, could I not use return inside a class while trying to retrieve many values? Quote Link to comment https://forums.phpfreaks.com/topic/272473-why-while-loop-is-not-working-inside-a-class/#findComment-1401965 Share on other sites More sharing options...
trq Posted December 29, 2012 Share Posted December 29, 2012 Your return statement needs to go outside of your while loop. This has nothing to do with the fact that your code is within a class. As has already been said, return exits the current function. The code within your while loop is all over the place anyway actually. Replace your while loop with this: $results = array(); while ($row = mysql_fetch_array($cat)) { $results[] = $row['name']; } return $results; I would also seriously consider removing your classes all together. They are not being used at all like they are designed to be used. Quote Link to comment https://forums.phpfreaks.com/topic/272473-why-while-loop-is-not-working-inside-a-class/#findComment-1401969 Share on other sites More sharing options...
Sanjib Sinha Posted December 29, 2012 Author Share Posted December 29, 2012 Many thanks. It works and I understood the trick. But if you kindly clarify the last line I would also seriously consider removing your classes all together. They are not being used at all like they are designed to be used. I will be grateful. Would you suggest to bring the whole thing under one class? Quote Link to comment https://forums.phpfreaks.com/topic/272473-why-while-loop-is-not-working-inside-a-class/#findComment-1401994 Share on other sites More sharing options...
cpd Posted December 29, 2012 Share Posted December 29, 2012 (edited) Your hierarchy is complete nonsense. You've written, in English: "CatClass is a ConnectClass.". This is because you've extended the CatClass to the ConnectClass but in reality a cat has absolutely nothing to do with a database connection. Further more you've ploughed a shed load of logic into single methods; you've included data retrieval and processing all in one method which doesn't make sense especially considering the name of your method. Consider separating your logic into parts e.g. a Database class can have methods such as __construct() (that creates the connection upon instantiation), getConnection(), selectDatabase() and so on. This can be instantiated and passed to the Cat class via a constructor. Plus the points above regarding the return statement and finally, you don't need to put a "Class" suffix after every class. You can't instantiated anything other than concrete classes so its unnecessary effort. Edited December 29, 2012 by CPD Quote Link to comment https://forums.phpfreaks.com/topic/272473-why-while-loop-is-not-working-inside-a-class/#findComment-1402002 Share on other sites More sharing options...
Sanjib Sinha Posted December 29, 2012 Author Share Posted December 29, 2012 As you have suggested, I am trying to restructure my class codes in this way. First the ConnectClass.php //this is a simple class to establish connection //with the database class ConnectClass { private $_connection; private $_database; public function __construct() { $this->_connection = $con; $this->_database = $db; } public function selectDatabase() { $con = mysql_connect("localhost", "root", ""); if (mysql_errno ()){ throw new RuntimeException('Cannot access database: '.mysql_error()); } else { $db = '12reach'; mysql_select_db($db, $con); } } } Next the CategoryClass.php /* * CategoryClass basically extends ConnectClass * to establish connection with the database * and retrieve datas from category table */ include 'ConnectClass.php'; class CategoryClass extends ConnectClass{ public function __construct() { $this->selectDatabase(); } public function categoryName() { $cat = mysql_query("SELECT * FROM `category` LIMIT 0 , 30"); if (!$cat){ die ('Error'); } //since we dont want to exit the loop without having //all the table names, so we get our results in an array $results = array(); while ($row = mysql_fetch_array($cat)) { $results[] = $row['name']; } //now it is time to go outside the loop and return all table names return $results; } } Please suggest, if it can be modified or be written in a better way? So that connection and other part be more secured. Quote Link to comment https://forums.phpfreaks.com/topic/272473-why-while-loop-is-not-working-inside-a-class/#findComment-1402032 Share on other sites More sharing options...
Christian F. Posted December 29, 2012 Share Posted December 29, 2012 (edited) The category class uses a DB connection, but it's not a database connection. Send the DB connection object as a parameter to the constructor, but don't extend the DB class with the category class. Think of it in terms of chess: A knight is an extension of the piece, but the board uses the pieces. Thus you'll have to send the pieces (object instances) to the board, as it makes no sense to extend the board from a piece. Same way with categories and the DB connection. abstract class Piece { private $_colour; private $_move_rule; private $_name; public function move ($vector) {} public function set_colour () { $this->colour = $colour == 'white' ? 'white' : 'black'; } public function get_colour () {return $this->colour;} public function get_name () {return $this->name;} } class Knight implements Piece { private $_name = "Knight"; private $_move_rule = "1fx2s"; } class ChessBoard implements GameBoard { private $_height = 16; private $_width = 16; private $_players = 2; private $_pieces = array (); public function add_piece (Piece $piece, $x_pos, $y_pos) { } } // Generate the chess board. $game = new ChessBoard (); // Generate the chess pieces. $knight_white = new Knight ('white'); // Add the chess pieces to the game board. $game->add_piece ($knight_white, 1, 3); Just a quick example, to showcase the proper object inheritance and association. Edited December 29, 2012 by Christian F. Quote Link to comment https://forums.phpfreaks.com/topic/272473-why-while-loop-is-not-working-inside-a-class/#findComment-1402036 Share on other sites More sharing options...
Sanjib Sinha Posted December 29, 2012 Author Share Posted December 29, 2012 So many thanks for clearing the confusion. Each time I want to fetch a category name(here a category object), database connection opens up and closes, so it is really unneccessary to extend CategoryClass from ConnectClass. Connection object can be passed as an argument through Category constructor, so that with each instantiation of category, costructor will be called first and DB connection opens and closes. I will give it a try. Quote Link to comment https://forums.phpfreaks.com/topic/272473-why-while-loop-is-not-working-inside-a-class/#findComment-1402040 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.