tags:

views:

1310

answers:

4

Im trying to learn OOP, but the so called 'real world' examples in the books im reading arent helping me at all. I already know that some people think that learning oop for php is unnecessary, so i don't need more people telling me the same thing. All the examples like Pet, Car, Human arent helping me anymore. I need REAL LIFE examples that pertain to common php scripts, like registraion, user profile pages, etc...

Example... I seen this somewhere online

$user->userName = $_POST['userName'];//save username
$user->password = $_POST['password'];//save password
$user->saveUser();//insert in database

But ive also seen

$user->user = (array) $_POST;

where

private $user = array();

holds all the information in an array.

And within that same class lies

$user->getUser($uid);// which sets the $this->user array equal to mysqli_fetch_assoc() using the user id... so $this->user = mysqli_fetch_assoc();

Anways... I digress. Real World examples implementing oop in the many different php applications (registration, login, user account, etc..) would help.

A: 

Checkout the Akelos Framework, or CakePHP, they are represents very good code.

astropanic
Jumping into a large framework when trying to grasp the fundamentals of OOP is perhaps not a real aid to understanding. Especially since OOP is to a large part about applied concepts and you don't get them explained just by seeing them applied.
Joey
Zend framework! <offtopic>as an experienced developer I HATE cakePHP. too much magic.</offtopic>
Byron Whitlock
I'd lean away from cake these days. There's a lot of good code in there, but it was good code trying to jam an OOP framework into PHP4's limited object model.
Alan Storm
This is a terrible, terrible way to learn OOP.
Peter Bailey
Of course the code of CakePHP or Akelos is big, but You can't learn professional OOP concepts from small coding snippets listed in internet tutorials or books.
astropanic
+1  A: 

As astropanic said, you could take a look at the source code of a good PHP framework or library. I recommend Zend Framework, it's very modular and has a great, professional design. I would say it is a very good piece of object-oriented PHP code.

Still, I think it's not that easy to learn from a huge piece of production code, since it wasn't really made to teach you anything. But if you want real-world object-oriented PHP code, the Zend Framework (or Symfony, or maybe CakePHP) is probably the way to go.

mooware
+2  A: 

I'd advise you to stay away from any framework at this moment, if you do not know OOP, digging into zend or any other framework would be too much.

PHP OOP is quit funny... like ha ha funny, because it's supported, but PHP is not an OOP language like java or c#.

Short example just to underline my statement:

// define class
class User {
// define properties and methods
public $name = "";
}
// instantiate class
$user = new User; // or new User() or new user, it's all the same
echo $user->name;

but if you want to do OOP "on the fly" you can do the following:

$user = (object) array('name' => 'Peter');

and then

$user->name;

but you can use OOP like you would in java or c# but not to the same extend - and have in mind, popular systems like wordpress and drupal are not pure OOP! but you can do inheritance and other classing OOP stuff in PHP as well.

kristian nissen
I'm sorry, but `$user = (object) array('name' => 'Peter');` *IS NOT* OOP - or even as you say "OOP on the fly". that's just an object. Using objects != OOP. Obviously the usage of objects is an integral part of OOP, but its about *WAY* more than that.
Peter Bailey
+6  A: 

OOP is not really about how a single class looks and operates. It's about how instances of one or more classes work together.

That's why you see so many examples based on "Cars" and "People" because they actually do a really good job of illustrating this principle.

In my opinion, the most important lessons in OOP are encapsulation and polymorphism.

Encapsulation: Coupling data and the logic that uses that data together in a concise, logical manner Polymorphism: The ability for one object to look-like and/or behave-like another.

A good real-world example of this would be something like a directory iterator. Where is this directory? Maybe it's a local folder, maybe it's remote like an FTP server. Who knows!

This is encapsulation:

abstract class DirectoryIterator
{
  protected $root;

  public function __construct( $root )
  {
    $this->root = $root;
  }

  abstract public function getAll();
}

class LocalDirectoryIterator extends DirectoryIterator
{
  public function getAll()
  {
    // logic to get the current directory nodes and return them
  }
}

class FtpDirectoryIterator extends DirectoryIterator
{
  public function getAll()
  {
    // logic to get the current directory nodes and return them
  }
}

Each class/object is responsible for its own method of retrieving a directory listing. The data (variables) are coupled to the logic (class functions i.e, methods) that use the dta.

But the story is not over - remember how I said OOP is about how instances of classes work together, and not any single class or object?

Ok, so lets do something with this data - print it to the screen? Sure. But how? HTML? Plain-text? RSS? Let's address that.

<?php

abstract class DirectoryRenderer
{
  protected $iterator;

  public function __construct( DirectoryIterator $iterator )
  {
    $this->iterator = $iterator;
  }

  public function render()
  {
    $dirs = $this->iterator->getAll();
    foreach ( $dirs as $dir )
    {
      $this->renderDirectory( $dir );
    }
  }

  abstract protected function renderDirectory( $directory );
}

class PlainTextDirectoryRenderer extends DirectoryRenderer
{
  protected function renderDirectory( $directory )
  {
    echo $directory, "\n";
  }
}

class HtmlDirectoryRenderer extends DirectoryRenderer
{
  protected function renderDirectory( $directory )
  {
    echo $directory, "<br>";
  }
}

Ok, now we have a couple class trees for traversing and rendering directory lists. How do we use them?

// Print a remote directory as HTML
$data = new HtmlDirectoryRenderer( new FtpDirectoryIterator( 'ftp://example.com/path' ) );
$data->render();

// Print a local directory a plain text
$data = new PlainTextDirectoryRenderer( new LocalDirectoryIterator( '/home/pbailey' ) );
$data->render();

Now, I know what you're thinking, "But Peter, I don't need these big class trees to do this!" but if you think that then you're missing the point, much like I suspect you have been with "Car" and "People" examples. Don't focus on the minutiae of the example - instead try to understand what's happening here.

We've created two class trees where one (DirectoryRenderer) uses the other (DirectoryIterator) in an expected way - this is often referred to as a contract. An instance of DirectoryRenderer doesn't care which type of instance of DirectoryIterator it receives, nor do instances of DirectoryIterator care about how their being rendered.

Why? Because we've designed them that way. They just plug into eachother and work. This is OOP in action.

Peter Bailey
+2 if i could!!
mrinject