PHP while(variable=mysql_fetch_assoc) - explanation - php

I have been working with C# so this is quite strange for me:
while($variable=mysql_fetch_assoc)
{ $X=$variable['A'];
$Y=$variable['B'];
}
If it is like an ordinary loop, then X,Y will be reset with every loop, right?
I have not been able to look up in PHP manual how it works. I guess that in each loop it advances to next element of assoc.array. But what is this generally called in PHP? I am just not used to see '=' in loop condition.

Assignment in PHP is an expression that returns the value that was assigned. If a row was retrieved then the result will be non-false, which will allow the loop to continue.

mysql_fetch_assoc() (and its related functions) advance $result's internal pointer every time it gets called. So $variable will be assigned a new row array every time the while condition is checked. After the last row is returned, mysql_fetch_assoc() can't advance the internal pointer anymore, so the next attempt to call it will return false. Once $variable becomes false, the condition is no longer satisfied and the loop exits.
In PHP (also JavaScript et al), a condition is true as long as it doesn't evaluate to either zero, an empty string, NULL or false. It doesn't have to evaluate to a boolean value. That's why such a loop works.
EDIT:
If it is like an ordinary loop, then X,Y will be reset with every loop, right?
Yes, they'll be reassigned with the new values from each new row that is fetched.

Perhaps looking at the code like this would be useful:
while (($variable = mysql_fetch_assoc($result)) == true) {
// loops until the fetch function returns false (no more rows)
// $variable will have be an associative array containing the 'next' row from the recordset in $result
}
It's a shorthand way of doing this:
$variable = mysql_fetch_assoc();
while ($variable) {
// loop
$variable = mysql_fetch_assoc();
}

It means something like "until you can mysql_fetch_assoc() an element from the variable you pass to that function, then do the body of the while.
It returns an array if it can find an element, FALSE otherwise, so you can exit the loop.

It's just short form of this code:
$variable = mysql_fetch_assoc($res);
while($variable != FALSE) {
// do something
$variable = mysql_fetch_assoc($res);
}

Related

Array_push doesn't make new key, instead replaces current value

I'm kinda lost here.
So here is what i'm trying to do.
I have a session, that's called "test", i have set the session to be an array every time that $_POST['process'] isset.
The $_POST['process'] is containing a integer, that's fetched from a DB Table.
Here's my code:
if(isset($_POST['process']))
{
$_SESSION['test'] = array();
$array_merge = array_push($_SESSION['test'], $_POST['process']);
}
It work's at first time, here's the result:
[test] => Array
(
[0] => 21311
)
I was expecting, that it would create a new key, and assign it to the other value that get's fetched from $_POST['process'] - but instead it just overwrites the 0 key.
What am i doing wrong here?
Kind regards
In your code you're writing $_SESSION['test'] = array(); which is resetting the value of $_SESSION['test'] to an empty array. Therefore it has removed your previous value and have put in your new one.
To fix this check if $_SESSION['test'] is already set, if it's not do $_SESSION['test'] = array();, otherwise just insert new values.
Full example:
if(isset($_POST['process'])) {
if(!isset($_SESSION['test'])) {
$_SESSION['test'] = array();
}
$array_merge = array_push($_SESSION['test'], $_POST['process']);
}
Honestly, this is one precise case where using array_push() is a disadvantage versus its alternative square bracket syntax.
array_push() requires you to declare the empty array in advance; [] will not AND it is functionless AND it is more brief to code.
Furthermore, I am nearly 100% sure that you don't actually want to know the new element count after pushing. The PHP Manual says:
Returns the new number of elements in the array.
...so, if you do want to know the new count, then perhaps rename your variable from $array_merge to $array_size or $array_count or $array_length.
I know I wouldn't want to write an extra condition just to declare an empty variable then use a function to add a new element, especially when it can be done in one line
if(isset($_POST['process'])) {
$_SESSION['test'][] = $_POST['process']; // all done
}
This will work the first time and every time as desired.

While loop: only Variables can be passed by reference error

