2014-09-15 2 views
0

У меня возникла проблема с использованием переменной, сгенерированной в одной функции, как переменной во второй функции.Переменная scope - php - Использование переменных из одной функции в другую

Проблема:

Я получаю Примечание: Undefined переменной: параметр в функции валидации, на линии:

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

Когда вызов функции для splitRulesAndParameters просто заменен кода внутри функции, проблема уходит.

Сценарий:

Следующие две функции находятся в классе Validator, во-первых, Validate, использует второй, splitRulesAndParameters

Вот функция Validate:

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

Имеет смысл: '$ parameter' никогда не объявляется ... PHP создаст для вас новую переменную (и инициализирует ее до« null »), но она (по праву) выдаст уведомление –

+0

Измените свои' splitRulesAndParameters () ', чтобы вернуть массив' $ rule' и '$ parameter', и использовать значения из этого массива в вызове' $ this -> $ methodName ($ item, $ value, $ parameter) '.... или использовать свойства объекта для '$ this-> rule' и' $ this-> parameter' .... или даже рефакторинг для использования выделенного класса 'Rule' –

+0

См. это недавнее сообщение http://stackoverflow.com/questions/25842231/pass-php-var-from-one-function-to-another/25842271 # 25842271 и мой комментарий к сообщению –

ответ

1

Видя, как эта проблема уходит, если вы «инлайн» код в splitRulesAndParameters, я подозреваю, что переменная $parameters используется в этом методе. Если это так, просто этот метод вернуть Значение этой переменной и присвоить ее локальной переменной в validate метода вы публикуемую здесь:

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

После добавления этого к методу splitRulsAndParameters:

return $parameters; 

Сам метод также изменяет значение $rule. Опять же: переменная $rule является локальной для каждого метода. Он может иметь одно и то же имя, но это значение. Любые сделанные вами изменения до $rule в splitRulesAndParameters не отражены $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']; 

Это должно сделать это.

Побочное примечание:
Вы, кажется, проверки все что нуждается в проверке, даже если первая проверка не удалась.Если бы я тебя, я бы изменить это Fugly заявление:

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

Для более эффективной:

if (!$this->{$methodName}($item, $value, $parameter)) 
    return false;//if validation fails, return false 

Это останавливает дальнейшее valiation от выполняется: если один недопустимое значение, то просто остановить там. Продолжение бессмысленно, потому что набор данных еще не совсем прав.

Bonus:
Использование двоеточие, чтобы отделить имя метода, и какой-то параметр (ы) не позволяет указать несколько Params, тоже, и это позволяет упростить 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 
    ); 
} 

Tweak это немного лучше набора ваших потребностей

+0

спасибо Элиасу. это то, что я называю выше и выше =). Вы очень цените точки упрощения. – datavoredan

0

Вы не можете просто использовать переменную изнутри функции в другой функции. У вас должно быть возвращение переменная $parameter. Добавьте оператор возврата в конец splitRulesAndParameters и сохраните результат в переменной внутри validate ($parameter = $this->spli...).

+0

Вы пропустили бит, где также изменилось '$ rule': возврат' $ parameter' один не совсем сократил его здесь –

+0

@EliasVanOotegem О, право. Но ОП, похоже, все равно отказался от вопроса ... – Butt4cak3

0

вы на самом деле есть две проблемы здесь, потому что вы измените переменную & правила внутри вашей функции, но вы передаете его по ссылке. Итак, после выполнения fucntion переменная $ 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);

Смежные вопросы