Télécharger
cache.class.php (version : 2.0.1)
Dimanche 29 Novembre 2020 par Loïc Doumerc

Le principe de cette classe est de gérer les connexion aux bases de données de type MySQLi et de créer un petit système de mise en cache.

 

Le constructeur

Description

En gros, vous pouvez initialiser plusieurs connexions MySQLi mais par défaut la connexion se fera sur ce qui est paramètré dans le fichier cache.class.php.

$cache = new cache( [(string) $serveur = CONFIG_CACHE_SERVEUR] [,(string) $login = CONFIG_CACHE_LOGIN] [,(string) $mdp = CONFIG_CACHE_MDP] [,(string) $base = CONFIG_CACHE_BASE] [,(string) $dir = CONFIG_CACHE_DIR] [,(string) $charset = CONFIG_CHARSET]) : (cache);

 

Exemple

Mise en cache minimaliste

require_once('cache.class.php');
$cache = new cache();
if( $cache->start('echo-timestamp', CACHE_DUREE_DEFAULT ) )
{
	$result = $cache->query('SELECT UNIX_TIMESTAMP() as t');
	if( $row = $result->next() )
	{
		echo $row->t;
	}
$cache->end();
}

 

Les méthodes

(cache)->start

Commence une mise en cache

Description

start((string) $identifiant_cache [, (mixed) $expiration = CACHE_DUREE_DEFAULT]) : boolean

Liste des paramètres

$identifiant_cache

Chemin vers le fichier de chache, évitez les caractères spéciaux et changez le à chaque fois que vous utilisez start.

$expiration

Chemin vers le fichier de chache, évitez les caractères spéciaux et changez le à chaque fois que vous utilisez start.

Option Description Type
d Valeur par défaut, déclaré dans CACHE_DUREE_DEFAULT
La cache sera actualisé chaque jour.
string
m La cache sera actualisé chaque mois.
Ne pas confondre avec CACHE_1_MOIS qui lui donne une durée d'environ un mois
string
y La cache sera actualisé chaque année.
Ne pas confondre avec CACHE_1_AN qui lui donne une durée d'environ un ans
string
$NbDeSeconde Durée en seconde.
Vous pouvez aussi utiliser les constantes : CACHE_5_MIN , CACHE_1_JOUR CACHE_1_SEMAINE CACHE_1_MOIS CACHE_1_AN
int

(cache)->end

Termine la mise en cache, doit toujours être dans une condition de start

Description

(cache)->end( void ) : void

(cache)->escape

Protège les caractères spéciaux d'une chaîne pour l'utiliser dans une requête SQL, en prenant en compte le jeu de caractères courant de la connexion

Description

(cache)->escape( (string) $var) : (string)

(cache)->query

Exécute une requête SQL sur la base de données

Description

(cache)->query((string) $requete) : (requete)

(requete)->next

Retourne la ligne courante d'un jeu de résultat sous forme d'objet

Description

(requete)->next() : (objet)

(requete)->insert_id

Retourne l'identifiant automatiquement généré utilisé par la dernière requête

Description

(requete)->insert_id() : (int)

(requete)->num_rows

Retourne le nombre de lignes dans un résultat

Description

(requete)->num_rows() : (int)

(requete)->count

Alias de (requete)->num_rows

Description

(requete)->count() : (int)

(requete)->errno

Retourne le dernier code d'erreur produit

Description

(requete)->errno() : (int)

(requete)->error

Retourne une chaîne décrivant la dernière erreur

Description

(requete)->error() : (string)

(cache)->debug

Affiche le status complet de la connexion à MySQLi

Description

(cache)->debug() : (void)

 

Les fichiers

cache.class.php

<?php
/*********************************************************
 *  Fichier : cache.class.php
 *  Début du projet : 26 Novembre 2009 à 18h45
 *  Modification : 29 novembre 2020 22h19
 *  Adaptatation pour MySQLi le Lundi 10 Mars 2014
 *
 *      Une création de Loïc Doumerc www.loicdoumerc.fr
 *********************************************************/


