Forum Moderators: coopster
Is it possible, or do I need to create a new page?
Another words, If $book_array =5, then start a new page
Here is the code as exists:
function display_books($book_array)
{
//display all books in the array passed in
if (!is_array($book_array))
{
echo '<br />No items currently available in this category<br />';
}
else
{
//create table
echo '<table width = \"100%\" border = 0>';
//create a table row for each book
foreach ($book_array as $row)
{
$url = 'show_book.php?item_number='.($row['item_number']);
echo '<tr><td>';
if (@file_exists('images/'.$row['item_number'].'.jpg'))
{
$team = '<img src=\'images/'.($row['item_number']).'.jpg\' border=0>';
do_html_url($url, $team);
}
else
{
echo ' ';
}
echo '</td><td>';
$team = $row['player'].' of the '.$row['team'];
do_html_url($url, $team);
echo '</td></tr>';
}
echo '</table>';
}
echo '<hr/>';
}
As always, thanks for your help.
I was good up to this point:Locate the line that reads:display_books($book_array);
I found the code, but what has to ben done?
Do nothing at this moment. I just want you to know where the function is called from.
(I assume you still have a working copy of the store to play with). - Nope there are no html pages, the html is in the output_fns.php page.
That is correct but the code works right? That's all I was aiming for. A working example for you to play with.
I'll continue on to the next step in a bit.
I messed up, and not sure how. I don't get an error but my "data" is gone. I am told there is nothing in the category, when I know there is. That is the text that is displayed to a visitor (me) when I don't have anything in the category.
I played around with the limit "expression" but I still get the message.
In order to use the $offset var in the query, we have to be sure the variable exists and gets passed to the query. So in the file show_cat.php ABOVE the function get_books we need to add:
if (!isset($offset))
$offset = 0;
settype ($offset, "integer");
The first line checks for the existence of $offset and if it doesn't exist, it sets it to 0 - the beginning of the database results.
The second line is setting us up to convert the offset value we pass on the URL back into an integer so we can add to or subtract from it (in order to move forward or backward in our nav).
Add these and change the query and function arguments to include $offset. Also add the argument ($offset) to the get_books function in show_cat.php.
The show_cat page should work but should limit you to the first 5 records with no way of moving forward or backward - just yet. With me so far?
The problem with the details page (I think) was I had a coma in between the $offset and 3, like
"select * from books where catid='$catid' limit $offset[,] 3";
I pasted this in the show cat file.
if (!isset($offset))
$offset = 0;
settype ($offset, "integer");
// get the book info out from db
$book_array = get_books($catid);
The problem I am having now is adding html to the output page. If I do it line <hr\> it works, but if I do it below the line I get all kinds of errors. I played around with it but still got errors.
>> comma
From MySQL "[LIMIT [offset,] row_count ¦ row_count OFFSET offset]"
So the comma is not the issue the line should look like:
LIMIT $offset,5
// get the book info out from db
$book_array = get_books($catid);
Should now read:
$book_array = get_books($catid,$offset);
because we need to pass the offset to the query for use.
I changed limit to 3 so I can make sure it is working.
If you mean which file they will be added to then yes. Once we/you add them they will appear only when needed.
Ok, deep breath. Next step. A lot of stuff can go wrong here but part of learning PHP (any scripting/programming language) is learning how to troubleshoot and correct mistakes. So don't be afraid to comment out sections and echo the value of a variable to screen in order to see if your code is working. Testing bits of your code is a good way to narrow down where the problem lies and even to help you better understand how the code works.
A bit of explanation is in order for the next part. So far we've built a limit into the query and set the max number of records to be returned. The file output_fns.php is responsible for building the framework of our page but the base file - the one the URL displays - is still show_cat.php.
The function get_books($catid, $offset) is what we need to use to display the books. But we need to be able to change the offset in order to view all of the books AND we need to make sure we pass the $catid each time so the query knows which category to use. We'll do this by calling the function that get's the books each time we want to see more books. How? Well by calling the same base file again and telling it what the new offset is.
Here's where it gets challenging. I had you locate a spot in the function display_books() that was above the <hr>. Thats the line where I want you to build two links. These are for the 'Previous' and 'Next' navigation. Build one that subtracts 5 from $offset and then one that adds 5 to $offset and set the URL to pass the new values AND the catid. What page to link to? The base page - show_cat.php.
If you're not familiar with how to pass variables on the URL it goes like this.
thefile.php?&the bolding is only to get you to see that the first var is seperated from the filename with a? and all subsequent vars are seperated with &. This should give you a set of dumb links. In otherwords, the code is not yet set up to determine if you're at the beginning or the end of the records that meet the criteria of the query. That's next. Play with this and see if you can get it working.
I located display_books in the output_fns page but am very confused as to what to do and where to do it.
The html code I made for prev and next is on the show_cat page. I am not sure I undestand the +/- for the offset.
Would be be something like:
$next=($offset +5);
$prev=($offset -5);
I am going to have to read on how to pass the url too.
Guess I get the F today,
thanks
I located display_books in the output_fns page but am very confused as to what to do and where to do it.
That function (display_books) is what outputs the books. In that function there is a line that has the <hr>. Just above that is where we want to add our navigation. This is where I want you to add your Previous/Next links.
The html code I made for prev and next is on the show_cat page. I am not sure I undestand the +/- for the offset.
Your code needs to be in the display_books function. Remember, show_cat_php is strictly used to call functions and pass variables.
Would be be something like:$next=($offset +5);
$prev=($offset -5);I am going to have to read on how to pass the url too.
That sets you up for the value of $offset. You're halfway there. Let's do this. If you wanted to pass an offset of 5 and a catid of 13 to the show_cat.php file the URL would look like:
show_cat.php?offset=5&catid=13
It's that simple. So take this concept to the next level. Build the links within the display_books function above the <hr> tag so that one decrements $offset and the other increments it.
In show_cat.php:
// get the book info out from db
if (!isset($offset))
$offset = 0;
settype ($offset, "integer");
$book_array = get_books($catid,$offset);
display_books($book_array,$catid,$offset);
In output_fns.php:
function display_books($book_array,$catid,$offset)
{
//display all books in the array passed in
if (!is_array($book_array))
{
echo "<br>No books currently available in this category<br>";
}
else
{
//create table
echo "<table width = \"100%\" border = 0>";
//create a table row for each book
foreach ($book_array as $row)
{
$url = "show_book.php?isbn=".($row["isbn"]);
echo "<tr><td>";
if (@file_exists("images/".$row["isbn"].".jpg"))
{
$title = "<img src=\"images/".($row["isbn"]).".jpg\" border=0>";
do_html_url($url, $title);
}
else
{
echo " ";
}
echo "</td><td>";
$title = $row["title"]." by ".$row["author"];
do_html_url($url, $title);
echo "</td></tr>";
}
echo "</table>";
}
echo "<p>";
if ($offset > 0){
echo "<a href=\"show_cat.php?catid=".$catid."&offset=".($offset - 2)."\"><< Previous</a> - ";
}
echo "<a href=\"show_cat.php?catid=".$catid."&offset=".($offset + 2)."\">Next >></a></p>";
echo "<hr>";
}
In book_fns.php:
function get_books($catid,$offset)
{
// query database for the books in a category
if (!$catid ¦¦ $catid=="")
return false;
$conn = db_connect();
$query = "SELECT *
FROM books
WHERE catid='$catid'
LIMIT $offset,2";
$result = @mysql_query($query);
if (!$result)
return false;
$num_books = @mysql_num_rows($result);
if ($num_books ==0)
return false;
$result = db_result_to_array($result);
return $result;
}
The bolded items are what I changed/added. Your code is most likely different so you'll need to pick over what I give you here.
needed to add ($catid,$offset)to the book array because it was passing through the URL?
2 is now an "integer" but why not just put 2 there?
show_cat.php?catid=".$catid."&offset=".($offset - 2)." -- does this mean it takes the category and "returns" 2 items?
I noticed that it will give a next when there isn't another record. I am going to try to play with this to see if any of it sunk in.
Thanks again for the help.
Ok, so let me see if I get this. IT says that it will search "X" (this case 2) records in a given category.
I assume you mean the query. Yes, I used 2 for my tests. The offset is determined by the current offset ($offset) +/- (Next/Previous) 2. Again, 2 for my tests - change at will.
If offset (total number? of records?) is greater then 2 make two links,
one that will go back 2 records and one that will got forward 2 records.
Almost. Offset is only a pointer to where we want the query to return results from.
needed to add ($catid,$offset)to the book array because it was passing through the URL?
We needed to add these to the function so we could use them on the URL to indicate what offset and what category.
2 is now an "integer" but why not just put 2 there?
We're setting the offset to 'integer'. $offset could be any number and we need to make sure it's an integer so we can perform our basic math on it.
show_cat.php?catid=".$catid."&offset=".($offset - 2)." -- does this mean it takes the category and "returns" 2 items?
Nope. It simply means set the offset back two records. $offset starts at 0. If we move forward 2 the URL would look like this (hardcoded and skipping stuff)
show_cat.php?offset=(0+2) or offset = 2 which tells the query when you get the records start at record #2 (the third record). If we want to go back we have to subtract 2 instead. It's simple math which will get processed before the URL link is built and displayed.
I noticed that it will give a next when there isn't another record. I am going to try to play with this to see if any of it sunk in.
I've got to leave you something to add! ;)
It seems that offset rules over limit.
Not sure what you mean. They work together, but neither "rules". Anyway, here's how it goes.
I have records where id = a number 1-100. Let's assume there are no gaps in the series, so there are 100 records.
select id from mytable order by id limit 10
will return records numbered 1-10. It says, in plain English,
1. from the table mytable, get all id numbers
2. then make a list that puts them in order from lowest to highest.
3. now, give me the first ten from that list.
Note that SQL first applies the order and then the limit. That's a good thing. Otherwise you would get the first ten records MySQL finds (unpredictable) which would then be ordered.
select id from mytable order by id limit 0, 10
This is functionally the same as the first select, but adds a step. It says, in plain English,
1) from the table mytable, get all id numbers
2) then make a list that puts them in order from lowest to highest.
3) move forward in that list ZERO steps - so from record 1 to record 1.
4) now, starting with the current record, give me the NEXT ten from that list.
Now let's add an offset that really matters
select id from mytable order by id limit 1, 10
This will give you records 2-11. It tells the system
1) from the table mytable, get all id numbers
2) then make a list that puts them in order from lowest to highest.
3) move forward in that list ONE step - so from record 1 to record 2.
4) now, starting with the current record (i.e. #2), give me the NEXT ten from that list.
It is important to note that limit 1, 10 does NOT give you records 1-10. It gives you records (1 + offset) to (limit + offset).
Tom
Does the offset check the records each time? For example on this script (I am am correct) we are saying search the first 5 results of a table and display them 2 at a time. If there are more then 2 provide a link that will allow 2 more items. However does it check to so how many items are left?
Also, thinking out loud, for this line:
if ($offset > 0 .. links
I changed it to if ($offset > 2 thinking if the results were not greater than 2 the links wouldn't show, but it didn't happen.
But in playing around with the code I noticed a few things:
* not all my records are being shown, even if I change the limit to more then what I have
* there is duplication of some cards when I hit next
Look back at my previous post, explaining offset. I'll post more detail in a second...
MORE DETAIL
Assumptions
- 100 records
- 10 records per page
Based on my first post in this thread, you should know how to figure the number of pages and you will have links from page to page. Each of these links needs to have a GET parameter, as in
href="file.php?page=2"
In file.php, you now know which page of the result set you are on, using the variable $_REQUEST['page'] or $_GET['page']
If this is new to you, see the PHP manual on predefined variables.
Now, limit has two parameters
- results returned per query
- and offset
Which one has to change as you page through your results, your starting point, or the number of records that you return?
How will it change as you go from page to page?
Give it a try. I think it will make more sense in the long run if you try to work it out.
Tom
we are saying search the first 5 results of a table and display them 2 at a time.
I honestly haven't read all of this massive thread, but you can't be doing that. You always search within the entire table. Every query looks at all records, and then chooses according to the conditions you set.
The basics of what you are doing are:
1. look through ALL records EVERY time to find ones that match the critiera in the SELECT ... FROM ... WHERE... part (or JOIN if you are doing it that way). But the system does not return this. It goes on to the next step first.
2. Sort the records returned according to the ORDER BY the condition you set (col name and, if applicable, DESC). This still includes ALL records returned based on searching the ENTIRE table in step one. This is true every time you execute a query. But the system does not return this. It goes on to the next step first.
3. Return only the records stipulated by the LIMIT statement. So if it is "LIMIT 2, 2", as it would be if you are displaying two records per page and are on page two, it returns records 3-4. That's it. If steps 1 and 2 return 1000 records or 2, step three LIMITs this so that a maximum of two records are returned. If you want to find out what records 5-6 are, you must do another query, same as the first, but with "LIMIT 4, 2".
Tom
Now my major question after re readin the post. And maybe something I should have asked before hand. Should I load/input my data first before setting this up? Right now I may have 10 items or 100 items.
c) why do we want to limit the results if offset will display them in the qty that is desired?
Reread my posts and the manual on LIMIT. You still don't understand it. the offset in no way determines the quantity returned (actually, there is an exception, but we won't confuse you with that for the moment).
Tom
I have played around with the script and am stuck. Basically I have two things, the script returns the prev/next links even if nothing is left in the offset. I tried a else statement but got an error. I changed the offset number but that didn't work. I assume the script is looping because it displays text that is the beginnig of the function. How do I write this,
if $results (of the search) = no more, than stop.
Also, sometimes the item is repeated, I have noticed this in other "professional" sites as well. It is a pitfall of mysql?
Thanks
It is a pitfall of mysql?
Except in the case when cosmic radiation hits to computer and flips a bit, this is the fault of some programmer along the line, and in this case, not the mysql programmers (see quote after sig).
You need to test for total number of results returned so that you know where you are in the result set, how many you have left, whether to show links to subsequent pages and so on. This means issuing another two queries, either
1.
$result = mysql_query("SELECT id FROM mytable");
$total_returned = mysql_numrows($result);
2.
$result = mysql_query("SELECT count(*) as rowcount FROM mytable");
$total= mysql_fetch_assoc($result);
$total_returned = $total['rowcount'];
Tom
Numbers that fool the Fermat test are called Carmichael numbers, and little is known about them other than that they are extremely rare. There are 255 Carmichael numbers below 100,000,000. The smallest few are 561, 1105, 1729, 2465, 2821, and 6601. In testing primality of very large numbers chosen at random, the chance of stumbling upon a value that fools the Fermat test is less than the chance that cosmic radiation will cause the computer to make an error in carrying out a ``correct'' algorithm. Considering an algorithm to be inadequate for the first reason but not for the second illustrates the difference between mathematics and engineering.