Making the jump from procedural php to OO php?

Hello All,

Just wanted to pick your brains. I’ve been working with procedural php for about 2 years now on a regular basis and far from fluent with it (still have to google a lot), but have good knowledge of it and can build webpages and CMS systems with it fairly well.

I’m now thinking of making the jump to learning OO php. Now as I say I have a good working knowledge of procedural php, but am in no way some kind of guru!!

When would you say is best to start learning it? Should I consider myself some kind of ‘procedural php guru’ before taking up OO php and continue to work with procedural php or am I ready to take the leap now?

Just concerned that by taking this step now i’m jumping straight from ‘A’ to ‘C’ and missing out ‘B’ (if that makes sense!) When did any of you guys decide to take the leap forward?

Any advice kindly welcome?

If there was a ‘B’ it would likely be that you start to move some of your procedural code into functions.

Simple example, instead of just having:


include 'footer.php' ;

You might have


show_social_media_links('my page');
do_footer() ;

However, I did not do that, I went from ‘A to C’ - as you say.

It meant I had to really learn about how functions work ( which you simply call “methods” when learning OOP).

I did not do that thoroughly enough, and it wasn’t until I studied for my ZCE qualification that I really took the time to learn about functions in PHP.

There is not a lot to learn, but it is kinda critical!

You can start using OOP based PHP in your application from now, You need not spend separate time to learn OOP PHP, Just start using OOP concepts in the application you develop when you start using them, you will realize that they are easy than procedural and one day you will become OOP PHP Guru…

:slight_smile:

I actually continue to use includes for basic HTML as their is no need for PHP to parse it for me. :slight_smile:

[FPHP]include[/FPHP] invokes the parser.

Off Topic:

Though it’s useful to still use include, just in case you want to insert PHP.

I’d say the first step is coming up with some simple ideas of what you want OOP to accomplish. By the end of your OOP journey, you’ll be using objects everywhere to do everything, but at the beginning its fine to do one or two things.

So the first step is to come up with an idea, and make it using objects. All you really need to know is how to write an object and how to use methods. So, think about what kind of methods you need.

I think the first thing I did was a shopping cart class, so that’s a good place to start :slight_smile:

So, first of all think about the requirements:

[list]Add an item
Remove an item
Check if an item exists
Change quantities of an item
Retrieve quantities of a certain item
Get the items as an array
[/list]

So a good starting block would be to have the following class:

class Cart{
    public function addItem($Item){

    }
    public function removeItem($Item){

    }
    public function hasItem($Item){

    }
    public function updateQuantity($Item, $Quantity){

    }
    public function getQty($Item){

    }
    public function getItems(){

    }
}

Then, think about what goes inside those functions, and the properties you’d have in the class. You’d need an array to hold the items - perhaps the item ID being the key and the qty being the value. You’d also need to validate the array to clear any invalid or zero-qty items:

class Cart{
    protected $Items;
    public function __construct(){
        $this->Items = array();
    }
    public function addItem($Item, $Quantity = 1){
        if($this->hasItem($Item)){
            $Quantity += $this->getQty($Item);
        }
        $this->updateQuantity($Item, $Quantity);
    }
    public function removeItem($Item){
        if($this->hasItem($Item)){
            unset($this->Items[$Item]);
        }
        $this->validate();
    }
    public function hasItem($Item){
        return array_key_exists($Item, $this->Items);
    }
    public function updateQuantity($Item, $Quantity){
        $this->Items[$Item] = (int)$Quantity;
        $this->validate();
    }
    public function getQty($Item){
        return $this->hasItem($Item) ? $this->Items[$Item] : 0;
    }
    public function getItems(){
        return $this->Items;
    }
    protected function validate(){
        foreach($this->Items as $Item => $Qty){
            if($Qty < 1){
                unset($this->Items);
            }
        }
    }
}

So there you have a working shopping cart. That doesn’t really show the power of OOP, but it’s a start.

The next stage is where you realise that you can use multiple classes to behave the same way. This is by obeying set rules given by an Interface. This defines what public functions there should be, but doesn’t give any detail as to how they work:

Interface iCart{
    public function addItem($Item, $Quantity = 1);
    public function removeItem($Item);
    public function hasItem($Item);
    public function updateQuantity($Item, $Quantity);
    public function getQty($Item);
    public function getItems();
}

You can then define classes as implementing this interface, so they do the same thing overall but their functionality may be different. For example, you could have your above cart class:

