Main Website

Join our Newsletter to find out first about the Job Openings!

PHP Magic Methods, Abstract, Interfaces Classes and Traits

PHP Magic methods

Why were PHP Magic Methods created?

PHP magic methods were created to provide developers with a flexible and consistent way to customize and control the behavior of objects. 

They enable you to define how objects should behave in various situations without explicitly writing boilerplate code for every scenario.

They allow you to handle various scenarios dynamically, leading to cleaner, more maintainable code. 

By leveraging these magic methods, developers can write more expressive and efficient programs that can adapt to different requirements and changes, ultimately making the development process smoother and more productive.

What they offer

Dynamic Functionality: Magic methods allow developers to define how their objects interact dynamically. This means you can handle unpredictable scenarios like accessing non-existent properties or calling non-existent methods in a standardized way.

Cleaner Code: Instead of writing repetitive code to handle common tasks such as object initialization, cleanup, or property access, magic methods offer built-in solutions. This makes the code cleaner and more maintainable.

Enhanced Flexibility: They provide flexibility by allowing classes to define their own behavior when performing operations that are not explicitly defined. For example, what should happen when iterating over an object or when it is dumped for debugging.

Consistent Interface: Magic methods provide a consistent interface across different objects and classes, reducing the learning curve for understanding how different parts of a codebase interact with each other.

__construct()

Description: The __construct() method is the constructor method for a class. 

It is automatically called when an object is instantiated.

Use Case: It is used to initialize object properties and allocate resources.

PHP
            
                

class Contruct_Test {
public $property;

public function __construct( $value ) {
$this->property = $value;
}
}

$obj = new Construct_Test( value:’Hello, WPRiders!’ );
echo $obj->property; // Output: Hello, WPRiders!

__destruct()

Description: The __destruct() method is called when an object is destroyed or the script ends.

Use Case: It is used to clean up resources or execute any final code before the object is removed from memory.

PHP
            
                

class Destructor_Test {
public function __construct(){
echo “Object created \n”;
}

public function __destruct() {
echo ‘Object destroyed!’;
}
}

$obj = new Destructor_Test();
// Output: Object created!
// When script ends: Object destroyed!

__get($name)

Description: The __get() method is invoked when accessing a property that does not exist or is not visible.

Use Case: It is used to dynamically retrieve properties or perform operations when accessing a non-existent property.

PHP
            
                

class Get_Test {
private array $data = array(
‘name’ => ‘WPRiders’,
‘age’ => 9,
);

public function __get( $name ) {
return array_key_exists( $name, $this->data ) ? $this->data[ $name ] : null;
}
}

$obj = new Get_Test();
echo $obj->name; //Output: WPRiders

__set($name,$value)

Description: The __set() method is invoked when setting a value to a property that does not exist or is not visible.

Use Case: It is used to dynamically set properties or perform operations when attempting to store a value in a non-existent property.

            
                

class Set_Test {
private array $data = array();

public function __set( $name, $value ) {
$this->data[ $name ] = $value;
}

public function __get( $name ) {
return array_key_exists( $name, $this->data ) ? $this->data[ $name ] : null;
}
}

$obj = new Set_Test();
$obj->name = ‘WPRiders’;
$obj->milky_way = ‘Devs’;
echo $obj->name . ‘, ‘ . $obj->milky_way; // Output: WPRiders, Devs

__isset($name)

Description: The __isset() method is invoked when isset() or empty() is called on a non-existent or invisible property.

Use Case: It is used to check the existence of a property that is not otherwise accessible.

PHP
            
                

class Isset_Test {
private array $data = array( ‘name’ => ‘WPRiders’ );

public function __isset( $name ) {
return isset( $this->data[ $name ] );
}
}

$obj = new Isset_Test();
var_dump( isset( $obj->name ) ); // Output: bool(true)
var_dump( isset( $obj->cookie ) ); // Output: bool(false)

__unset($name)

Description: The __unset() method is invoked when unset() is called on a non-existent or invisible property.

Use Case: It is used to delete a value of a dynamic property.

PHP
            
                

class Unset_Test {
private array $data = array( ‘name’ => ‘WPRiders’ );

public function __unset( $name ) {
unset( $this->data[ $name ] );
}

public function __isset( $name ) {
return isset( $this->data[ $name ] );
}
}

