Professional Documents
Culture Documents
PHP OOP Kickstart
PHP OOP Kickstart
By Alex
alexwebdevelop.com
1
Contents
● Introduction
● Chapter 1 - Classes and Objects
○ Classes and objects in PHP
○ Class Properties
○ Class Methods
○ The $this keyword
○ The Class Constructor
○ Use different class methods together
● Chapter 2 - Visibility
○ Properties and methods visibility
○ When to use public and when private?
○ Getters and setters
● Chapter 3 - Inheritance
○ What does “Inheritance” mean?
○ Public, protected and private: how they work with inheritance
○ Method overriding
○ The parent:: keyword
○ Abstract classes
● Chapter 4 - Static Properties and Methods
○ The static keyword
○ Static methods
○ Static properties
○ The self:: keyword
● Conclusion
2
Introduction.
Object-oriented programming, or just OOP, is a powerful way to organize and write the
code of your apps.
When you first learn how to code, you simply organize your code into variables, functions
and control structures. This way of coding is called procedural programming.
For example, let’s say that you are writing a web application for your local library.
Your app organizes the books in the library, and each book is identified by a unique book
ID.
Now, let’s say that you want to read or change the title of a book.
With procedural programming, the way to do that is by creating two functions like this:
$bookId = 1;
setBookTitle($bookId, "My new book"); /* Set the book title */
echo getBookTitle($bookId); /* Print the book title */
These functions need to get the book ID as their argument, $bookId, to know which book
to work on.
Then, they need to search for the book on the database and perform the required
operation (in this case, reading or changing the title).
3
● You must have a dedicated argument for the book ID in every function. Moreover,
you need to keep the $bookId variable available whenever you need to call any of
those functions.
● Every single function needs to look for the book information on the database
every time, usually by executing a read query with the book ID. This is not
efficient.
● Suppose that your library has different types of books, such as physical books
and ebooks. Some operations, such as calculating the book’s length, need
different logic depending on the book type. In such cases, you have to duplicate
the functions or add complex checks to verify the book type.
● You don’t need to pass the book ID to different functions. Just pass it once to the
class.
● The class reads the book information from the database only once.
● OOP can automatically handle different types of books by using inheritance.
Chapter 1
This is the syntax to define a new, empty PHP class called Book:
class Book {
To create an object of the Book class you need to use the new operator, like this:
class Book {
So:
You can think of classes as complex types, and of objects as variables of that type.
Now, we want to use our new Book class for our library application.
The Book class will contain information about a specific book, as well as include the
functions to perform operations on that book.
Let’s begin by transforming our first procedural programming example into OOP and by
moving the $bookId variable and the title-related functions into the Book class.
Class Properties.
PHP classes can contain variables. Variables in classes are called properties.
class Book {
public $bookId;
}
The public keyword that you see before $bookId is the visibility operator. It tells whether
the property should be visible from outside the class.
Don’t worry about it for now, we’re going to deal with that later.
Class properties work exactly like normal PHP variables. They can be variables of any
type, such as numbers and strings, even objects of other classes.
class Book {
public $bookId;
public $title;
public $authors;
public $publishDate;
}
When you create an object of the Book class, that object contains all the properties of
the class.
To access those properties, you need to use the -> operator on the object.
Like this:
$bookId = 1;
$bookTitle = "My new book";
● You do NOT need to put a $ sign before the property name when using ->
● $bookId is the global variable named $bookId, which is defined in the global
scope of your script.
$myBook->bookId is the class property and it’s only visible in the scope of the
class. So, even if these variables share the same name, they live in different
places.
● You can read and assign new values to class properties just like you would do
with normal variables.
Class Methods.
PHP classes can also contain functions. Functions in classes are called methods.
Let’s move the setBookTitle() and setBookTitle() functions into our Book class:
class Book {
public $bookId;
public $title;
public $authors;
public $publishDate;
Just like properties, methods too have a visibility operator. In this case, both methods
have the public visibility operator, meaning that you can call them from outside the
class.
Again, don’t worry about that for now. It will all become clear very soon.
Note that we changed the functions names from setBookTitle() and setBookTitle() to
just setTitle() and setTitle(), removing “book” from the names.
The reason is that we are defining them inside the Book class, so it’s already clear that
the context of those functions is the book.
This is another cool fact about classes: they already set the context so you don’t need
to make it explicit in the properties and methods names.
Notice how, for the same reason, the properties are named $title, $authors etc., instead
of being named $bookTitle, $bookAuthors etc.
(I kept $bookId that way for the sake of the tutorial, but you are free to rename it into
$id).
Like this:
Note that class methods are functions, so you need to use the proper syntax when
calling them: use the parentheses and pass them the correct arguments.
The setTitle() and getTitle() methods are not doing anything, though.
Let’s fix that.
We want setTitle() to set the class $title property to the title received as its argument,
and getTitle() to return the value of the $title property.
The methods inside a class have access to all the class’ properties and methods, so
they can share the same information and functionalities.
PHP provides a specific keyword for accessing the class’ own elements: $this.
Inside a class method, the $this keyword works like a virtual object of the current class.
You can use the -> operator on $this to access the class' own properties and methods.
So, here is how to let the setTitle() and getTitle() methods set and read the $title
property:
11
class Book {
public $bookId;
public $title;
● Make sure that you understand the difference between the class’ property
($this->title) and the method’s argument ($title).
getTitle() simply uses the return keyword to return the value of the class’ property $title.
Run the following code snippet and try changing the title string:
12
class Book {
public $bookId;
public $title;
This method is special because you do not call it explicitly. Instead, it is automatically
called when you create an object of the class.
The role of the Constructor is to initialize the class’ properties to their default values and
to handle the object creation arguments, if any.
13
Let’s create the Constructor for our Book class that initializes the class’ properties to
some default values:
class Book {
public $bookId;
public $title;
public $authors;
public $publishDate;
// Other methods...
}
Now, when you create a new Book object, the Constructor automatically assigns the
default values to the class’ properties:
Note how you can use standard PHP functions from inside the class methods.
For example, the Constructor uses the PHP time() function to initialize the $publishDate
property to the current Timestamp, calculated at the exact moment when the $myBook
object is created.
We want to make sure that each object of the Book class has a valid book ID saved in its
$bookId property.
A simple way to do that is by setting the $bookId property using the -> operator. But this
is not the best solution.
Like this:
Now the $bookId property is not initialized to 0, but to the value passed as the first
argument of the Constructor.
Now you may be wondering: how do you pass arguments to the Constructor?
Simple: they are passed when you create the class object with the new operator.
Like this:
15
$bookId = 5;
$myBook = new Book($bookId);
Just like a normal PHP function, if the Constructor requires an argument you cannot call
it without one. Therefore, you cannot create a Book object without the $bookId
argument.
If you try creating a new Book object with no arguments, PHP exits with a fatal error:
After all, all that setTitle() does is to set $title to the value we pass to it. And similarly, all
that getTitle() does is to return $title.
As a general rule, it is better to use dedicated methods to handle the class properties.
● First
Most of the time, methods perform other operations other than just setting a
class’ property.
For example, setTitle() can also update the database with the new book title.
● Second
By using methods, you can perform proper validation on the data. If you set the
class’ property directly instead, no validation occurs.
For example, setTitle() may check that the new title is not empty and that its
length does not exceed a certain value.
Let’s edit our setTitle() method to check the new title length before updating the $title
property.
Let’s also make setTitle() return false if the title is not correct, and true if the title is
correct.
Now we can rely on setTitle() for the title validation, like this:
$bookId = 5;
$title = "My new book";
$myBook = new Book($bookId);
if ($myBook->setTitle($title)) {
Just like with normal functions, it is a good idea to write small, specific class methods
that perform simple and well defined tasks.
So, what we want to do is to create a specific method for the title validation.
The setTitle() method will call this new validation method and, depending on its return
value, decide whether to update the class $title property.
18
if ($valid) {
$this->title = $title;
}
return $valid;
}
return true;
}
We created a new method called isTitleValid() that takes the $title argument.
This method checks the length of $title, and returns true if the length is between 1 and
256, or false otherwise.
setTitle(), instead of including the validation code itself, calls the isTitleValid() method
by using the $this operator (remember? It’s the operator to access the class' own
properties and methods).
If isTitleValid() returns true, it means the new title is valid and, only in this case, it
updates the class $title property.
Chapter 2
Visibility
20
Visibility affects how the property or the method can be “seen” by developers who
create objects of that class.
Remember how all the properties and methods we wrote have the public keyword
before them?
That is their visibility operator.
● public,
● private,
● or protected
To understand what visibility is about, let’s consider the two possible ways to access a
class property or method:
Class’ methods can always use $this to access the class’ properties and methods.
However, there’s an important rule for when you use the -> operator from an object:
In other words, you can NOT use the -> operator from an object to access protected and
private properties and methods.
For example, let’s change the $bookId visibility from public to private:
21
class Book {
private $bookId;
public $title;
public $authors;
public $publishDate;
Now, while you can still access the $title, $authors and $publishDate properties from an
object, you cannot access $bookId because it is declared as private.
$bookId = 5;
$myBook = new Book($bookId);
echo $myBook->bookId;
// Fatal error: Cannot access private property Book::$bookId
22
For example, if you define the isTitleValid() method as private, you can still access it
from other methods, such as setTitle(), but you cannot call it from the object with ->
● The first purpose is to provide an interface to the developer who uses the class
to create objects.
For example, the setTitle() and getTitle() functions are meant to be used by the
developer that creates the object.
● The second purpose is to implement functionalities that are used only by the
class itself, but that are not meant to be used from the outside.
We want the setTitle() function to update the database with the new book title.
So, let’s create a new method called updateDbTitle() that does exactly that.
This method is meant to be called by setTitle(), but we don’t want developers to call it
directly. We want developers to use setTitle() only.
Like this:
23
if ($valid) {
$this->title = $title;
$this->updateDbTitle();
}
}
The updateDbTitle() method executes a database query on the “books” table, updating
the “title” column with the value from the $title class property.
The affected row is the one with the same ID as the $bookId class property.
Note how class methods can use global variables by using the global keyword, just like
normal PHP functions do.
The updateDbTitle() method is private. Developers cannot create a Book object and call
it from the object with the -> operator.
Only class methods can, like setTitle() does.
For instance, we do not want developers to change it directly, otherwise they would skip
the validation process and the database update operation performed by setTitle().
class Book {
private $bookId;
private $title;
// etc...
}
The same goes for $bookId (the Constructor sets it, and then it should not be changed),
$authors (you want to create a method to set this too), $publishedDate and every other
property you’ll decide to add.
However, some class properties are useful for the developers who use the class.
For example, a developer who creates a Book object may need to get the title or the
authors to print them.
But being those properties private, the developer cannot access them directly.
Getters
Getters are public class methods that simply return the value of a class property.
They let developers get the value of that property while keeping the property itself
private.
class Book {
private $bookId;
private $title;
Setters
Setters are public class methods that set a class property.
As you probably have already guessed, setTitle() is a perfect example of a setter.
Setter methods usually perform some validation on the value to make sure it is correct.
They can also perform additional operations, such as updating the database.
26
Chapter 3
Inheritance
27
As you work on the app, you note that your library needs to handle different types of
books.
Hard-cover books, illustrated books, ebooks, comic books, and so on.
All types of books share some common attributes, such as title and authors.
However, they also have specific features not shared with the other types.
For example:
● ebooks have a “words” attribute but not a “pages” attribute (the length of an
ebook is expressed in words)
● illustrated books have colored pages, but classic books don’t
● comic books have multiple fonts, but other books have only one
● and so on
The same goes for the operations that you can perform on them:
So, how do you represent all these different types of books in your app?
This solution, however, creates a lot of duplicated code because many functionalities
28
For example, the getTitle() function would work the same on all the classes, but you’d
have to implement it in each class nonetheless:
class PhysicalBook {
public $bookId;
public $title;
class Ebook {
public $bookId;
public $title;
For example:
29
class Book {
private $bookId;
private $pages;
private $words;
private $type;
In this solution, the Book class has a new property called $type.
The class Constructor takes a new argument, the type of the book, that goes into $type.
Therefore, getLength() needs to check $type and either return the $words value or the
$pages value depending on the book type.
30
● Objects will always have unused properties and methods, which can be
confusing and inefficient.
● Methods that need to check the book type become more complex (like
getLength()).
● If you need to add a new type of book, you have to go through all the class code
and change it to include the new type.
Your Book class acts as a base, general purpose class that works for all types of books.
This base class includes properties and methods that are common to all types of
books, such as the title and the authors.
For example:
31
class Book {
private $bookId;
private $title;
private $authors;
// Other methods...
}
Now, let’s say that you need to include comic books in your library.
Comic books should include all the basic books features, and on top of those include
the font used for the comic balloons. This will be an additional property that only comic
books have.
What you want to do is create a new ComicBook class that inherits from the base Book
class.
When a class inherits from another, it includes all the base class’ properties and
methods and can add more of its own.
32
private $balloonFont;
$bookId = 1;
$myComicBook = new ComicBook($bookId);
echo $myComicBook->getTitle();
$myComicBook->setBalloonFont('Comic Sans');
echo $myComicBook->getBalloonFont();
When this happens, the ComicBook class gets all the public and protected methods
from the Book class.
Book is called the parent or base class. ComicBook is called the child or extended class.
You can see from the above example how $myComicBook, which is a ComicBook object,
does have the getTitle() method because it has inherited it from the Book class.
33
On top of that, ComicBook also has the $balloonFont property and the setBalloonFont()
method, which the base Book class lacks.
Visibility affects from where the property or the method can be accessed.
Private properties and methods can be accessed only from the methods of the class
itself by using $this. They can NOT be accessed by methods of child classes.
Protected properties and methods fall in between. Like private, they cannot be
accessed from outside the class. However, they can be accessed from the methods of
child classes. We’ll see how in a minute.
PRIVATE NO YES NO
34
Method overriding.
One of the most useful features of class inheritance is method overriding.
A child class automatically gets the parent’s class methods, and it can implement new
methods of its own.
Another thing a child class can do is to replace a parent’s method with a new one with
the same name. This operation is called method overriding.
Comic books may be part of a comic series, so we add a $seriesTitle property to our
ComicBook class.
When we get the comic book title with getTitle(), we also want to include the series title,
without affecting the base Book class.
To do that, you need to define the getTitle() method again in the ComicBook class to
include the series title.
class Book {
protected $title;
And here’s the child ComicBook class overriding the getTitle() method:
private $seriesTitle;
The ComicBook getTitle() method is different from the base class’ one. Objects of the
Book class will run the Book’s method, while objects of the ComicBook class will run the
ComicBook’s method.
So, if you call getTitle() from a Book object, the Book’s method is called:
But if you call getTitle() from a ComicBook object, then the ComicBook’s method is
called instead:
36
Note how we used the protected visibility for the $title property.
● The property or method are NOT visible from outside the class, by using the ->
operator on an object.
● However, protected properties and methods ARE visible from child classes.
By making it protected, $title is still not accessible from outside the class (by using the
-> operator on an object), but it can be accessed from a method of a child class.
The new ComicBook setTitle() method should do everything that the Book method does,
and on top of that echo a “done” message.
if ($valid) {
$this->title = $title;
$this->updateDbTitle();
}
}
We said that the new ComicBook method must do everything that the base method
does, and after that echo the “done” message.
However, writing all the base method code again is not a good idea.
It would create useless code duplication, and you would also have to replicate the code
of the two private methods called by setTitle() (because, since they are private, you
cannot call them from the inherited class).
The solution is to call the base class method from the child class method.
How?
Once you override a method, you cannot call it with $this anymore, because that would
call the current class method.
To call the method of the parent class you need to use the parent:: keyword.
Abstract classes.
Abstraction is an advanced OOP topic.
Don’t worry: in this tutorial we are not going into the details. However, I think it’s
important to have an idea of what abstraction is and how it works in principle.
Now, imagine that any book in the library is a hard-cover book, an illustrated book, an
ebook or a comic book. No other choices are possible.
You create a base Book class as well as child classes for each book type, so you can
take advantage of inheritance.
However, you do not want to make it possible to create objects of the base Book class.
In other words, you want to use the Book class only for coding purposes, but there
should not be Book objects lying around in the library app. Any object should be of one
of the child classes.
39
You are required to create one or more child classes of that class, and create objects of
those child classes instead.
Here’s how to declare the Book class as abstract using the abstract keyword:
Now you can create objects of the ComicBook class, but you cannot create objects of
the Book class because it is declared as abstract.
// OK
$myComicBook = new ComicBook();
Chapter 4
For example, when you create an object of the Book class or the ComicBook class, that
object represents a specific, well defined book.
In fact, it is the exact book with the ID that you pass to the class Constructor.
In some cases you want to use the Book class to perform generic operations on books.
Not operations on a specific book, like the setTitle() method does (it changes the title of
a specific book), but operations related to all books.
For example, let’s say that you want to search your library for a book with a specific title.
In this case you cannot create a book object, because you don’t know the ID of the book
you are looking for (or even if a book with that title exists in the first place).
So, you need a way to define a “search function” that works on the entire book
collection, instead of a specific book.
Static methods are defined with the static keyword, and you can call them without
creating a class object first.
Static methods.
Here’s how to define a static method in the Book class:
class Book {
In this example, bookFromTitle() is a static method that searches the database for a
book with the title passed as argument.
If found, it returns the book ID. Otherwise it returns NULL.
To call a static method, you need to use a different syntax compared to non-static
methods.
You do not need to create an object, but you simply use the class name followed by ::
and the static method.
Like this:
Static properties.
You can also define static properties.
Just like static methods, you can access static properties by using the class::property
syntax without creating an object.
Static properties are useful to store shared attributes for the entire class, that do not
depend on a specific instance of the class.
For example, you can save the list of available book languages inside an array:
class Book {
//...
}
$langs lists all the available languages, but it’s not related to a single book in particular.
Therefore, it makes sense to define it as a static property.
This is different from a property such as $title, since each Book instance has its own
$title that is separated from the others.
44
To let developers access its value, you can implement a getter function just like you
learned for non-static properties.
In this case, you want to create a static method that works as the getter function for a
static property.
From inside a class method, you can access the class’ static properties and methods
with the self:: keyword.
For example, here’s how to create a static getter method that returns the value of the
$langs static property:
Conclusion
Next Steps
46
Conclusion.
Congratulations for finishing this guide!
If you liked it (or if you didn’t), please take a minute to send me an email and tell me
what you think. Your opinion is very important to me.
If you have any questions about PHP OOP and the topics discussed in this guide, send
me an email or meet me on my Facebook group: Alex PHP café.
Next steps?
First, make sure to follow my curated weekly PHP newsletter.
It’s the perfect resource for developers who want to improve their PHP skills week after
week.
If you are looking for more OOP tutorials, you can start from the following:
If you want to give a boost to your PHP skills, take a look at my professional courses:
● JUMP START
Go from zero to PHP developer in just 9 days. Even if you are an absolute
beginner.
Alex
Copyright note
The images used in this PDF have been downloaded from FreePik.
This PDF and its content is copyright of the Alex Web Develop website and has been registered on an
authorized copyright registry.