Lesson 10 - Static class members in PHP pt. 2 - constants
In the previous tutorial, Static class members in PHP, we introduced you all to static members and went over how to use them. In today's lesson, we will stick to the same topic and go deeper into detail with static members.
Password validation
Let's keep on working on our previous example. Imagine that our people had to be registered in an informational system. Other than their name, they would also need a password. Before creating a Human instance, we would have to validate the password that had been entered, to make sure it's not too short.
The password length validation method logically belongs to the Human class. However, at the moment that we would need to validate the password (most likely when a form is submitted), we wouldn't have a Human instance. However, in order to create a Human instance, we would need to know his/her first and last name, age and password (as these are required in the Human class' constructor). However, in order to call the password validation method, we need a Human instance. We'll work around this issue by making the password validation method static. This way, we will be able to call it without having to create an instance while still having it in the Human class, where it belongs.
This particular validation approach is simple, ideally, we'd have to make sure the password doesn't contain accent characters, etc. We will add a $password instance variable to the Human class. Hopefully, you understand why the $password variable is private.
private $password;
Now, modify the constructor so that users can only be created when a password is entered:
public function __construct($firstName, $lastName, $age, $password) { $this->firstName = $firstName; $this->lastName = $lastName; $this->age = $age; self::$peopleCount++; $this->id = self::$peopleCount; $this->password = $password; }
Modify PhpProgrammer's constructor from the previous lessons in a similar way because we will need it later on.
The password would also have to be hashed somehow, to keep it simple, though, we'll put that sort of thing off to the side for the next couple of courses. Now, let's add the public static validPassword() method:
public static function validPassword($password) { return (mb_strlen($password) >= 5); }
The method returns true when the password length is greater than 5 characters, otherwise, it returns false. Other than the use of mb_strlen(), there really is nothing particularly interesting about this method. As you may know, mb_strlen() supports UTF-8, unlike its outdated relative strlen(). In other words, in order to be able to use it, we'll have to set the encoding in our document. Let's add it somewhere at the very beginning:
mb_internal_encoding("UTF-8");
For more information, refer to the official PHP manual.
Now let's get our user registration going in the main document:
{PHP} require_once('classes/Human.php'); require_once('classes/PhpProgrammer.php'); mb_internal_encoding("UTF-8"); $password = 'passwordissword'; if (Human::validPassword($password)) { $human = new Human('John', 'Smith', 32, $password); echo("Password OK"); } else echo('Password must be at least 5 characters long');
{PHP} class Human { public $firstName; public $lastName; public $age; private $tiredness = 0; public $id; private static $peopleCount = 0; private $password; public function __construct($firstName, $lastName, $age, $password) { $this->firstName = $firstName; $this->lastName = $lastName; $this->age = $age; self::$peopleCount++; $this->id = self::$peopleCount; $this->password = $password; } public function sleep($time) { $this->tiredness -= $time * 10; if ($this->tiredness < 0) $this->tiredness = 0; } public function run($distance) { if ($this->tiredness + $distance <= 20) $this->tiredness += $distance; else echo("I'm too tired."); } public function greet() { echo('Hi, my name is ' . $this->firstName); } protected function fullName() { return $this->firstName . ' ' . $this->lastName; } public function __toString() { return $this->firstName . ' - ' . $this->id; } public static function validPassword($password) { return (mb_strlen($password) >= 5); } }
{PHP} class PhpProgrammer extends Human { public $ide; public function __construct($firstName, $lastName, $age, $password, $ide) { $this->ide = $ide; parent::__construct($firstName, $lastName, $age, password); } public function greet() { echo("Hello world! I'm $this->firstName"); } public function program() { echo("I'm programming in {$this->ide}..."); } }
We can call the validation method without even having to create an instance, which is really handy in this case.
Constants
Constants are a type of static class members. As you already know from math classes, constants are unchangeable values. Constants are always static, i.e. they don't require the static modifier. We declare them using the "const" keyword, so they always belong to a certain class. We name them in UPPER_CASE and use underscores instead of spaces. Also, it's best to declare them at the very beginning of a class, even before properties.
Constant Pi
Let's add the constant Pi to our Math.php class that we made in the previous lesson:
const PI = 3.14159265358979;
Now, let's go ahead and use it in index.php:
{PHP} require_once("classes/Math.php"); $radius = 5; $area = Math::PI * Math::square($radius); echo("Circle area is $area cm<sup>2</sup>.");
{PHP} class Math { const PI = 3.14159265358979; public static function square($base) { return $base * $base; } }
The result:
Minimum password length constant
Constants come in handy for storing things like minimum password lengths and whatnot. If we ever decide to change it, or wanted to use it somewhere else, we would be able to because it is static and only defined once. Now let's add the PASSWORD_LENGTH constant into our Human.php class, with its value set to 5:
const MIN_PASSWORD_LENGTH = 5;
Now, replace the 5 in the validPassword() method with the constant we just defined. Since it is a static class member, the only way to access it from inside the class is using the "self" keyword:
public static function validPassword($password) { return (mb_strlen($password) >= self::MIN_PASSWORD_LENGTH); }
Now the program works as it did before. Constants are accessible from outside of the class as well:
echo('Welcome to the user registration page, pick a user name and password of at least ' . Human::MIN_PASSWORD_LENGTH . ' characters');
We use constants every time we define a value that should not change during runtime. Another common use for constants is setting limits, i.e. maximum number of member events:
const MAX_EVENTS = 50;
Enumeration types (ENUM) in PHP
Constants in PHP are also often used to replace enumerated values, which PHP does not support. Although we could make a class that mimicks them, using constants is best in this case, because they are much simpler.
When you have a variable that can only consist of a single value from a specific enumerated list, use constants.
Message type
To get a better feel of what enumerated values are and do, we'll make a short little example program. We will use them when storing a message that generated by our content management system. The message will either be informative (blue with an "i" icon), an error (red with cross icon) or successful (green with tick).
We'll use an associative array to represent the message, where the key is the message type and the value is the message text. Without any knowledge of constants, we'd be forced to use a string to store the message type:
$message = array( 'type' => 'success', 'text' => 'Article has been successfully published', );
Later on, we'll assign a CSS class to each message type, as well as sort them by type. Since we want to assign the right message text simple and clear, we'll make constants enumerated values. Constants are declared at the very beginning of a class (our IDE will even autocomplete them for us).
class MessageManager { const TYPE_INFO = 0; const TYPE_SUCCESS = 1; const TYPE_ERROR = 2; public function addMessage($type, $text) { . . . }
Everything is much clearer now. In the rough draft above, the addMessage() method creates an array with the message, and stores it afterward. I completely left out the inner mechanism to keep the lesson simple. We would then be able to call the addMessage() method like this:
$messageManager = new MessageManager(); $messageManager->addMessage(MessageManager::TYPE_SUCCESS, 'Article has been successfully published');
We'll make a really similar class to this in the MVC object-oriented CMS in PHP course to display user messages. You'll make it there eventually, don't worry
Note: People used to declare constants using the define() function in outdated versions of PHP. However, the constants created using this function did not belong to any class, and completely did away with everything that OOP stands for.
In the next lesson, Static class members in PHP pt. 3 - do's and don'ts, we will keep working with static members and use them to make a static database wrapper and a static registry. We will also go over some more theory about good and bad ways of using static members. Today's lesson code files can be downloaded in the attachment below.
Did you have a problem with anything? Download the sample application below and compare it with your project, you will find the error easily.
Download
By downloading the following file, you agree to the license terms
Downloaded 29x (3.64 kB)
Application includes source codes in language PHP