$obj = new Unset_Test();
unset( $obj->name );
var_dump( isset( $obj->name ) ); // Output: bool(false)

 __call($name, $args)

Description: The __call() method is invoked when calling an inaccessible or non-existent method on an object.

Use Case: It is used to handle method calls dynamically, allowing for flexible method management.

PHP
            
                

class Call_Test {
public function __call( $name, $arguments ) {
echo “Calling method ‘$name’ with arguments ” . implode( ‘, ‘, $arguments ) . ‘
‘;
}
}

$obj = new Call_Test();
$obj->WPRiders( ‘arg1’, ‘arg2’ );
// Output: Calling method ‘WPRiders’ with arguments arg1, arg2

$obj->Potato( ‘French fries’, ‘Baked’, ‘Mashed’ );
// Output: Calling method ‘Potato’ with arguments ‘French fries’, ‘Baked’, ‘Mashed’

__callStatic($name,$args)

Description: The __callStatic() method is invoked when calling an inaccessible or non-existent static method.

Use Case: It is used to handle static method calls dynamically.

PHP
            
                

class Call_Static_Test {
public static function __callStatic( $name, $arguments ) {
// var_dump($arguments);
// array(2) {
// [0]=>
// string(5) “Test1”
// [1]=>
// string(6) “Test 2”
// }
echo “Calling static method ‘$name’ ” .implode( ‘, ‘, $arguments ).”\n”;
}
}

Call_Static_Test::WPRiders( ‘Test1’, ‘Test 2’ );

__toString()

Description: The __toString() method is invoked when an object is treated as a string (e.g., in echo or print).

Use Case: It provides a string representation of the object.

PHP
            
                

class To_String_Test {
private array $value = array( ‘Awesome’ );

public function __construct( $value ) {
$this->value[] = $value;
}

public function __toString() {
return implode( ‘, ‘, $this->value );
}
}

$obj = new To_String_Test( ‘Hello, WPRiders!’ );
echo $obj; // Output: Awesome, Hello, WPRiders!

__invoke()

Description: The __invoke() method is called when an object is used as a function.

Use Case: It allows objects to be callable, adding flexibility to how the object is used.

PHP
            
                

class Invoke_Test {
public function __invoke( $name ): string {
return “Hello, $name!”;
}
}

$obj = new Invoke_Test();
echo $obj( ‘WPRiders’ ); // Output: Hello, WPRiders!

__clone()

Description: The __clone() method is called when an object is cloned.

Use Case: It performs operations needed to complete the cloning process (e.g., deep copying).

Clone_Test: This is a simple class with a single property value.

Clone_Test_Example: This class contains a property “$property”, which is an instance of Clone_Test.

__construct: Initializes property with an instance of Clone_Test.

__clone: Overrides the clone method to ensure that when Clone_Test_Example is cloned, the Clone_Test instance inside it is also deeply cloned.

Demonstration:

Create an instance $clone_test_object of Clone_Test.

Create an instance $obj1 of Clone_Test_Example with $clone_test_object as its property.

Clone $obj1 to create $obj2.

Modify the value property of Clone_Test in $obj2 to “WPRiders”.

Show that the original object $obj1 still has the value as “Hello”, reflecting that a deep copy was effectively made.

PHP
            
                

class Clone_Test {
public $value;

public function __contruct( $value ) {
$this->value = $value;
}
}

class Clone_Test_Example {
public $property;

public function __Contruct( Clone_Test $property ) {
$this->property = $property;
}

public function __clone () {
// Deep copying the nested object
$this->property = clone $this->property;
}

// Creating an instance of Close_Test
$clone_test_object = new Clone_Test( value: ‘Hello’ );

// Creating an instance of Clone_Test_Example
$obj1 = new Clone_Test_Example( $clone_test_object );

// Cloning obj1
$obj2 = clone $obj1;

// Modifying the inner object value in the cloned object
$obj2->property->value = ‘WPRiders’;

echo $obj1->propery->value; // Output: Hello
echo $obj2->property->value; // Output: WPRiders
}

 __debugInfo()

Description: The __debugInfo() method is called when an object is dumped via var_dump().

Use Case: It customizes the information displayed for debugging.

PHP
            
                

