Simple PHP Class-Based Querying

Simple PHP Class-Based Querying

Tutorial Details
  • Program: PHP
  • Version (if applicable): 5.1.6+
  • Difficulty: Moderate
  • Estimated Completion Time: 30-45 min

Though it is usually advisable to use some sort of framework or CMS, sometimes a project is small enough such that those options would weigh down the development. However, even in smaller projects, separating presentational elements from backend querying should not be ignored. This tutorial will walk you through creating a basic class-based querying engine for PHP and MySQL.


Step 1. Setup the Project

The first thing we are going to want to do is make some specific files and directories. Here’s how I like to setup my projects. You can, of course, feel free to change the names and structure to your liking. Just make sure you change the require’s later on as well.

Make directories

We’ll need a new directory to hold everything. In this case, I called it tut. Inside of that, I put my configuration files in a directory called conf. Then, I will make an inc directory (short for include) and put a “class” directory inside of that.

Add Files

Then, inside /conf, we will make config.php. Inside /inc/class we will make DAL.php. Finally, in the root directory, we will make index.php.

DAL stands for “Data Access Layer” or “Data Access Link”.

In multi-tiered architecture, it is essentially used to translate database query results into objects and vice-versa.


Step 2. Setup the Database

We need to make a database and populate it with some data. For the purposes of this tutorial, it will just be a two-table database with a single one-to-many relationship. This is just so we can show our querying engine spanning at least one relationship.

Create tables

So, in a database named “tut”, let’s make a table called makes and a table called models. The makes table will have fields “id” and “name” and the models table will have fields “id”,”make”, and “name”.

Add some data

Now we can just add some makes (like Ford, Chevy, etc.) as data in the makes table and some models that those manufacturers are responsible for.

This tutorial assumes you have some working knowledge of databases and SQL, so I won’t go into details about the relation/foreign key setup.


Step 3. The Database Connection

Usually, I don’t like working with raw constants in PHP. I will typically define a bunch of things then make some functions to hook into those constants. For this example, let’s just keep things simple and use the constants.

Define connection variables

In our /conf/config.php file, let’s setup our database connection variables. While we are at it, let’s throw an include to our DAL.php script.

<?php

// Include DAL
require_once(dirname(dirname(__FILE__)) . '/inc/class/DAL.php');

// Database
define ( 'DB_HOST', 'localhost' );
define ( 'DB_USER', 'root' );
define ( 'DB_PASSWORD', 'password1' );
define ( 'DB_DB', 'tut' );

?>

This setup assumes you are running MySQL on it’s default port.

Create connection function

Now, inside /inc/class/DAL.php, we will make a function that we will use to connect to our database.

The connection, as well as all forthcoming queries, will live inside a class named DAL. Wrapping all database involvement inside a single class allows us to manipulate our queries later without needing to touch business or presentation layer scripts. Also, it provides some degree of mock namespacing.

In the case of this class, we will add a constructor even though it doesn’t need to do anything.

<?php 

class DAL {
	
  public function __construct(){}
  