I am running into a "Only variables should be passed by reference" error, because on the code I am using there is a line that does not put the explode() result into a variable. As required when using strict PHP standards.
However because the explode() function is used in a While loop I can't think of a appropriate solution.
My code looks like
function user_exists($username) {
rewind($this->fp);
while(!feof($this->fp) && trim($lusername = array_shift(explode(":",$line = rtrim(fgets($this->fp)))))) {
if($lusername == $username)
return 1;
}
return 0;
}
Any suggestions on how to solve this?
I think maybe you need to sit back and break your code apart a bit and take a look at what is happening.
First, condition is while !feof($this->fp)
From the manual:
feof — Tests for end-of-file on a file pointer
One thing you will notice here is that feof() is only a test which returns true or false. It does not advance the pointer position while looping over, so while using this function, somewhere else in your while loop there needs to be something that advances the pointer or else you will have an infinite loop.
Second condition is:
trim($lusername = array_shift(explode(":",$line = rtrim(fgets($this->fp)))))
First function from left to right is trim(), which returns a string. From our handy dandy comparison table we see that when doing if ((String) $var) it evaluates to false if and only if the string is empty ("") or the number zero as a string ("0"), otherwise it returns true. Personally I tend to really hate using if ((String) $var) (first because it's slightly unclear to newbies unless you know your comparison table well and second because 99% of the time people are doing that they are actually checking for string length, in which case I would want it to return true for the string "0"). So assuming that you don't need it to return false for "0" we could change this to strlen($var) > 0 and then manipulate the variable within the loop. That should greatly simplify things here.
So now we have:
while (!feof($this->fp) && strlen($var) > 0) { /*...*/ }
This will loop over until either we are at the end of the file or $var is an empty line. Everything else can be offloaded into the body of the while loop, so it is much easier to break apart.
So this is what we have now:
$line = rtrim(fgets($this->fp));
$lusername = array_shift(explode(":",$line)));
Uh-oh! There's that "nasty" error:
Strict Standards: Only variables should be passed by reference in /path/to/file.php on line x.
So we can see from here, the part producing the error is not explode(), but array_shift(). See also: Strict Standards: Only variables should be passed by reference
What this means is that since array_shift() modifies the array, it requires it to be by reference. Since you are not passing an actual variable but instead the result of a function, PHP is unable to modify it. It's similar to doing something like function($var) = 3;. Of course you can't do that. Instead you need to save the value to a temporary variable. So now we have:
$line = rtrim(fgets($this->fp));
$split = explode(":",$line);
$lusername = array_shift($split);
Woo hoo! No more warning message.
So putting this together, we now have:
while (!feof($this->fp) && strlen($lusername) > 0) {
$line = rtrim(fgets($this->fp));
$split = explode(":",$line);
$lusername = array_shift($split);
if($lusername == $username) {
return 1;
}
}
Also, as mentioned earlier, the fgets() will advance the pointer, which allows the !feof($this->fp) part in the while statement to vary.

php is_array() test on $value[] - not sure why it won't register as an array

