简体   繁体   中英

How to refer to next and previous array value?

I'm trying to make a simple blog. On the bottom of the page content i placed pagination which displays links to next and previous blog entry, with the blog title in the link that I'm getting from the database table called "pages", column "menu_name". I did this by first making a query and creating an array through a function in the class called "Blog" and then setting some variables:

$sql = "SELECT * FROM pages ";
$sql .= "ORDER BY id DESC ";
$pages = Blog::find_by_sql($sql);
$blog_page = reset($pages);
$page_id = Blog::find_by_id(isset($_GET['page']) ? $_GET['page'] : $blog_page->id);

Then I made the code for the previous blog link as follows:

public function pagination_previous(){
    global $address; //$address = "list_blogs.php?page=";
    global $page_id;
    global $pagination; //a class for storing functions that handle pagination
    global $pages;
    if($pagination->has_next_page()){
        echo "\n        <a class=\"olderblog\" href=" . $address;
        echo $pagination->next_page();
        echo " title=\"Newer Blog\">&laquo; ";
        foreach($pages as $page => $value){
            if($page_id->id + 1 == $value->id){
                echo $value->menu_name;
            }
        };
        echo "</a> ";   
    }else{
        echo "";
    }   
}

This is the function has_next_page()

public function has_previous_page(){
    return $this->previous_page() >= 1 ? true : false;  
}

and this is previous_page():

public function previous_page(){
    global $blog;
    return $this->current_page - 1;
}

This worked great until I decided to make admin area from where I can delete blog entries. The problem starts when I delete a blog entry with id let's say 6. Since there is no more item with id=6 in the database table "pages", the links to next or previous page on the pages that came before and after the missing page are empty but still point to the page=6 since has_previous_page() subtracts 1 from $current_page. I half-way figured out a way out of this mess by setting the pagination_next() function like this:

public function pagination_next(){
    global $address;
    global $pagination;
    global $page_id;
    global $pages;
    if($pagination->has_previous_page()){
        foreach($pages as $page => $value){
            if($page_id->id - 1 == $value->id){

                echo "\n        <a class=\"newerblog\" href=" . $address;
                echo $value->id;
                echo " title=\"Older Blog\">";
                echo $value->menu_name;
                break;
            }

        }
        echo " &raquo;</a> ";   
    }else{
        echo "";
    }   
}

This however still does not work because of the if condition inside the foreach loop. I need to set this condition in both pagination_previous() and pagination_next() to reference the next and previous array item based on its array index ($page), not on the id ($value->id) but I can't figure this out for the life of me. This is how the array $pages looks like:

Array
(
[0] => Blog Object
    (
        [id] => 8
        [subject_id] => 2
        [menu_name] => Aliquam sed interdum
        [position] => 4
        [visible] => 1
        [created] => 
        [content] => 
    Aliquam sed interdum tortor. Vivamus et blandit velit...

[1] => Blog Object
    (
        [id] => 7
        [subject_id] => 2
        [menu_name] => Vestibulum ante ipsum
        [position] => 3
        [visible] => 1
        [created] => 
        [content] => 
    Vestibulum ante ipsum primis in faucibus orci luctus et ultrices...

[2] => Blog Object
    (
        [id] => 5
        [subject_id] => 2
        [menu_name] => Praesent massa mi
        [position] => 2
        [visible] => 1
        [created] => 
        [content] => 
    Praesent massa mi, pretium et leo vitae, aliquam...

[3] => Blog Object
    (
        [id] => 4
        [subject_id] => 2
        [menu_name] => Nam interdum tincidunt
        [position] => 1
        [visible] => 1
        [created] => 
        [content] => 
    Nam interdum tincidunt purus quis lacinia. Aliquam erat volutpat.
)

)

Can someone help me out with this?

Thank you all for your answers, but unfortunately none of them helped me solve my problem. After exhausting all options, I definitely concluded that the only way to solve this without messing up the entire code is to figure out how to refer to the next or previous existing $value->id in the if condition without adding or subtracting 1 to get to the next page, because that causes empty links to appear when id is missing from the database. If anyone can solve this puzzle, I will be eternally grateful to that person.

You could turn your previous_page function to something along these lines :

public function previous_page( )
{
    global $blog;

    $prev = -1; // Initialize

    $arrayKeys = array_keys( $blog );

    rsort( $arrayKeys );    //  Sort keys array in reverse order

    while( list( $key ,$cursor ) = each( $arrayKeys ) )
    {
        if( $cursor == $this->current_page )
        {
            if( list( $key ,$prev ) = each( $arrayKeys ) ) return $prev;
            break;
        }
    }
    return $prev;
}

The below might give more understanding :

//  Test data

$array = array( 0 => 'Obj 0' ,1 => 'Obj 1' ,2 => 'Obj 2' ,3 => 'Obj 3' ,4 => 'Obj 4' , );


$current = 3;   //  Try with any valid key of the array


//  Get the keys into an array

$arrayKeys = array_keys( $array );

//  Search for next

$next = -1; // Initialize

sort( $arrayKeys ); //  Sort the keys array

while( list( $key ,$cursor ) = each( $arrayKeys ) )
{
    if( $cursor == $current )
    {
        if( list( $key ,$cursor ) = each( $arrayKeys ) )
        {
            $next = $cursor;
        }
        break;
    }
}
//  Search for previous

$prev = -1; // Initialize

rsort( $arrayKeys );    //  Sort keys array in reverse order

while( list( $key ,$cursor ) = each( $arrayKeys ) )
{
    if( $cursor == $current )
    {
        if( list( $key ,$cursor ) = each( $arrayKeys ) )
        {
            $prev = $cursor;
        }
        break;
    }
}

if( $prev <> -1 )   echo '<br>Prev : ' ,$array[$prev];
if( $next <> -1 )   echo '<br>Next : ' ,$array[$next];

I recommend using sql to get the previous and next blog entries

previous post

select * from pages where id = ( select max(id) from pages where id < <current_post_id> )

next post

select * from pages where id = ( select min(id) from pages where id > <current_post_id> )

Full-featured option might be to have a persistent sequence index field on your blog objects. Pagination can check for prev/next sequence indexes. You can either write your function to blindly assume they are truly sequential ( and make sure you re-index them when deleting posts ) for easy +1/-1 implementation or write a function that finds the next highest/lowest ( probably from the db ). This would allow you to move them around arbitrarily as well as ensure existence. Decouple order from arbitrary object id.

在数组的foreach循环使用array_values函数更新数组索引之前,它将重新索引数组,因此现在您的逻辑将保持不变并正常运行。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM