PHP Pandas: Classes

← Back to Index

Well, now we're really cooking with fire. We get to learn about classes!

Classes give our applications structure. They allow for object-oriented programming. You've probably heard of that term before? It means treating our code as objects, bringing familiarity to how we use objects in the real world. Let's stick with the baby steps, though, shall we?

First Class

So how do we create a class? Let's take a look at some code. First we're going to need a purpose for our class. Let's get started with object-oriented programming, and create a class that will represent a book. We'll call the class Book.

<?php

class Book
{

}

The syntax for a class, is fairly similar to that of a function. You may have already spotted the block surrounded by { curly } braces. On the first line we have the keyword class and then the name of the class that we want to create.

It's good practice to name your classes with an uppercase letter at the beginning. It's also good practice to have a separate file for your class, with a similar file name. For example, the class above would be contained in a file called Book.php.

For the purpose of simplifying the examples of the book. I'll be keeping classes in the same file for now.

We can't really do much with the class as it stands, let's give it some properties. Properties are used to store data within the class. For our book, they'll be used to further describe the book.

Let's think about the properties of a book for a moment. I can think of several.

  • Title.
  • Author.
  • Publisher.
  • Year of publishing.

Let's reflect these properties on our Book class. Here goes nothing!

<?php

class Book
{
    var $title;

    var $author;

    var $publisher;

    var $yearOfPublication;
}

Variables that belong to a class, are called 'class properties'. For now, we'll use the var keyword, along with the typical variable notation to define our class properties. Don't worry about the var keyword too much, we'll take a look at some alternatives later.

We're now ready to start working with our class.

Instances

The class that we've defined, is actually a blueprint. We can use it to make a new instance of a Book object. The key word there is new. An instance, is a class that we can use. We can have multiple instances of the same class. It's something that's really hard to explain in text, so let's look at a code sample.

<?php

class Book
{
    var $title;

    var $author;

    var $publisher;

    var $yearOfPublication;
}

$book = new Book;

We create a new instance of the Book class, and assign it to the $book variable. We do this using the new keyword, and then the class name that we wish to instantiate. Now that we have an instance of class, we can play with its properties. Let's start by setting the properties for our book.

<?php

// Define the Book class.
class Book
{
    // Declare properties.
    var $title;
    var $author;
    var $publisher;
    var $yearOfPublication;
}

// Create a new book instance.
$book = new Book;

// Set properties.
$book->title                = 'Game of Thrones';
$book->author               = 'George R R Martin';
$book->publisher            = 'Voyager Books';
$book->yearOfPublication    = 1996;

You can set the properties of a class instance by using the object -> operator, which consists of a dash - followed by a greater-than > symbol. Next, you specify the name of the property that you wish to access.

In the above example, we use the assignment = operator to set the class properties of our instance. We can also retrieve them using the object operator. Let's echo each of our class properties, appended with a newline character.

<?php

// Define the Book class.
class Book
{
    // Declare properties.
    var $title;
    var $author;
    var $publisher;
    var $yearOfPublication;
}

// Create a new book instance.
$book = new Book;

// Set properties.
$book->title                = 'Game of Thrones';
$book->author               = 'George R R Martin';
$book->publisher            = 'Voyager Books';
$book->yearOfPublication    = 1996;

// Echo properties.
echo $book->title               . PHP_EOL;
echo $book->author              . PHP_EOL;
echo $book->publisher           . PHP_EOL;
echo $book->yearOfPublication   . PHP_EOL;

We once again use the object -> operator to echo the properties of the book instance. Executing our code yields the following output.

Game of Thrones
George R R Martin
Voyager Books
1996

Earlier, I mentioned that we can have multiple instances of classes, so lets define two books, each with different properties. I'm going to omit the class declaration for now, just to simplify the examples.

<?php

// Define the Book class.
class Book
{
    // Declare properties.
    var $title;
    var $author;
    var $publisher;
    var $yearOfPublication;
}
// Book class definition would be here.

// Create a new book instance.
$first = new Book;

// Set properties.
$first->title                = 'Game of Thrones';
$first->author               = 'George R R Martin';
$first->publisher            = 'Voyager Books';
$first->yearOfPublication    = 1996;

// Create another book instance.
$second = new Book;

// Set properties.
$second->title                = 'The Colour Of Magic';
$second->author               = 'Terry Pratchett';
$second->publisher            = 'Colin Smythe';
$second->yearOfPublication    = 1983;

In the above example, we've created two book instances. They both have their own unique set of properties. They are individuals. What we've done, is created a complex storage mechanism for information. Right now, our classes don't have a huge advantage over using an array to store this information. Why don't we unlock some other secrets that classes have to offer?

Default Values

Our classes are blueprints for new instances of objects. Sometimes, the values that we expose may have defaults. For example, the majority of books will be in a paperback format. However, rarely, you may need to mark a book as hardback format.

