Jump to content

Recommended Posts

I've been reading up on it, and I'm just wondering, what's the difference between using classes, and an external php page with functions on it? =/

 

This is the question everyone seems to ask themselves when they first start.

 

It's important to note that classes aren't just a way to group functions.  While you can go that route, that doesn't mean you're truly programming in an object oriented way.  The heart of OOP is the dynamic interaction of objects at runtime.  Objects create other objects, which, in turn, communicate with even more objects.  These objects themselves contain objects, which do different things based on the data passed to them.

 

What does this all mean?

 

The biggest difference you'll see if/when you grasp OOP is the lesser number of outright scripts involved in the creation and running of a website.  Instead of having a host of scripts, each with a different job (index.php brings the user to login.php, which may then forward them to another script), you'll have one script which will delegate to the correct object when a request is formed.  If a user needs to be logged into the system, the script calls on the login object to do the work.  Need to display database records?  The script calls the display object, which, in turn, accesses the database object.  In PHP 5, this is made easier (and more dynamic) by the __autoload() function, which automatically loads class files when an object of that type is created/accessed.  It removes the need to keep track of your includes/requires.

 

The thing to keep in mind is that classes are more than merely a way to group functions.  If that's all you view them as, you might as well just stick with procedural programming.  If you're interested in 'getting' OOP, I suggest getting PHP 5 Objects, Patterns, and Practice by Matt Zandstra (http://www.amazon.com/PHP-Objects-Patterns-Practice-Second/dp/1590599098/ref=sr_1_2?ie=UTF8&s=books&qid=1211888410&sr=1-2) and Design Patterns: Elements of Reusable Object-Oriented Software by the Gang of Four (http://www.amazon.com/Design-Patterns-Object-Oriented-Addison-Wesley-Professional/dp/0201633612/ref=pd_bbs_sr_1?ie=UTF8&s=books&qid=1211888480&sr=1-1).

This might be more than you can chew at this point, but check out the sample chapter from O'Reilly's Head First Design Patterns.

 

http://www.oreilly.com/catalog/hfdesignpat/chapter/ch03.pdf

 

Try and do that with procedural code (it can be done, just not as easily).

Ah, I think I kind of get what you mean.

 

So when people use $db->stuff it does all the database connect stuff?

 

Using databases as an example, imagine you build a site and need to move it to another host with mssql instead of mysql, or maybe you build a cms that you want to use on different sites. You'll have to go through all of the php and change all the code that deals with mysql databases to mssql.

 

A well written set of database abstraction objects will allow you to run database queries, without worrying about connecting to the database or what kind of database it is.

Ah, I think I kind of get what you mean.

 

So when people use $db->stuff it does all the database connect stuff?

 

Using databases as an example, imagine you build a site and need to move it to another host with mssql instead of mysql, or maybe you build a cms that you want to use on different sites. You'll have to go through all of the php and change all the code that deals with mysql databases to mssql.

 

A well written set of database abstraction objects will allow you to run database queries, without worrying about connecting to the database or what kind of database it is.

But still can't you do this with functions?

Ah, I think I kind of get what you mean.

 

So when people use $db->stuff it does all the database connect stuff?

 

Using databases as an example, imagine you build a site and need to move it to another host with mssql instead of mysql, or maybe you build a cms that you want to use on different sites. You'll have to go through all of the php and change all the code that deals with mysql databases to mssql.

 

A well written set of database abstraction objects will allow you to run database queries, without worrying about connecting to the database or what kind of database it is.

But still can't you do this with functions?

 

Yeah, the DB example isn't the best.

 

Here's one: you have a large site.  On each page, you allow the user several different ways to interact with it.  They can login, post comments, access database records, etc.  It makes the most sense to invoke this functionality dynamically when the user makes a particular request.  How can we do that?

 

Well, one method is to have a controller that's nothing more than a switch statement that includes the right script based on the request passed in:

<?php
   switch ($_REQUEST['action']){
      case "index":
         include("index.php");
         break;
      case "login":
         include("login.php");
         break;
      .
      .
      .
   }
?>

 

This is okay for a small site, but not for one that expects a lot of different possible requests, or for a site that needs to grow or change.  It's just too awkward to maintain.

 

Enter OOP.  I can do the same thing as above with this:

<?php
   require_once("data/config.php5");

   MP_controller_Controller::run();
?>

 

Obviously, the code that actually does things is hidden within the run() method, and subsequent methods.  But, my code is short and sweet.  Here's MP_controller_Controller:

<?php
   class MP_controller_Controller{
      private function __construct(){}

      static function run(){
         $instance = new MP_controller_Controller();
         $instance->init();
         $instance->handleRequest();
         $instance->display();
      }

      private function init(){}

      private function handleRequest(){
         $request = new MP_controller_Request();
         $commandFactory = new MP_command_CommandFactory();
         $command = $commandFactory->getCommand($request);
         $command->execute($request);
      }

      private function display(){
         $sessReg = MP_base_SessionRegistry::getInstance();

         if(!$sessReg->isEmpty()){
            $user = $sessReg->getUser();

            if($user){
               echo "Welcome back, {$user->getName()}<br /><br />\n\n";
            }
         }
      }
   }
?>

 

Again, not much to it.  The run() method calls four methods of its own:

 

1. It ensures we have a controller object that we can use in order to execute the proper command.

2. It runs an initialization method (init()).  In this case, that method is empty.

3. It runs handleRequest(), which is the heart of the entire operation.

4. It runs display(), which isn't necessary, and added for my own testing.

 

Like I mentioned above, handleRequest() is the interesting part.  It creates a new MP_controller_Request object, which is basically a wrapper around $_REQUEST with some helper functions thrown in.  I then create a new CommandFactory, which is an object that creates 'commands' based on request data, and retrieve the proper command from it based on a particular user request.  Finally, the command executes, doing what it's supposed to do (logging a user into the system, or posting a comment to the site, etc.).

 

Admittedly, this is a lot of up-front work for something small, and there are other objects being used in this operation as well.  So, this isn't recommended for small sites.  But it's flexible.  Need to add more functionality to the site?  Add a new command object.  Need to modify the way something is done?  Modify the command object that represents that process.  Need to remove a portion of the site?  Remove that/those command object(s).  It's as simple as that.  No need for dozens of if/else clauses or switch cases.  Everything is handled dynamically.

 

Even better, everything is modular.  I can use the Front Controller on any site I want.  Similarly, I can use the same command on multiple sites without thinking about it.  Once you have a foundation of basic objects, you can swap components in and out with very little trouble.  Dependencies are minimized as objects, by their very nature, tend to be self-contained.

 

I hope this made some sense.  It took me a while to get the point, too, so keep at it.  It'll sink in eventually. :)

I've been reading up on it, and I'm just wondering, what's the difference between using classes, and an external php page with functions on it? =/

After reading all of the responses and then re-reading your original question, I think we've all missed the mark in answering the original question.  IMO, the answer to the OP is there is no difference.  Zip, nada, nothing.  They're essentially the same.

 

Regardless of doing it procedurally or with OOP, the code has to do the following things:

  • Parse the URL into a controlling script (index, users, clients, etc.) and possibly a sub-function within that script (add, delete, edit, etc.)
  • Parse any parameters in the URL (if using mod_rewrite, otherwise the params are in $_GET)
  • include the controlling script (ensure that the file exists) and invoke the sub-function (ensure the sub-function exists) within it
  • dump the output

 

The algorithm doesn't change whichever you choose.  I'll even go as far to say that neither method is easier or more difficult to maintain than the other, regardless of the size of the site.

 

Now OOP does excel over procedural in many ways.

 

Cosmetically OOP usually turns out to be less typing in the client code.  Since all function names need to be unique, in procedural programming you end up with really long functions:

<?php
  $board = forum_create_board();
  forum_set_board_title( $board, 'The New Board' );
  forum_set_board_description( $board, 'This is our newest board!' );
  forum_save_board( $board );
?>

vs. the OOP client code:

<?php
  $board = new Forum_Board();
  $board['title'] = 'The New Board';
  $board['description'] = 'This is our newest board!';
  $board->save();
?>

That's so much more pleasant to type.

 

OOP also gives the creator of the server code more control over how it will be used.  Most compiled procedural languages group data into structs (short for structures), which are most similar to associative arrays in PHP.  Most languages that use structs do not provide any sort of visibility into the members of a struct; therefore all members are what we'd call public.

For example, if we had an employee struct with members: id, name, age, then client code could do this:

/* This is mock C code */
struct employee = employee_find_by_id( 1 ); /* find employee in DB */
employee.id = 2; /* the id is managed by the DB and should therefore be read-only, but we can't enforce this in C */
employee_save( employee );

However, with OOP the programmer of the employee class can control how the id property is accessed and thus control if it is read-only or writable.  This type of control helps make client code less prone to errors and hacks (quick fixes to get something to work).

 

Where OOP really takes off is in concepts like inheritance, polymorphism, interfaces, etc.  You can accomplish all of these things in procedural programming, but only through writing the code that makes these behaviors possible, which is tedious for the programmer.  These concepts are built directly into an OOP language, so you don't have to write any extra code to make inheritance or polymorphism work, they just do.

  • 2 weeks later...

I have written a mini-blog post which you may find interesting: http://nick.stinemates.org/wordpress/?p=26

 

I get this question asked a LOT. Really, it comes down to organization and maintainability of previous code.

 

Can you encapsulate outside of OOP? I guess you could, but you'd come up with a system that's a lot like OOP.

We all ask this question when we first started with OOP.  I still can't quite answer it as well as these guys have.  Anything you can do with OOP you can do with procedural standards.  The biggest thing I've found is that it doesn't look as clean, and clean coding is what everyone should adhere to.

 

I've also found that, if you name your classes and methods well, you can figure out pretty quick what's going on by looking at the raw code.

 

My favorite part of objects are the public/private and static properties they contain.  I love having to ability to do this:

 

<?php
$user = new User();
if(!$user->logged_in) {
Header("Location: login.php");
}

echo "Welcome to OOP, $user->username!";
?>

 

Now, the code inside the object is just as many lines as the procedural functions would have, which is the part that becomes confusing for a newbie.  At least it was for me.  It's not about the code INSIDE the objects, necessarily, but the code in which you USE the object.  That's why OOP is better.

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.