class Debug_Info_Test {
private string $secret = ‘hide form debug’;
private string $second_secret = ‘shown’;

public function __debugInfo() {
return array(
‘revealed’ => ‘This is exposed’,
‘test’ => $this->another_test(),
‘the_secret’ => $this->second_secret,
);
}

private function another_test(): string {
return ‘stuff’;
}
}

$obj = new Debug_Info_Test();
echo ‘< pre >‘;

var_dump( $obj );

echo ‘< / pre > ‘;

// Output:
// object(Debug_Info_Test)#1 (3) {
// [“revealed”]=>
// string(15) “This is exposed”
// [“test”]=>
// string(5) “stuff”
// [“the_secret”]=>
// string(5) “shown”
// }

General Considerations

Naming Conventions

Magic methods must always start with double underscores (__). This distinguishes them from regular methods and indicates their special behavior.

Performance

Magic methods can introduce overhead, so use them accordingly. Overusing them can lead to performance hits due to the additional processing they entail.

IDE and Tool Support

Magic methods may not be as easily understood by code analysis tools, IDEs, or static analyzers compared to regular methods. This can impact features like autocompletion, refactoring, and lining.

Specific Restrictions and Considerations

__construct() and __destruct()

No return value: These methods should not return any value. Doing so will cause a fatal error.

Not inheritable by default: If you define a __construct() or __destruct() in a child class, it will not automatically inherit the parent’s constructor or destructor. You have to call the parent’s constructor or destructor explicitly using parent::__construct() or parent::__destruct().

__get() and __set()

Visibility: These methods are only triggered on inaccessible (protected or private) or non-existing properties. They will not be called for public properties that exist.

Side-effects: Overuse of these methods can lead to code that is difficult to understand and maintain, as property accesses are made dynamic and can have side effects.

__call() and __callStatic()

Non-existence: These are only called if the method being invoked does not exist or is not visible within the class scope.

Parameter handling: You must handle the parameters within these methods since the called method does not exist, PHP passes the method name and arguments to these methods.

__toString()

Return type: This method must return a string. Returning any other type will result in a fatal error.

Context: It is typically used when an object is used in a string context (e.g., with print or echo).

__invoke()

Callable context: This method allows an object to be called like a function. It must accept any arguments passed during invocation and execute logic accordingly.

__clone()

Deep copy logic: Use this method to define deep copy logic. Be cautious of circular references and ensure that nested objects are cloned properly to avoid shared references.

__debugInfo()

Return structure: This method should return an associative array. The array keys will be the names of the displayed properties, and the values will be the corresponding values to display.

Best Practices

Keep It Simple

Avoid overly complex logic within magic methods. They should be used to handle common, predictable scenarios and not replace well-structured, explicit code.

Document Usage

Clearly document the purpose and behavior of any magic methods in your classes. This is crucial for maintainability and for helping other developers understand their behavior.

Consistency

Follow consistent naming conventions and usages for magic methods across your codebase to reduce confusion and make the code more predictable.

Explicit Over Implicit

Use magic methods accordingly and prefer explicit method calls and property access whenever possible. Magic methods should enhance, not replace, clear and maintainable code structures.

Abstract, Interfaces, and Traits

Abstract Classes

Definition

An abstract class is a class that cannot be instantiated on its own and is meant to be extended by other classes. It can contain both fully implemented methods and abstract methods (methods without implementation).

Restrictions

Cannot be instantiated: You cannot create an instance of an abstract class.

Must be extended: Other classes must extend the abstract class and implement all its abstract methods.

Recommendations

Use abstract classes when you have a common base with both implemented methods and methods that need to be overridden by subclasses.

PHP
            
                

// Class representing an abstract Animal.
// This class provides a template for animal objects,
// enforcing subclasses to implement
// the make_sound method, while also providing a default
// implementation for the move method.

abstract class Animal {
// Abstract method (must be implemented in subclasses)
abstract protected function make_sound();

// Concrete method
public function move(): string {
return ‘I can move’;
}
}

// Dog class extends the Animal class.
// The Dog class includes a method for producing a sound specific to dogs.

class Dog extends Animal {
public function make_sound(): string {
return ‘Le Woof!’;
}
}

$dog = new Dog();
echo $dog->make_sound(); // Output: Le Woof!
echo $dog->move(); // Output: I can move

Interfaces

Definition