Let's add a format property to our book class. We can save time for ourselves by giving the class property a default value of 'Paperback'. Let's examine the following code snippet.

<?php

// Define the Book class.
class Book
{
    // Declare properties.
    var $title;
    var $author;
    var $publisher;
    var $yearOfPublication;
    var $format = 'Paperback';
}

We've assigned a default value to the $format property, by providing an assignment operator, followed by the default value. This line ends with a semicolon. Let's check to make sure that our $format property is set by default. We can do this by creating a new instance of a Book, and echoing the value stored in $format.

<?php

// Define the Book class.
class Book
{
    // Declare properties.
    var $title;
    var $author;
    var $publisher;
    var $yearOfPublication;
    var $format = 'Paperback';
}

// Create a new book instance.
$book = new Book;

// Echo the default value.
echo $book->format;

We've simply instantiated the book, and echoed the value. What response to we receive?

Paperback

Just as expected! Of course, we're free to change this value if we please. It's simply a default to help simplify the process of creating books.

<?php

// Define the Book class.
class Book
{
    // Declare properties.
    var $title;
    var $author;
    var $publisher;
    var $yearOfPublication;
    var $format = 'Paperback';
}

// Create a new book instance.
$book = new Book;

// Change the value of format.
$book->format = 'Hardback';

// Echo the value of format.
echo $book->format;

If we execute our code once more, we'll receive the following value.

Hardback

Great! You can set your default values to all scalar types including strings, ints, floats and even arrays with multiple values, both associative and indexed. There's one catch though, remember, there's always a little catch. When defining your default values, you can't set them to the results of functions. This is illegal. The PHP police will come and take you away if you try to do so.

It means that the following would not be possible.

<?php

// Create a book class.
class Book
{
    var $bar = strtoupper('foo');
}

Note that the strtoupper() function is an in-built PHP function to transform strings to their uppercase variants. So foo would become FOO. However, in this context, setting the defaults for a class property, it will result in a syntax error.

There's methods to the madness.

It's time to start using methods. Methods are what we call functions that belong to classes. Let's examine these wording differences one more, shall we?

| General       |  Class                    |
|-------------------------------------------|
| Variable      | Property / Attribute      |
| Function      | Method                    |

When you're looking for help, knowing the distinction between a function and a method will make it much more simple to communicate with other developers. It's worth taking the time now to learn these names.

How do we define a method on our class? Well it's simple. In fact, you already know the format! Let's create a simple function to say hello.

<?php

// Define the Book class.
class Book
{
    // Declare properties.
    var $title;
    var $author;
    var $publisher;

    // Declare a method.
    function sayHello()
    {
        return 'Hello!';
    }
}

// Create a new book instance.
$book = new Book;

// Change the value of format.
$book->format = 'Hardback';

// Execute the hello method.
echo $book->sayHello();

Once again, we use the function keyword to define a new function. The format is exactly the same to that which we learned in the previous chapter, except that the function now sits within the curly { braces } of our class.

We can execute our class function using the object -> operator that we used to retrieve and set our class properties. We need to add the rounded ( brackets ) to the end of our method name, just as we did with functions.

For example:

<?php

echo $book->sayHello();

We receive a friendly response from our class.

Hello!

Great! We can include as many methods as we like within our class structures, so go ahead and make a few more methods to learn the syntax.

Can't touch $this

Okay, you actually can touch $this. In fact, you're going to need to.

When writing functions for your classes, you're likely going to want to access your class properties, or even call other class methods. You can do this by using the $this property.

The $this property is a shortcut to reference the current class instance. You can use it to access class properties and other methods from within a class method. Let's take a look at this in action.

<?php

// Define the Book class.
class Book
{
    // Declare properties.
    var $title;
    var $author;
    var $publisher;

    // Declare a method.
    function summary()
    {
        echo 'Title: '      . $this->title        . PHP_EOL;
        echo 'Author: '     . $this->author       . PHP_EOL;
        echo 'Publisher: '  . $this->publisher    . PHP_EOL;
    }
}

// Create a new book instance.
$book = new Book;

// Set class properties.
$book->title        = 'Reaper Man';
$book->author       = 'Terry Pratchett';
$book->publisher    = 'Victor Gollancz';

// Output a book summary.
$book->summary();

That's a big chunk of code, isn't it? Let's break it up a little. First we'll take a look at the summary() method.

<?php

// Declare a method.
function summary()
{
    echo 'Title: '      . $this->title        . PHP_EOL;
    echo 'Author: '     . $this->author       . PHP_EOL;
    echo 'Publisher: '  . $this->publisher    . PHP_EOL;
}

Within the summary method, we output a string label for each field. Next, we concatenate the field value, by using $this to refer to the current instance, and then the object -> operator, and finally the property. Finally, we append a PHP newline character for clarity.

<?php