/***********************************************************************************************************************
		
EXEMPLES
				
require_once('cache.class.php');

$cache = new cache([(string) $serveur = CONFIG_CACHE_SERVEUR][,(string) $login = CONFIG_CACHE_LOGIN][,(string) $mdp = CONFIG_CACHE_MDP][,(string) $base = CONFIG_CACHE_BASE][,(string) $dir = CONFIG_CACHE_DIR][,(string) $charset = CONFIG_CHARSET]) : (cache);
        Permet de configuer une connexion différente de celle par defaut.

if( $cache->start((string) $identifiant_cache [,(mixed $expiration) = CACHE_DUREE_DEFAULT] ) ) //expiration en secondes ou variable "d" pour quotidien,  "m" pour mensuel, "y" pour annuel 
{
	$result = $cache->query('SELECT UNIX_TIMESTAMP() as t');
	if( $row = $result->next() )
	{
		echo $row->t;
	}

$cache->end();//Si on commence : on termine ;)
}

********************** ou sans mise en cache **********************	

$result = $cache->query('SELECT UNIX_TIMESTAMP() as t');
if( $row = $result->next() )
{
	echo $row->t;
}

$cache->debug();//Affiche le debugage


/***********************************************************************************************************************
 *
 *	/!\ Pensez à configurer vos identifiants à la base de données (par défaut)
 *
 ***********************************************************************************************************************/ 

define('CONFIG_CACHE_SERVEUR', 'localhost');
define('CONFIG_CACHE_LOGIN', 'root');
define('CONFIG_CACHE_MDP', 'password');
define('CONFIG_CACHE_BASE', 'cache');
define('CONFIG_CACHE_DIR', 'cache/');//Doit se terminer par un "/"
define('CONFIG_CHARSET', 'utf8mb4');// null | latin1 | utf8 | utf8mb4 ...  Liste disponible sur votre serveur en executant la requete : show charset;


/***********************************************************************************************************************
 *
 *	Quelques constantes bien utiles
 *
 ***********************************************************************************************************************/   

define('CACHE_5_MIN', 300);
define('CACHE_1_JOUR', 86400);
define('CACHE_1_SEMAINE', 604800);//7 jours
define('CACHE_1_MOIS', 2592000);//30jours
define('CACHE_1_AN' , 31536000);//365jours


define('CACHE_DUREE_DEFAULT', 'd');


/***********************************************************************************************************************
 *
 *	La classe requête stock et gère les requêtes SQL.
 *	Seule la méthode next() est appelée depuis votre code, voir demonstration.
 *
 ***********************************************************************************************************************/     
class requete
{	
	//Pointeur Mysql
	var $myParent = null;

	var $requete = null;//On stock la requete
	
	var $result = null;
	var $rows = array();
	var $pointeur = 0;
	var $pointeur_max = null;
	var $num_rows = 0;
	var $errno = 0; //Retourne le numéro d'erreur de la dernière commande MySQL
	var $error = '';//Retourne le texte associé avec l'erreur générée lors de la dernière requête
	var $insert_id = null;


	var $time_query = null;
	var $duree = null;

	//Les fonctions MySql
	function setParent( &$parent )
	{
		unset($myParent);	
		$this->myParent = &$parent;
	}


	function execute( &$parent , $query , $options = array() )
	{
		$this->setParent($parent);	
		$this->querySQL($query);
		return $this;
	}

	
	function VerifConnect()
	{		
		return $this->myParent->VerifConnect();
	}


	//private
	function querySQL($query)
	{		
		$this->requete = $query;//Stockage de la requete
		$this->time_query = microtime(true);//Date de la requete		

		if( $this->VerifConnect() )
		{
			$this->result = $this->myParent->resource->query( $query );

			$this->duree = microtime(true) - $this->time_query;

			//Init des variables gardées en mémoire.
			$this->rows = array();
			$this->pointeur_max = 0;
			
			
			$this->errno = $this->myParent->resource->errno;
			$this->error = $this->myParent->resource->error;
			$this->insert_id = $this->myParent->resource->insert_id;
			
			if( $this->errno == 0 )
			{
				if( @preg_match('#^(\s*)?SELECT|SHOW#i', $query ) )
				{
					$this->num_rows = $this->result->num_rows;
					while($row = $this->result->fetch_object())
					{
						$this->rows[$this->pointeur_max] = $row;
						$this->pointeur_max++;
					}
					$this->result->close();/* Libération du jeu de résultats */
				}
				else
				{
					$this->num_rows = $this->myParent->resource->affected_rows;
				}
			}
			else
			{
			$this->num_rows = 0;
			}	
		}
		else
		{
			$this->error = 'Non execute';
			$this->duree = 0;//Pas d excution
			return null;
		}
	}


	function next()
	{
		if( $this->pointeur < $this->pointeur_max )
		{
			$pointeur = $this->pointeur;
			$this->pointeur++;
			return $this->rows[$pointeur];
		}
		else
		{
			return null;
		}
	}

	
	function insert_id()
	{
		return $this->insert_id;
	}


