变量作用域-php-在另一个函数中使用来自一个函数的变量

变量作用域-php-在另一个函数中使用来自一个函数的变量,php,function,oop,scope,Php,Function,Oop,Scope,我在使用一个函数中生成的变量作为第二个函数中的变量时遇到问题 问题是: 我注意到:未定义变量:validate函数中的参数,在以下行: $this->$methodName($item,$value,$parameter) OR $valid=false; 当对splitrules和parameters的函数调用被函数中的代码简单地替换时,问题就消失了 情景: 以下两个函数都在Validator类中,第一个为validate,使用第二个为splitrules和parameters 下面是

我在使用一个函数中生成的变量作为第二个函数中的变量时遇到问题

问题是: 我注意到:未定义变量:validate函数中的参数,在以下行:

$this->$methodName($item,$value,$parameter) OR $valid=false;
当对splitrules和parameters的函数调用被函数中的代码简单地替换时,问题就消失了

情景: 以下两个函数都在Validator类中,第一个为validate,使用第二个为splitrules和parameters

下面是验证函数:

public function validate($data, $rules)
{
    $valid= true;

    foreach($rules as $item=>$ruleSet)
    {
        $ruleSetArray=explode('|',$ruleSet);

        foreach($ruleSetArray as $rule)
        {
            $this->splitRulesAndParameters($rule);
            
            $methodName='validate'.ucfirst($rule);
            $value = isset($data[$item]) ? $data[$item] : NULL;
            
            if(method_exists($this, $methodName))
            {
                $this->$methodName($item,$value,$parameter) OR $valid=false;
            }
        }
    }

    return $valid;
}
这是splitRulesAndParameters函数

public function splitRulesAndParameters($rule)
{
    $position = strpos($rule, ':');
    if($position !==false)
    {
        $parameter = substr($rule,$position + 1);
        $rule = substr($rule,0,$position);
    }
    else
    {
        $parameter='';
    }
}

不能只在一个函数中使用另一个函数中的变量。必须返回变量
$parameter
。在
splitRulesAndParameters
的末尾添加一个return语句,并将结果存储在
validate
$parameter=$this->spli…
)中的一个变量中。

如果在
splitRulesAndParameters
中“内联”代码,问题就会消失,我怀疑该方法中使用了
$parameters
变量。如果是这样,只需让该方法返回该变量的值,并将其分配给您在此处发布的
validate
方法的局部变量:

$parameters = $this->splitRulesAndParameters($rule);
将其添加到
splitRulsAndParameters
方法后:

return $parameters;
该方法本身还修改
$规则
值。同样:这个
$rule
变量是每个方法的局部变量。它可能具有相同的名称,但值是副本。在
splitrules和parameters
中对
$rule
所做的任何更改都不会反映在
validate
方法中的
$rule
中。如果我是你,我会写:

public function splitRulesAndParameters($rule)
{
    $position = strpos($rule, ':');
    if($position !==false)
    {
        return array(
            'parameter' => substr($rule, $position+1),
            'rule'      => substr($rule, 0, $position)
        );
    }
    return array(
        'parameter' => null,//no param == null, IMO, change to '' if you want
        'rule'      => $rule
    );
}
然后,要更改
验证中的变量,请执行以下操作:

$split = $this->splitRulesAndParameters($rule);
$rule = $split['rule'];
$parameter = $split['parameter'];
应该这样做

旁注:
您似乎正在验证所有需要验证的内容,即使第一次验证失败。如果我是你,我会改变这个愚蠢的说法:

$this->$methodName($item,$value,$parameter) OR $valid=false;
为了提高效率:

if (!$this->{$methodName}($item, $value, $parameter))
    return false;//if validation fails, return false
这将停止执行任何进一步的有效性验证:如果一个值无效,那么就到此为止。继续是没有意义的,因为数据集无论如何都不是完全有效的

奖金:
使用冒号分隔方法名称和一些参数也允许您指定多个参数,并允许您简化
splitRulesAndParameters
更多:

protected function splitRulesAndParameters($rule)
{
    $all = explode(':', $rule);
    return array(
        'rule'   => array_shift($all),//removes first element in array
        'params' => $all//rest of the array
    );
}

稍微调整一下,以便更好地满足您的需要

实际上,这里有两个问题,因为您更改了函数中的&rule变量,但是您通过引用传递它。因此,在功能完成后,$规则变量与之前相同

以您现在的方式解决此问题的方法是将函数更改为:

public function splitRulesAndParameters(&$rule)
{
    $position = strpos($rule, ':');
    if($position !==false)
    {
        $parameter = substr($rule,$position + 1);
        $rule = substr($rule,0,$position);
    }
    else
    {
        $parameter='';
    }
    return $parameter;
}

换线

$this->splitRulesAndParameters($rule);

$parameter=$this->splitRulesAndParameters($rule)

有道理:
$parameter
从未声明过。。。PHP将为您创建一个新变量(并将其初始化为
null
),但它将(正确地)发出通知修改
splitRulesAndParameters()
以返回
$rule
$parameter
的数组,并在调用
$this->$methodName($item,$value,$parameter)时使用该数组中的值
。。。。或者对
$this->rule
$this->parameter
使用对象属性。。。。或者甚至重构以使用专用的
规则
类请看这篇最近的帖子和我在帖子上的评论您也错过了
$Rule
被修改的地方:仅返回
$parameter
并不能完全解决问题here@EliasVanOotegem哦,对了。但是OP似乎已经放弃了这个问题…谢谢Elias。这就是我所说的高于和超越=)你关于简化的观点也很受欢迎