This is an archived tutorial from the kirupa.com legacy collection. It covers software that may no longer be available, but it is kept online because the ideas still hold up.
This tutorial is an introduction to object oriented programming (OOP) with PHP. Upon finishing this tutorial, you should have the basic tools necessary to begin navigating the world of OOP. Throughout, we will build upon one example while key terms and nuances to OOP with PHP are introduced. In addition, some time will be spent showing how to integrate object oriented PHP with MySQL.
Not surprisingly, object oriented programming is focused
around objects. While the idea of objects may be foreign to
you in coding terms, understanding what objects are and why
we use them shouldn't take long. In short, our
non-programming world is comprised of objects. Computers,
fish, clouds, people, and cars are all objects. Objects have
properties like color, size, name, and speed. Objects can
also be comprised of other objects: cars have doors; doors
have handles; handles have plastic levers; so on and so
forth. Objects are everywhere around us. For this reason,
many programmers find object oriented programming relatively
easy to understand.
So how do objects translate into code? If we were building a
website about users, we would create one or many user
objects. Objects are created using classes. Classes are
groups of related variables and functions. Variables hold
our object's properties like color, size, and speed.
Functions perform actions like set variable values or open
files. In this example, we could create user objects with a
User class. You can think of the User class as a template
for any user objects.
Creating an object is called instantiation
(creating an instance). Let's instantiate a user object and
code the corresponding User class:
Note: As this tutorial
progresses, code will be removed so that you don't get lost
and can focus on the task at hand. Feel free to keep or add
back code from previous examples.
Right now this user can't do anything and doesn't have any
attributes. Within classes, we use methods (aka functions)
and variables to give our objects functionality and
properties. Let's redo our first example so that our users
can have a name:
As you can see, methods are declared using
function [methodName] format, as is standard in PHP. This
simple example shows us how we can apply a name to the
object, then access the name. Continue on to learn about how
we handle variables and methods within classes.
Note about PHP versions: If you are running
PHP4, the above code will not work for you. Please continue
on to the next section for an explanation.
Within classes, we first define our
variables. In this case, our first variable is $name. A
handy feature of PHP5 (not PHP4) is increased visibility
control. Our $name variable currently has a visibility of
private. Private visibility means that the variable can only
be accessed via the methods inside the class (like setName
and getName). If we set the variable visibility to public,
our variable could be accessed externally (without the
methods). The final visibility setting for a variable is
protected, which means that variable access is limited to
parent and inherited classes, which we will discuss more
later.
In PHP4, public is the only visibility option and public
variables are declared using var instead of public. Let's
take a look at how variable visibility works by adding a
$location variable and setting it to public visibility:
So which variable visibility should you
choose? The answer is that it depends. In general, you
should be fine using private. Private is especially useful
because it supports encapsulation - the ability to hide data
and only make it accessible through a given interface. In
OOP, an interface represents the functionality given to a
particular object.
Just as we set a variable's visibility, we can also set
visibility for methods. By default, if we don't set the
visibility of our methods, they will be set to public. For
the sake of time, we will not dig into examples with
different method visibility. Continue on to learn about an
important and useful method, the constructor.
Note about $this: Within methods, we refer to class
variables and other methods using $this->. This can be seen
within the setName and getName methods. $this is a default
variable created upon instantiation and enables an object to
reference itself.
Note about naming conventions: While set[PropertyName]
and get[PropertyName] are popular method names because they
are easily understood, they are not required. You can name
these methods whatever you want.
Now is a good time to look at the constructor method. The constructor is a method that will automatically be run when an object is instantiated. In PHP5, we have methods called "Magic Methods" (i.e. __construct, __destruct, and a few others) which begin with two underscores. In PHP4, the constructor method would be given the same name as the class itself. So in PHP4, if we have a class named User, our constructor method would also be named User (not __construct). Remember, you do not need to call the constructor method explicitly because it will be automatically run when an instance of that class is created. Here's a constructor in action:
Now you might be starting to see one of the benefits of OOP - much of the code lies in the background. We could include files containing our classes to hide the heavy duty code even more. Because the naming conventions of classes and methods are fairly self explanatory, we won't need to constantly look back at our included files. Continue reading to find out how we can use arrays to speed up our process.
Right now, it's tedious to set each property using a set method - there must be an easier way. That's where associative arrays combined with our constructor come in handy. Let's create our user object and give it several properties upon instantiation:
I have kept the set methods in case we want to change the properties, but now the properties are established up front via __construct. That is, we passed our $attribs array to the object on instantiation, which in turn passed $attribs to the constructor automatically. The advantage to using associative arrays for this purpose is that we don't need to explicitly set all of our variables with the methods. This is extremely handy when integrating PHP with MySQL data, which we will cover soon. But first, we need to learn a little bit about method interaction and object grouping.
At this point, our methods do not interact. Let's add a little functionality to our example by converting full state names to the appropriate abbreviations.
In this example, we used a full state name to get its
corresponding abbreviation. We did this using a class with a
static variable. Static variables generally do not change
and can be accessed without methods. These variables act
more as reference and can be useful for things like your
database connection settings and other site wide variables.
Static variables are usually named with all capital letters.
Next, we will learn to integrate our object oriented PHP
with MySQL.
In this section, we will kill two birds with one stone.
Not only will we learn how to integrate OO PHP and MySQL,
but we will learn how to group objects. In this case, you
will create a e>UsersGroup class which will
contain an array of User objects. Each of those
User objects will be created using a row from a
MySQL query. To try this practical example, you will first
need to create a Users table in a MySQL database. I am using
a MySQL database named `kirupa_oop`. Use the queries below
to create the table and insert the sample data.
This very simple table just has two columns:
`user_id` and `user_name`. You may wish to add your own name
to this table to spice things up.
As promised, we will create a UsersGroup class. This group
will contain an array of User objects, each of which is
created using data from our MySQL table. All of my tables
are on a database named `kirupa_oop`. If your database is
not named `kirupa_oop`, you must change the database name in
the Settings class shown below. Here is our UsersGroup class
in action:
The first thing to note is that we are holding our
database connection and table name information inside our
Settings class, within static variables. In the
event that we need to change our database name, table names,
database usernames, etc. we will only do it in our
Settings class (which is preferably in a separate,
included file). Our User class is nothing new -
it only holds the name property and still receives an array
of data via __construct.
Let's look at the code for the UsersGroup class. If you have connected to a MySQL database with PHP before, the connection should be nothing new. The only difference is that we use static variables for our connection settings. We do the same for our table names because within double quotes, our Settings class static variables cannot be parsed. That is, just using Settings::$TABLES['tbl_users'] directly in our double-quoted SQL query will cause an error.
Our SQL query produces an array of rows, which we assign to $result. Using a while loop, we go through our $result array. Each element in $result is an array of values (like id and name). Again, this should look very familiar to anyone who has used PHP to access a MySQL database. Now comes the OOP part: we then pass each row ($row) from our MySQL query to our addUser method. First, the addUser method checks if it's being passed an array of data (like $row) or a whole User object. In this case, we are passing an array of data. Using that array of data, addUser creates a User object ($noob), then adds that user object to the group array ($group).
Note about column names: When our User object is created with array data, the constructor is looking for an array element called name. To fulfill this request, we use a SQL alias, which can be seen in $sql. If we did not alias user_name AS name the $row variable would not hold an array element called name but rather user_name. Thus, it would not correctly populate the name variable in our User object. I prefer to keep customization in my SQL rather than my PHP class methods because I am more likely to reuse PHP class methods than SQL queries. For instance, if I create a Dogs class, I would also want a getName method and constructor. Rather than modify several PHP methods to support dogs instead of users, I would rather modify one SQL query. Alternatively, you could also rename your user_name column to just name. This would maximize reusability, but may hurt your ability to understand more complex SQL queries and database designs.
You might be thinking this class is overly complex. After all, you can probably code all of this in 15 lines within a regular PHP page. So where's the advantage? Well, look at how we use our objects:
Really, that's 4 lines of code to echo out all of the users in our table. All of the database connection, querying, and real code is sitting behind the scenes. Remember, we are going to include our classes as separate files. On top of that, our classes are very reusable (aka modular). Our code is beautifully generalized and hidden from plain sight. It should also coded semantically, so it's easy to understand. Debugging and maintenance time should be decreased significantly. In the end, we're going to reuse this code for many sites and save tons of time and energy.
So that's a basic user table accessed with a
UsersGroup class. But what if we want some users to
be Administrators and others just plain Users - how can we
do that? For the answer, let's continue on with the topic of
inheritance.
To make this system more robust, we don't want all of the users in our group to have the same status. Some users need to be administrators, others moderators, and others just regular users. How can we account for this in our objects? The answer is nheritance - the ability for one class to inherit methods and properties from another class. First, let's take a look at inheritance in code:
As you can see, our Admin
object has inherited the functionality of the User
class using the keyword extends. On top of
that, our Admin is given some additional
functionality. In this case, our User class is
known as the superclass. In PHP, a class may only inherit
one superclass. There are more nuances to inheritance, but
this tutorial will only cover the basics. In a more
realistic scenario, we would code more functionality for
just administrators. Perhaps something like:
For the sake of time and focus, these methods haven't actually been coded. But this should give you some insight into how inheritance works and why it can be useful.
Continue on for a few parting words and direction.
By now, you should understand what objects, how to create them, and how to access their properties and methods. This tutorial is by no means all-encompassing. In fact, this is just the tip of the iceberg and was designed as such. For further reading, I suggest HP5: Objects, Patterns, and Practice by Matt Zandstra. In addition, you could read through the OOP documentation provided at php.net.
As you begin to understand OOP more and your PHP code becomes more object oriented, you will find more code reusable and ultimately save time and energy. Pre-existing code resources such as PEAR and PHPClasses.org will become increasingly useful.
If you have questions related to this tutorial or PHP in general, post them in the Server-Side forum here at kirupa.com.
|
|
Esherido |
Just a final word before we wrap up. What you've seen here is freshly baked content without added preservatives, artificial intelligence, ads, and algorithm-driven doodads. A huge thank you to all of you who buy kirupa's books, became a paid subscriber, watch the videos, and/or interact on the forums.
Your support keeps this site going! 😇
:: Copyright KIRUPA 2026 //--