Beginning Object-Oriented Programming in PHP

AID: 2626
  • Status: Published

9681 points

  • Bygr8gonzo
  • TypeTutorial
  • Posted on2010-03-07 at 21:23:11
Awards
  • Community Pick
  • Experts Exchange Approved
Imagine if someone tells you to hammer 10 nails into a board. The best tool for the job would be a hammer, right? You COULD go take lessons on how to use a Super Screwdriver 9000, but that would make absolutely no sense. A Super Screwdriver 9000 might be able to use any type of screw in the world, but it wouldn't help you hammer in those 10 nails, so you wouldn't use it and after a while, you would start to forget what you've learned about that special screwdriver.

This is a common problem for experienced PHP developers that are learning the (relatively) new object-oriented programming (OOP) capabilities of PHP, or for anyone that is trying to learn how  to do OOP in PHP. They want to learn how to do it, but they don't know WHEN to use it properly, so they don't use it, and then the knowledge just fades away after a while.

Traditional vs. Object-Oriented


So let's start by comparing traditional top-down programming with object-oriented programming. Let's assume we're trying to define some variables that describe two houses.

Traditional top-programming might look like this:

<?
$house1_type = "Apartment";
$house1_address = "123 Main Street";

$house2_type = "Mansion";
$house2_address = "123 Money Street";
?>
                                    
1:
2:
3:
4:
5:
6:
7:

Select allOpen in new window


Object-oriented programming isn't that different, and might look like this:

<?
class House
{
  public $type = "";
  public $address = "";
  public $residents = array();
}

$house1 = new House();
$house1->type = "Apartment";
$house1->address = "123 Main Street";

$house2 = new House();
$house2->type = "Mansion";
$house2->address = "123 Money Street";
?>
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:

Select allOpen in new window


Looks pretty similar, right? Your first thought might be, "Why would I want to write MORE code to do the same thing?!" It doesn't make any sense, does it? That's because you are probably a little lazy, but in a good way. Most good programmers are; they want to write LESS code and do MORE, which is a good goal to have. But it's not always the BEST goal.

Object-Oriented Programming: Why and When to Do It


Here's the basic, BEST difference between object-oriented programming and traditional programming:

Object-Oriented Programming is more organized.

That's not to say that it's always better, though! I have a REALLY messy home office, but I know exactly where everything is. My wife, on the other hand, hates the mess and it would take her a long time to find anything in it. But if I'm the only one using that office, then I can keep it messy, right?

The differences in programming are similar. Traditional top-down programming can START OUT clean, and if your script will always stay small, then it's a great way to bang out a quick, efficient program. If your application grows, then it will almost always get messy over time as you add more features and stuff. The larger the application becomes, the harder it becomes to maintain and document. Plus, as an application grows, you often end up having more people work on it with you. Be honest - would YOU want to suddenly have to work on a large project with tons of messy code everywhere? Probably not.

Back to my messy office - I could spend a few minutes to organize all my papers and junk and put them into labeled boxes. If my wife kept having to go into the office to get documents, or if I hired someone to work in the room with me, then it would benefit all of us for me to be organized. Nobody would have to ask me where to find things, and I'd probably still be able to find things pretty easily. Plus, as I hired more and more people, I would get more and more benefit out of keeping the office organized. I could even have people dedicated to working on documents in specific boxes. Or, if I wanted to send all of my tax documents to my friend who does my taxes, then I could just send him/her the box labeled "Tax Stuff" instead of trying to go around and gather up all the different papers from the mess. (I'm using these examples for a reason - you'll see later.)

Could I have 10 people working in a messy office? Yes, it's POSSIBLE, but it's definitely not AS easy and simple as having them all work in an organized office.

SO, the moral of this story is that it's sometimes good to spend a little more time at the beginning and write a little more code to save you a LOT of time later on. It's simply good planning so you can be more lazy later.

Let me bring those office examples back to the technical world. Despite some additional code in the beginning, there are several reasons for object-oriented code:

  • Easier to maintain as code grows.

  • Easier to document.

  • Easier for others to learn.

  • More portable (for selling, sharing, or reusing code)


Now that we have some reasons WHY you should sometimes use object-oriented programming, and you know WHEN to use it, let's talk about HOW to do it.

Object-Oriented Programming: How to Do It


The most basic element of OOP PHP programming is a "class." A class looks like this:

