Magic Methods and Predefined Constants in PHP
PHP provides a set of special predefined constants and magic methods to your programs. Unlike the constants you would set using define()
, the value of the constants depend on where they are used in your code and are used to access read-only information about your code and PHP. The magic methods are reserved method names you can use in your classes to hook into special PHP functionality.
If you haven’t heard about PHP’s magic methods and constants yet, then this article is for you! I’ll review some of the more useful ones and how you can use them in your code.
Predefined Constants
The predefined constants are used to access information about your code. The constants here are written in all capital letters between double underscores, like __LINE__
and __FILE__
for example. Here are some of the useful constants that are made available by PHP:
__LINE__
returns the line number in the source file the constant appears at, like this:
<?php
echo "line number: " . __LINE__; // line number: 2
echo "line number: " . __LINE__; // line number: 3
echo "line number: " . __LINE__; // line number: 4
__FILE__
represents the name of your file, including its full path, like this:<?php
echo "the name of this file is: " . __FILE__;
// the directory and name of file is: C:wampwwwindex.php
__DIR__
represents only the path to the file:<?php
echo "the directory of this file is: " . __DIR__;
// the directory of this file is: C:wampwww
__CLASS__
returns the name of the current class:<?php
class Sample
{
public function __construct() {
echo __CLASS__;
}
}
$obj = new Sample(); // Sample
__FUNCTION__
returns the name of the current function:<?php
function mySampleFunc() {
echo "the name the function is: " . __FUNCTION__;
}
mySampleFunc(); //the name of function is: mySampleFunc
__METHOD__
represents the name of the current method:<?php
class Sample
{
public static function myMethod() {
echo "the name of method is: " . __METHOD__;
}
}
Sample::myMethod(); // the name of the method is: myMethod
__NAMESPACE__
returns the name of the current namespace:<?php
namespace MySampleNS;
echo "the namespace is: " . __NAMESPACE__;
// the name space is: MySampleNS
Magic Methods
Magic methods provide hooks into special PHP behavior. Unlike the constants earlier, their names are written in lower/camel-case letters with two leading underscores, like __construct()
and __destruct()
.
__construct()
is magic method which PHP invokes to create object instances of your class. It can accept any number of arguments.
<?php
class MySample
{
public function __construct($foo) {
echo __CLASS__ . " constructor called with $foo.";
}
}
$obj = new MySample(42);
// MySample constructor called with 42
As its name implies, the __destruct()
method is called when the object is destroyed by PHP’s garbage collector. It accepts no arguments, and it is commonly used to perform any clean up operations that may be needed such as closing a database connection.
<?php
class MySample
{
public function __destruct() {
echo__CLASS__ . " destructor called.";
}
}
$obj = new MySample; // MySample destructor called
Our next magic methods deal with property overloading, and provide a way for PHP to handle calls to properties and methods that have not been defined (or are not accessible to us).
PHP invokes the __get()
method if a property is undefined (or inaccessible) and called in a getter context. The method accepts one argument, the name of the property. It should return a value which is treated as the value of the property.
The __set()
method is called for undefined properties in a setter context. It accepts two arguments, the property name and a value.
<?php
class MySample
{
private $myArray = array();
public function __set($prop, $value) {
$this->myAarray[$prop] = $value;
}
public function __get($prop) {
return $this->myArray[$prop];
}
public function __isset($prop) {
return isset($this->myArray[$prop]);
}
public function __unset($prop) {
unset($this->myArray[$prop]);
}
public function __toString() {
return __CLASS__ . ":" . $this->name;
}
}
$obj = new MySample();
if (!isset($obj->name)) {
$obj->name = "Alireza";
}
echo $obj->name; // Alireza
echo $obj; // MySample:Alireza
In the above example code, the property name
is not defined in the class. I attempt to assign the value “mysample” to it, and PHP invokes the magic method __set()
. It receives “name” as the $prop
argument and “Alireza” as $value
, and I store the value in the private $myArray
array. The __get()
method works in a similar fashion; when I output $obj->name
, the __get()
method is called and “name” is passed in for the $prop
argument.
There are other magic methods which help us with retrieving and inspecting inaccessible member variables as well which appear in the sample code: __isset()
, __unset()
, and __toString()
. Both __isset()
and __unset()
are triggered by the functions with the same name (sans the underscores) in PHP.
__isset()
checks whether the property is set or not, and accepts one argument which is the property we want to test. __unset()
receives one argument which is the name of the property that the program wants to unset.
In many cases, representing an object as string is useful, such as for output to a user or another process. Normally PHP presents them as ID in memory, which is not good for us. The __toString()
method helps us represent the object as a string. The method is triggered in any situation where an object is used as a string, for example: echo "Hello $obj"
. It can also be called directly like any other normal public method, which is preferable to hacks such as appending an empty string to force coercion.
Summary
OOP programming can produce more maintainable and testable code. It helps us create better and standard PHP code. Also, it makes it possible to take advantage of the magic methods and constants which PHP makes available.
Image via Stepan Kapl / Shutterstock