OOP: display result of a database with while loop

PHP programming forum. Ask questions or help people concerning PHP code. Don't understand a function? Need help implementing a class? Don't understand a class? Here is where to ask. Remember to do your homework!

Moderator: General Moderators

lauthiamkok
Forum Contributor
Posts: 153
Joined: Wed Apr 01, 2009 2:23 pm
Location: Plymouth, United Kingdom

OOP: display result of a database with while loop

Post by lauthiamkok »

Hi,
I am very new to OOP in PHP, I have mysite running with the conventional procedure, such as displaying my site menu in this way in a php file, menu.php

Code: Select all

<?php
$sql = "
SELECT *
FROM menu
ORDER BY order ASC";

$result = mysql_query($sql);
?>

<ul>
	<?php 
	while($row = mysql_fetch_assoc($result))
	{ 
	?>
	<li><a href="<?php echo $row['link'];?>"><?php echo $row['name'];?></a></li>
    <?php
	}
	?>
</ul>
now I would like to practise it in OOP, so I would like to separate PHP core code and html, class_lib.php, and menu.php

this is what I would put in class_lib.php,

Code: Select all

$mysqli= new MySQLi('localhost', 'root', 'xxx', 'my_db');

Class menu
{

public function get_menu()
	{

	$mysqli = new mysqli();

	$sql = "
	SELECT *
	FROM menu
	ORDER BY order ASC";

	$result = $mysqli->query($sql);
	}

}
so in my menu.php, I would just want to instantiate the menu object, and pulling data from the menu class,

Code: Select all

<ul>
	<?php 
        $menu = new menu();
	$menu->get_menu();
	while($row = $menu->fetch_assoc())
	{ 
	?>
	<li><a href="<?php echo $row['link'];?>"><?php echo $row['name'];?></a></li>
    <?php
	}
	?>
</ul>
but i won't get anything, I think probably my idea is incorrect??

will be grateful if u know how to correct this.

many thanks,
Lau
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: OOP: display result of a database with while loop

Post by Eran »

First, you have an error in your SQL - 'order' is a reserved word in MySQL, so you need to wrap it with backticks like so:

Code: Select all

SELECT * FROM menu
ORDER BY `order` ASC
Second, though you are using objects, this code is not really "object-oriented" - you are merely wrapping your previous procedural approach with a class. Using classes can give you much - such as abstraction, composition, reuse etc.

Consider the following:

Code: Select all

<?php
class Menu {
	public function getItems() {
		$db = new Db();
		$sql = "SELECT * FROM menu 
		ORDER BY `order` ASC";
		return $db -> fetchAll($sql);        
	}
}

class Db {
	protected $_adapter = null;
	protected $_error = null;
	public function __construct($username = 'root',$password = '1234',$database = 'yourdb') {
		$this -> _adapter = new mysqli(null,$username,$password,$database);
	}
	
	public function fetchAll($query) {
		$result = $this -> _adapter -> query($query);
		if($result) {
			return $result -> fetch_all(MYSQLI_ASSOC);
		} else {
			$this -> _error = $this -> _adapter -> error;
			return false;
		}
	}
	
	public function getError() {
		return $this -> _error;
	}
}

$menu = new Menu();
$items = $menu -> getItems();
if(is_array($items)) {
	foreach($items as $item) {
		
	}
}  
lauthiamkok
Forum Contributor
Posts: 153
Joined: Wed Apr 01, 2009 2:23 pm
Location: Plymouth, United Kingdom

Re: OOP: display result of a database with while loop

Post by lauthiamkok »

hello! thanks for this. wow... the code looks beautiful! and it looks very advanced to me! lol
I will need to spend some time to look into it.
many thanks :D
lauthiamkok
Forum Contributor
Posts: 153
Joined: Wed Apr 01, 2009 2:23 pm
Location: Plymouth, United Kingdom

Re: OOP: display result of a database with while loop

Post by lauthiamkok »

Hi, now I am trying to develop the code further with adding another class, a page class, which I can send parameter into this class, and fetch the content from the database,

Code: Select all

class Page {
        var $_title = null;
		public function __construct($title) {
			$this -> _title = $title;
		}
		