class House {
}
                                    
1:
2:

Select allOpen in new window


By itself, a class does nothing. It's like a function - you can create/define a function, but if you don't USE it, then it just sits there and does nothing. So the above piece of code simply defines a class called House.

To make use of your House class, you simply create an "instance" of it by using the "new" command, like this:

$yourHouse = new House();
                                    
1:

Select allOpen in new window


That creates a variable call $yourHouse, which is an instance of the House class. You can create as many instances as you want, so assuming I am not homeless, then maybe I can have a house, too:

$yourHouse = new House();
$myHouse = new House();
                                    
1:
2:

Select allOpen in new window



Class Properties


Without any sort of definition or identifying characteristics, there's really no difference between $yourHouse and $myHouse. So let's define our houses a bit further by specifying a mailing address. First, we need to update our class definition so that it can hold the mailing address:

class House {
	public $mailingAddress = "123 Default Address Street";
	public $numberBedrooms = 2;
}
                                    
1:
2:
3:
4:

Select allOpen in new window


These 2 extra lines of code are really simple. We've created two class "properties" called $mailingAddress (because a mailing address is typically a property/characteristic of a house) and $numberBedrooms (because most houses also have at least 1 bedroom).

Don't worry about what "public" means for now - just use it in front of your class properties. You can probably guess that the "123 Default Address Street" is the default value for this property, and 2 is the default value for $numberBedrooms.

So now when we create instances called $yourHouse and $myHouse, both of them automatically come with the mailing address "123 Default Address Street" and 2 bedrooms. Now, there are a lot of houses that have 2 bedrooms, so the default value could be handy here, but every house has a different address, so having a default address probably isn't necessary, so let's just take it out:

class House {
	public $mailingAddress;
	public $numberBedrooms = 2;
}
                                    
1:
2:
3:
4:

Select allOpen in new window


Now $mailingAddress is just a property that doesn't have any default address. Let's create our houses and give them addresses:

$yourHouse = new House();
$yourHouse->mailingAddress = "123 Your Street";

$myHouse = new House();
$myHouse->mailingAddress = "444 My Street";
                                    
1:
2:
3:
4:
5:

Select allOpen in new window


Just in case you didn't catch it, assigning a value to the property of an instance is simply:

$instance_variable->property_name = value;
                                    
1:

Select allOpen in new window


Seeing the property value later is similar:

$myHouse = new House();
$myHouse->mailingAddress = "444 My Street";
echo $myHouse->mailingAddress; // Will display "444 My Street"
echo $myHouse->numberBedrooms; // Will display "2"
                                    
1:
2:
3:
4:

Select allOpen in new window



Class Methods


That's all you need to know about basic class properties, but the real meat of a class is in the class "methods", which are simply functions that are defined inside of a class, like this:

class House {

	// Our Class Properties
	public $mailingAddress;
	public $numberBedrooms = 2;
	
	// Our Class Methods
	public function cleanTheHouse()
	{
		for($i = 1; $i <= $this->numberBedrooms; $i++)
		{
			echo "Cleaning bedroom " . $i;
		}
	}
}
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:

Select allOpen in new window


Now we're getting somewhere! We again see the "public" keyword, and again, we're going to ignore it for now. The cleanTheHouse() class method is a very simple function. All it does is run a basic loop that goes from 1 to the number of bedrooms, and then echoes out a message that says "Cleaning bedroom 1", then "Cleaning bedroom 2", and so on until all the bedrooms have been "cleaned".

So what if YOUR house had 10 rooms and mine had 5? How would this function know how many rooms to clean? The secret is in the $this keyword. The $this keyword references the current instance, no matter if it's $yourHouse or $myHouse. So if I created this code:
$yourHouse = new House();
$yourHouse->numberBedrooms = 10;
$yourHouse->cleanTheHouse();

$myHouse = new House();
$myHouse->numberBedrooms = 5;
$myHouse->cleanTheHouse();
                                    
1:
2:
3:
4:
5:
6:
7:

Select allOpen in new window



Then $yourHouse would have a loop that cleaned 10 bedrooms, while $myHouse would have 5 rooms cleaned. The $this keyword is one of the most useful tools you'll have when creating class methods, because it allows you to reference properties ONLY for the current instance of that class. If I didn't have $this, then I wouldn't know how many bedrooms to clean! If I guessed 10, then it might work for $yourHouse, but that would be wrong for $myHouse, which only has 5 bedrooms.

