Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.syntblaze.com/llms.txt

Use this file to discover all available pages before exploring further.

The :: operator, formally known as the Scope Resolution Operator (and internally referred to as Paamayim Nekudotayim), is a token that allows access to static properties, static methods, and constants of a class. It also facilitates access to inherited or overridden class members within an inheritance hierarchy. While it resolves the scope in which a specific class member is defined, it explicitly maintains the object instance context ($this is preserved and forwarded) when invoking an overridden non-static method from an instance context.

Syntax Mechanics

The operator requires two operands: a scope identifier on the left and a member identifier on the right. When accessing static properties via the scope resolution operator, the dollar sign ($) must precede the variable name. Constants and methods do not use the $ prefix.
class Configuration {
    public const TIMEOUT = 30;
    public static string $environment = 'production';
    
    public static function getStatus(): string {
        return 'active';
    }
}

// Accessing a class constant
Configuration::TIMEOUT;

// Accessing a static property (requires the $ prefix)
Configuration::$environment;

// Invoking a static method
Configuration::getStatus();

Class Name Resolution (::class)

The scope resolution operator is used in conjunction with the class keyword to resolve the fully qualified name of a class. The ClassName::class pseudo-constant evaluates to a string containing the fully qualified class name, including its namespace. Because this resolution occurs at compile time, it does not trigger autoloading and works even if the class does not exist.
namespace App\Services;

class PaymentProcessor {}

// Resolves to the string "App\Services\PaymentProcessor"
echo PaymentProcessor::class; 

Dynamic Scope Resolution

The left operand does not have to be a hardcoded class name. It can be a variable containing a string of the class name, or an instantiated object variable, allowing for dynamic scope resolution at runtime.
class Logger {
    public static function log(): void {
        echo "Logging execution...";
    }
}

// Using a string variable
$classReference = 'Logger';
$classReference::log(); 

// Using an instantiated object variable
$loggerInstance = new Logger();
$loggerInstance::log();

Internal Scope Keywords

When used inside a class definition, the :: operator is typically paired with three specific contextual keywords to resolve scope relative to the current class hierarchy:
  1. self (Early Binding): Resolves to the class in which the code is explicitly written and compiled. It does not account for inheritance.
  2. static (Late Static Binding): Resolves to the class that was initially called at runtime. If a child class calls an inherited method, static:: evaluates to the child class, whereas self:: evaluates to the parent class where the method was defined.
  3. parent: Resolves to the immediate parent class. It is used to access any visible method, constant, or static property defined in the parent class, regardless of whether the child class has overridden it.
class ParentClass {
    public static function targetMethod(): string {
        return "Parent Method\n";
    }
}

class ChildClass extends ParentClass {
    public static function targetMethod(): string {
        return "Child Method\n";
    }

    public static function demonstrateScope(): void {
        // Resolves to the method defined in the class where this code is written (ChildClass)
        echo self::targetMethod();   

        // Resolves to any visible method in the immediate parent (ParentClass)
        echo parent::targetMethod(); 

        // Resolves to the class of the runtime caller (Late Static Binding)
        echo static::targetMethod(); 
    }
}

Instance Context Preservation

When the :: operator is used to invoke a non-static method from within an existing object instance (typically using parent:: or self::), the PHP engine resolves the method’s scope but does not change the calling context. The current object instance ($this) is automatically forwarded to the resolved method.
class BaseEntity {
    public function getEntityClass(): string {
        // get_class() relies on the runtime instance ($this)
        return get_class($this);
    }
}

class UserEntity extends BaseEntity {
    public function getEntityClass(): string {
        // Scope is resolved to BaseEntity, but $this remains the UserEntity instance
        return parent::getEntityClass();
    }
}

$user = new UserEntity();
echo $user->getEntityClass(); // Output: UserEntity
Master PHP with Deep Grasping Methodology!Learn More