The problem with public variables is that they allow functions to be called and variables to set from anywhere within your script, which is generally not a smart thing. Think back to before - we had a dogtag object $DogTag inside each dog object as well as a $Name variable, but they had repeated information inside.

If we had changed the $Name variable, would $DogTag have been updated automatically? Of course not - it would have remained the same, which was different to the new $Name value:

$poppy = new poodle; $poppy->Name = "Poppy"; $poppy->DogTag = new dogtag; $poppy->DogTag->Words = "My name is
Poppy. If you find me, please call 555-1234"; $poppy->Name = "Penny";
print $poppy->DogTag->Words;

If you try that, you will see the problem. This has arisen because we have allowed any part of our script to directly access the internals of our dog objects. Here is one solution:

class dog {
    public $Name;
    public $DogTag;

    public function setName($NewName) {
        $Name = $NewName;
        $DogTag->Words = "My name is $NewName. If you find me, please call 555-1234";

This time the dog object has embedded logic in that knows how to handle a renaming properly. As long as people use the setName() function, the dog's name and its dog tag will get updated with just one call.

Given the above script, however, it is still possible for some unscrupulous, lazy, or ignorant programmer to write $poppy->Name = "Rover", thereby not using the special setName() function we've provided. This is where private variables come in - we can instruct PHP that the variable $Name is private, and can therefore only be changed with the class its part of. Here is the new code:

class dog {
    private $Name;
    private $DogTag;

    public function setName($NewName) {

Note that both $Name and $DogTag are private, which means no one can access them unless doing so in a function that is part of the object, such as setName(). Note that setName() itself remains public - we want this to be accessible by anyone.

Now if our lazy programmer comes along and tries to set $Name directly using code like $poppy->Name, they will not get what they were expecting. You see, if they try to alter a private variable directly PHP will automatically spit out an error message. However, if that private variable was inherited from another class, PHP will try to accommodate their request by having a private variable and a public variable. Yes, this is somewhat confusing, however the following code should clear things up:

    class dog {
        private $Name;

    class poodle extends dog { }

    $poppy = new poodle;
    $poppy->Name = "Poppy";

Running that script will output the following:

poodle Object
[Name:private] =>
[Name] => Poppy

Notice that there are two Name variables - one that is private and cannot be touched, and another that PHP creates for local use as requested. Clearly this is confusing, and you should try to avoid this situation if possible.

Note that private functions and variables can only be accessed by the exact class that owns them - child classes cannot access private parent functions variables. To do this, you need the protected keyword instead.


Want to learn PHP 7?

Hacking with PHP has been fully updated for PHP 7, and is now available as a downloadable PDF. Get over 1200 pages of hands-on PHP learning today!

If this was helpful, please take a moment to tell others about Hacking with PHP by tweeting about it!

Next chapter: Protected >>

Previous chapter: Public

Jump to:


Home: Table of Contents

Copyright ©2015 Paul Hudson. Follow me: @twostraws.