Let's add one last class method that uses an argument and returns a value:

class House {

	// Our Class Properties
	public $mailingAddress;
	public $numberBedrooms = 2;
	
	// Our Class Methods
	public function cleanTheHouse()
	{
		for($i = 1; $i <= $this->numberBedrooms; $i++)
		{
			echo "Cleaning bedroom " . $i;
		}
	}

	public function hasMoreThanRooms($numRooms)
	{
		if($this->numberBedrooms > $numRooms)
		{
			return true;
		}
		else
		{
			return false;
		}
	}
}

$yourHouse = new House();
$yourHouse->numberBedrooms = 10;
if($yourHouse->hasMoreThanRooms(8))
{
	print "Your house has more than 8 rooms? Wow.";
}
else
{
	print "You don't have more than 8 bedrooms? Where am I supposed to sleep?";
}

$myHouse = new House();
$myHouse->numberBedrooms = 5;
if($myHouse->hasMoreThanRooms(4))
{
	print "My house has more than 4 rooms? Wow.";
}
else
{
	print "I don't have more than 4 bedrooms? Where are you supposed to sleep?";
}
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:

Select allOpen in new window




The result of running this is:

      Your house has more than 8 rooms? Wow.
      My house has more than 4 rooms? Wow.

Scope: Public and Private


Speaking of houses, every house has an inside and an outside, right? If you have a mirror in your bathroom, then there's a good chance that nobody outside your house could see that mirror. Most houses also have windows on the outside, and anyone inside or outside can see that window. This whole concept of having some things that are visible only in the privacy of your home (private) and some things that are visible by anyone (public) - that whole concept is called "scope" and it's the last important, basic thing about classes.

Whenever we've created class properties or methods with "public" in front of their names, we've been declaring them to be visible to any code inside or outside of the class. It might help to visualize the different code locations:

class House {

  public $window = "clear";
  private $bathroomMirror = "shiny";

  // Inside the class - code in here can access the values
  // of $window AND $bathroomMirror
  
  public function doSomething()
  {
    echo $this->window; // Will show "clear"
    echo $this->bathroomMirror; // Will show "shiny"
    echo $this->runSecretFormula();  // Will show "Hello world!";
  }

  private function runSecretFormula()
  {
    return "Hello world!";
  }
}

// Outside the class - code here can only access the value of $window.
// Trying to access $bathroomMirror from here would not work.
$myHouse = new House();
echo $myHouse->window; // Will show "clear"
echo $myHouse->bathroomMirror; // OH NO! Will give you a big, fat, fatal error if you try to run the script!
echo $myHouse->runSecretFormula(); // OH NO! Will also give you an error!
                                    
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:

Select allOpen in new window



There are a variety of opinions on when and where you should use private/public functions. It's very common for programmers new to OOP to just use "public" for everything, since it doesn't really have any limits. So why use private at all?

For me, it really comes down to security. I always assume the worst when I'm programming, and I assume that a hacker will figure out a way to run some PHP code on my system. If I have a super-secret password inside of a class property, then I certainly don't want to make it easy for a hacker to run some code that echoes that password and gets it! If I make it private, then if the hacker tries to echo it, then he/she will just get an error!

You might be saying to yourself, "But if a hacker could run PHP code, then he/she could probably just use PHP functions to show the source code of the class and see the password!" You would be right, but there are ways to help protect against that. For example, there are many PHP script compilers out there that will turn your source code into machine language (which actually runs faster). So by using a combination of compilation and private methods/properties, you can make it very difficult for hackers to gain access to code and properties that should be kept... well... private.

In addition to private and public scopes, there is also a scope called "protected", but that will be covered in my advanced OOP article, when we talk about extending classes.

For now, these are all the basics you need to know about how to create and use a USEFUL class. Thanks for reading!
Asked On
2010-03-07 at 21:23:11ID2626
Tags

php

,

object-oriented programming

,

OOP

,

class

,

public

,

private

,

$this

Topic

PHP Scripting Language

Views
2602

Comments

Expert Comment

by: b0lsc0tt on 2010-03-26 at 21:11:20ID: 11979