  private function dbconnect() {
    $conn = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD)
      or die ("
Could not connect to MySQL server"); mysql_select_db(DB_DB,$conn) or die ("
Could not select the indicated database"); return $conn; } } ?>

Notice that the scope of the dbconnect method is private. This is because we should not need to connect to the database from outside our DAL. Instead, we will have public query methods which will call the dbconnect from inside the DAL. A little confusing? No worries, read on.


Step 4. Create Generic Query Tools

To abstract our queries so that we can reuse short pieces of code, we will need two things. First, we will need some sort of “generic query result” class. Second, we will need a generic querying method inside our DAL.

Create generic query result class

The purpose of all of this is to be able to convert SQL queries into objects and minimize use of the ugly while($row = mysql_fetch_array($result)) loop. Objects are far easier to work with and allow us to use properties instead of array keys.

In short, we want to make a class that will create property names on the fly and store data associated with those properties.

We will put this class inside our /inc/class/DAL.php script. Since it is a new class, it will be outside the DAL class.

class DALQueryResult {

  private $_results = array();

  public function __construct(){}

  public function __set($var,$val){
    $this->_results[$var] = $val;
  }

  public function __get($var){	
    if (isset($this->_results[$var])){
      return $this->_results[$var];
    }
    else{
      return null;
    }
  }
}

Create generic query method

Now, inside our DAL class, we need to make a generic querying method that will turn SELECT queries into DALQueryResult objects.

Basically, we want to turn each returned field name into a property of the DALQueryResult object.

private function query($sql){

  $this->dbconnect();

  $res = mysql_query($sql);

  if ($res){
    if (strpos($sql,'SELECT') === false){
      return true;
    }
  }
  else{
    if (strpos($sql,'SELECT') === false){
      return false;
    }
	else{
	  return null;
	}
  }

  $results = array();

  while ($row = mysql_fetch_array($res)){

    $result = new DALQueryResult();

    foreach ($row as $k=>$v){
      $result->$k = $v;
    }

    $results[] = $result;
  }
  return $results;		
}

Here is a private function that accepts a SQL query. It connects to the database and runs the query. Then, it checks to see if there are any results. If there are not any results, it returns null on a SELECT query, false on other queries. If the query was successful and the query was not a SELECT query, it will return true. If it was a SELECT, then it converts the results into an array of DALQueryResult objects. This mimics the results that one would normally get from a mysql_query.


Step 5. Write a Specific Query

Now we are ready to actually write a SQL query. DAL queries should be very specific both in name and purpose. Let’s make one that finds all models of a given make.

This will be our first public method.

public function get_models_by_make_name($name){
  $sql = "SELECT models.id as id, models.name as name, makes.name as make FROM models INNER JOIN makes ON models.make=makes.id WHERE makes.name='$name'";
  return $this->query($sql);
}

Here we are just writing the query and returning the result in the form of DALQueryResult objects. Our generic query method takes care of the itterations and decision making.

Finished DAL

At this point, our DAL.php script is finished. It should look like the following.

<?php 

class DALQueryResult {
	
  private $_results = array();

  public function __construct(){}

  public function __set($var,$val){
    $this->_results[$var] = $val;
  }

  public function __get($var){	
    if (isset($this->_results[$var])){
	  return $this->_results[$var];
	}
    else{
	  return null;
	}
  }
}

class DAL {

  public function __construct(){}
  
  public function get_models_by_make_name($name){
    $sql = "SELECT models.id as id, models.name as name, makes.name as make FROM models INNER JOIN makes ON models.make=makes.id WHERE makes.name='$name'";
    return $this->query($sql);
  }
  
  private function dbconnect() {
    $conn = mysql_connect(DB_HOST, DB_USER, DB_PASSWORD)
    	or die ("<br/>Could not connect to MySQL server");
		
    mysql_select_db(DB_DB,$conn)
    	or die ("<br/>Could not select the indicated database");
	
	return $conn;
  }
  
  private function query($sql){

    $this->dbconnect();

    $res = mysql_query($sql);

    if ($res){
      if (strpos($sql,'SELECT') === false){
        return true;
      }
    }
    else{
      if (strpos($sql,'SELECT') === false){
        return false;
      }
      else{
        return null;
      }
    }

    $results = array();

    while ($row = mysql_fetch_array($res)){

      $result = new DALQueryResult();

      foreach ($row as $k=>$v){
        $result->$k = $v;
      }

      $results[] = $result;
    }
    return $results;		
  }  
}

?>

Step 6. Use the DAL

Now, let’s finally head over to our /index.php script and display our results using the DAL. All we need to do is include our /conf/config.php file, instantiate the DAL, and do something with the data. Here’s an example.

<?php 
// include configuration
require_once(dirname(__FILE__) . '/conf/config.php');

// instanciate a new DAL
$dal = new DAL();

// array of makes to check
$makes = array('Ford','Chevy','Honda');

// cycle through the makes
foreach ($makes as $make){
  $results = $dal->get_models_by_make_name($make);
  echo "<h1>Models by $make</h1>";
  
  // check if there were any results
  if ($results){
  	echo "<ul>";
  	
	// cycle through results
	foreach ($results as $model){
  		echo "<li>$model->make $model->name (Database ID: $model->id)</li>";
  	}
  	echo "</ul>";
  }
  else{
    // Display a message concerning lack of data
  	echo "<p>Sorry, we have no information regarding that manufacturer.</p>";
  }
}
?>

As you can see, we now have results that we can call the field names as properties of a PHP object.


Step 7. Taking Things one Step Further

Often, it will be useful to convert the generic DALQueryResult into a more specific object. In this case, you can write business objects that accept a DALQueryResult as a constructor parameter. Then, you just use that to build the new object.

Here’s an example

<?php

class CarModel{
  private $_id;
  private $_make;
  private $_name;
  
  public function __construct(DALQueryResult $result){
    $this->_id = $result->id;
    $this->_make = $result->make;
    $this->_name = $result->name;
  }
  public function __get($var){
    switch ($var){
	  case 'id':
	    return $this->_id;
		break;
	  case 'make':
	    return $this->_make;
		break;
	  case 'name':
	    return $this->_name;
		break;
	  default:
	    return null;
	    break;
	}
  }
  public function __toString(){
    return $this->_name;
  }
}

?>

Then, just write a query to return an array of these objects instead of an array of generic DALQueryResult objects.

Remember, always name your queries very specifically.

public function get_models_by_make_name_as_CarModel($name){
  // Reuse existing query
  $results = $this->get_models_by_make_name($sql);
  
  // check for results
  if (!$results){
    return $results;
  }
  else{
    // array to hold CarModel objects
    $object_results = array();
    // cycle through and convert to CarModel objects
    foreach ($results as $result){
      object_results[] = new CarModel($result);
    }
    // return array of CarModel objects
    return object_results;
  }
}

Building specific objects can become very useful when calculations are needed to extract meaningful data from fields.


Hope you all enjoyed the tutorial! Good luck.

Note: Want to add some source code? Type <pre><code> before it and </code></pre> after it. Find out more
  • guru

    looks cool !

  • http://www.stookstudio.com Erwin Heiser

    Not a bad tut, but why not use mysqli?
    http://www.php.net/manual/en/mysqli.overview.php

    • http://www.pockyworld.com pocky

      or just use PDO…

      • Jack Watson-Hamblin

        Or PHPActiveRecord…? http://www.phpactiverecord.org/

      • http://www.philipdamra.com djheru

        If you don’t know what a database abstraction layer is, and only know how to access a database in a procedural manner, you probably wont be able to make good use of PDO.

  • Marcin

    While a nice and useful article to teach some general PHP techniques, even for the simplest of projects, dropping the CodeIgniter folder + making some quick changes to config files is usually worth the trouble. Takes no longer than 2 minutes, and gets even faster if you check-out a pre-configured CI installation from your private repo.

  • http://www.philohermans.com Philo Hermans

    Nice tutorial for starters :)
    Ill stick with CodeIgniter :P