	function num_rows()//Pour toutes les comptages possibles, SELECT + UPDATE
	{
	return $this->num_rows;
	}
	//Alias
	function count(){return $this->num_rows();}


	function errno()
	{
		return $this->errno;
	}



	function error()
	{
		return $this->error;
	}
}

/***********************************************************************************************************************
 *
 *	La classe la plus importante.
 *
 ***********************************************************************************************************************/  
class mysql
{	
	//Connexion Mysql
	var $resource = null;
	var $isErreurConnect = false;
	var $isConnect = false;
		
	var $serveur = null;
	var $login = null;
	var $mdp = null;
	var $base = null;
	var $dir = null;
	var $charset = null;

	//Cache des requetes
	var $requetes = array();


	function __construct($serveur = null , $login = null , $mdp = null , $base = null , $dir = null , $charset = null) 
	{
	//reset de variable
		$this->resource = null;
		$this->isErreurConnect = false;
		$this->isConnect = false;
		$this->debugmode = null;

		$this->serveur = is_null($this->serveur) ? (  is_null($serveur) ? CONFIG_CACHE_SERVEUR : $serveur ) : $this->serveur;
		$this->login = is_null($this->login) ? (  is_null($login) ? CONFIG_CACHE_LOGIN : $login ) : $this->login;
		$this->mdp = is_null($this->mdp) ? (  is_null($mdp) ? CONFIG_CACHE_MDP : $mdp ) : $this->mdp;
		$this->base = is_null($this->base) ? (  is_null($base) ? CONFIG_CACHE_BASE : $base ) : $this->base;
		$this->dir = is_null($this->dir) ? (  is_null($dir) ? CONFIG_CACHE_DIR : $dir ) : $this->dir;
		$this->charset = is_null($this->charset) ? (  is_null($charset) ? CONFIG_CHARSET : $charset ) : $this->charset;                        
	}	
	
	//Set valeur de connexion
	function config( $serveur = null , $login = null , $mdp = null , $base = null , $dir = null , $charset = null)
	{
		$this->serveur = is_null($this->serveur) ? (  is_null($serveur) ? CONFIG_CACHE_SERVEUR : $serveur ) : $this->serveur;
		$this->login = is_null($this->login) ? (  is_null($login) ? CONFIG_CACHE_LOGIN : $login ) : $this->login;
		$this->mdp = is_null($this->mdp) ? (  is_null($mdp) ? CONFIG_CACHE_MDP : $mdp ) : $this->mdp;
		$this->base = is_null($this->base) ? (  is_null($base) ? CONFIG_CACHE_BASE : $base ) : $this->base;
		$this->dir = is_null($this->dir) ? (  is_null($dir) ? CONFIG_CACHE_DIR : $dir ) : $this->dir;
		$this->charset = is_null($this->charset) ? (  is_null($charset) ? CONFIG_CHARSET : $charset ) : $this->charset;
	}


	function initialisation()
	{
		//reset de variable
		$this->resource = null;
		$this->isErreurConnect = false;
		$this->isConnect = false;
		$this->debugmode = null;

		
		$this->config();//Valeurs de connexion par defaut si necessaire.
	}


	function VerifConnect()
	{
		if( $this->isConnect == false && $this->isErreurConnect == false )
		{			
			$modif_ini = false;
			if (!ini_get('display_errors'))
			{
			//On fait rien si c deja desactivé
			}
			else
			{
				@ini_set('display_errors', 'off');
				$modif_ini = true;
			}

			$this->resource = new mysqli($this->serveur, $this->login, $this->mdp, $this->base);
			if($modif_ini){ @ini_set('display_errors', 'on'); }     


			if( $this->resource )
			{				
				if( phpversion() > '5.3.0' )
				{
				/*
				* Ceci est le style POO "officiel"
				* MAIS $connect_error était erroné jusqu'en PHP 5.2.9 et 5.3.0.
				*/
					if ($this->resource->connect_error) 
					{
						$this->isConnect = false;
						$this->isErreurConnect = true;
					}
					else
					{
						$this->isConnect = true;
						$this->isErreurConnect = false;
						$this->resource->set_charset($this->charset);
					}
				}
				else
				{            
				/*
				* Utilisez cette syntaxe de $connect_error si vous devez assurer
				* la compatibilité avec les versions de PHP avant 5.2.9 et 5.3.0.
				*/
					if (mysqli_connect_error()) 
					{
					$this->isConnect = false;
					$this->isErreurConnect = true;
					}
					else
					{
					$this->isConnect = true;
					$this->isErreurConnect = false;
					$this->resource->set_charset($this->charset);                
					}
				}
			}
			else
			{
				$this->isErreurConnect = true;
			}
		}
	return $this->isConnect;
	}

	
	//Execute et garde en cache les requetes (de façon général, que des requete de type SELECT ou SHOW).
	function query( $query )
	{		
		$req = new requete();
		$this->requetes[] = $req;//Pour le debuggage
		return $req->execute($this, $query);
	}
	