// Create a new book instance.
$book = new Book;

// Set class properties.
$book->title        = 'Reaper Man';
$book->author       = 'Terry Pratchett';
$book->publisher    = 'Victor Gollancz';

// Output a book summary.
$book->summary();

Next, we create a new Book instance, and populate the fields present. Finally, the summary() method is called on the instance. Let's take a look at the output that we receive from executing this code.

Title: Reaper Man
Author: Terry Pratchett
Publisher: Victor Gollancz

We receive a clean representation of our book. As you can see, the properties were accessed correctly using the $this property.

We can also use $this to call instance methods. Let's take a look at an example, shall we?

<?php

// Define the Example class.
class Example
{
    // First function.
    function first()
    {
        return $this->second();
    }

    // Second function.
    function second()
    {
        return $this->third();
    }

    // Third function.
    function third()
    {
        return "Well that was rather pointless, wasn't it?";
    }
}

Here, we can see a chain of methods.

  • The first() method uses $this to return the value of the second() method.
  • The second() method uses $this to return the value of the third() method.
  • Finally, the third() method returns a string value.

It's not a very practical example in the real world, but it does help to illustrate that function and method calls can be nested in a nearly endless fashion.

Nearly endless, within limitations of memory, and the depth of the PHP call stack. It's quite a large number by default though, you normally won't run into any problems unless you make a mistake with a loop.

Constructors

Constructors are special methods. They are called automatically when you create a new instance of the class. This gives you a great opportunity to set your class properties to values that you might otherwise be unable to set. For example, the results of a function or method.

To define a constructor, we need only create a method with the name __construct(). It's worth noting that there are two _ underscores at the beginning of the function name. Unfortunately, while PHP is an extremely flexible language, it often falls short when it comes to descriptive or convenient function names, and __construct() is no exception. Don't worry! It will soon become second nature.

<?php

// Define the Panda class.
class Panda
{
    // LOUD NAME PROPERTY
    var $loudName;

    // Contructor method.
    function __construct()
    {
        $this->loudName = $this->makeNameLoud('Lushui');
    }

    // NAME LOUDENING METHOD
    function makeNameLoud($name)
    {
        return strtoupper($name);
    }
}

Here, we have a class with a method called makeNameLoud(), which performs a case transformation on a string. We've already discovered that we can't set default values for class properties using functions or methods directly, so instead, we use the __construct() method to set the initial value.

How can we check if the constructor has been executed on instantiation? Oh that's right, we just need to check the $loudName property! Let's try it out!

<?php

// Create a new class instance.
$panda = new Panda;

// Output loud name.
echo $panda->loudName;

We instantiate the Panda class, and echo the value of the loudName property. Let's check the value that we receive.

LUSHUI

Ouch, that's a loud panda for sure. Since the name is in uppercase, it's clear that our class constructor has been executed.

Let's try to make that constructor a little more dynamic. Constructors are methods, and so they take parameters. Let's give the constructor a $name parameter to be able to set the loud name of a panda upon instantiation. Here's how our class looks.

<?php

// Define the Panda class.
class Panda
{
    // LOUD NAME PROPERTY
    var $loudName;

    // Contructor method.
    function __construct($name)
    {
        $this->loudName = $this->makeNameLoud($name);
    }

    // NAME LOUDENING METHOD
    function makeNameLoud($name)
    {
        return strtoupper($name);
    }
}

All that we've changed in the above example, is the addition of a $name parameter in the constructor, which is passed to the makeNameLoud() method. Let's take a look at the new usage of this class, shall we?

<?php

// Create a new class instance.
$panda = new Panda('Lushui');

// Output loud name.
echo $panda->loudName . PHP_EOL;

// Create a new class instance.
$secondPanda = new Panda('Pali');

// Output loud name.
echo $secondPanda->loudName;

In the above example, we instantiate two different instances of the Panda class. When we instantiate the class, we pass a string for the panda name into a pair of rounded ( brackets ) just as we would using a normal function.

We echo the values for loudName for each of the panda instances and receive...

LUSHUI
PALI

...in response.

You can even keep the brackets if you aren't providing a parameter. For example, for a class with no parameters to its constructor, then the following is perfectly legal.

<?php

$panda = new Panda();

However, I personally like to leave them out to increase clarity. It's up to you!

Note that since a constructor is called during the instantiation of a new object, it's a bad idea to use a return statement within. In fact, if you try it, PHP will shout at you. Actually, if you try it, I'll shout at you, and I'm generally a nice guy.

My books are available online for free to encourage learning. However, if you'd like for me to keep writing, then please consider buying a digital copy over at Leanpub.com.

It's available in PDF, ePub, and Kindle format, and contains a bunch of extras that you won't find on the site. I have a full-time job, and I write my books in my spare time. Please consider buying a copy so that I can continue to write new books from the comfort of my sofa!