I'm very new to web programming, and I'm working through a Vikram Vaswani's How to Do Everything With PHP and MySQL. Near the end, he shows how to do a web program which shows news items and allows the user to edit and add different news items. The code doesn't seem to work and I've tweaked it to get it to work, but I'm still confused. In particular, I have the following code (this website isn't handling the breaks very well)
// if records present
if (mysql_num_rows($result) > 0)
{
// iterate through resultset
// print article titles
while($row == mysql_fetch_object($result));
{
?>
<li><?php echo $row->StockName;?></li>
<?php
$row = mysql_fetch_object($result);
echo $row->Ticker;
echo $row->StockName;
<br>
Now, the book had while ($row = mysql_fetch_object($result)); - but that didn't do anything. So I changed it to an equal comparison operator. I'm thinking that with the $row = mysql_fetch_object($result) at the bottom in the loop, it should move onto the next row of the table since this is the normal behavior per http://us2.php.net/manual/en/function.mysql-fetch-object.php and per my own testing. I can do this differently with a for loop or something but I would like to figure out why it isn't working how I expect here.
It should definitely be:
while($row = mysql_fetch_object($result))
{
}
It looks like you've got a semicolon at the end of the while line, and that would end the while loop right then. Instead you should be opening up a block of code with parenthesis. If no results are returned, then it will be false and exit the while loop.
In your while loop, the mysql_fetch_object() returns the next row in your $result. If you're testing with == operator it cannot be true.
Related
I have a database result set created from a PDO object.
The array contains all the data. Now I want to print the results but I want to start the printing from a specific index and not from the start.The start index is specified from a user. Please don't tell me to modify the query because this is not what I want. Also I've searched everywhere and didn't found any solutions to this.
I simplified my code so it's more understandable and easier to come to the point.
Thanks for any-kind of help. :>)
$res2=$conn->prepare("SELECT COUNT(*) FROM blogs");
$res2->execute();
while($r=$res2->fetch(PDO::FETCH_BOTH)){
// I have 37 records in $res2 and want to start echoing from record number 10.
//for example I want to echo out $r['title'] but not from the first but from the 5th or 10th index.
}
Use an if() statement and a counter:
$userInput = 5;
$i = 0;
while($r=$res2->fetch(PDO::FETCH_BOTH)){
if($i >= $userInput){
// echo your output here
}
$i++;
}
this is the PHP code i have:
while($row1 = mysql_fetch_object($query1)) {
echo "*".$row1->id."*";
while ($row2 = mysql_fetch_object($query2)) {
echo "%".$row2->id."%";
}
}
I want it to output for example: *1*%1%%2%%3%%4%*2*%1%%2%%3%%4%*3*%1%%2%%3%%4%
But what this loop outputs is: *1*%1%%2%%3%%4%*2**3*
(It only outputs the $row2 values in the first loop of $row1.
How can I fix this? Thanks.
A few things to note about mysql_fetch_object(). From the PHP document:
Warning: This extension is deprecated as of PHP 5.5.0
Please note above.
returns an object with properties that correspond to the fetched row and moves the internal data pointer ahead.
Please note what I bolded.
The $result object (in your code this would be $query2) is an iterative object that has a pointer pointing to the current item.
Current Item
|
v
[1][2][3][4]
When your first loop hits your second loop, it iterates over the whole thing, such that at the end, the object now looks something like this:
Current Item
|
v
[1][2][3][4]
For each iteration of the first loop, after the first time, the mysql_fetch_object() function basically goes like this:
mysql_fetch_object() ~
1. Get the next time
2. Uh, there are no more objects because we're at item [4]. Return done.
So, how do you get it to work? You could simply save the results into an array and then iterate over that array or you can reset the pointer with mysql_data_seek() (which is also deprecated as of 5.5).
To reset the data pointer, it would be something like this:
while($row1 = mysql_fetch_object($query1)) {
echo "*".$row1->id."*";
while ($row2 = mysql_fetch_object($query2)) {
echo "%".$row2->id."%";
}
// put the result pointer back to the front
mysql_data_seek($query2, 0)
}
Note1, This SO question/answer helped me find the function to use to reset the pointer.
Note, the downside is that you're calling a function that's creating an object, which creates processing overhead every time it runs.
The other option would be save the results into an array and just loop through the array every time:
$secondary_result = array();
while ($row2 = mysql_fetch_object($query2)) {
$secondary_result[] = $row2;
}
while($row1 = mysql_fetch_object($query1)) {
echo "*".$row1->id."*";
foreach($secondary_result as $row2) {
echo "%".$row2->id."%";
}
}
Note, this method will be creating extra memory usage of storing the objects in an array, but it would save on CPU processing as you're not re-creating the objects over and over again, as well as calling a function.
If you just print output, you can consider just saving the result first. No matter now many times you loop over $secondary_result, the final result will always be the same (as per your code, the first loop shows no signs of being directly influencing the second result).
In that case, this makes much more sense
$buffer = '';
while ($row2 = mysql_fetch_object($query2)) {
$buffer .= "%".$row2->id."%";
}
while($row1 = mysql_fetch_object($query1)) {
echo "*".$row1->id."*";
echo $buffer;
}
but I really don't know why you'd do that. If you're doing a nested loop, usually it's because the result of the first loop is affecting the second loop.
But I hope that helps!
Cheers!
EDIT
Per #Blazemonger's comment about looking ahead, the PDO equivalent would be: MySqli:Fetch-Object
When you have a result object from using the PDO function, you would loop like this:
while($row1 = $query1->fetch_object()) {
echo "*".$row1->id."*";
while ($row2 = $query1->fetch_object()) {
echo "%".$row2->id."%";
}
// put the result pointer back to the front
$query2->data_seek(0);
}
The above example shows both the fetch Object and pointer reset versions of MySqli.
The problem is that once you iterate fully through $query2, that's the end of your results. The next time through your $row1 loop, you're still at the end of $query2 and have no results left. Try using mysql_data_seek to go back to the start of your results:
while($row1 = mysql_fetch_object($query1)) {
echo "*".$row1->id."*";
mysql_data_seek($query2, 0);
while ($row2 = mysql_fetch_object($query2)) {
echo "%".$row2->id."%";
}
}
if you really need to repeat your second query data many times, get it into array first, and loop over this array as many times as you need.
First of all: The mysql_* functions are deprecated and will be removed in PHP 5.5. Consider using mysqli or PDO instead.
That being said; back to your question:
Each result set contains an internal pointer to one of the records in the result set. Initially, this pointer points to the first record, and is advanced with each call to mysql_fetch_object.
After your first inner loop, the internal pointer of the $query2 result set will already be at the end of the list, so subsequent calls to mysql_fetch_object will only return FALSE.
If your inner query depends on values from $row1, you will need to re-execute the second query within your outer loop. Otherwise, you can reset the result pointer with mysql_data_seek.
Perhaps you're not getting anything when you call $row2 = mysql_fetch_object($query2) which would give you the output you're getting.
After the first loop there are no more results for query2 to return. So the while is false in each additional loop. You would want to reset the query with mysqli_data_seek or storing all the data in a separate array and looping through that instead.
Please also note:
Per the documentation http://us2.php.net/manual/en/function.mysql-fetch-object.php
The mysql extension is deprecated as of PHP 5.5.0, and will be removed
in the future. Instead, the MySQLi or PDO_MySQL extension should be
used
I have a really strange problem with range();
According to docs :
Create an array containing a range of elements
But when I do :
foreach (range(900,950,1) as $art_id){
//ob_start();
//do stuff
//do a lot more stuff
echo $art_id;
//ob_get_clean(); }
or even
$arts_id = range (900, 920);
foreach ($arts_id as $art_id){
//ob_start();
//do stuff
//do a lot more stuff
echo $art_id;
//ob_get_clean(); }
The output is strangly repeating itself in a series like
"900,900,901,900,901,902,900,901,9002,903,900..."
meaning it is comming back to the first ID after each loop.
(1st iteration -> 900
2nd iteration -> 900,901
3rd iteration -> 900,901,902
...)
When I just put a manual array it works perfectly in order and no duplicates :
$arts_id = array(900,901,902,903,904,905,906,907,908,909,910...);
What Am I doing wrong (again ?? )
EDIT I
here is the whole script :
http://pastebin.com/ZHm3ub6n
It is actually a slightly modified version of the slashdot scraping example included in the simplehtmldom script . Nothing special.
It is executed inside WP but OUTSIDE the loop ..
It must be in the rest of your code, because this works fine.
please share more of the script.
It looks like the foreach is nested within a similair foreach,
$arts_id = range (900, 920);
foreach ($arts_id as $art_id){
foreach (range (900,$art_id) as $art_id2){
echo $art_id2."<br/>";
}
}
This produces an output you've described
EDIT
Personally i'd add the the function scraping_slashdot a reset of the variable $ret just in case.
for example:
$ret = array();
Currently the echo of $output is within the loop, which creates an output like the following:
Article 1
Article 1, Article 2
Article 1, Article 2, Article 3
etc.
place echo $output outside the loop, or $ouptut = ''; inside the loop.
Why is this not possible? Is there some way I can make the resolut not to be empty?
$sqlAllInfo = "SELECT item1, item2 FROM example";
$resAllInfo = mysql_query($sqlAllInfo);
while($rowAllInfo = mysql_fetch_assoc($resAllInfo)){
echo $rowAllInfo['item1'];
}
$rowAllInfo = mysql_fetch_assoc($resAllInfo);
echo $rowAllinfo['item2'];
Thanks for your time
No, the result will always be empty after your while loop, because the while loop extracts all value from the result resource..the while loop continues looping while there is still information to extract, and will finish when it is empty or when an error occurs
if you ment to get the last entry
$rowAllInfo still contains the last entry ;)
You are looping through the result set using while until there are no more results left. The while loop exits when mysql_fetch_assoc returns false, because there are no more results. Calling mysql_fetch_assoc again still means that there are no more results.
This line:
while($rowAllInfo = mysql_fetch_assoc($resAllInfo)){
assigns a new value to rowAllInfo and afterwards checks whether it is still "true"-ish (as "true" as PHP can be ;-) )
Now, after the last row is fetched, mysql_fetch_assoc() will return false, which is then assigned to $rowAllInfo. As $rowAllInfo is now "false", the loop will not execute anymore, but - look - it's too late! You Variable already has the value false assigned to it.
Even after that, you call mysql_fetch_assoc() once again. But, as you have already fetched all rows within your loop, no more rows are left, and once again $rowAllInfo is set to "false".
So, whatever you are trying to do - this is probably not your way. A common way to achieve what I understand you are trying to do is the following:
$allRows = array();
while( $row = mysql_fetch_assoc($res) ) {
$allRows[] = $row;
}
// show the array we just created...
echo print_r( $arrRows, 1 );
Some people say you should not use mysql_fetch_assoc more than one time, why is that?
e.g.: I want to display two tables one with users who paid for membership, other with users who did not, so instead of querying database 2 times I query it one time and get $result variable with both types of users then I run loop mysql_fetch_assoc and see if list['membership'] = 'paid' then echo ...
Second time I loop loop mysql_fetch_assoc and see if list['membership'] = 'free' then echo ...
What uses less resources considering I got about equal amount of users who registered and unregistered.
Think of your query result set as a sausage, and mysql_fetch_assoc() as a knife that slices off a piece of that sausage. Every time you fetch a row, another piece of sausage is cut off, and it's always a NEW piece of sausage. You can't go and cut off a previously cut piece, because it's been eaten already.
Quote by Typer85 (link):
Please be advised that the resource result that you pass to this function can be thought of as being passed by reference because a resource is simply a pointer to a memory location.
Because of this, you can not loop through a resource result twice in the same script before resetting the pointer back to the start position.
For example:
<?php
// Assume We Already Queried Our Database.
// Loop Through Result Set.
while( $queryContent = mysql_fetch_row( $queryResult ) {
// Display.
echo $queryContent[ 0 ];
}
// We looped through the resource result already so the
// the pointer is no longer pointing at any rows.
// If we decide to loop through the same resource result
// again, the function will always return false because it
// will assume there are no more rows.
// So the following code, if executed after the previous code
// segment will not work.
while( $queryContent = mysql_fetch_row( $queryResult ) {
// Display.
echo $queryContent[ 0 ];
}
// Because $queryContent is now equal to FALSE, the loop
// will not be entered.
?>
The only solution to this is to reset the pointer to make it point at the first row again before the second code segment, so now the complete code will look as follows:
<?php
// Assume We Already Queried Our Database.
// Loop Through Result Set.
while( $queryContent = mysql_fetch_row( $queryResult ) {
// Display.
echo $queryContent[ 0 ];
}
// Reset Our Pointer.
mysql_data_seek( $queryResult );
// Loop Again.
while( $queryContent = mysql_fetch_row( $queryResult ) {
// Display.
echo $queryContent[ 0 ];
}
?>
Of course you would have to do extra checks to make sure that the number of rows in the result is not 0 or else mysql_data_seek itself will return false and an error will be raised.
Also please note that this applies to all functions that fetch result sets, including mysql_fetch_row, mysql_fetch_assos, and mysql_fetch_array.
When someone says you can't call mysql_fetch_assoc() twice, they mean against the same resource. The resource result you pass in to mysql_fetch_assoc() is done by reference. You'll need to reset the position of the pointer before you can use mysql_fetch_assoc() a second time.
EDIT: And to do so, try using mysql_data_seek().
It appears that what you want to do is to treat the query result as an array (rows) of arrays(fields). But that's not really what the mysql library provides. What I will often do is in fact copy the rows into an array of arrays (just loop on mysql_fetch until empty) and then do what I want with my own rowset using array functions that PHP provides for the purpose. This also minimizes the amount of time the table is locked.