Доступ к константе класса и статический метод из строки - PullRequest
8 голосов
/ 21 февраля 2012

У меня есть строка, содержащая имя класса, и я хочу получить константу и вызвать (статический) метод из этого класса.

<?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;
    }
}
?>

Как я и ожидал (более или менее), используя $variable::CONSTANT или $variable::method(); не работает.

Прежде чем спросить, что я пробовал;Я перепробовал так много вещей, которые в основном забыл.

Какой лучший способ сделать это?Заранее спасибо.

Ответы [ 5 ]

27 голосов
/ 21 февраля 2012

Чтобы получить доступ к константе, используйте constant():

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

Имейте в виду : если вы работаете с пространствами имен, вам нужно специально добавить свойпространство имен к строке, даже если вы вызываете constant() из того же пространства имен!

Для вызова вам нужно будет использовать call_user_func():

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

Однако: все это не очень эффективно, так что вы, возможно, захотите еще раз взглянуть на дизайн вашей иерархии объектов.Там может быть лучший способ достичь желаемого результата, используя наследование и т. Д.

2 голосов
/ 21 мая 2017

в php 7 вы можете использовать этот код

echo 'my class name'::$b;
2 голосов
/ 21 февраля 2012

Используйте call_user_func для вызова статического метода:

call_user_func(array($className, $methodName), $parameter);
1 голос
/ 21 февраля 2012

Классы, определенные как абстрактные, не могут быть созданы, и любой класс, который содержит хотя бы один абстрактный метод, также должен быть абстрактным.Методы, определенные как абстрактные, просто объявляют сигнатуру метода - они не могут определять реализацию.

При наследовании от абстрактного класса все методы, помеченные как абстрактные в объявлении класса родителя, должны быть определены потомком;Кроме того, эти методы должны быть определены с одинаковой (или менее ограниченной) видимостью.Например, если абстрактный метод определен как защищенный, реализация функции должна быть определена как защищенная или общедоступная, но не закрытая.Кроме того, подписи методов должны совпадать, то есть подсказки типа и количество обязательных аргументов должны быть одинаковыми.Это также относится к конструкторам начиная с PHP 5.4.До 5.4 подписи конструктора могли отличаться.См. http://php.net/manual/en/language.oop5.abstract.php

1 голос
/ 21 февраля 2012

Вы можете достичь этого, установив временную переменную.Не самый элегантный способ, но он работает.

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');
}

Я полагаю, это связано с неоднозначностью ::, по крайней мере с тем, на что намекает сообщение об ошибке (PHP Parse error: syntax error, unexpected T_PAAMAYIM_NEKUDOTAYIM)

...