views:

684

answers:

2

hi , i'm using Smarty with my php code and i like to cache some of website pages so i used the following code :

// TOP of script
ob_start();   // start the output buffer
$cachefile ="cache/cachefile.html";
// normal PHP script 
$smarty->display('somefile.tpl.html') ;
$fp = fopen($cachefile, 'w'); // open the cache file for writing
fwrite($fp, ob_get_contents()); // save the contents of output buffer to the file
fclose($fp); // close the file
ob_end_flush(); // Send the output to the browser

but when i print ob_get_contents() at end of the php file it's empty ! and actually the created cache file is also empty ! so how could i cache the files in php when i using smarty i know i can use smarty cache but it isn't work for me for some reason .

in addition please give me information about APC cache . how to use it? is it worth using in my case , i thin it's just for caching database queries , i read the php manual about it but i can't get anything :) tanks .

+1  A: 

I've mashed up some of the code from the documentation (located here) for a more complete example of the smarty cache. Also, I'm not sure what you were using in your example, but you should be using smarty's methods to manipulate the cache.

    require('Smarty.class.php');
    $smarty = new Smarty;

    // 1 Means use the cache time defined in this file, 
    // 2 means use cache time defined in the cache itself
    $smarty->caching = 2; 

    // set the cache_lifetime for index.tpl to 5 minutes
    $smarty->cache_lifetime = 300;

    // Check if a cache exists for this file, if one doesn't exist assign variables etc
    if(!$smarty->is_cached('index.tpl')) {
        $contents = get_database_contents();
        $smarty->assign($contents);
    }

    // Display the output of index.tpl, will be from cache if one exists
    $smarty->display('index.tpl');

    // set the cache_lifetime for home.tpl to 1 hour
    $smarty->cache_lifetime = 3600;

    // Check if a cache exists for this file, if one doesn't exist assign variables etc
    if(!$smarty->is_cached('home.tpl')) {
        $contents = get_database_contents();
        $smarty->assign($contents);
    }

    // Display the output of index.tpl, will be from cache if one exists
    $smarty->display('home.tpl');

As for APC cache, it will work the same way that smarty does. They both store the data in a file for a specific amount of time. Every time you wish to access the data, it checks if the cache is valid, and if so returns the cache value.

However, if not using smarty you can use APC as such:
This example goes through storing the result of a DB query in the cache, similarly, you can modify this to instead store the entire page output so you don't have to run expensive PHP functions frequently.

// A class to make APC management easier
class CacheManager  
{  
     public function get($key)  
     {  
          return apc_fetch($key);  
     }  

     public function store($key, $data, $ttl)  
     {  
          return apc_store($key, $data, $ttl);  
     }  

     public function delete($key)  
     {  
          return apc_delete($key);  
     }  
}

Combined with some logic,

function getNews()  
{  
     $query_string = 'SELECT * FROM news ORDER BY date_created DESC limit 5';  

     // see if this is cached first...  
     if($data = CacheManager::get(md5($query_string)))  
     {  
          // It was stored, return the value
          $result = $data;  
     }  
     else  
     {  
          // It wasn't stored, so run the query
          $result = mysql_query($query_string, $link);  
          $resultsArray = array();  

          while($line = mysql_fetch_object($result))  
          {  
               $resultsArray[] = $line;  
          }  

       // Save the result inside the cache for 3600 seconds
          CacheManager::set(md5($query_string), $resultsArray, 3600);  
     }  

     // Continue on with more functions if necessary 
}

This example is slightly modified from here.

Ian Elliott
@lan Elliott yes , Smarty caching is good idea but i can't use it . because i have only one $smarty->display('index.tpl') ; and the rest of other pages like news.tpl come into my index.tpl center like this {include file=$page_center} then in news.php file i use this line $smarty->assign('page_center' , 'news.tpl'); but when i enable caching it's still show me the default content of page center not news.tpl but when i truned of caching it's working fine .
mehdi
@mehdi That sounds like you need to use custom cache-ids - allowing you to cache as many version of `index.tpl` as you want. e.g. in `news.php` you'd call `$smarty->display('index.tpl', 'news|' . $article_id);` For help pages you might use a cache-id of `'help|' . $topic` etc. (Using the pipe character to structure your cache-ids allows you to selectively clear the cache - e.g. clear all news articles at once.)
searlea
+1  A: 

Do you mean you are calling ob_get_contents() again after you called ob_end_flush() ? If so, the stuff you wrote to the file will have been "deleted" from PHP's memory.

If you wish to still output the HTML, save ob_end_flush to a variable first, then pass that to fwrite. You can use the variable later down the page.

DisgruntledGoat