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.
Related
I'm trying to find the best way to compare dates outside a while statement. I wrote a function and set the while loop inside. Taking in account that I need to compare every single date from the loop with $this_new_date, how can I achieve this?
function getDates(){
$returnDates = array();
while($result = mysqli_fetch_array($allDatesQuery)){
$returnDates[] = date("Y-n-j",strtotime($result['date']));
}}
if($returnDates===$this_new_date){
//do something here
}
Please note that if you are going to use the MySQLi extension (http://php.net/manual/en/book.mysqli.php) you will need to use a while loop to store your data unless you are running PHP >= 5.3 in which case you can use mysqli_fetch_all (http://php.net/mysqli_fetch_all).
Option 1
Perform the date comparison inside the query. This is going to be your absolute best/fastest option. That way PHP does not even need to do anything.
Example:
SELECT * FROM table WHERE date = ?;
Then use a prepared statement to pass your date value to the query: http://php.net/manual/en/mysqli.quickstart.prepared-statements.php
Option 2
Assuming you need to perform this date comparison in PHP the while loop is still going to be the fastest because unless the date you're looking for is the very last record you can likely get away without having to read the entire query result.
function is_date_in_query($this_new_date, $allDatesQuery) {
while($result = mysqli_fetch_array($allDatesQuery)) {
if (strtotime($this_new_date) == strtotime($result['date'])) {
return TRUE;
}
}
return FALSE;
}
if (is_date_in_query($this_new_date, $allDatesQuery)) {
// yes the date is inside - do something
}
else {
// no the date is not inside - do something else
}
But you say you cannot use a while loop so let's look at another option.
Option 3
Use a combination of mysqli_fetch_all, in_array and array_column. This prevents any while loops but requires you to load the entire query result.
Example:
// Put ALL rows into an array
$result_array = mysqli_fetch_all($allDatesQuery, MYSQLI_ASSOC);
// Check if the date is anywhere in the result array
if (in_array(date('Y-m-d', strtotime($this_new_date)), array_column($result_array, 'date'))) {
// yes the date is inside - do something
}
else {
// no the date is not inside - do something else
}
Here is a working example (updated): https://eval.in/868105
you could do something like this:
...
$matchedDates = array_filter($returnDates, function($value) use($this_new_date){
return $value == $this_new_date;
});
var_dump($matchedDates);
I have two "buttons" to move the array cursor to the next record or to the prior record. The function using "next" to move to the next (older) record works correctly.
However, the function to move to the prior ("prev") record (which is toward the top of the array) does not work correctly. I suspect that may be related to using "mysqli_data_seek". My belief was that it would set the cursor to the current location and then backtrack to the previous record. Instead the cursor continues to moves forward as if "next" was used instead of "prev". How can I backtrack to the prior record?
function return_next_issue()
{
// Newer Issue - Moves up towards the top of the array.
// mysqli_data_seek($_SESSION['result'], 0);
while($row=mysqli_fetch_array($_SESSION['result'], MYSQL_NUM))
{
if($_SESSION['issuenum'] == $row[0])
{
break;
}
}
prev($_SESSION['result']);
$row=mysqli_fetch_row($_SESSION['result']);
return $row[0];
}
since the mysqli_result object is in the session and shared, you might want to initialize the internal pointer to 0 to make sure you know you are going to seek from the start. You can also create a variable that increments over the iteration to identify the index you need and seek for the previous one.
function return_next_issue()
{
// Newer Issue - Moves up towards the top of the array.
$i = 0;
mysqli_data_seek($_SESSION['result'], 0);
while($row=mysqli_fetch_array($_SESSION['result'], MYSQL_NUM))
{
if($_SESSION['issuenum'] == $row[0])
{
break;
}
$i++;
}
mysqli_data_seek($_SESSION['result'], $i - 1);
$row=mysqli_fetch_row($_SESSION['result']);
return $row[0];
}
Please note that your code won't work if $_SESSION['issuenum'] is 0 or if is greater than the number of rows available, and therefore so do the code I am providing.
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;
}
I have a foreach loop, that will loop through an array, but the array may not exist depending on the logic of this particular application.
My question relates to I guess best practices, for example, is it ok to do this:
if (isset($array))
{
foreach($array as $something)
{
//do something
}
}
It seems messy to me, but in this instance if I dont do it, it errors on the foreach. should I pass an empty array?? I haven't posted specific code because its a general question about handling variables that may or may not be set.
Just to note: here is the 'safest' way.
if (isset($array) && is_array($array)) {
foreach ($array as $item) {
// ...
}
}
Try:
if(!empty($array))
{
foreach($array as $row)
{
// do something
}
}
That's not messy at all. In fact, it's best practice. If I had to point out anything messy it would be the use of Allman brace style, but that's personal preference. (I'm a 1TBS kind of guy) ;)
I'll usually do this in all of my class methods:
public function do_stuff ($param = NULL) {
if (!empty($param)) {
// do stuff
}
}
A word on empty(). There are cases where isset is preferable, but empty works if the variable is not set, OR if it contains an "empty" value like an empty string or the number 0.
If you pass an empty array to foreach then it is fine but if you pass a array variable that is not initialized then it will produce error.
It will work when array is empty or even not initialized.
if( !empty($array) && is_array($array) ) {
foreach(...)
}
I would say it is good practice to have a 'boolean' other value that is set as 0 (PHP's false) to start, and any time some function adds to this array, add +1 to the boolean, so you'll have a definite way to know if you should mess with the array or not?
That's the approach I would take in an object oriented language, in PHP it could be messier, but still I find it best to have a deliberate variable keeping track, rather than try to analyze the array itself. Ideally if this variable is always an array, set the first value as 0, and use it as the flag:
<?PHP
//somewhere in initialization
$myArray[0] = 0;
...
//somewhere inside an if statement that fills up the array
$myArray[0]++;
$myArray[1] = someValue;
//somewhere later in the game:
if($myArray[0] > 0){ //check if this array should be processed or not
foreach($myArray as $row){ //start up the for loop
if(! $skippedFirstRow){ //$skippedFirstRow will be false the first try
$skippedFirstRow++; //now $skippedFirstRow will be true
continue; //this will skip to the next iteration of the loop
}
//process remaining rows - nothing will happen here for that first placeholder row
}
}
?>
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);
}