I am just doing some experimenting. How do I print the value of this $chvalues[] or test (as below) it's an array. Is it possible to print this out as-is? $chvalues[] (yes my input field is properly defined with name=seminar etc...)
$chvalues = array();
if (isset($_POST['seminar'])) {
foreach ($_POST['seminar'] as $ch => $value) {
$chvalues[] = $value;
if(is_array('$chvalues[]')) {
echo "Yes. It's an Array.";
}
}
}
I am trying to test this:
if(is_array('$chvalues[]')) { ...
I get this:
Fatal error: Cannot use [] for reading in...
You are reading the array as a string by using single quotes around it (which should just return false).
You should use if(is_array($chvalues)) without the brackets.
$chvalues will always be an array, because you just assigned it to one the line before, as well as at the start of your code, before the loop.
Maybe you meant to check $value, or run the is_array() after the loop and not initialize $chvalues as an array before running the loop.
Following a variable by [] is only for appending new elements to the end of the array within the variable. If you want to look at the array then just use the variable itself.
if(is_array($chvalues)) {
...
You only use $value[] for accessing the "top" element of the $value array, the unset next position, if you will.
Change it to $chvalues in the is_array() function.
To print an array, it depends on output. Check print_r for debugging.
Also don't use quotes as they make the array act like a string, in this case (because they are single quotes) the string '$chvalues[]' is being tested for being an array.
Two problems here. First, everytime you do $chvalues[] with empty brackets, you are appending a new empty element onto your array. So when you do:
if(is_array($chvalues[]))
You always get an empty element, never an array.
Instead you probably want:
if(is_array($chvalues))
Second problem is you cannot single-quote '$chvalues[]' as you have done. It should have no quotes as in my first code block above.
don't use $chvalues[], just $chvalues (without single quotes inside the is_array function).
$chvalues = array();
if (isset($_POST['seminar'])) {
foreach ($_POST['seminar'] as $ch => $value) {
$chvalues = $value;
if(is_array($chvalues)) {
echo "Yes. It's an Array.";
}
}
}
You really want, is_array($chvalues) (which will always be true in your code) or, if you're trying to find out if the last item added to $chvalues is an array, you should call is_array($value). If you don't have that option (not sure why you wouldn't), then you can use is_array(end($chvalues)) to test the last thing added to the array. I will warn, though, that you will need to call reset to iterate through $chvalues with foreach.
Of course, you could also call $arr = array_keys( $chvalues ); is_array($chvalues[end($arr)]);, but that gets very silly (especially since I left out the last paren originally).

Why does my while loop never end

I've been trying to present my data from my database using PHP. My while loops keep running.
function makeCollection(){
$images = mysql_query("select file_id from images where collection_id = 1");
//returns file_id
$fileIds = mysql_fetch_array($images, MYSQL_NUM );
//get file ids from $images into array
while($fileIds != false){
echo($fileIds[0]);
}
}
I have three objects that fit with id = 1, 2, and 3 (it's on auto-increment). Shouldn't the loop iterate through then stop after the third? It just write '1' for infinity.
You need to call the function within the loop condition so it can be evaluated multiple times. Right now you just call it only once, that's going to tell PHP to fetch only the first row. If it's not false (i.e. MySQL returned at least one row), your while loop will be infinite.
while (($fileIds = mysql_fetch_array($images, MYSQL_NUM )) !== false) {
echo $fileIds[0];
}
By calling it every time the loop condition is checked, PHP internally advances the result set pointer so it can cover all rows in the result set. Eventually this function will return false and terminate the loop.
while($fileIds != false){
echo($fileIds[0]);
}
You're not doing anything to advance the loop field inside the loop. You have a line immediately before the loop which sets $fileIds, but as things stand, it only ever gets called once because it is outside the loop.
What you need is to put that inside the loop, probably inside the while() itself, as follows:
while(($fileIds = mysql_fetch_array($images, MYSQL_NUM)) !== false) {
....
}
Hope that helps.

count of false gives 1 and if of an empty array gives false. why?

I have a function which returns only one row as array.
I give a query as a parameter which will exactly gives only one row.
function getFields($query)
{
$t =& get_instance();
$ret = $t->db->query($query);
if(!$ret)return false;
else if(!$ret->num_rows()) return array();
else return $ret->row_array();
}
$ret = getFields('query string');
What i thought was ...
if there is an error then i can check it like if(!$res)//echo error
if it is empty i can check it like if(!count($res))// no rows
else i assume that there is a row and continue the process...
BUT
when there is an error false is returned. In if(count($ret)) gives 1.
If($ret) conditions fails (gives false) if i return as empty array.
//
$ret = getFields('query string');
if(!$fes)jerror('status,0,msg,dberror');
if(!count($fes))jerror('status,1,msg,no rows');
// continue execution when there atleast one row.
this code is called using ajax. so i return a json response.
why count gives 1 and if empty array gives false.
i just wanted to code with logical conditions instead of giving more relations conditions. just to reduce code.
Where can i get all these BUGGING stuff of php so that i can make sure i should not end up making logical errors like the above.
BUGGING - in the above sentence
bugging i referred as not a bug but
things bugs us. things which makes us
logical errors.
I edited this following code to include the following meanwhile i got this as the reply by https://stackoverflow.com/users/451672/andrew-dunn
i can do it like this but still i want to know why for the above explanation
if($fes===false)jerror();
if(!$fes)jsuccess('status,4');
"why count gives 1" - see http://docs.php.net/count:
If var is not an array [...] 1 will be returned.
"and if empty array gives false." - see http://docs.php.net/language.types.boolean#language.types.boolean.casting:
When converting to boolean, the following values are considered FALSE:
[...]
an array with zero elements
Why don't you just check if $ret === false first?
If $myVariable is not array, but empty, then
$count = count($myVariable);
gives 1.
For this situation I check whether the variable is "array" or "bool(false)". If output is array, I use count, if it isn't an array I set number to zero.
if (is_array($myVariable)) {
$count = count($myVariable);
} else {
$count = 0;
}

Categories