		public function getPage() {
                $db = new Db();
                $sql = "SELECT *
				FROM root_pages
				WHERE root_pages.pg_url = '".$_title."'";
                return $db -> fetchAll($sql);        
        }
}

Code: Select all

	$page = new Page('home');
	$item = $page->getPage();
	print_r($item);
but I won't get anything unless I replace the $_title with the fixed parameter, like this,

Code: Select all

class Page {
        var $_title = null;
		public function __construct($title) {
			$this -> _title = $title;
		}
		
		public function getPage() {
                $db = new Db();
                $sql = "SELECT *
				FROM root_pages
				WHERE root_pages.pg_url = 'home'";
                return $db -> fetchAll($sql);        
        }
}
then I get the result...

something I got it wrong here??

thanks.
lauthiamkok
Forum Contributor
Posts: 153
Joined: Wed Apr 01, 2009 2:23 pm
Location: Plymouth, United Kingdom

Re: OOP: display result of a database with while loop

Post by lauthiamkok »

got it sorted!

Code: Select all

protected $_title = null;
		public function __construct($title) {
			$this -> _title = $title;
		}
		
		public function getPage() {
                $db = new Db();
                $sql = "SELECT *
				FROM root_pages
				WHERE root_pages.pg_url = '".$this-> _title."'";
                return $db -> fetchAll($sql);        
        }
but not quite understand why have to replace

Code: Select all

$_title
with

Code: Select all

$this-> _title
...
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: OOP: display result of a database with while loop

Post by Eran »

If you have worked with functions before, you probably noticed that you can't access variables created outside the function unless you pass those as parameters to the function (or use the keyword 'global' but we'll ignore that for now). The reason for that is the inside of the function is in a separate scope from the main program or other functions.

You can't access '$_title' inside the function getPage() since it was not created there nor passed in as a parameter. In fact, no where in your code did you declare a variable named '$_title' - you did have '$title' but it's not exactly the same and it was in a different scope (a different function). Fortunately, class functions have a shared scope, which is accessed through the '$this' keyword. You can refer to class variables (and functions) using the $this scope, just as you did in your second attempt.
lauthiamkok
Forum Contributor
Posts: 153
Joined: Wed Apr 01, 2009 2:23 pm
Location: Plymouth, United Kingdom

Re: OOP: display result of a database with while loop

Post by lauthiamkok »

class functions have a shared scope, which is accessed through the '$this' keyword. You can refer to class variables (and functions) using the $this scope
thanks for this reply. now I understand it thoroughly! thanks :D

now I am trying to separate, the variables in the __construct() from

Code: Select all

public function __construct($hostname = 'localhost',$username = 'root',$password = '1234',$database = 'my_db')
to

Code: Select all

protected $hostname = 'localhost';
		protected $username = 'root';
		protected $password = '1234';
		protected $database = 'my_db';
		
		#make a connection
        public function __construct() {
				$this -> hostname;
				$this -> username; 
				$this -> password;
				$this -> database;
				$this -> _adapter = new mysqli($hostname,$username,$password,$database);
        }
but it fails to connect to the database... I have used $this -> to pass the variables into public function __construct() ... have I done something incorrectly again...?

thanks! :)
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: OOP: display result of a database with while loop

Post by Eran »

The basic concept here is that $variable is not the same as $this -> variable, though you are still treating it the same.
So in your code:

Code: Select all

public function __construct() {
     $this -> hostname;
     $this -> username;
     $this -> password;
     $this -> database;
     $this -> _adapter = new mysqli($hostname,$username,$password,$database);
}
The first 4 lines in the function do absolutely nothing. You are just calling variables by their name and doing nothing with them. The last line tries to create the adapter using 4 variables that are undefined in the scope of this function.
It should be :

Code: Select all

public function __construct() {
     $this -> _adapter = new mysqli($this -> hostname,$this -> username,$this -> password,$this -> database);
}
Though now you can't pass different parameters through the constructor as you removed the function parameters, so basically all those parameters are hard coded and can't be changed without changing the class. Not sure if that's what you tried to achieve
lauthiamkok
Forum Contributor
Posts: 153
Joined: Wed Apr 01, 2009 2:23 pm
Location: Plymouth, United Kingdom