Good explanation and info.  I have had similar thoughts to what you described when explaining the difference between OOP and "top down" programming.  I still struggle some to see the uses of OOP as I program because so much of what I have done has just been for me and using scripting.  I even look at OO code written by others just about every day of the week and am glad it is designed that way.  Oh well ... it gives me something to look forward to as I try to program better and smarter. :)

I look forward to reading your more advanced article next.  Big YES vote for being helpful.  I have heard it before but the explanation and info is good and helpful.  Thanks!

bol

Expert Comment

by: cms1978 on 2011-06-07 at 01:04:17ID: 28069

Very cool, maybe you can help on this one, how does a visual basic software get variables from a php page?

example, I have AccID and ProdID in my clients accounts in my website that is in php pages, but some how vb can know about these php variables and protects ebooks for my clients with a license key?

I think this website just has key gen php code, and this vb software just checks for a license key and validates it.

the software has 2 php variables for clients to input there account id and there product id, next a insert for a ebook to protect and then an output field, where they can store there protected file on there pc. they then insert this prodId and add new product name, email, website, thankyou page for there users to download this ebook.

when the user opens the ebook, they get a screen saying to insert a license key, continue trial, or buy. the buy button goes to my clients website to buy it.

any idea on how they have done this?

I have a basic idea, but don't know how to call php variables to a visual basic software?

how do I get, edit php variables for a vb script?

Add your Comment

Please Sign up or Log in to comment on this article.

Join Experts Exchange Today

Gain Access to all our Tech Resources

Get personalized answers

Ask unlimited questions

Access Proven Solutions

Search 3.2 million solutions

Read In-Depth How-To Guides

1000+ articles, demos, & tips

Watch Step by Step Tutorials

Learn direct from top tech pros

And Much More!

Your complete tech resource

See Plans and Pricing

30-day free trial. Register in 60 seconds.

Loading Advertisement...

Top PHP Experts

  1. Ray_Paseur

    1,354,218

    Genius

    3,734 points yesterday

    Profile
    Rank: Savant
  2. DaveBaldwin

    284,951

    Guru

    4,300 points yesterday

    Profile
    Rank: Genius
  3. StingRaY

    144,754

    Master

    4,000 points yesterday

    Profile
    Rank: Wizard
  4. jason1178

    143,172

    Master

    1,000 points yesterday

    Profile
    Rank: Genius
  5. bportlock

    123,643

    Master

    1,600 points yesterday

    Profile
    Rank: Genius
  6. ChrisStanyon

    111,336

    Master

    0 points yesterday

    Profile
    Rank: Sage
  7. Roads_Roads

    106,350

    Master

    0 points yesterday

    Profile
    Rank: Genius
  8. maeltar

    95,247

    Master

    0 points yesterday

    Profile
    Rank: Guru
  9. gr8gonzo

    95,168

    Master

    0 points yesterday

    Profile
    Rank: Sage
  10. smadeira

    82,088

    Master

    0 points yesterday

    Profile
    Rank: Wizard
  11. Slick812

    77,062

    Master

    0 points yesterday

    Profile
    Rank: Sage
  12. johanntagle

    74,700

    Master

    2,000 points yesterday

    Profile
    Rank: Sage
  13. logudotcom

    67,088

    Master

    0 points yesterday

    Profile
    Rank: Genius
  14. COBOLdinosaur

    65,841

    Master

    0 points yesterday

    Profile
    Rank: Genius
  15. leakim971

    63,819

    Master

    0 points yesterday

    Profile
    Rank: Genius
  16. un1x86

    56,406

    Master

    0 points yesterday

    Profile
    Rank: Master
  17. Derokorian

    46,763

    10 points yesterday

    Profile
    Rank: Guru
  18. marqusG

    44,475

    10 points yesterday

    Profile
    Rank: Sage
  19. DrDamnit

    42,892

    0 points yesterday

    Profile
    Rank: Genius
  20. ahoffmann

    40,068

    0 points yesterday

    Profile
    Rank: Genius
  21. designatedinitializer

    37,800

    0 points yesterday

    Profile
    Rank: Master
  22. maestropsm

    37,678

    0 points yesterday

    Profile
    Rank: Guru
  23. TerryAtOpus

    34,800

    0 points yesterday

    Profile
    Rank: Genius
  24. xterm

    32,850

    0 points yesterday

    Profile
    Rank: Sage
  25. kaufmed

    31,808

    0 points yesterday

    Profile
    Rank: Genius

Hall Of Fame