变量范围 - php - 使用另一个函数中的变量

时间:2014-09-15 09:39:02

标签: php function oop scope

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

问题:

我在验证函数中得到注意:未定义的变量:参数,在这一行:

$this->$methodName($item,$value,$parameter) OR $valid=false;

splitRulesAndParameters 的函数调用简单地替换为函数中的代码时,问题就会消失。

场景:

以下两个函数都在Validator类中,第一个是验证,使用第二个函数, splitRulesAndParameters

这是验证功能:

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

3 个答案:

答案 0 :(得分:1)

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

$parameters = $this->splitRulesAndParameters($rule);

将此内容添加到splitRulsAndParameters方法后:

return $parameters;

方法本身也会修改$rule值。再说一遍:这个$rule变量是每个方法的本地变量。它可能具有相同的名称,但值是副本。您对$rulesplitRulesAndParameters所做的任何更改均未在$rule方法的validate中反映出来。如果我是你,我会写:

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

然后,更改validate中的变量:

$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

停止执行任何进一步的valiation:如果一个值无效,那么就停在那里。继续是没有意义的,因为数据集无论如何都不完全有效。

加成:
使用冒号分隔方法名称和一些参数确实允许您指定多个参数,并且它允许您更简化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
    );
}

稍微调整一下以更好地满足您的需求

答案 1 :(得分:0)

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

答案 2 :(得分:0)

这里你实际上有两个问题,因为你更改了函数中的& rule变量,但是你通过引用传递它。因此,在完成功能之后,$ 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);