Return with ternary expression breaks foreach loop on first iteration
Ok, i tested what follows and i'll just let you know what i discovered:
echo ('-1' < 0) ? 'true' : 'false'; // will echo "true"
echo ('1' > 0) ? 'true' : 'false'; // will echo "true"
# Notice that '-1' and '1' are strings
Now let's take an array, coming from the database after filtering all the result in order to get only rows with UID = 1
.
$this->a = array(
[0] => array(
'UID' => '1',
'PID' => '91',
'Amount' => '-1'
),
[1] => array(
'UID' => '1',
'PID' => '92',
'Amount' => '1'
),
[2] => array(
'UID' => '1',
'PID' => '93',
'Amount' => '1'
)
);
Now i want to create a function posAmount($PID)
that returns true
if 'Amount' > 0
or false
if 'Amount' < 0
. (Notice: Amount = 0 is something i don't really care). Also i'd like to write as similar func开发者_Python百科tion called negAmount($PID)
that returns the exactely opposite of the first. I'd like, now, to introduce you to my twin functions:
public function posAmount($pid)
{
foreach ($this->a as $a)
{
if (count($this->a) == 0) { return false; }
return ($a['PID'] == $pid and $a['Amount'] > 0) ? true : false;
}
}
public function negAmount($pid)
{
foreach ($this->a as $a)
{
if (count($this->a) == 0) { return false; }
return ($a['PID'] == $pid and $a['Amount'] < 0) ? true : false;
}
}
The cool fact is that, regarding the first array (which, i checked with var_dump()
keeps its nature trough the entire script):
$istance->negAmount(91); // Returns true, as expected
$istance->posAmount(92); // Returns false, as NOT expected.
# Why do God wants me to get mad?
The problem is that you are always returning on the first iteration of the foreach loop. You should rewrite the functions like this:
public function negAmount($pid) {
if (count($this->a) == 0) { return false; }
foreach ($this->a as $a) {
if ($a['PID'] == $pid) {
if ($a['Amount'] < 0) {
return true;
}
}
}
return false;
}
public function posAmount($pid) {
if (count($this->a) == 0) { return false; }
foreach ($this->a as $a) {
if ($a['PID'] == $pid) {
if ($a['Amount'] > 0) {
return true;
}
}
}
return false;
}
May just be a typo in your demo code, but - OP correctedposAmount
method is looping $this->a
, whereas the other is looping $this->votes
You've got some odd things in your code. Why are you checking the count of $this->a
from within a foreach
loop? It would make more sense to check the count before you start looping.
Also, you've got some logic errors in your comparison. You're only comparing the first iteration through the loop... it will either return true or false for the first index of the array and never even look at the others. You'll want to match the PID in the loop before you compare - and return - any thing. Like so:
public function posAmount($pid)
{
if (count($this->a) == 0) { return false; }
foreach ($this->votes as $a) {
if ($a['PID'] == $pid)
return $a['Amount'] > 0 ? true : false;
}
return false;
}
public function posAmount($pid)
{
if (count($this->a) == 0) { return false; }
foreach ($this->votes as $a) {
if ($a['PID'] == $pid)
return $a['Amount'] < 0 ? true : false;
}
return false;
}
The problem is you're trying to compare a string to an int without trying to convert it. Change $a['Amount']
to (int)$a['Amount']
and see what happens.
So here you iterate $this->a:
public function posAmount($pid)
{
foreach ($this->a as $a)
But here $this->votes:
public function posAmount($pid)
{
foreach ($this->a as $a)
Typo or what...
精彩评论