使用函数名作为字符串从另一个类调用可调用函数

时间:2015-05-09 08:57:45

标签: php

我要做的是使用我提取的数据从名为GeneralRules的类中调用函数。我使用rulename var来调用函数。我试图使用call_user_func,但它返回了一个致命的错误。

<?php
namespace Validat;
require_once '\..\vendor\autoload.php';
use Rules\GeneralRules;
class Validator
{
    private $RuleName,$GRules;
    private $_Fields=[];
    public function __construct(){
    $this->GRules = new GeneralRules;
    }
    public function ExtractData(array $Rule){
        foreach ($Rule as $key => $values){
            $this->RuleName = $key;
            $this->_Fields = $values;
        }
        if (is_callable($this->GRules->{$this->RuleName}(""))){
            echo "Callable";
        }
    }
}

编辑1:触发错误的代码

    <?php
namespace Validat;
require_once '\..\vendor\autoload.php';
use Rules\GeneralRules;
use Errors\ErrorHandler;
use Errors\Errors;
class Validator
{
    private $RuleName,$GRules,$ErrorH;
    private $_Fields=[],$_Errors=[];
    public function __construct(){
    $this->GRules = new GeneralRules;
    $this->ErrorH = new ErrorHandler;
    }
    public function ExtractData(array $Rule){
        foreach ($Rule as $key => $values){
            $this->RuleName = $key;
            $this->_Fields = $values;
        }
        var_dump($this->_Fields);
        if (is_callable(array($this->GRules,$this->RuleName)))
           if( call_user_func($this->GRules->$this->RuleName,$this->_Fields[1])){
               echo "pass";
           }
           else 
               $this->_Errors=$this->ErrorH->AddError($this->_Fields[0].' '.Errors::get('Errors/'.$this->RuleName));
    }
} 

1 个答案:

答案 0 :(得分:0)

call_user_func()

问题出现在你的眼前:你检查一个符号是否可以调用,但你将其他东西传递给if (is_callable(array($this->GRules, $this->RuleName))) if (call_user_func(array($this->GRules, $this->RuleName), $this->_Fields[1])){

这是你应该怎么做的:

$this->GRules->$this->RuleName

为什么原始代码不起作用?

它不能像您尝试的那样工作,因为PHP从左到右解释表达式$this->GRules

  • GeneralRules$this->GRules->$this;
  • 类型的对象
  • $this:第二个object转换为字符串(如果类Validator未实现__toString()),则可能$this->GRulesobject最有可能没有属性$this->GRules->$this;这使NULL评估为NULL;
  • 在最后一步,RuleName没有属性$this->RuleName,这会触发致命错误。

您可以通过在if (call_user_func($this->GRules->{$this->RuleName}, $this->_Fields[1])){ 周围使用花括号来提示PHP如何评估此表达式:

$this->RuleName

这样PHP知道必须首先评估$this->RuleName;它会从中生成一个字符串,然后将其替换为大表达式以获得所需内容。

我建议你使用暴露在顶部的第一种方式;读者更清楚你想做什么:调用方法,其名称存储在$this->GRules中存储的对象的Marker中。

相关问题