PhpFastCache Guide

Thor

Honorary Master
Joined
Jun 5, 2014
Messages
44,413
Reaction score
7,522
Location
Bellville
Hoping someone would be willing to explain/show me how to use this library.

Normally for caching, I used the file system, roughly like this:

PHP:
<?php
	// define the path and name of cached file
	$cachefile = 'cached-files/'.date('M-d-Y').'.php';
	// define how long we want to keep the file in seconds. I set mine to 5 hours.
	$cachetime = 18000;
	// Check if the cached file is still fresh. If it is, serve it up and exit.
	if (file_exists($cachefile) && time() - $cachetime < filemtime($cachefile)) {
   	include($cachefile);
    	exit;
	}
	// if there is either no file OR the file to too old, render the page and capture the HTML.
	ob_start();
?>
	<html>
		output all your html here.
	</html>
<?php
	// We're done! Save the cached content to a file
	$fp = fopen($cachefile, 'w');
	fwrite($fp, ob_get_contents());
	fclose($fp);
	// finally send browser output
	ob_end_flush();
?>

What I want to do now is use the PhpFastCache library instead. What I want is for someone to show me how you would handle DB queries.

Take for example this test page:

PHP:
<table style="width:100%">
  <tr>
    <th>Name</th>
    <th colspan="2">Cellphone</th>
  </tr>
  <tr>
<?php
$stmt = $pdo->query('SELECT name, cellphone FROM users');
foreach ($stmt as $row)
{
    echo <td>. $row['name'] .</td>;
    echo <td>. $row['cellphone'] .</td>;
}
?>
  </tr>
</table>

How would you go about to cache that using phpFastCache and then what driver would you use, SQLite or the Filesystem?
 
Last edited:
Did you read the documentation? Surely there is a getting started guide?

Caching data belongs in your service layer, not in your views.


The driver I would use is predis/redis. But this is largely irrelevant, they are all implementations of the same interface and are interchangeable.

If the above code is a snapshot of how you are actually structuring php apps, you should not be looking at caching. Your complexity and unmaintainability will skyrocket.

Using a service layer and https://github.com/phpro/annotated-cache is the way I would go. Caching now becomes meta information instead of an implementation detail
 
Last edited:
Caching data belongs in your service layer, not in your views.

Just a simple example to explain it, no need for MVC/OOP and other stuff.


If the above code is a snapshot of how you are actually structuring php apps, you should not be looking at caching. Your complexity and unmaintainability will skyrocket.

Stop making assumptions, again illustrative only.

The driver I would use is predis/redis. But this is largely irrelevant, they are all implementations of the same interface and are interchangeable.

I don't find it irrelevant, if I use SQLite then DB queries and access times will be different than if I use the filesystem where if you host on a SSD should be fine vs Disk drives and Memory will be different to SSD as well.

Off-topic, but what I was trying to ask is if the aim is to limit DB queries, would caching to SQLite be the right way, essentially just a different DB vs using the filesystem or memory instead.

Back to the question, how would you write this using PhpFastCache:

PHP:
<table style="width:100%"> 
  <tr> 
    <th>Name</th> 
    <th colspan="2">Cellphone</th> 
  </tr> 
  <tr> 
<?php 
$stmt = $pdo->query('SELECT name, cellphone FROM users'); 
foreach ($stmt as $row) 
{ 
    echo <td>. $row['name'] .</td>; 
    echo <td>. $row['cellphone'] .</td>; 
} 
?> 
  </tr> 
</table>
 
You asked which driver to use. You did not specify anything about the environment.

Also I told you which driver I recommend. Redis. I don’t recommend SQLite, and filesytem would be used for local development mostly.

From the README.md/documentation on the github repository:

Code:
use phpFastCache\Helper\Psr16Adapter;

$Psr16Adapter = new Psr16Adapter($defaultDriver);

if(!$Psr16Adapter->has('test-key')){
    // Setter action
    $data = 'lorem ipsum';
    $Psr16Adapter->set('test-key', 'lorem ipsum', 300);// 5 minutes
}else{
    // Getter action
    $data = $Psr16Adapter->get('test-key');
}

Just replace the

Code:
    $data = 'lorem ispum”

