2

I am retrieving all files in a directory and cache the value so that I don't have to retrieve it again and again

$memefiles = glob("usermemes/*.jpeg"); 
$total_pages = ceil(sizeof($memefiles)/$num_rec_per_page);

Is there any way to cache this result so that I don't have to perform these functions again and again.

Sheel Ranjan
  • 167
  • 3
  • 12

2 Answers2

1

Use cookies. In order to store array in cookies you will have to encode it in json and then later decode it using json_decode(). Use the code below

 <?php

    if(!isset($_COOKIE['calculation'])) {
    $memefiles = glob("usermemes/*.jpeg"); 
    $total_pages = ceil(sizeof($memefiles)/$num_rec_per_page);
    setcookie('calculation', json_encode($memefiles), time() + (8640000000 * 30), "/"); // Set the cookie for unlimited time
    }
    else{
    $memefiles = json_decode($_COOKIE['calculation'],true);
    }
    ?>

Hope this helps you

Utkarsh Dixit
  • 4,267
  • 3
  • 15
  • 38
  • I have one more doubt. Will it increase performance if the directory has many files? – Sheel Ranjan Feb 15 '15 at 07:15
  • @Sheel Ranjan It would defiantly increase the performance if the directory has many files – Utkarsh Dixit Feb 15 '15 at 08:37
  • I think you have not stored the array in Cache, should I do it like this `setcookie('memes', $memefiles, time() + (8640000000 * 30), "/");` – Sheel Ranjan Feb 15 '15 at 08:47
  • Can I just replace `$_COOKIE['calculation']` with `$_SESSION['calculation']` This is because the number of files need to be updated regularly. – Sheel Ranjan Feb 15 '15 at 09:11
  • The reason why i haven't used session in the code is that after you close the window the session will be lost and you will have to do the calculation again. If you want to set the cookie again then just use $_COOKIE['calculation'] = "your_value"; – Utkarsh Dixit Feb 15 '15 at 09:13
  • But `$total_pages` will still need to be calculated for each user, first time they visit the page, right? And recent changes (30 days, really?) to the usermemes directory will not be accessible for the users, unless they delete their cookies - right? – davidkonrad Feb 15 '15 at 09:37
1

There is many ways to optimize or cache, the best way depends on what you are trying to cache, the quantity and the desired refresh frequency. Examples are

  • store calculated result in session, a database or file - then look it up
  • do calculations upfront, lookup them up then needed
  • store your pages (PHP output in files) and deliver stored versions to users
  • use a cache / HTTP-accelerator like Varnish.

In this case, I think an upfront calculation would satisfy your needs. Simply put your code in a single script, calculate.php, that saves the calculated $total_pages value to a file :

<?
$memefiles = glob("usermemes/*.jpeg"); 
$total_pages = ceil(sizeof($memefiles)/$num_rec_per_page);
file_put_contents('totalpages.dat', $total_pages);
?>

Now setup a cron job, running calcaulate.php every 1 minute, 5 minutes, every hour or what your needs is. If you are running on a windows server, you should use the Task Scheduler equivalence instead. Setting up cronjobs is very easy, but it vary between systems and GUI / commandline tools, there is difference if you have a on-site server or are using a professional webhost. So search stackoverflow for cron jobs suiting your particular situation.

Assuming you have a cron job up running, saving the value of $total_pages to a file, then you are retrieving your value on the webpage by

$total_pages = file_get_contents('totalpages.dat');

This will by guarantee boost the performance of all pages in need of delivering the $total_pages value. Compared to the accepted answer, this solution has some significant advantages :

  • the task is runned only once, each time, no matter if you have 1, 10.000 or 1.000.000 users / pageloads.
  • users can still receive nearly fresh or almost live data. How fresh is determined by the cronjob frequency.
Community
  • 1
  • 1
davidkonrad
  • 83,997
  • 17
  • 205
  • 265
  • How will I store the array `$memefiles` in this case? – Sheel Ranjan Feb 15 '15 at 12:27
  • @SheelRanjan, since `$memefiles` just is a simple array, you can save it to the file as string with `$content_to_file = implode(',', $memefiles);` and then you read the content from the file, convert it back to array with `$memefiles = explode(',', $content_from_file);` – davidkonrad Feb 15 '15 at 12:46
  • After imploding and exploding will I still have the performance boost? – Sheel Ranjan Feb 15 '15 at 12:58
  • @SheelRanjan, defently! Reading a string and convert it to array is by all means much, much faster than loading a directory over and over. Besides that, the output of `file_get_contents` is being cached itself, see http://stackoverflow.com/q/9555658/1407478 the content of the file you are storing your values in will most likely be held in memory by the operating system itself. So in practice you end up reading a string from memory, once in a while updated by the cron job = a true cache. – davidkonrad Feb 15 '15 at 13:13
  • 1
    It is 2 times fast on first run and 200 times faster on second run! – Sheel Ranjan Feb 15 '15 at 13:44
  • @SheelRanjan - cool :) Thank you for responding back with the IRL effect! Nice to know. – davidkonrad Feb 15 '15 at 13:54