views:

30

answers:

3

I'm placing an entire pagination script into a function so I can use it more times. The code is long but there's just one part I'm having trouble with.

After I call the function paginate($connection, "categories"); I use

$sql = "SELECT * FROM categories ORDER BY cat_name LIMIT $start, $limit";

etc..

and I get these errors.

Notice: Undefined variable: start Notice: Undefined variable: limit You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right syntax to use near '' at line 1

It's not recognizing the variables I have in the function I called above the query. I never put this much code in a function before so I'm not sure what I have to do. I tried returning those undefined variables (in the function) but that didn't work.. I'm also trying to avoid using globals - I heard they've become deprecated.

Below is the actual function

function paginate($connection, $tableName) {

//Pagination
$targetpage = "http://localhost/website/all_categories.php";    
$limit = 4; //sets how many rows to display on each page

//count rows
$sql = "SELECT COUNT(*) as num FROM $tableName";
$total_pages = $connection->query($sql) or die(mysqli_error($connection)); 
$row = $total_pages->fetch_assoc();
$total_pages = $row['num'];

//if there's no page number, set it to the first page
$stages = 3;
$page = isset($_GET['page']) ? $_GET['page'] : 0;
$start = empty($page) ? $start = 0 : $start = ($page - 1) * $limit;

// Initial page num setup
    if ($page == 0){$page = 1;}
    $prev = $page - 1;  
    $next = $page + 1;                          
    $lastpage = ceil($total_pages/$limit);      
    $LastPagem1 = $lastpage - 1;                    


    $paginate = '';
    if($lastpage > 1)
    {   

        $paginate .= "<div class='paginate'>";
        // Previous
        if ($page > 1){
            $paginate.= "<a href='$targetpage?page=$prev'>previous</a>";
        }else{
            $paginate.= "<span class='disabled'>previous</span>";   }



        // Pages    
        if ($lastpage < 7 + ($stages * 2))  // Not enough pages to breaking it up
        {   
            for ($counter = 1; $counter <= $lastpage; $counter++)
            {
                if ($counter == $page){
                    $paginate.= "<span class='current'>$counter</span>";
                }else{
                    $paginate.= "<a href='$targetpage?page=$counter'>$counter</a>";}                    
            }
        }
        elseif($lastpage > 5 + ($stages * 2))   // Enough pages to hide a few?
        {
            // Beginning only hide later pages
            if($page < 1 + ($stages * 2))       
            {
                for ($counter = 1; $counter < 4 + ($stages * 2); $counter++)
                {
                    if ($counter == $page){
                        $paginate.= "<span class='current'>$counter</span>";
                    }else{
                        $paginate.= "<a href='$targetpage?page=$counter'>$counter</a>";}                    
                }
                $paginate.= "...";
                $paginate.= "<a href='$targetpage?page=$LastPagem1'>$LastPagem1</a>";
                $paginate.= "<a href='$targetpage?page=$lastpage'>$lastpage</a>";       
            }
            // Middle hide some front and some back
            elseif($lastpage - ($stages * 2) > $page && $page > ($stages * 2))
            {
                $paginate.= "<a href='$targetpage?page=1'>1</a>";
                $paginate.= "<a href='$targetpage?page=2'>2</a>";
                $paginate.= "...";
                for ($counter = $page - $stages; $counter <= $page + $stages; $counter++)
                {
                    if ($counter == $page){
                        $paginate.= "<span class='current'>$counter</span>";
                    }else{
                        $paginate.= "<a href='$targetpage?page=$counter'>$counter</a>";}                    
                }
                $paginate.= "...";
                $paginate.= "<a href='$targetpage?page=$LastPagem1'>$LastPagem1</a>";
                $paginate.= "<a href='$targetpage?page=$lastpage'>$lastpage</a>";       
            }
            // End only hide early pages
            else
            {
                $paginate.= "<a href='$targetpage?page=1'>1</a>";
                $paginate.= "<a href='$targetpage?page=2'>2</a>";
                $paginate.= "...";
                for ($counter = $lastpage - (2 + ($stages * 2)); $counter <= $lastpage; $counter++)
                {
                    if ($counter == $page){
                        $paginate.= "<span class='current'>$counter</span>";
                    }else{
                        $paginate.= "<a href='$targetpage?page=$counter'>$counter</a>";}                    
                }
            }
        }

                // Next
        if ($page < $counter - 1){ 
            $paginate.= "<a href='$targetpage?page=$next'>next</a>";
        }else{
            $paginate.= "<span class='disabled'>next</span>";
            }

        $paginate.= "</div>";       


}
 echo $total_pages.' Results';
 // pagination
 echo $paginate;


}//end function
A: 

edit: you're apparently defining $start inside your function. If it's defined before your SQL statement, it'll be, obviously, accessible. However, I doubut your pagination function will be very useful if you don't pass it $start or $end. You can also define default values with this syntax:

function paginate($connection, $tableName, $start=0, $end="ALL") {

original follows

Functions have their own scope; you should pass the function the variables defined outside it:

function paginate($connection, $tableName, $start, $end) {

The only exception are the superglobals $GLOBALS, $_GET, $_POST, $_COOKIE, $_REQUEST, $_SESSION, $_FILES, $_ENV and $_SERVER.

You can also access functions defined outside any function through the superglobal array $GLOBALS or by adding global $var; in the beginning of the function implementation. You are, however, discouraged to do so, except (arguably) for application scoped configuration directives.

Artefacto
see http://docs.php.net/language.variables.scope
VolkerK
Thank you! You've convinced me to just use global $var. It makes everything much simpler :)
Cyber Junkie
@Cyber Well, I hope I didn't. Otherwise you'll curse me when you have bugs because some global is being changed somewhere and you don't know where. Just pass the extra parameters instead.
Artefacto
This is why you should never even mention globals to beginners.
Mike Sherov
lol! sorry, globals just made more sense to me. Mike, I'll use the code you provided.
Cyber Junkie
+1  A: 

(Note - this isn't necessarily the problem, but...)

$start = empty($page) ? $start = 0 : $start = ($page - 1) * $limit;

should be

$start = empty($page) ? 0 : ($page - 1) * $limit;
Amber
Thank you for noticing! I changed it immediately :)
Cyber Junkie
A: 

You are setting $start and $limit inside the function, but you are not returning these variables. The variables inside the function have their own local scope, and so cannot be accessed from outside the function.

You need to return the variables that you need outside the function. As you are require more than one variable, you can return these in an associative array. For example, if you place this as the last line of your function:

return array( 'start' => $start, 'limit' => $limit );

...you can call the function like this:

$result = paginate($connection, "categories");

...and use the result like this:

$sql = 'SELECT * FROM categories ORDER BY cat_name LIMIT ' .
    $result['start'] . ', ' . $result['limit'];
Mike
You code works perfectly! This will be handy in my php venture :) Thank you!
Cyber Junkie