Access class constant and static method from string

22,619

Solution 1

To access the constant, use constant():

constant( $this->myClass.'::CONSTANT' );

Be advised: If you are working with namespaces, you need to specifically add your namespace to the string even if you call constant() from the same namespace!

For the call, you'll have to use call_user_func():

call_user_func( array( $this->myclass, 'method' ) );

However: this is all not very efficient, so you might want to take another look at your object hierarchy design. There might be a better way to achieve the desired result, using inheritance etc.

Solution 2

in php 7 you can use this code

echo 'my class name'::$b;

or

#Uncomment this lines if you're the input($className and $constName) is safe.
$reg = '/^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$/';
if(preg_match($reg,$className) !== 1 || preg_match($reg,$constName) !== 1)
    throw new \Exception('Oh, is it an attack?');
$value = eval("return $className::$constName;");

Solution 3

You can achieve it by setting a temporary variable. Not the most elegant way but it works.

public function runMethod() {
    // Temporary variable
    $myclass = $this->myclass;
    // Get the selected constant here
    print $myclass::CONSTANT;

    // Call the selected method here
    return $myclass::method('input string');
}

I guess it's to do with the ambiguity of the ::, at least that what the error message is hinting at (PHP Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM)

Solution 4

Use call_user_func to call static method:

call_user_func(array($className, $methodName), $parameter);

Solution 5

Classes defined as abstract may not be instantiated, and any class that contains at least one abstract method must also be abstract. Methods defined as abstract simply declare the method's signature - they cannot define the implementation.

When inheriting from an abstract class, all methods marked abstract in the parent's class declaration must be defined by the child; additionally, these methods must be defined with the same (or a less restricted) visibility. For example, if the abstract method is defined as protected, the function implementation must be defined as either protected or public, but not private. Furthermore the signatures of the methods must match, i.e. the type hints and the number of required arguments must be the same. This also applies to constructors as of PHP 5.4. Before 5.4 constructor signatures could differ. Refer to http://php.net/manual/en/language.oop5.abstract.php

Share:
22,619
Tim S.
Author by

Tim S.

Front-end developer that likes stuff.

Updated on July 20, 2021

Comments

  • Tim S.
    Tim S. almost 3 years

    I have a string containing the class name and I wish to get a constant and call a (static) method from that class.

    <?php
    $myclass = 'b'; // My class I wish to use
    
    $x = new x($myclass); // Create an instance of x
    $response = $x->runMethod(); // Call "runMethod" which calls my desired method
    
    // This is my class I use to access the other classes
    class x {
        private $myclass = NULL;
    
        public function __construct ( $myclass ) {
            if(is_string($myclass)) {
                // Assuming the input has a valid class name
                $this->myclass = $myclass;
            }
        }
    
        public function runMethod() {
            // Get the selected constant here
            print $this->myclass::CONSTANT;
    
            // Call the selected method here
            return $this->myclass::method('input string');
        }
    }
    
    
    // These are my class(es) I want to access
    abstract class a {
        const CONSTANT = 'this is my constant';
    
        public static function method ( $str ) {
            return $str;
        }
    }
    
    class b extends a {
        const CONSTANT = 'this is my new constant';
    
        public static function method ( $str ) {
            return 'this is my method, and this is my string: '. $str;
        }
    }
    ?>
    

    As I expected (more or less), using $variable::CONSTANT or $variable::method(); doesn't work.

    Before asking what I have tried; I've tried so many things I basically forgot.

    What's the best approach to do this? Thanks in advance.