2
$files = glob('docs/*.xml');
 foreach($files as $file){
 $xml = new SimpleXMLElement($file, 0, true);
 echo'
 <tr>
 <td>' . $xml->doctype . '</td>
 <td><a href="viewdoc.php?docname=' . basename($file, '.xml') . '&username='. $xml->startedby .'&myname='. $_SESSION['username'] .'">' . basename($file, '.xml') . '</a></td>
 <td><a href="viewprofile.php?name='. $xml->startedby .'">'. $xml->startedby .'</a></td>
 <td>'. $xml->date .'</td>
 <td>* * * * *</td>
 <td></td>
 </tr>
 ';
}

The code above is a loop that show me all files in docs folder. I wish to have only 10 xml files in 1 page and split every page anouter 10 files. How can I do that?

copypaste
  • 175
  • 1
  • 2
  • 13
  • You should take a look into the SPL: http://php.net/class.globiterator + http://php.net/class.limititerator - It's worth. The problem has been solved already ;) For Pagination I think I have left code on this website reagarding a *`PageIterator`* or *`PagingIterator`*. Related: http://stackoverflow.com/a/15741465/367456 – hakre Jun 21 '13 at 08:45

2 Answers2

3

You can split out the $files array with one of the following , both of these methods require a $page variable to be set that would be an integer showing which 10 xml file page you want to view.

// this will make files an array for 10 element 
$files = glob('docs/*.xml');
$files = array_chunk($files, 10);
foreach($files[$page-1] as $file){ 
$xml = new SimpleXMLElement($file, 0, true);
echo'
    <tr>
    <td>' . $xml->doctype . '</td>
    <td><a href="viewdoc.php?docname=' . basename($file, '.xml') . '&username='. $xml->startedby .'&myname='. $_SESSION['username'] .'">' . basename($file, '.xml') . '</a></td>
    <td><a href="viewprofile.php?name='. $xml->startedby .'">'. $xml->startedby .'</a></td>
    <td>'. $xml->date .'</td>
    <td>* * * * *</td>
    <td></td>
    </tr>
    ';
}

Or you could use array slice to get whichever 10 you wanted

$files = glob('docs/*.xml');
$files = array_slice($files, ($page-1)*10, 10);
foreach ($files as $file){
$xml = new SimpleXMLElement($file, 0, true);
echo'
    <tr>
    <td>' . $xml->doctype . '</td>
    <td><a href="viewdoc.php?docname=' . basename($file, '.xml') . '&username='. $xml->startedby .'&myname='. $_SESSION['username'] .'">' . basename($file, '.xml') . '</a></td>
    <td><a href="viewprofile.php?name='. $xml->startedby .'">'. $xml->startedby .'</a></td>
    <td>'. $xml->date .'</td>
    <td>* * * * *</td>
    <td></td>
    </tr>
    ';
}
Orangepill
  • 24,500
  • 3
  • 42
  • 63
  • You will have to supply a $page variable that shows which 10 element chuck you want ... $page 1 = xml files 1-10, $page 10 = xml files 91-100 – Orangepill Jun 21 '13 at 05:26
  • can we continue the question in chat room? http://chat.stackoverflow.com/rooms/32192/private – copypaste Jun 21 '13 at 23:42
  • Sorry for the spam, but you didn't came back to me, please help me out in chat room. – copypaste Jun 28 '13 at 16:01
1

You should make much more use of Iterators in PHP to divide the job even:

//Pages
$perPage = 10; // Avoid magic numbers

$files      = new GlobIterator('docs/*.xml');
$filtered   = new FileXmlDoctypeFilterIterator($files, $requestedType);
$count      = iterator_count($filtered);
$pagination = new LimitPagination($_GET['page'], $count, $perPage);

foreach ($pagination->getLimitIterator($filtered) as $file)
{
    $xml = simplexml_load_file($file);
    ...
}

So how does this work? First of all by using the pre-defined GlobIterator which by it's name you might already see what it does. But instead of returning an array as glob() does, it is an iterator.

This is done especially here to allow stacking with other iterators here. For example with the next one which is a concrete FilterIterator so you need to move the code you currently have for the filter decision into this iterator. It's documented in the PHP manual how that works.

Then the count of all filtered files is obtained with the iterator_count() function which then is used with the LimitPagination object that completely encapsulates the pagination into an object of it's own. See my answer to XML pagination with PHP for more information about it.

It offers another iterator via $pagination->getLimitIterator($filtered) so that it will offer those filtered files that are within the specified page ($_GET['page'] in the example above). It does also offer a list of pages so that you can output the links to other pages.

So what was done here:

  1. Your problem with filtering files has been encapsulated into a filter-iterator.
  2. Your problem with pagination has been encapsulated into a pagination-object which provides an iterator as well.
  3. Your problem filtering the globbed files has been solved by turning the array into an iterator.

Technically you can solve all these as well with arrays, however the big benefit with iterators here is that those are much more flexible than arrays.

You can for example further improve this by creating an iterator that will create a special child of SimpleXMLElement which also carries the algorithm to get the doctype and which knowns about the file-path. Giving this a distinct interface will help with the filter-iterator.

Also as pagination is involved it can make sense to cache the filter-iterator so that the count operation does not weight too hard.

The benfits of iterators here clearly is the code-reuse, e.g. the LimitPagination object just works with any kind of pagination for which you provide the data to paginate in form of an iterator.

If you want to stick with arrays, you need to turn that one into an ArrayPagination object and instead of the filter-iterator you can make use of array_filter() with a callback function that filters your files. And if you use the arrays for prototyping, there is also ArrayIterator so you can switch from arrays to iterator in between (and there is CallbackFilterIterator which should also allow you to re-use your array filter function).

Community
  • 1
  • 1
hakre
  • 193,403
  • 52
  • 435
  • 836