You are on page 1of 48

PHP OOP KICKSTART

The easiest guide to get started with


Object-Oriented PHP quickly.

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:

function setBookTitle(int $bookId, string $title) {


/* Set the book title... */
}

function getBookTitle(int $bookId): string {


$title = "";
/* Get the book title... */
return $title;
}

$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

This way of coding comes with some problems:

● 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.

Object-oriented programming solves these problems.


Instead of having a book identifier (the $bookId variable) and a list of functions, with
OOP you have special elements called classes that take care of everything.

Classes solve all the problems listed before:

● 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.

Let’s see how OOP works in practice in PHP.


4

Chapter 1

Classes and Objects


5

Classes and objects in PHP.


Classes are the fundamental blocks of object-oriented programming (OOP).

A class is a container that includes variables and functions.


The variables in the class are called the class’ properties. The functions in the class are
called the class’ methods.

This is the syntax to define a new, empty PHP class called Book:

class Book {

A class is just a definition, a blueprint.


To actually use it, you need to create an object of that class.

To create an object of the Book class you need to use the new operator, like this:

class Book {

$myBook = new Book();

So:

● Book is the class name.


● $myBook is an object of the Book class.

You can think of classes as complex types, and of objects as variables of that type.

In fact, that’s exactly how PHP considers them.


6

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.

For example, here’s how to create a class property named $bookId:

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.

Let’s add a few more properties related to books:


7

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";

$myBook = new Book();


$myBook->bookId = $bookId;
$myBook->title = $bookTitle;

echo "Book ID is: " . $myBook->bookId;


// Output: “Book ID is: 1”

echo "Book title is: " . $myBook->title;


// Output: “Book title is: My new book”
8

A few important things to note:

● 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;

public function setTitle(string $title) {


}

public function getTitle(string $title) {


}
}
9

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).

Now, let’s get back to our methods.


To call a class method, you can use the same -> operator used to access the class’
properties.

Like this:

$newBookTitle = "Title 2.0";

$myBook = new Book();


$myBook->setTitle($newBookTitle);
10

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.

To do that, we need to learn about the $this keyword.

The $this keyword.


You just learned how classes are collections of variables (properties) and functions
(methods) that share the same context.
In our case, all the properties and methods are related to books.

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.

Note that $this only works inside the class’ 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;

public function setTitle(string $title) {


$this->title = $title;
}

public function getTitle() {


return $this->title;
}
}

setTitle() access the $title property with: $this->title

A couple of important notes:

● Again, do not add a $ between “->” and “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.

Now try it for yourself.

Run the following code snippet and try changing the title string:
12

class Book {

public $bookId;
public $title;

public function setTitle(string $title) {


$this->title = $title;
}

public function getTitle() {


return $this->title;
}
}

$title = "Have fun changing this title";

$myBook = new Book();


$myBook->setTitle($title);
echo "My book title is: " . $myBook->getTitle();

The Class Constructor.


There is a special method that you can define in your class: the Constructor.

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 Constructor has the special name: __construct()


(with two underscores.)

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;

public function __construct() {


$this->bookId = 0;
$this->title = "no title set";
$this->authors = "no authors set";
$this->publishDate = time();
}

// Other methods...
}

Now, when you create a new Book object, the Constructor automatically assigns the
default values to the class’ properties:

$myBook = new Book();

echo $myBook->bookId; // Output: 0


echo $myBook->title; // Output: "no title set"
echo $myBook->authors; // Output: "no authors set"
echo $myBook->publishDate; // Output: the current Timestamp
14

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.

Now let’s take one step further.

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.

A much better solution is to require the book id value to be passed as an argument to


the class Constructor.

Like this:

public function __construct(int $bookId) {


$this->bookId = $bookId;
$this->title = "no title set";
$this->authors = "no authors set";
$this->publishDate = time();
}

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);

echo $myBook->bookId; // Output: 5

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:

$myBook = new Book(); // Missing argument!

Fatal error: Uncaught ArgumentCountError: Too few arguments to


function Book::__construct(), 0 passed in and exactly 1 expected

Why use setTitle() and getTitle() instead of using the


properties directly?
Now, you may be wondering: what’s the point of using methods such as setTitle() and
getTitle(), when you can simply set and read the $title property with the -> operator?

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.

There are two reasons for that.


16

● 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.

public function setTitle(string $title) {

/* Check the length of $title */


$len = mb_strlen($title);

if ($len < 1 || $len > 256) {


/* Length not ok, return false */
return false;
}

/* Length ok, set the title and return true */


$this->title = $title;
return true;
}
17

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)) {

echo 'New title set correctly.';


}
else {

echo 'The new title is not valid!';


}