part

BUT

you won’t be able to cache a PDO statement. It throws an exception in the __serialize method, which is what caching libraries use to turn a php object into a non php context.

Normally you do not cache database results. You cache the result of a function that returns the array of dataset result rows mapped to domain objects
 
Last edited:
You asked which driver to use. You did not specify anything about the environment.

Also I told you which driver I recommend. Redis. I don’t recommend SQLite, and filesytem would be used for local development mostly.

From the README.md/documentation on the github repository:

Code:
use phpFastCache\Helper\Psr16Adapter;

$Psr16Adapter = new Psr16Adapter($defaultDriver);

if(!$Psr16Adapter->has('test-key')){
    // Setter action
    $data = 'lorem ipsum';
    $Psr16Adapter->set('test-key', 'lorem ipsum', 300);// 5 minutes
}else{
    // Getter action
    $data = $Psr16Adapter->get('test-key');
}

Just replace the

Code:
    $data = 'lorem ispum”

part

Makes zero sense, please type it out.

This is what the documentation says, not sure where you got your code from.

PHP:
<?php
/**
 *
 * This file is part of phpFastCache.
 *
 * @license MIT License (MIT)
 *
 * For full copyright and license information, please see the docs/CREDITS.txt file.
 *
 * @author Khoa Bui (khoaofgod)  <[email protected]> http://www.phpfastcache.com
 * @author Georges.L (Geolim4)  <[email protected]>
 *
 */
// Include composer autoloader
require __DIR__ . '/../../vendor/autoload.php';
// OR require_once("../src/phpFastCache/phpFastCache.php");
date_default_timezone_set("Europe/Paris");
use phpFastCache\CacheManager;
use phpFastCache\Core\phpFastCache;
// Setup File Path on your config files
CacheManager::setDefaultConfig([
  "path" => sys_get_temp_dir(),
]);
// In your class, function, you can call the Cache
$InstanceCache = CacheManager::getInstance('sqlite');
// OR $InstanceCache = CacheManager::getInstance() <-- open examples/global.setup.php to see more
/**
 * Try to get $products from Caching First
 * product_page is "identity keyword";
 */
$key = "product_page";
$CachedString = $InstanceCache->getItem($key);
if (is_null($CachedString->get())) {
    //$CachedString = "Files Cache --> Cache Enabled --> Well done !";
    // Write products to Cache in 10 minutes with same keyword
    $CachedString->set("Files Cache --> Cache Enabled --> Well done !")->expiresAfter(5);
    $InstanceCache->save($CachedString);
    echo "FIRST LOAD // WROTE OBJECT TO CACHE // RELOAD THE PAGE AND SEE // ";
    echo $CachedString->get();
} else {
    echo "READ FROM CACHE // ";
    echo $CachedString->getExpirationDate()->format(Datetime::W3C);
    echo $CachedString->get();
}
echo '<br /><br /><a href="/">Back to index</a>&nbsp;--&nbsp;<a href="./' . basename(__FILE__) . '">Reload</a>';
 
I have added more detail to the bottom of my previous post
 
PHP:
<table style="width:100%">  
  <tr>  
    <th>Name</th>  
    <th colspan="2">Cellphone</th>  
  </tr>  
  <tr>  
<?php  
$users = $userRepository->findAll();  
foreach ($users as $user)  
{  
    echo <td>. $user['name'] .</td>;  
    echo <td>. $user['cellphone'] .</td>;  
}  
?>  
  </tr>  
</table>

becomes

PHP:
<table style="width:100%">  
  <tr>  
    <th>Name</th>  
    <th colspan="2">Cellphone</th>  
  </tr>  
  <tr>  
<?php
$cache = new Psr16Adapter($defaultDriver);


if(!$cache->has('users')){
    $users = $userRepository->findAll();
    $cache->set('users', $users, 300);// 5 minutes
}else{
    $users = $cache->get('users');
}

foreach ($users as $user)  
{  
    echo <td>. $user['name'] .</td>;  
    echo <td>. $user['cellphone'] .</td>;  
}  
?>  
  </tr>  
</table>
 
Really glad I spent the time and effort to give real replies here.
 
Top
Sign up to the MyBroadband newsletter
X