Reputation: 3756
I am having trouble using a variable generated in one function, as a variable in a second function.
I get Notice: Undefined variable: parameter in the validate function, on the line:
$this->$methodName($item,$value,$parameter) OR $valid=false;
When the function call for splitRulesAndParameters is simply replaced with the code within the function, the problem goes away.
The following two functions are both within the Validator class, the first, validate, makes use of the second, splitRulesAndParameters
Here is the validate function:
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;
}
And here is the splitRulesAndParameters function
public function splitRulesAndParameters($rule)
{
$position = strpos($rule, ':');
if($position !==false)
{
$parameter = substr($rule,$position + 1);
$rule = substr($rule,0,$position);
}
else
{
$parameter='';
}
}
Upvotes: 0
Views: 85
Reputation: 76408
Seeing as the problem goes away if you "inline" the code in splitRulesAndParameters
, I suspect the $parameters
variable is used in that method. If so, simply have that method return the value of this variable, and assign it to a variable local to the validate
method you've posted here:
$parameters = $this->splitRulesAndParameters($rule);
After adding this to the splitRulsAndParameters
method:
return $parameters;
The method itself also modifies the $rule
value. Again: this $rule
variable is local to each method. It may have the same name, but the value is a copy. Any changes you make to $rule
in splitRulesAndParameters
is not reflected by $rule
in your validate
method. If I were you, I'd write:
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
);
}
Then, to change the variables in validate
:
$split = $this->splitRulesAndParameters($rule);
$rule = $split['rule'];
$parameter = $split['parameter'];
That ought to do it.
Side-note:
You seem to be validating everything that needs validating, even if the first validation failed. If I were you, I'd change this fugly statement:
$this->$methodName($item,$value,$parameter) OR $valid=false;
To a more efficient:
if (!$this->{$methodName}($item, $value, $parameter))
return false;//if validation fails, return false
That stops any further valiation from being executed: if one value is invalid, then just stop there. To continue is pointless, because the data-set is not entirely valid anyway.
Bonus:
Using a colon to separate the method name, and some parameter(s) does allow you to specify multiple params, too, and it allows you to simplify the splitRulesAndParameters
some more:
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 this a little to better suite your needs
Upvotes: 1
Reputation: 792
You actually have two problems here, because you change the &rule variable inside your function, but you are passing it by reference. So after the fucntion is done the $rule variable is the same as it was before.
The way to solve this in the manner you are doing it right now would be to change the function to:
public function splitRulesAndParameters(&$rule)
{
$position = strpos($rule, ':');
if($position !==false)
{
$parameter = substr($rule,$position + 1);
$rule = substr($rule,0,$position);
}
else
{
$parameter='';
}
return $parameter;
}
and change the line
$this->splitRulesAndParameters($rule);
to $parameter = $this->splitRulesAndParameters($rule);
Upvotes: 0
Reputation: 2429
You can't just use a variable from inside a function in another function. You have to return the variable $parameter
. Add a return statement to the end of splitRulesAndParameters
and store the result in a variable inside validate
($parameter = $this->spli...
).
Upvotes: 0