Use different class methods together.


Let’s take one small step further.

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

Here’s how to do it:

public function setTitle(string $title) {


$valid = $this->isTitleValid($title);

if ($valid) {
$this->title = $title;
}

return $valid;
}

public function isTitleValid(string $title) {


$len = mb_strlen($title);

if ($len < 1 || $len > 256) {


return false;
}

return true;
}

So, what happens here?

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.

Finally, it returns the Boolean value returned by isTitleValid() to the caller.


19

Chapter 2

Visibility
20

Properties and methods visibility.


Class properties and methods have a special attribute: visibility.

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.

The visibility operator can assume three possible values:

● public,
● private,
● or protected

To understand what visibility is about, let’s consider the two possible ways to access a
class property or method:

● From a class object, with the -> operator


● From a method inside the class, with the $this operator

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:

you can only access public properties and methods.

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;

public function __construct(int $bookId) {


$this->bookId = $bookId;
$this->title = "no title set";
$this->authors = "no authors set";
$this->publishDate = time();
}
}

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.

Trying to do so will result in a fatal error:

$bookId = 5;
$myBook = new Book($bookId);

echo $myBook->title; // Output: "no title set"

echo $myBook->bookId;
// Fatal error: Cannot access private property Book::$bookId
22

The same applies to methods.

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 ->

When to use public and when private?


The properties and methods of a class can serve two different purposes:

● 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.

Let’s take an example.

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.

So, we make this new method private.

Like this:
23

private function updateDbTitle() {


global $pdo;
$query = 'UPDATE books SET title = ? WHERE id = ?';
$values = [$this->title, $this->bookId];
$stmt = $pdo->prepare($query);
$stmt->execute($values);
}