class Cart implements iCart{
    protected $Items;
    public function __construct(){
        $this->Items = array();
    }
    public function addItem($Item, $Quantity = 1){
        if($this->hasItem($Item)){
            $Quantity += $this->getQty($Item);
        }
        $this->updateQuantity($Item, $Quantity);
    }
    public function removeItem($Item){
        if($this->hasItem($Item)){
            unset($this->Items[$Item]);
        }
        $this->validate();
    }
    public function hasItem($Item){
        return array_key_exists($Item, $this->Items);
    }
    public function updateQuantity($Item, $Quantity){
        $this->Items[$Item] = (int)$Quantity;
        $this->validate();
    }
    public function getQty($Item){
        return $this->hasItem($Item) ? $this->Items[$Item] : 0;
    }
    public function getItems(){
        return $this->Items;
    }
    protected function validate(){
        foreach($this->Items as $Item => $Qty){
            if($Qty < 1){
                unset($this->Items);
            }
        }
    }
}

And maybe a class which uses a mysql database instead:

class MySQLCart implements iCart{
    protected $Database;
    protected $CartID;
    public function __construct(PDO $Database, $CartID){
        $this->Database = $Database;
        $this->CartID = $CartID;
    }
    public function addItem($Item, $Quantity = 1){
        if($this->hasItem($Item)){
            $Quantity += $this->getQty($Item);
        }
        $this->updateQuantity($Item, $Quantity);
    }
    public function removeItem($Item){
        $Query = $this->Database->prepare('DELETE FROM Cart WHERE CartID = :CartID AND Item = :Item');
        $Query->bindValue(':CartID', $this->CartID);
        $Query->bindValue(':Item', $Item);
        return $Query->execute();
    }
    public function hasItem($Item){
        return $this->getQty() > 0;
    }
    public function updateQuantity($Item, $Quantity){
        $Query = $this->Database->prepare('REPLACE INTO Cart (CartID, Item, Quantity) VALUES (:CartID, :Item, :Quantity)');
        $Query->bindValue(':CartID', $this->CartID);
        $Query->bindValue(':Item', $Item);
        $Query->bindValue(':Quantity', $Quantity);
        return $Query->execute();
    }
    public function getQty($Item){
        $Query = $this->Database->prepare('SELECT Quantity FROM Cart WHERE CartID = :CartID AND Item = :Item');
        $Query->bindValue(':CartID', $this->CartID);
        $Query->bindValue(':Item', $Item);
        $Query->execute();
        if(false !== ($Qty = $Query->fetchColumn())){
            return $Qty;
        }
    }
    public function getItems(){
        $Query = $this->Database->prepare('SELECT Quantity FROM Cart WHERE CartID = :CartID');
        $Query->bindValue(':CartID', $this->CartID);
        $Query->execute();
        $Return = array();
        while($Row = $Query->fetch(PDO::FETCH_ASSOC)){
            $Return[$Row['Item']] = $Row['Quantity'];
        }
    }
}

Of course, the above (untested) mysql-driven-cart certainly isn’t the most efficient solution possible, but it was pure example. Apart from the constructor required, both would be accessed in the same way and do the same things - meaning you can modify your application’s functionality massively simply by replacing one object with another.

As you get further and further into OOP, you find more and more uses, somewhat less basic than a shopping cart. You will start playing with objects representing databases and records in databases (Models), you will find yourself writing classes to deliver a full webpage based on a simple command, and a completely different page based on a small change in said command.

I suppose that’s what OOP really is. Planning an application by what things should do, and then filling in the gaps in different ways to make it as flexible as possible.

A great way to start is by reading through some of the threads in Application Design, a sub-forum of PHP.

It may be too much to take in, at first, so take it as lightly as you can, but pick up on any tips that you can.

Magic. Thanks for the advice. I was actually going to start redevloping one of the CMS systems I created using OOP, but maybe a shopping cart is a good idea.

My plan is to learn OO PHP, brush-up on the procedual stuff I don’t know then go for the Zend PHP 5 Certification . Anyone helped get a job off the back of this certiication? I’m guessing potential employers look on this certificate favorably?

What I mean is that there is no point in doing something like this:


$strHTML = 'SOME HTML BLOCK';

echo $strHTML;

//OR

echo <<<HTML

HTML Block

HTML;

When you can just create a simple html file and include it wherever you need it.