We've all got secrets, haven't we? Mine is that I've stolen countless red pandas from Cardiff Zoo. I've got them all stashed away in my basement, where I'm training them for a third world war. Actually, just pretend you didn't hear all that.
If you've got something that you don't want people messing with, you're going to want to keep it private. Some things are meant to be shared, and will be publicly available. Sometimes, you're willing to share your secrets, but you'll want to protect them so that they can't damage you.
Your code is no different. Others may want to use your class, and that's just fine, but you don't want them fiddling with things that might break its functionality. We can help others to use our code in a sensible manner by defining scope on our methods and properties.
Public
Up until now, we've been using var
to declare class properties, and only function
to create our class methods. Declaring variables in this way makes them public.
A public property can be accessed from outside a class instance by using the object ->
operator. For example:
<?php
$panda = new Panda;
echo $panda->name;
Public methods can be called on an instance using the object ->
operator once more.
<?php
$panda = new Panda;
echo $panda->squeak();
Since our properties and methods so far have been public, why don't we start indicating their scope with a more descriptive keyword?
The truth is, most programmers won't use var
to declare their class properties. Instead, it's better to use the public
keyword. Let's take a look at an example, shall we?
<?php
class Panda
{
public $coat = 'fluffy';
}
This is how you're going to declare your public class properties from now on, isn't it? Go on, promise me! It's just a better way of doing it!
How about those public methods? Well we can apply the public
keyword to those too, and you definitely should. Let's take a look at a quick example.
<?php
class Panda
{
public $coat = 'fluffy';
public function getCoat()
{
return $this->coat;
}
}
We've put the keyword public
just before the keyword function
. It won't make any difference, but it's now clearer that the function is a public one.
So we haven't really learned any new tricks in this section, have we? At least we found a way to make our code more descriptive. Don't worry! In the next section we'll be learning something new. I promise!
Private
In the previous section, we used the public
keyword to mark our class properties and methods as public. Let's try marking a class property as private
instead, shall we?
We'll start by modifying our previous example.
<?php
class Panda
{
// Declare a private property...
private $coat = 'fluffy';
// ... and a public method.
public function getCoat()
{
return $this->coat;
}
}
In the above example, you'll notice that the $coat
property has now been marked as private by using the private
keyword. For now, we'll leave the getCoat()
method as public.
Let's try to play with that private $coat
property. We'll just try to echo it out.
<?php
// Create a new panda.
$panda = new Panda;
// Try to echo the coat property.
echo $panda->coat;
What do you think will happen when we execute the above piece of code? Well let's find out already!
Fatal error: Cannot access private property Panda::$coat
Because our property is now marked as private
, we can't access it from outside the class. We'll receive a fatal error if we decide to do so. We've protected that $coat
property from our grubby little hands!
You can't set the property either! Let's give it a go.
<?php
// Create a new panda.
$panda = new Panda;
// Try to set the coat property.
$panda->coat = 'slimey';
Let's execute the code once again.
Fatal error: Cannot access private property Panda::$coat
We receive the same error message as when we tried to retrieve the value of the property.
Let's try accessing that public method. I'll attach the class to the example once again to refresh your memory.
<?php
class Panda
{
// Declare a private property...
private $coat = 'fluffy';
// ... and a public method.
public function getCoat()
{
return $this->coat;
}
}
// Create a new panda.
$panda = new Panda;
// Try to echo the coat property.
echo $panda->getCoat();
The method is public, so when we try to call it, we receive the following result.
fluffy
If the $coat
property is private, then how is the getCoat()
method able to access it? Well you see, the scope of a method or property, only applies to retrieving, setting, or calling it from outside of the class. Class methods have access to all of the other properties and other methods, regardless of the scope.
Let's change the getCoat()
method to private
.
<?php
class Panda
{
// Declare a private property...
private $coat = 'fluffy';
// ... and a private method.
private function getCoat()
{
return $this->coat;
}
}
// Create a new panda.
$panda = new Panda;
// Try to echo the coat property.
echo $panda->getCoat();
Let's execute the code once more.
Fatal error: Call to private method Panda::getCoat()
Since our method has now been given private
scope, we are unable to call it on our method instance.
Let's add a public method alongside our private one.
<?php
class Panda
{
// Declare a private property...
private $coat = 'fluffy';
// ... and a private method...
private function getCoat()
{
return $this->coat;
}
// ... and a public one.
public function noReallyGetCoat()
{
return $this->getCoat();
}
}
// Create a new panda.
$panda = new Panda;
// Try to echo the coat property.
echo $panda->noReallyGetCoat();
We've added a new method called noReallyGetCoat()
, which makes an internal call to the getCoat()
method. Let's see what happens when that method is executed.
fluffy
As we discovered earlier, scope does not affect internal calls to methods, or accessing properties from within the class. For this reason, the public noReallyGetCoat()
method is able to make a call to the private getCoat()
method.
You can make a class constructor private, but then you won't be able to instantiate it. This might be useful later when you learn more about the
static
keyword.
Protected
Protected properties are a little different. From the outset they look to function exactly like properties within the private
scope. If you were to try and access them directly, you would be unable to.
So why do we have two types of scope that are the same? Well, this is one of those sithations where being an author is really difficult. I'd like to teach you about the protected scope now, however, it's hugely related to a future chapter on abstract classes. Difficult, right? Let's instead share a light overview of protected, and we'll examine it in detail later.
In a later chapter, you'll learn about abstract
classes. Ones which can be extended by other classes so that they can share common functionality. If you have a private
property or method on the abstract class or "base class" (the base template), then any classes that extend the class are unable to modify the methods or properties directly. However, if you were to instead define these methods and properties as protected
, then you'd be able to overwrite their purpose within your extending classes.
Does this sound complicated? Don't worry! It will become much clearer in the Abstract chapter which will arrive later.
Static
There's another scope for variables and methods called static
, but this one is a little more complicated, and is best saved for an entire chapter of its own.
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!