public function setTitle(string $title) {


$valid = $this->isTitleValid($title);

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.

The same logic applies to the $title property.

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().

Therefore, the $title property too must be private:


24

class Book {

private $bookId;
private $title;
// etc...
}

Getters and setters.


Most of the time, you want all class properties to be private.

Think about $title.


You do not want developers to assign any kind of value to it. Instead, you want them to
use the dedicated setTitle() method, so that proper validation can be done and all the
required steps are performed (such as the database update).

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.

So, what do we do?

In object-oriented programming this problem is solved by implementing methods called


getters and setters.
25

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.

The getTitle() method is a perfect getter example:

class Book {

private $bookId;
private $title;

// Getter method for $title


public function getTitle() {
return $this->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

What does “Inheritance” mean?


You created the Book class that lets you represent books and perform operations on
them.

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:

● physical books can be “shelved”, but ebooks cannot;


● you can number the panels in a comic book, but not in other types of books;
● you can copy a picture from an illustrated book, but not from books that have no
pictures
● and so on

So, how do you represent all these different types of books in your app?

Option #1: Use different classes?


The simplest solution is to have different classes for different book types. A
PhysicalBook class, an Ebook class, a ComicBook class, and so on.

This solution, however, creates a lot of duplicated code because many functionalities
28

are still common to all types of books.

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;

public function getTitle() {


return $this->title;
}
}

class Ebook {

public $bookId;
public $title;

public function getTitle() {


return $this->title;
}
}

Option #2: Put everything in the same class?


Another solution is to implement all possible features in your Book class with
properties and methods, and include an additional $type property that specifies the
book type.
Depending on the book type, some properties will not be set and some methods will do
nothing.

For example:
29

class Book {

private $bookId;
private $pages;
private $words;
private $type;

public function __construct(int $bookId, string $type) {


$this->bookId = $bookId;
$this->type = $type;
}

public function getLength() {


if ($this->type == 'ebook') {
return $this->words;
}
else {
return $this->pages;
}
}
}

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.

The getLength() method returns the book length.


However, length is different for physical books and ebooks (for physical books it’s the
number of pages, for ebooks it’s the number of words).

Therefore, getLength() needs to check $type and either return the $words value or the
$pages value depending on the book type.
30

This solution has several problems:

● You must pass the book “type” to the Constructor.

● 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.

The solution: inheritance.


Inheritance provides the best solution.

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.

Let’s keep this class simple for the sake of clarity.

For example:
31

class Book {

private $bookId;
private $title;
private $authors;

public function __construct(int $bookId) {


$this->bookId = $bookId;
$this->title = "no title set";
$this->authors = "no authors set";
}

public function setTitle(string $title) {


$this->title = $title;
}

public function getTitle() {


return $this->title;
}

// 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

Here’s how this works in practice:

class ComicBook extends Book {

private $balloonFont;

public function setBalloonFont(string $font) {


$this->balloonFont = $font;
}

public function getBalloonFont() {


return $this->balloonFont;
}
}

$bookId = 1;
$myComicBook = new ComicBook($bookId);
echo $myComicBook->getTitle();

$myComicBook->setBalloonFont('Comic Sans');
echo $myComicBook->getBalloonFont();

Let’s see what happens here.

The PHP extends keyword makes ComicBook inherit from Book.

When this happens, the ComicBook class gets all the public and protected methods
from the Book class.

(You’ll see what protected means in a minute).

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.

Public, protected and private: how they work with


inheritance.
Class properties and methods have a visibility attribute.

Visibility affects from where the property or the method can be accessed.

Public properties and methods can be accessed from anywhere.

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.

Here’s a recap table:

Access from Access from the Access from child


objects using -> class methods classes methods

PUBLIC YES YES YES

PROTECTED NO YES YES

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.

Let’s take an example.

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.

Let’s see how it works.

Here’s a simplified version of the base Book class:

class Book {

protected $title;

public function setTitle(string $title) {


$this->title = $title;
}

public function getTitle() {


return $this->title;
}
}
35

And here’s the child ComicBook class overriding the getTitle() method:

class ComicBook extends Book {

private $seriesTitle;

public function setSeriesTitle(string $title) {


$this->seriesTitle = $title;
}

public function getTitle() {


return $this->title . ' (Series: ' . $this->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:

$myBook = new Book();


$myBook->setTitle('Book title');

// This prints: "Book title"


echo $myBook->getTitle();

But if you call getTitle() from a ComicBook object, then the ComicBook’s method is
called instead:
36

$myComicBook = new ComicBook();


$myComicBook->setTitle('Comic book title');
$myComicBook->setSeriesTitle('Series title');

// This prints: "Comic book title (Series: Series title)"


echo $myComicBook->getTitle();

Note how we used the protected visibility for the $title property.

protected means that:

● 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.

In our previous examples, $title used to be private.


However, a child class cannot access the private properties of the parent class. If $title
was private, the ComicBook getTitle() method couldn’t have had access to it.

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 parent:: keyword.


Let’s go back to our previous example about method overriding, and let’s say that we
want to override the setTitle() method too.

The new ComicBook setTitle() method should do everything that the Book method does,
and on top of that echo a “done” message.

This is the Book setTitle() method:


37

public function setTitle(string $title) {


$valid = $this->isTitleValid($title);

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.

Here's how it works:


38

class ComicBook extends Book {

// Other properties and methods…

public function setTitle(string $title) {

parent::setTitle($title); // Call the Book's setTitle() method


echo "done!";
}
}

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.

Let's go back again to our library app.

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

The way to do that is to declare the Book class as abstract.

You can not create an object of an abstract class.

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:

abstract class Book {

// properties and methods...


}

class ComicBook extends Book {

// properties and methods...


}

Now you can create objects of the ComicBook class, but you cannot create objects of
the Book class because it is declared as abstract.

Trying to create a Book object will result in a fatal error:

// OK
$myComicBook = new ComicBook();

// Fatal error: Uncaught Error: Cannot instantiate abstract class Book


$myBook = new Book();
40

Chapter 4

Static Properties and


Methods
41

The static keyword.


A class object represents a specific instance of that class.

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.

The way to do that is by defining a static method.

Static methods are defined with the static keyword, and you can call them without
creating a class object first.

Let’s see how they work.


42

Static methods.
Here’s how to define a static method in the Book class:

class Book {

public static function bookFromTitle(string $title) {


$id = NULL;
// search the book by its title on the database...
return $id;
}
}

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:

$title = 'The Two Towers';


$id = Book::bookFromTitle($title);
43

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 {

private static $langs = [


'English',
'French',
'Chinese'
// more languages here...
];

//...
}

$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

The self:: keyword.


In the last example, the $langs static property is defined as private.

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:

public static function availableLanguages() {


return self::$langs;
}
45

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.

Make sure to add my address (alex@alexwebdevelop.com) to your Contacts to make


sure my emails will reach your inbox.

If you are looking for more OOP tutorials, you can start from the following:

● PHP Inheritance: How to Inherit Classes in PHP


● PHP Abstract Classes Explained
● PHP Constructors Explained
● PHP Interfaces Explained
● PHP Traits Explained
47

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.

● PHP SECURITY MASTERY


Make Your PHP Apps Secure From Attacks.

You are welcome to share this guide with everyone.


If you do so, make sure to link my website too (alexwebdevelop.com).

See you in the weekly newsletter,

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.

You might also like