Understanding scope in PHP classes
So far, we’ve just dealt with the public
scope, which is the default scope visibility in PHP. However, two others scope visibilities exist, named private
and protected
.
Let’s say we wanted to protect the author name so its value cannot be changed outside of the context of this PHP class.
If we go back to functions.php
, and after this $author1
assignment, let’s assign a new value to the name property, for example Steve Jobs.
$author1 = new Author('Mark Shust'); $author1->name = 'Steve Jobs';
If you refresh the page, you’ll see that Steve is now replacing me! I don’t ever want this to happen, because over time I may have a lot of code floating around, and it’ll be impossible to predict which PHP classes change or modify other PHP class properties. So, we can add a restriction to any class property that makes sure this can’t be done.
Let’s change our class property scope to private
. This completely changes the visibility of this class so it cannot be accessed outside of the scope of this class.
If we refresh our page, we will get an error that tells us that it cannot access this class property. This is exactly what we want! Let’s check our functions.php
file again, and of course, PHPStorm is also telling us this.
Let’s remove this assignment of Steve Jobs. But you’ll notice that this updated scope visibility also affected the output of these class properties. This is because this class property is now completely private!
Since we now have no way to retrieve the $name
property, we need to create a new class method with a public
visibility, which retrieves the value of this class property.
Let’s create a new public function
named getName
:
<?php declare(strict_types=1); class Author { public function __construct( public string $name ) {} public function getName(): string { return $this->name; } }
We will be sure to define a return type of string
to keep our code predictable. The call to $this->name
refers to the $name
class property we are creating within the constructor. This function is simple — it just returns that value. This means that we can now access the name
property from outside of this class.
We can now assign update the author
values of the posts array to call getName()
rather than the direct property reference, since this is no longer an option.
<?php declare(strict_types=1); require('classes/Author.php'); function getPosts(): array { $author1 = new Author('Mark Shust'); $author2 = new Author('Betsy Sue'); return [ [ 'title' => 'How to learn PHP', 'content' => 'This is how you learn PHP.', 'author' => $author1->getName(), ], [ 'title' => 'How to learn MySQL', 'content' => 'This is how you learn MySQL.', 'author' => $author1->getName(), ], [ 'title' => 'How to learn Nginx', 'content' => 'This is how you learn Nginx.', 'author' => $author2->getName(), ], ]; } function getPostText(int $numPosts): string { return $numPosts === 1 ? 'post' : 'posts'; }
When we refresh the page, we can see that we can now once again access this name
class property.
Scope essentially locks down how class properties are accessed outside of the context of a class. We won’t go into the protected
property scope, but know that it is a slightly more open scope & visibility than private
, as it lets classes of classes access class properties. private
locks it down so only direct instances of a class can access the property.