Lesson Weekend

Lesson Goals:

  • Learn about constructor methods
  • Learn about passing arguments into an object with its constructor
  • Learn to add optional constructor arguments with default values

Intro - what are we going to learn and why?

In this lesson, we're going to learn more about methods, and how we can make our objects easier to use with one kind of method called a constructor.

So, you are the owner of a used car dealership, but you decide you're sick of that and you want to get into the music business. You're going to open an online music store where people can buy CDs from you. So we're going to create a class for a CD in the way that we know how, and then we're going to make it better. First, let's think about what properties a CD would have; a title, an artist, an image for cover art, and a price. We'll declare the class, and instantiate a few CDs to display. Let's put this into a file named Cd.php, and download 3 images and name them to match the paths specified in the $cover_art property.

Cd.php
<?php 

    class CD
    {
        public $title;
        public $artist;
        public $cover_art;
        public $price;
    }

    $first_cd = new CD();
    $first_cd->title = "Master of Reality";
    $first_cd->artist = "Black Sabbath";
    $first_cd->cover_art = "images/reality.jpg";
    $first_cd->price = 10.99;

    $second_cd = new CD();
    $second_cd->title = "Electric Ladyland";
    $second_cd->artist = "Jimi Hendrix";
    $second_cd->cover_art = "images/ladyland.jpg";
    $second_cd->price = 10.99;

    $third_cd = new CD();
    $third_cd->title = "Nevermind";
    $third_cd->artist = "Nirvana";
    $third_cd->cover_art = "images/nevermind.jpg";
    $third_cd->price = 10.99;

    $cds = array($first_cd, $second_cd, $third_cd);
?>
<!DOCTYPE html>
<html>
<head>
    <link rel='stylesheet' href='https://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css'>
    <title>My CD Store</title>
</head>
<body>
    <div class="container">
        <?php 
            foreach ($cds as $album) {
                echo "<div class='row'>
                    <div class='col-md-6'>
                        <img src='$album->cover_art'>
                    </div>
                    <div class='col-md-6'>
                        <p>$album->title</p>
                        <p>By $album->artist</p>
                        <p>$$album->price</p>
                    </div>
                </div>
                ";
            }
        ?>
    </div>
</body>
</html>

Explain code above

Nothing new here. We instantiate 3 CDs and set each property. Then we put the CDs into an array so that we can loop through them in the HTML and display them using some <div>s with bootstrap classes for formatting.

Now we're going to get rid of the extra code devoted to setting properties by writing a method.

If you launch your server and open this in the browser, you can see each album's cover displayed with its title, artist and price. It all works, but it would be nice if we could clean this code up. For example, there are 15 lines of code devoted to creating each object and setting each of its properties. Wouldn't it be nice if we could write a method to do that for us? Add this code to your CD class declaration.

Cd.php
function __construct($album_name, $band_name, $image_path, $album_price)
{
    $this->title = $album_name;
    $this->artist = $band_name;
    $this->cover_art = $image_path;
    $this->price = $album_price;
}

This is a constructor. It uses the keyword __construct, and is run automatically.

This method is called a constructor. It's a normal method, except that by naming it __construct, it is run automatically whenever you instantiate a CD object. Any kind of setup that needs to happen in your object should happen in the constructor. In this case, we are passing the method an argument for each property that we want to set. So now, we can create CDs with all their properties set in only one line of code, instead of 5.

Instantiate the objects using the constructor.

Cd.php
$first_cd = new CD("Master of Reality", "Black Sabbath", "images/reality.jpg", 10.99);
$second_cd = new CD("Electric Ladyland", "Jimi Hendrix", "images/ladyland.jpg", 10.99);
$third_cd = new CD("Nevermind", "Nirvana", "images/nevermind.jpg", 10.99);

How the constructor gets its arguments.

Each argument is automatically passed into the constructor method when the new CD object is instantiated, and we have told the constructor to set each property to one of these arguments. The arguments passed to the constructor are exactly like arguments sent to other methods and functions. The parameters are declared in the __construct method's parentheses using the $ at the beginning, all lowercase, with words separated by underscores. They are passed into the object in a comma separated list inside of the parentheses used next to the class name when we instantiate it using the new keyword.

Setting defaults

Now, we can make this even easier. Notice that the price of each cd is $10.99. Let's say that this is your default price. You may have one or two albums every now and then that are cheaper or more expensive, but if most albums are going to cost the same you don't want to type that price every time you make a new CD object. Let's set a default value for an album's price in its constructor.

Cd.php
function __construct($album_name, $band_name, $image_path, $album_price = 10.99)
{
    $this->title = $album_name;
    $this->artist = $band_name;
    $this->cover_art = $image_path;
    $this->price = $album_price;
}

Now, if a CD is to be sold at the standard price of $10.99, we don't need to include the price as an argument when we instantiate the CD.

Cd.php
$first_cd = new CD("Master of Reality", "Black Sabbath", "images/reality.jpg");
$second_cd = new CD("Electric Ladyland", "Jimi Hendrix", "images/ladyland.jpg");
$third_cd = new CD("Nevermind", "Nirvana", "images/nevermind.jpg");   

If we do want to set a different price, it can be included as an argument and still have instantiation only take one line of code. Let's add one more album: an extremely rare and expensive one! Don't forget to put it in the array after instantiating it too.

Cd.php
$fourth_cd = new CD("I don't get it", "Pork Lion", "images/porklion.jpg", 49.99);
...
$cds = array($first_cd, $second_cd, $third_cd, $fourth_cd);

A constructor method sets up your object.

It is always named __construct.

Its arguments are passed in when the object is instantiated. This can be used to set properties.

You can set default values for the arguments by using an = in the declaration:

class CD
{
    function __construct($album_name, $band_name, $image_path = "images/default.jpg", $album_price = 10.99)
    {
        $this->title = $album_name;
        $this->artist = $band_name;
        $this->cover_art = $image_path;
        $this->price = $album_price;
    } 
}

$cd = new CD("Master of Reality", "Black Sabbath", "images/reality.jpg", 10.99);
$another_cd = new CD("Electric Ladyland", "Jimi Hendrix", "images/ladyland.jpg");
$yet_another_cd = new CD("Funhouse", "The Stooges");