An interface defines a contract that other classes must implement. Interfaces can only define method signatures without any actual implementation.

Restrictions

No implementation allowed: You can only declare methods in an interface. No implementation of the methods is allowed.

Class must implement all methods: Any class implementing the interface must implement all the method declarations.

Recommendations

Use interfaces to define a contract that different classes can implement, ensuring a consistent API across different classes.

PHP
            
                

// Interface Logger
// Defines a contract for logging messages

interface Logger{
public function log( $message );
}

// Class File_Logger
// Implements the Logger interface to log messages to a file

class File_Logger implements Logger {
public function log( $message ) {
file_put_contents( ‘log.txt’, $message . PHP_EOL, FILE_APPEND );
}

public function test( $file ) {

}
}

$logger = new File_Logger();
//Appends “This is a log message.” to log.txt
$logger->log( ‘This is a log message.’ );

Traits

Definition

Traits are a mechanism for code reuse in single inheritance languages like PHP. A trait allows you to include methods in multiple classes.

Restrictions

No state: Traits cannot define properties. They can only contain methods and constants.

Conflict resolution: If two traits inserted into a class have a method with the same name, you’ll get a fatal error unless you resolve the conflict.

Recommendations

Use traits to reuse methods across multiple classes when inheritance is not an option.

PHP
            
                

/ This trait provides a simple logging functionality.
// The `log` method outputs a message prefixed with
// “Logging message:”.

trait Logger_Trait {
public function log( $message ) {
echo “Logging message: $message”;
}
}

// The Doggo class utilizes logging capabilities
// provided by Logger_Trait.
// By employing Logger_Trait, instances of Doggo can
// log messages using the predefined `log` method.

class Doggo {
use Logger_Trait;
}

// This class represents a product and includes
// logging functionality.
// The `Product` class utilizes the `Logger_Trait` to
// provide simple logging capabilities.

class Product {
use Logger_Trait;
}

$user = new Doggo();
// Output: Logging message: Doggo goes bark bark!
$user->log( ‘Doggo goes bark bark!’ );

$product = new Product();
// Output: Logging message: Product created
$product->log( ‘Product created’ );

In Conclusion …

Each of these OOP tools serves a unique purpose and provides a powerful means to effectively structure and manage your code. 

Understanding where and how to use them can greatly enhance the robustness and maintainability of your applications.

Mihai Irodiu - Technical Team Leader - Inside WPRiders

This article is written by Mihai, Technical Team Leader @WPRiders.

Do you like this article? Share it and send us your feedback! Check out our articles page, where you might find other interesting posts. Also, if you want to learn more about business, check out the WPRiders Blog!
Don't forget to subscribe Receive WPRiders' newsletter for the freshest job openings, sent directly to your inbox. Stay informed and never miss a chance to join our team!

Navigate to

Your future career is right here

Check some other articles we wrote

Read all the Articles
Hidden Job Search Mistakes That Are Killing Your LinkedIn Profile in 2025 - Inside WPRiders Article
Hidden Job Search Mistakes That Are Killing Your LinkedIn Profile in 2025
Did you know that 93% of companies search for candidates on LinkedIn? Your profile might be hurting your job search without you knowing it. Job seekers often make critical mistakes that keep recruiters from noticing them. Incomplete profiles get skipped instantly. Generic headlines fail to capture attention. These small oversights can substantially affect your career […]
DocsFromTemplate 7 Key Features and Benefits of Automating Document Workflows - Inside WPRiders Article
DocsFromTemplate: 7 Key Features and Benefits of Automating Document Workflows
What is DocsFromTemplate? DocsFromTemplate is a powerful WordPress plugin that automates the generation of professional, branded PDF documents from Gravity Forms submissions. It allows users to create and manage templates for documents such as contracts, invoices, applications, and reports. By eliminating the need for manual intervention, DocsFromTemplate ensures efficiency, consistency, and accuracy in document generation. […]
The Story Behind WPRiders Being Your Best WordPress Partner in 2025 - Inside WPRiders Article
The Story Behind WPRiders Being Your Best WordPress Partner in 2025
You know how everyone claims to be the best at what they do? Well, we actually have proof to back that up! Pretty cool, right? At WPRiders, we’re not just another WordPress agency making empty promises—we’re the team that actually delivers what others just talk about. Let me tell you something exciting, and yes, I […]