- Community Pick
- Experts Exchange Approved
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:
Object-oriented programming isn't that different, and might look like this:
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:
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:
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:
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:
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:
Now $mailingAddress is just a property that doesn't have any default address. Let's create our houses and give them addresses:
Just in case you didn't catch it, assigning a value to the property of an instance is simply:
Seeing the property value later is similar:
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:
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:
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:
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:
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!
by: b0lsc0tt on 2010-03-26 at 21:11:20ID: 11979
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