php - Automatic Pagination Help Needed
Get the solution ↓↓↓I have this script:
<?php
if(urldecode($_SERVER['REQUEST_URI']) == "/?articles")
{
include("Articles.php");
}
?>
Which allows me to setup a custom URL for a page. Now, the problem occurs comes when I need URLs like these:
/?articles | Page that contains newest articles which loads when user clicks "< Previous" button
/?articles&1 | Page that contains older articles which loads when user clicks "Next >" button
/?articles&2 | Page that contains older than older articles
/?articles&3 | Page that contains old articles
/?articles&4 | Page that contains old articles
/?articles&5 | Page that contains oldest articles
/?articles&6 | Page that contains oldest articles, also last page in the pagination
And so on. Namely, the code in the script above would be like this:
if(urldecode($_SERVER['REQUEST_URI']) == "/?articles&1")
{
include("Articles-500.php");
}
if(urldecode($_SERVER['REQUEST_URI']) == "/?articles&2")
{
include("Articles-499.php");
}
if(urldecode($_SERVER['REQUEST_URI']) == "/?articles&3")
{
include("Articles-498.php");
}
if(urldecode($_SERVER['REQUEST_URI']) == "/?articles&4")
{
include("Articles-497.php");
}
if(urldecode($_SERVER['REQUEST_URI']) == "/?articles&5")
{
include("Articles-496.php");
}
if(urldecode($_SERVER['REQUEST_URI']) == "/?articles&6")
{
include("Articles-495.php");
}
But each time the page with the newest articles gets filled (contains 10 articles per page) I have to update the script like this:
if(urldecode($_SERVER['REQUEST_URI']) == "/?articles&1")
{
include("Articles-505.php");
}
if(urldecode($_SERVER['REQUEST_URI']) == "/?articles&1")
{
include("Articles-504.php");
}
if(urldecode($_SERVER['REQUEST_URI']) == "/?articles&1")
{
include("Articles-503.php");
}
if(urldecode($_SERVER['REQUEST_URI']) == "/?articles&1")
{
include("Articles-501.php");
}
if(urldecode($_SERVER['REQUEST_URI']) == "/?articles&1")
{
include("Articles-500.php");
}
I also need you to tell me how to use it practically in my navigation, id est:<A href="?">Next</A>
and<A href="?">Previous</A>
Answer
Solution:
What you can do, in order to have this created dynamically is to use the function that can list you all the files in a directory.
So given that you would have the files:
- Articles-1.php
- Articles-2.php
- Articles-3.php
- ...
Now, if your articles are indeed named as above (Articles-1.php and not Articles-001.php) you will face the problem that a simple alphabetical sort won't work.
Indeed, Articles-99.php will always show up earlier than Articles-505.php in a simple alphabetical sort.
But, hopefully, PHP offers us the really neat sorting which is .
This function implements a sort algorithm that orders alphanumeric strings in the way a human being would while maintaining key/value associations. This is described as a "natural ordering". An example of the difference between this algorithm and the regular computer string sorting algorithms (used in
sort()
) can be seen in the example below.
Sorting vianatsort()
is nicer than my originalusort
idea, all credit for this idea goes to dД±lo sГјrГјcГј's answer.
Still, we need the sorting to be in a reverse order, and this can be provided using theSORT_NATURAL
flag on .
SORT_NATURAL - compare items as strings using "natural ordering" like
natsort()
Source: https://www.php.net/manual/en/function.sort.php
Credit for the usage of this flag goes to Seh Horng's answer
// Listing all the articles pages
$articles = glob("Articles-*.php");
// Applying reverse natural sorting, with SORT_NATURAL flag on rsort
rsort($articles, SORT_NATURAL);
/**
* Extracting the selected page out of the REQUEST_URI,
* and transform it an integer
*/
$selectedPage = intval(
str_replace("/?articles&", "", urldecode($_SERVER['REQUEST_URI']))
);
/**
* This is a sanity check;
* just in case someone tries to access a page that does not exists,
* like the page 99999999999
* It also tackles the case when intval fails and returns 0
* causing the index to be 0 - 1 = -1
*
* By the way, doing this check also covers your default behaviour
* on the URL /?articles
*/
if(array_key_exists($selectedPage - 1, $articles)){
/**
* We need to remove one from the selected page,
* remembering an array start at 0 in PHP
*/
include $articles[$selectedPage - 1];
} else {
include "Articles.php";
}
This should give you the right include dynamically.
Answer
Solution:
<?php
/*Supposing this our url : path/?articles&3
and we have in serveur this articles
articles-498.php
articles-500.php
articles-499.php
articles-496.php
articles-497.php
articles-495.php
*/
$current_url = parse_url($_SERVER['REQUEST_URI']);
$path = $current_url["path"]; //return articles&3
preg_match_all('!\d+!', $current_url["query"], $matches); //get the number of article
$index = current($matches)[0]; // now we have the index is 3
$articles = glob("articles-*.php"); // for get all the article
rsort($articles, SORT_NATURAL); // sort the article to get the new article 500-499-498 ...
$pages=array();
for($i=0;$i<count($articles);$i++){
$x = $i+1;
$pages["articles&".$x]=$articles[$i];
}
// This array will return like this print_r($pages);
/*
Array
(
[articles&1] => articles-500.php
[articles&2] => articles-499.php
[articles&3] => articles-498.php
[articles&4] => articles-497.php
[articles&5] => articles-496.php
[articles&6] => articles-495.php
*/
/* here we check if the artile is exist in our serveur*/
if(file_exists($pages["articles&".$index])){
//if exists
$current = array_search($pages["articles&".$index], $pages); // get the current article articles&3
$Next = array_search($pages["articles&".intval($index+1)], $pages); // this is next article 3+1 [articles&4] => articles-497.php
$Previous = array_search($pages["articles&".intval($index-1)], $pages); // this is Previous article 3-1 [articles&2] => articles-499.php
//include the current article
include($pages["articles&".$index]);
// and then show your tag a like this
echo "<br><a href='$path?".$Previous."'>Previous</a> Current Page :
".$current." <a href='$path?".$Next."'>Next</a>";
}elseif($current_url["query"] == "articles"){
include("articles.php");
echo "<br><a href='$path?articles&1'>Next</a>";
}else{
echo "Page Not Found <a href='$path?articles'>Back to articles</a> !!";
}
// final reuslt is
/*
content of articles&3
<a href='path/?articles&2'>Previous</a> Current Page : articles&3 <a href='path/?articles&4'>Next</a>
*/
die;
?>
Version Online DEMO CHECK HERE
Answer
Solution:
$articles=glob('Article-*.php');
$sortedArticles=natsort($articles);
$articleIndex=$_GET['articles'] ?? null;
$article=$sortedArticles[$articleIndex] ?? "Article.php";
include_once (string)$article;
Answer
Solution:
Assuming that there will always be only 6 articles. You can try the following script:
<?php
//get array of php files in the current folder matching Articles-*.php
$phpfiles = glob("Articles\-*.php");
//sort by descending order
$sorted = rsort($phpfiles, SORT_NATURAL);
//use only the first 6 php files in the sorted array list
if(urldecode($_SERVER['REQUEST_URI']) == "/?articles&1")
{
include($sorted[0]);
}
if(urldecode($_SERVER['REQUEST_URI']) == "/?articles&2")
{
include($sorted[1]);
}
if(urldecode($_SERVER['REQUEST_URI']) == "/?articles&3")
{
include($sorted[2]);
}
if(urldecode($_SERVER['REQUEST_URI']) == "/?articles&4")
{
include($sorted[3]);
}
if(urldecode($_SERVER['REQUEST_URI']) == "/?articles&5")
{
include($sorted[4]);
}
if(urldecode($_SERVER['REQUEST_URI']) == "/?articles&6")
{
include($sorted[5]);
}
?>
Answer
Solution:
Why not use $_GET global? If you already use parameters in URL then php should put them inside $_GET, you just have to assign values to them.
With URL like this:
/?articles=1
You will have seted $_GET['articles'] which you can check if exist and if it does just include Article.
if(isset($_GET['articles'])) {
include("Articles.php");
}
And this method will also help you with pagination because you will have actual value in $_GET['articles'] so you could just do something like this:
<a href="?articles=<?= $_GET['articles'] + 1 ?>">Next</a>
and
<a href="?articles=<?= $_GET['articles'] - 1 ?>">Previous</a>
and you will have to create if for checking when to hide previous or next button accordingly based on value of $_GET['articles'] (if it's equal to 1 then hide previous if equal to 6 hide next)
Or if you want to separate pagination and page action then you could just use two parameters:
/?page=articles&pagination=1
For your problem with including articles I would use DirectoryIterator which will allow you to iterate over all files in given folder and choose 6 newest files by using filectime() which return timestamp of when file was created and getting first 6 biggest values.
For example (created with this answer):
$dir = new DirectoryIterator(__DIR__);
$articles = [];
foreach ($dir as $file) {
if ($file->isDot()) continue; // here we check if it's not a hidden file
$articles[] = array(
"path" => $file->getPathname(),
"cTime" => filectime($file->getPathname())
);
}
$columns = array_column($articles, 'cTime');
array_multisort($columns, SORT_DESC, $articles);
print_r($articles);
Which will return all files in the directory in which script is placed, sorted by time they were created by newest (Descending).
This method is especially good because you don't depend on names and enumeration but on time the files were created. You can change it to time when they were modified so the updated posts will be newest.
NOTES
I'm pretty sure you know this but to have to sanitize data if you are giving user access and possibility to change it. I'm taking about $_GET from which I recommend getting values. Here is good answer on how to.
I also recommend to check if value is in proper format, for example pagination- it must be always an positive integer and lower or equal then 6:
if (isset($_GET['pagination']) && filter_var($_GET['pagination'], FILTER_VALIDATE_INT) !== false && $_GET['pagination'] > 0 && $_GET['pagination'] <= 6) {
// code here
}
Share solution ↓
Additional Information:
Link To Answer People are also looking for solutions of the problem: dompdf image not found or type unknown
Didn't find the answer?
Our community is visited by hundreds of web development professionals every day. Ask your question and get a quick answer for free.
Similar questions
Find the answer in similar questions on our website.
Write quick answer
Do you know the answer to this question? Write a quick response to it. With your help, we will make our community stronger.