	//Protège les caractères spéciaux d'une commande SQL
	function escape_string($string)
	{		
		if( $this->VerifConnect() )
		{
			return $this->resource->real_escape_string($string);
		}
		else
		{
			return $string;//Pas de connection
		}
	}
	//Alias
	function escape($string){return $this->escape_string($string);}	
}


class cache extends mysql
{
	// Adresse de la page mise en cache
	private $fichier;	
	private $isBuffer;

	
	// METHODES 			
	public function start($fichier, $expiration = CACHE_DUREE_DEFAULT)
	{
		$this->isBuffer = false;//Reset
		$this->fichier = CONFIG_CACHE_DIR . $fichier .'.cache.php';

		if(file_exists($this->fichier))
		{
			$t = filemtime($this->fichier);

			if( !$this->isExpire($t, $expiration) )
			{
				//Lecture du fichier en cache
				readfile($this->fichier);
			}
			else
			{
				//On commence la bufférisation
				$this->tamponStart();
			}
		}
		else
		{
			//On commence la bufférisation
			$this->tamponStart();            
		}

		return $this->isBuffer;
	}
	
	private function isExpire($timeFile, $expiration)
	{
		if( is_string($expiration) &&  $expiration == 'd')
		{
			return (date('dmY',$timeFile) == date('dmY') ? false: true);
		}
		else if( is_string($expiration) &&  $expiration == 'm')
		{
			return (date('mY',$timeFile) == date('mY') ? false: true);
		}
		else if( is_string($expiration) &&  $expiration == 'y')
		{
			return (date('Y',$timeFile) == date('Y') ? false: true);
		}                        
		else
		{
			$now = time();
			return ($timeFile + $expiration < $now);
		}      
	}

	private function tamponStart() 
	{
		$this->isBuffer = true;
		ob_start();
	}
	
	public function end()
	{ 
		if( $this->isBuffer )
		{
			$tampon = ob_get_contents();
			ob_end_clean();
			file_put_contents($this->fichier,$tampon);
			echo $tampon;
		}
	}


	function clean_req($query)
	{
		return preg_replace('#\s+#', ' ' , $query);
	}

	function debug()
	{
		echo '<div class="debug" style="color: #555555; background-color: #eeeeee; border: 1px solid #cfcfcf;	padding: 5px 10px; margin: 10px 20px; font: normal 12px \'Trebuchet MS\', \'Lucida Grande\', Verdana, Georgia, Sans-Serif; ">';
		
		echo '<h2>Connexion MySQL : ' . ($this->isConnect ? '<span style="color:green;">oui</span>' : '<span style="color:red;">non</span>').'</h2>';
		echo '<h2>Erreur de connexion : ' . ($this->isErreurConnect ? '<span style="color:red;">oui</span>' : '<span style="color:green;">non</span>') .'</h2>';
		
		foreach( $this->requetes  as $key => $value )
		{
			echo 'id : ' . $key . '<br>';
			echo 'req : ' . $this->clean_req($value->requete) . '<br>' ;
			echo 'exec time : ' . date('Y-m-d h:m:i',$value->time_query) . '<br>' ;
			echo 'duree : ' . round($value->duree,3) . '<br>' ;
			echo empty($value->error) ? '' : '<span style="color:red;">erreur : ' . $value->error  . '</span><br>' ;
			echo 'num rows : ' . $value->num_rows() . '<br>' ;
			
			echo '<br>';
		}
		echo '</div>';
	}
}


//(PHP 5) file_put_contents — Écrit un contenu dans un fichier
if (!function_exists('file_put_contents')) 
{
	function file_put_contents($filename, $data) 
	{
		$f = @fopen($filename, 'w');
		if (!$f)
		{
			return false;
		}
		else
		{
			$bytes = fwrite($f, $data);
			fclose($f);
			return $bytes;
		}
	}
}

À propos

Je suis développeur depuis près de 20 ans.
Principalement dans le milieu web.

Toutes mes classes