  • http://www.daniel-petrie.com Daniel Petrie

    I was thinking why not use mysqli as well, but either way a good tut to show how to use classes for database interaction.

  • http://www.oswosmedia.com Osvaldo

    A good tutorial. Best organized and explained. A found it very useful too.
    Thank you.

  • Barry Wood

    If you’re going for an abstraction layer why wouldn’t you use PDO?

    • Brant
      Author

      It was more of an academic exploration for me. I’ve done similar things in other contexts and I wanted to see what the translation over to PHP was like.

    • http://www.philipdamra.com djheru

      I think the author is intending to provide an introduction to the concepts that make up an abstraction layer for people that are unfamiliar with the concept. A person that has learned these concepts will be able to use PDO more effectively than they would’ve before following this tutorial.

  • EllisGL

    In my tests, I have found using a do..while is ~12% faster.

    $cnt = mysql_num_rows($res);

    if($cnt > 0)
    {
    do
    {
    $row = mysql_fetch_array($res);
    $result = new DALQueryResult();

    foreach($row as $k=>$v)
    {
    $result->$k = $v;
    }

    $results[] = $result;
    }while(–$i);
    }

    Btw, nice job =)

    • Brant
      Author

      Good to know, Thanks!

  • http://www.htcphones.net Aram

    coooool.. thanks a lot :)

  • http://www.flickr.com/photos/lorenzhs nuk

    Quick Tip: Don’t use PHP. Seriously!

    • http://johnathanbarrett.me Johnathan Barrett

      Quick Tip: Don’t be so fucking stupid. Seriously.

    • http://www.gostomski.co.uk Damian Jakusz-Gostomski

      Seriously, if you’re going to make such a bold statement, you should at least have some sort of justification, such as “Don’t use PHP because…”

      Is there any need to call connect at the start of the query method? Would it not be better to have the connection set as aclass variable, and check if it’s set? I’ve not checked but assume it’s more efficient?

      • Brant
        Author

        It all depends. In this instance, yes you’re probably right.

        I’ve done this mostly in environments where I need to hit multiple databases and I’m used to connecting several different times.

        Just a habit.

    • Carlos Caniguante

      Quick Tip: Please kill yourself and stop wasting air.

    • Peter C.

      Quick Tip: Don’t feed the troll.

    • Jesse

      You guys have got to be kidding me. “Kill yourself…”, really?

  • Paul

    Shouldnt

    else{
    // array to hold CarModel objects
    $object_results = array();
    // cycle through and convert to CarModel objects
    foreach ($results as $result){
    object_results[] = new CarModel($result);
    }
    // return array of CarModel objects
    return object_results;
    }

    be

    else{
    // array to hold CarModel objects
    $object_results = array();
    // cycle through and convert to CarModel objects
    foreach ($results as $result){
    $object_results[] = new CarModel($result);
    }
    // return array of CarModel objects
    return $object_results;
    }

  • http://ds.laroouse.com esranull

    very good post thanks a lot

    • dani

      Seriously esranull! Are you a ROBOT?! You always post the same 5 words all over again. I dont think saying thank you! thank you so so very much and crap like that adds to the quality of the site! I you want to promote your site, then buy ad space!

      • http://andrewdotson.com Andrew

        Haha I was wondering the same

      • Daniel

        Six actually.

  • http://verrinimunari.it Nicolo Verrini

    Thank you so much,
    I really dig this !
    So tired of using php frameworks. It’s time to create our crud functions !!

  • http://brettic.us Brett Millett

    In my opinion, I think a tutorial that uses the fundamentals of the language is ideal. Yes, these types of things are pre-built for you in a framework, but you shouldn’t always use a framework. It’s okay if you don’t use MVC for everything. It’s okay if you don’t use PDO. This example shows a database abstraction class for a very SPECIFIC use case. It’s not a bad thing. Really.

    Disclaimer: I never write anything that’s not MVC and I use a framework for every new project (whether it’s my own limited framework or an open-source fully-featured version.) I do this for speedier development, for collaboration, and for the maintainability advantages inherit in this architectural pattern. However, from an academic level I fully support my previous statements. :)

  • Commenter

    A few issues, Checking if ‘SELECT’ exists in a query? what if it was a field or part of an insert, the query would be assumed as a select query – not good.

    Not using PDO – which would be recommended especially in such a thing – also links in with OOP and such.

    The name – DAL? If you meant DataBase Abastaction Layer then DBAL is the standard :/

    DIEing from within functions – not advised, throwing exceptions would be best and showing how to catch them and deal with them.

    However, its a good tutorial for an introduction.

  • http://butenas.com Ignas

    Useless… Inventing the wheel… I’m the side of those who said just take some simple framework and do your job. While the others shoose CI, I wrote my CMS using Zend Framework. Who is interested in frameworks knows the differences between them and chooses what he wants. Nettuts becoming playground for kids… Few lats post was just for number of posts and none of them was really great.

    • Marcus Schumann

      That’s a really stupid thing to say. In the same regards, I could ask you why the hell you developed a CMS. Why didn’t you use WordPress? Or Drupal? Or any of the other 1000 already done CMS’s. Reinventing the wheel man. Come on..

      Honestly, I code because it’s fun and it’s great learning new stuff. If you don’t learn them or practice them you’ll be a horrible coder if you always have to rely on other people’s codes.

      • Nosferatu

        Agree

      • http://butenas.com Ignas

        Why I developed my CMS? That’s why because Drupal is not object oriented and it is very slow. After one year spent with it, I just need to go far away from that CMS. WordPress.. show me really great e-shop solution written with wordpress. WordPress is not a CMS, it is engine for bloging. It was invented to do great blogs. If you still not know.

    • http://www.philipdamra.com djheru

      It’s not reinventing the wheel, it’s teaching the basics.

      So you created a CMS with ZF. I wonder about the kind of person who would disparage people who are learning the basics, just to brag about how “advanced” you are. What’s next, going to a kid’s karate class to kick some ass?

      • Djkanna

        It’s hard to not reinvent the wheel these days, you say you created a ‘CMS’ with a framework, well I have bad news for you! It’s been done before. There you go, you’ve just reinvented a wheel…..

      • http://butenas.com Ignas

        Nice advise. I will do that today!

  • http://www.codeforest.net Codeforest

    Great intro into some basics of OOP thinking and DBAL (or DAL as you called it).

    You should not use die, but I understand that this tut is only to present the technique .

    Eager for more.

    • Muhammad Omar

      Why shouldn’t use die, is it slower? or what?

  • slier

    just want to ask why u create an instance of the DAL for every result row?

    while ($row = mysql_fetch_array($res)){

    $result = new DALQueryResult();

    foreach ($row as $k=>$v){
    $result->$k = $v;
    }

    $results[] = $result;
    }

    • Ami

      Have to agree on that one! Its a very dangerous way to waste resources. What happens now when you get back 1000 results which is not unusual.. This is just simply bad practice. Just like having 2 classes in one file..

    • http://jdesign.us/ Zack Hovatter

      He’s creating an instance of the Result each row, not the actual DAL.

    • Darren

      He doesn’t, he creates an instance of DALQueryResult which is a different class.

  • http://twitter.com/netjunky88 Eugene

    I have to say that planting two classes in one file is a bad practise. As I understand you will not be able to use autoload for those classes.

  • Justin

    This is a shocker.

    * Not using mysqli or pdo – prepared statements damnit!
    * Connecting every time you query
    * Creating model specific queries in a generic DAL
    * Multiple classes in one file
    * Running multiple queries when only one is needed
    * Dieing in class methods

    I understand all of the above was overlooked because the article was just trying to teach some aspect … no, just no. You don’t teach people to run red lights in order to demonstrate the accelerator pedal.

    • http://twitter.com/netjunky88 Eugene

      Well. I’m not using mysqli or PDO, but there should be defenetly some improving in this tutorial to call it tutorial.

      For example: I use separatley two classes with identical method names, but one is for MySQL and other is for PostgreSQL. So it is quite easy for me to switch between them. I just need to change the name of the class I instantiate and that’s it. I’m already using another DB.

      It does have pros and cons, but I stick with this path of developing work with DB. Also it’s a gain of experience.

    • Savageman

      Yes, PDO is the standard now.

      Connecting every time we query is not really a problem because PHP will reuse the connexion if the user/pass is the same. But that’s still a bad practice, I agree.

      Multiple class in one file is not necessarily bad IMO. Not every class is loosely coupled. It can be more efficient to put several classes in the same file if you always need to use them together. It’s almost the case here.

      In this case, one query is needed, I agree. But we need to be more precise on when it’s needed or not. It’s not necessarily good to combine queries with JOIN. In fact, a lot of SQL optimization I made involved splitting queries and removing a JOIN (and then querying with fk IN ([fks]) ).

      But this tut is rather bad, I have to agree with you. Usually, Tutsplus standard is much higher. I’m disappointed.

    • Markus

      Exactly what I was thinking. Especially if the tutorial is meant for beginners it’s very important to at least mention all these points. Teaching people to do things “wrong” is not a very good idea IMHO.

      But who’s to blame? The PHP community is very active and if you google for php database tutorials there will be a lot of results. The problem is however that most of those tutorials are outdated. If people use those outdated tutorials to learn and then write tutorials themselves those will be outdated, too.

      Currently the best way to learn PHP is not to learn PHP but any other language, like C# oder Java, and then to try to bring over the learned concepts to PHP.

  • http://philip@philipdamra.com djheru

    I appreciate the tutorial. Obviously, one doesn’t want to reinvent the wheel, but with PHP, like anything else, it is good to learn the basics first.

    I would make the same comments as others about using exceptions instead of die, but the point of the tut is not teaching about Exception. If someone finds this tutorial useful, they probably don’t know much about exception handling.

    Making the transition from the procedural method of interacting with a database to an object oriented way is essential. ActiveRecord and Zend_Db_Table_Abstract aren’t going to do you much good unless you already know the basics.

    • Markus

      Yeah, but teaching people to code in an object oriented way by not using the existing classes but connecting using the old an IMHO outdated procedural interface?

      No Sir, that doesn’t make any sense.

  • Abhishek Oza

    Great Tutorial,for beginners, especially.

  • nih

    Not like this.

    get_model_by_make_name(“‘”); and BOOM.

  • Thomas

    DAL could be Data Access Layer

  • http://www.tenaxtechnologies.com outsourcing web development

    It’s simple and good for begginers.
    Thanks for the tutorial.

  • fingerlicking

    isn’t this the same??? Both null and false return a false boolean

    else{
    if (strpos($sql,’SELECT’) === false){
    return false;
    }
    else{
    return null;
    }
    }

    • Neo

      No, they arent. If query failed, and was not a select statement, then return false as it was an operation that either worked or it didn’t. If it was a select, do not return anything.

      Inversely, if the query passed, and was not a select statement, simply return true saying the operation was successful. If it WAS a select, return the values of the result in the object.

      Observe the top-level logic closely, you’ll see it.

  • Kelly Te Huna

    I think this tutorial is perfect for what it is – an introduction to using and creating a SIMPLE data access layer. It sucks the poor guy gets ripped on for trying to help. Maybe some of you should present your idea of how a Data Access Layer SHOULD be presented – WITHOUT using a prebuilt one. Just a thought…

    Like creating a good, reusable class, the author did well to focus on what he was trying to convey, kept the code short and to the point and got on with the task of teaching the concept. Had he got in to exception handling and long winded query checking to determine the TYPE of query being executed, the code might have obscured the intent. With tutorials, intent is all that matters.

    PDO, CI, Zend, Kohana – they all contain/are great DAL’s, but learning this stuff really helps you appreciate a good DAL.

    Well written tutorial, I thought. Very basic, very simple.

    • Markus

      Sure, it’s simple and it’s to the point (somehow). But important aspects are missing. It’s ok to not explain the stuff in detail, but it should have been mentioned.

      If you read the comments from the beginners there are some like “Great, just what I needed”. Those guys will probably use the code without changes! There should be at least a warning, that the class described is not ready for use as it is, that important parts are missing.

  • dinkan

    thanks for this one.. i was really waiting for something like this…

  • David

    Thank you for the tutorial!

  • http://www.archivetr.net/ dellopos

    Thanx. Very nice.

  • Aaron

    Great tutorial!! I’m the type who can’t stand using a framework unless I know exactly what’s going on behind the curtain. What if something takes your framework away? Seems like a great idea to know the foundation level basics. Keep this type of article coming!

  • http://www.jsxtech.com Jaspal Singh

    Nice tutorial for beginners.
    I’m already working on PHP 5 OOPS.
    Thanks for sharing.

  • http://www.escodent.de Daniel S

    No matter if it’s a basic tutorial, but you have to teach that mysqli is better than mysql. Newbie’s shalt not use these old functions.

  • Cong Thanh

    Thanks a lot !

    if($res){
    if(strpos($sql,’SELECT’)===false){
    return true;
    }
    }else{
    if(strpos($sql,’SELECT’)===false){
    return false;
    }
    else {
    return null;
    }
    }
    Would you like to explain this usage in your code to me ?
    Thanks again !

  • http://thangdc.com thangdc

    Great, article.
    It clearly to development, and could be reused.
    Thanks for share

  • http://www.clickddl.com/ clickddl

    very goood site. thank you.

  • Ali

    Thank for the nice post good beginner tutorial but you should have used pdo .

  • http://www.goldsniff.com halim

    Well,
    i’ve seen all the comments and of course there will always be a pro and con,
    however, this tutorial has bring me a good understanding about database layer.

    Thanks for sharing
    Cheers! :)

  • Boabkuma

    We always talk about not reinventing the wheel. Just google cms or framework and you will be amaze to see dozens of cms and frameworks everyone with it justification why it should be used. Why? because everything has not been invented yet. I advice everyone to write his or her own framework or cms, enjoy the adventure , the craziness, late night sleep, loneliness etc. When you are tired and feeling like you cant move forward anymore just give up and take a look at what the big guys out there has to offer. if you become stubborn and decide to ignore their offer then you are on you way to create the next big framework or cms or social site or payment gateway who knows. Do not let the phrase reinventing the wheel destroy your adventure.

  • http://twitter.com/rafib Rafi B.

    Why not use an ORM ?

  • Urkruk

    An excellent presentation of a DB interface layer, and all the comments are quite useful too.
    Thank you !

  • http://www.lovelyseen.com jozaf

    really good learning tutorial some time i think we should take entertainment so visit this link may be you feel relax.

  • http://a.com daniel

    great article, very nice explaining the whole concept in an easy to understand way.
    Thanks!

  • http://www.shopbestnaturals.com Best naturals

    I am very happy to be here because this is a very good site that provides lots
    of information about the topics covered in depth. Im glad to see that people are
    actually writing about this issue in such a smart way, showing us all different sides
    to it. Please keep it up. I cant wait to read whats next.

  • http://twitter.com/renofizaldy Reno Fizaldy

    Simple and Powerful, Great tutorial

  • http://none Jeze

    Thanks for this great tutorial,

    And to all the flamers,
    be a little respectful, he actually tries to tutor others… free of charge!
    giving criticism is perfectly fine but if your going to brag and moan,
    I suggest you write a tutorial yourself, which is an art itself.

  • http://www.dedyblack.co.cc Dedy Black

    look simple but complicated for me

  • Selvin Ortiz

    This short, simple tutorial can be greatly improved without adding to it’s complexity by creating a base object that interacts with the database via the “DAL” and defines methods like save(), find(), findby(), findall(), fetch(), etc.

    Most of this methods can be defined as static thanks to PHP 5.3+ late static bindings and extending classes would inherit those methods.

  • ali

    not easy for the beginners…