Re: OOP: display result of a database with while loop

Post by lauthiamkok »

Code: Select all

public function __construct() {
     $this -> _adapter = new mysqli($this -> hostname,$this -> username,$this -> password,$this -> database);
}
awww... that is the proper way to do it and I didn't think of that! feeling shame of myself! :oops:

thank you so much for this guidance. I will keep this thread of post as my ultimate reference!

thanks :D
lauthiamkok
Forum Contributor
Posts: 153
Joined: Wed Apr 01, 2009 2:23 pm
Location: Plymouth, United Kingdom

Re: OOP: display result of a database with while loop

Post by lauthiamkok »

Code: Select all

Though now you can't pass different parameters through the constructor as you removed the function parameters, so basically all those parameters are hard coded and can't be changed without changing the class. Not sure if that's what you tried to achieve
I dunno what I am going to achieve yet at this stage - only try to understand single line of it and developing it.

will probably pass different parameters through the constructor again when I can see farther later.

thank you for this 'warning'... :)
lauthiamkok
Forum Contributor
Posts: 153
Joined: Wed Apr 01, 2009 2:23 pm
Location: Plymouth, United Kingdom

Re: OOP: display result of a database with while loop

Post by lauthiamkok »

I have now tried to pass different parameters through the constructor, but it won't connect to the database for some reason...

Code: Select all

class Db {
protected $_adapter = null;
protected $_error = null;
public function __construct($hostname,$username,$password,$database) 
	{
		$this -> _adapter = new mysqli($hostname,$username,$password,$database);
	}

}

Code: Select all

/* Database connection details and params */
# the host used to access DB
define('DB_HOST', 'localhost');

# the username used to access DB
define('DB_USER', 'root');

# the password for the username
define('DB_PASS', '1234');

# the name of your databse 
define('DB_NAME', 'your_db'); 

/* Make the MySQL connection */
$hostname = DB_HOST;
$username = DB_USER;
$password = DB_PASS;
$database = DB_NAME;

$db = new db($hostname,$username,$password,$database);
have I instantiated the db object correctly? or any extra thing I need to put in the class? :roll:

Thanks
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: OOP: display result of a database with while loop

Post by Eran »

I'm not sure why you felt you need to define constants to pass in parameters (you might as well use class constants instead). Other than that, those are not really your database settings, are they? those are the mock settings I put in the post, you should use your real database name, username and password
lauthiamkok
Forum Contributor
Posts: 153
Joined: Wed Apr 01, 2009 2:23 pm
Location: Plymouth, United Kingdom

Re: OOP: display result of a database with while loop

Post by lauthiamkok »

pytrin wrote:I'm not sure why you felt you need to define constants to pass in parameters (you might as well use class constants instead). Other than that, those are not really your database settings, are they? those are the mock settings I put in the post, you should use your real database name, username and password
yes I realise about the mock setting. this is my real setting, $hostname = 'localhost',$username = 'root',$password = 'tklau',$database = 'lau_thiam_kok_2010'

class constants - do u mean it in this way below which is in the class Db?

Code: Select all

public function __construct($hostname = 'localhost',$username = 'root',$password = 'tklau',$database = 'lau_thiam_kok_2010')
if so, then I have to modify the parameters every time when I change the database? I thought I could pass the parameter into the class Db and leave this class untouched always...

thank you.

cheers :)
User avatar
Eran
DevNet Master
Posts: 3549
Joined: Fri Jan 18, 2008 12:36 am
Location: Israel, ME

Re: OOP: display result of a database with while loop

Post by Eran »

In my opinion it's best to create a configuration file (ini or PHP file) and pass the configuration options from there
lauthiamkok
Forum Contributor
Posts: 153
Joined: Wed Apr 01, 2009 2:23 pm
Location: Plymouth, United Kingdom

Re: OOP: display result of a database with while loop

Post by lauthiamkok »

pytrin wrote:In my opinion it's best to create a configuration file (ini or PHP file) and pass the configuration options from there
ok. will work on a configuration php file. thanks for this again! :D
Post Reply