admin janvier 8th, 2009
Voici une fonction qui permet avec une logique identique au Sql de filtrer les données d’un tableau sur des colonnes, et aussi donc de filtrer un résultat Sql.
Pour par exemple filtrer une liste de produit sur la taille, la couleur, le prix, tout critère disponible dans le tableau passer par ce genre de fonction soulage le serveur sql d’une requête par utilisateur.
Comment cela fonctionne :
1 - Un tableau de donnée avec de colonnes
$db_produit=array();
$db_produit[0]["codebar"]="111111";
$db_produit[0]["listestailles"]=array("M","XL");
$db_produit[0]["listescouleurs"]=array("Rouge","vert");
$db_produit[0]["prix"]=30;
$db_produit[0]["prix_remise"]=5;
$db_produit[1]["codebar"]="1122211";
$db_produit[1]["listestailles"]=array("M","L","S");
$db_produit[1]["listescouleurs"]=array("bleu","vert");
$db_produit[1]["prix"]=150;
$db_produit[1]["prix_remise"]=120;
//etc...
Les critères de filtrage des données :
$critere_restriction=array();
$critere_restriction["affichetaille"]=45;
$critere_restriction["affichecouleur"]="bleu";
$critere_restriction["prixmin"]=10;
$critere_restriction["prixmax"]=30;
if (count($critere_restriction)>0)
{
// Restreint l'affichage des produits aux produits selectionnes
$callback_func = create_function('$db_produit , $critere_restriction','
if (
( ($critere_restriction["affichetaille"]!="" &&
in_array($critere_restriction["affichetaille"],(array)$db_produit["listestailles"]))
|| $critere_restriction["affichetaille"]=="" )
&&
( ($critere_restriction["affichecouleur"]!="" &&
in_array($critere_restriction["affichecouleur"],(array)$db_produit["listescouleurs"]))
|| $critere_restriction["affichecouleur"]=="" )
&&
( (
is_numeric($critere_restriction["prixmax"]) &&
is_numeric($critere_restriction["prixmin"])
&&
(
(
$db_produit["prix"]<=$critere_restriction["prixmax"] &&
$db_produit["prix"]>=$critere_restriction["prixmin"]
)
||
(
$db_produit["prix_remise"]!=-1 && is_numeric($db_produit["prix_remise"]) &&
$db_produit["prix_remise"]<=$critere_restriction["prixmax"] &&
$db_produit["prix_remise"]>=$critere_restriction["prixmin"]
)
)
|| $critere_restriction["prixmin"]==""
)
)
)
{return true;}
');
// Filtre la base
$db_produit=array_key_filter($db_produit,$critere_restriction,$callback_func);
unset($critere_restriction);
$nombre_total_de_resultat=count($db_produit);
}
La partie qui permet de faire les conditions de filtrage est celle ci. Vous faites simplement une condition qui répond à votre besoin.
Dans cette condition on retourne le résultat de la ligne du tableau si elle correspond à un des critères demandé :
if (
( ($critere_restriction["affichetaille"]!="" &&
in_array($critere_restriction["affichetaille"],(array)$db_produit["listestailles"]))
|| $critere_restriction["affichetaille"]=="" )
&&
( ($critere_restriction["affichecouleur"]!="" &&
in_array($critere_restriction["affichecouleur"],(array)$db_produit["listescouleurs"]))
|| $critere_restriction["affichecouleur"]=="" )
&&
( (
is_numeric($critere_restriction["prixmax"]) &&
is_numeric($critere_restriction["prixmin"])
&&
(
(
$db_produit["prix"]<=$critere_restriction["prixmax"] &&
$db_produit["prix"]>=$critere_restriction["prixmin"]
)
||
(
$db_produit["prix_remise"]!=-1 && is_numeric($db_produit["prix_remise"]) &&
$db_produit["prix_remise"]<=$critere_restriction["prixmax"] &&
$db_produit["prix_remise"]>=$critere_restriction["prixmin"]
)
)
|| $critere_restriction["prixmin"]==""
)
)
)
{return true;}
Voici la fonction de filtrage :
// # array_key_filter ###################################################
// # Permet de filtrer un tableau sur ses colonnes
// # Retour : tableau filtre
function array_key_filter($array,$criteres_restriction=array(),$callback)
{
$ret = array();
foreach($array as $key_recherche=>$array_resultat_page)
{
if ($callback($array_resultat_page,$criteres_restriction))
{
$ret[]=$array_resultat_page;
}
}
return $ret;
}
admin janvier 8th, 2009
Voici un système de cache d’une grande simplicité qui permet :
- De mettre en cache uniquement certaines parties de pages délivrées à l’internaute
- De mettre en cache n’importe quelle donnée sous forme de tableau (Ce qui est très intéressant pour soulager un serveur SQL par exemple)
Pour mettre en cache la sortie d’un script par exemple ou d’une partie de la sortie de ce script :
<?php
// Group , Id, TTL en secondes
if (!OutputCache::Start("myGroup", "myID", 600)) {
// Generate some output (as you do)...
OutputCache::End();
}
?>
Si votre sortie affiche des informations “aléatoires” ou différentes à chaque affichage de la page, il suffit de passer un nombre aléatoire dans le nom du groupe et de l’id du fichier de cache. Idem en cas de site multilingue, ou pour gérer la cache selon les rubriques d’un site.
Ex :
// Mise en cache de 5 possibilites d'affichage
$alea_cache=rand (1,5);
$cache_ttl=600;
if
(!OutputCache::Start("Groupe_Prod_".$code_langue."_".$id_rubrique."_".$alea_cache,
"Produit_BF_".$code_langue."_".$id_rubrique."_".$alea_cache,$cache_ttl)) {
// Ici on passe le code php qui va afficher les données
echo "Fichier de cache
".Produit_BF_".$code_langue."_".$id_rubrique."_".$alea_cache;
OutputCache::End();
}
Pour mettre en cache un tableau de donnée (array), ou le résultat d’une requête Sql.
<?php
if (!$data = DataCache::Get("myGroup", "myOtherID")) {
$mesdonnees=array("A","B","C");
// Group - Id - TTl en secondes
DataCache::Put("myGroup", "myOtherID", 600, $mesdonnees);
}
print_r($mesdonnees);
?>
Voici le code de la classe :
<?php
/**
*
o------------------------------------------------------------------------------o
* | This package is licensed under the Phpguru license 2008. A quick
summary is |
* | that the code is free to use for non-commercial purposes. For
commercial |
* | purposes of any kind there is a small license fee to pay. You can read
more |
* | at:
|
* | http://www.phpguru.org/static/license.html
|
*
o------------------------------------------------------------------------------o
*
* © Copyright 2008 Richard Heyes
*/
/**
* Caching Libraries for PHP5
*
* Handles data and output caching. Defaults to /dev/shm
* (shared memory). All methods are static.
*
* Eg: (output caching)
*
* if (!OutputCache::Start('group', 'unique id', 600)) {
*
* // ... Output
*
* OutputCache::End();
* }
*
* Eg: (data caching)
*
* if (!$data = DataCache::Get('group', 'unique id')) {
*
* $data = time();
*
* DataCache::Put('group', 'unique id', 10, $data);
* }
*
* echo $data;
*/
class Cache
{
/**
* Whether caching is enabled
* @var bool
*/
public static $enabled = true;
/**
* Place to store the cache files
* @var string
*/
protected static $store = '/dev/shm/';
/**
* Prefix to use on cache files
* @var string
*/
protected static $prefix = 'cache_';
/**
* Stores data
*
* @param string $group Group to store data under
* @param string $id Unique ID of this data
* @param int $ttl How long to cache for (in seconds)
*/
protected static function write($group, $id, $ttl, $data)
{
$filename = self::getFilename($group, $id);
if ($fp = fopen($filename, 'xb')) {
if (flock($fp, LOCK_EX)) {
fwrite($fp, $data);
}
fclose($fp);
// Set filemtime
touch($filename, time() + $ttl);
}
}
/**
* Reads data
*
* @param string $group Group to store data under
* @param string $id Unique ID of this data
*/
protected static function read($group, $id)
{
$filename = self::getFilename($group, $id);
return file_get_contents($filename);
}
/**
* Determines if an entry is cached
*
* @param string $group Group to store data under
* @param string $id Unique ID of this data
*/
protected static function isCached($group, $id)
{
$filename = self::getFilename($group, $id);
if (self::$enabled && file_exists($filename) &&
filemtime($filename) > time()) {
return true;
}
@unlink($filename);
return false;
}
/**
* Builds a filename/path from group, id and
* store.
*
* @param string $group Group to store data under
* @param string $id Unique ID of this data
*/
protected static function getFilename($group, $id)
{
$id = md5($id);
return self::$store . self::$prefix . "{$group}_{$id}";
}
/**
* Sets the filename prefix to use
*
* @param string $prefix Filename Prefix to use
*/
public static function setPrefix($prefix)
{
self::$prefix = $prefix;
}
/**
* Sets the store for cache files. Defaults to
* /dev/shm. Must have trailing slash.
*
* @param string $store The dir to store the cache data in
*/
public static function setStore($store)
{
self::$store = $store;
}
}
/**
* Output Cache extension of base caching class
*/
class OutputCache extends Cache
{
/**
* Group of currently being recorded data
* @var string
*/
private static $group;
/**
* ID of currently being recorded data
* @var string
*/
private static $id;
/**
* Ttl of currently being recorded data
* @var int
*/
private static $ttl;
/**
* Starts caching off. Returns true if cached, and dumps
* the output. False if not cached and start output buffering.
*
* @param string $group Group to store data under
* @param string $id Unique ID of this data
* @param int $ttl How long to cache for (in seconds)
* @return bool True if cached, false if not
*/
public static function Start($group, $id, $ttl)
{
if (self::isCached($group, $id)) {
echo self::read($group, $id);
return true;
} else {
ob_start();
self::$group = $group;
self::$id = $id;
self::$ttl = $ttl;
return false;
}
}
/**
* Ends caching. Writes data to disk.
*/
public static function End()
{
$data = ob_get_contents();
ob_end_flush();
self::write(self::$group, self::$id, self::$ttl, $data);
}
}
/**
* Data cache extension of base caching class
*/
class DataCache extends Cache
{
/**
* Retrieves data from the cache
*
* @param string $group Group this data belongs to
* @param string $id Unique ID of the data
* @return mixed Either the resulting data, or null
*/
public static function Get($group, $id)
{
if (self::isCached($group, $id)) {
return unserialize(self::read($group, $id));
}
return null;
}
/**
* Stores data in the cache
*
* @param string $group Group this data belongs to
* @param string $id Unique ID of the data
* @param int $ttl How long to cache for (in seconds)
* @param mixed $data The data to store
*/
public static function Put($group, $id, $ttl, $data)
{
self::write($group, $id, $ttl, serialize($data));
}
}
?>
Il est évident que dès qu’un site commence à monter en charge, ce genre d’outil est très efficace et simple à implémenter. Je l’utilise sur de nombreux site à forte fréquentation et ce dernier ne m’a jamais posé de problème. Il n’a pour le moment et ce depuis 2005 que des avantages. A vos éditeurs de code pour les intéressés.
Référence :
http://www.phpguru.org/static/Caching.html
admin janvier 8th, 2009
Voici une fonction qui permet de connaitre le poids “d’un fichier distant” pour ceux qui travaillent sur des scripts en php4 et qui ne disposent pas de la fonction get_headers disponible en php5.x.
function Remote_Filesize($url) {
$sch = parse_url($url, PHP_URL_SCHEME);
if (($sch != "http") && ($sch != "https") && ($sch != "ftp") && ($sch
!= "ftps")) {
return false;
}
if (($sch == "http") || ($sch == "https")) {
$headers = @get_headers($url, 1);
if (!is_array($headers)){$headers=array();}
if ((!array_key_exists("Content-Length", $headers))) { return
false; }
return $headers["Content-Length"];
}
if (($sch == "ftp") || ($sch == "ftps")) {
$server = parse_url($url, PHP_URL_HOST);
$port = parse_url($url, PHP_URL_PORT);
$path = parse_url($url, PHP_URL_PATH);
$user = parse_url($url, PHP_URL_USER);
$pass = parse_url($url, PHP_URL_PASS);
if ((!$server) || (!$path)) { return false; }
if (!$port) { $port = 21; }
if (!$user) { $user = "anonymous"; }
if (!$pass) { $pass = "phpos@"; }
switch ($sch) {
case "ftp":
$ftpid = ftp_connect($server, $port);
break;
case "ftps":
$ftpid = ftp_ssl_connect($server, $port);
break;
}
if (!$ftpid) { return false; }
$login = ftp_login($ftpid, $user, $pass);
if (!$login) { return false; }
$ftpsize = ftp_size($ftpid, $path);
ftp_close($ftpid);
if ($ftpsize == -1) { return false; }
return $ftpsize;
}
}
admin novembre 21st, 2008
Il arrive parfois que les tableaux de donnée Array en PHP se corrompent quand il se présente des accents ou apostrophes “à la Word” dans les contenus que on les stock en base de donnée Mysql via un serialize().
Dans ce cas, le tableau ne devient plus utilisable si on fait un unserialize() !
Pour palier à ce problème voici deux fonctions que j’utilise qui me garantissent que le stockage en base ne va pas corrompre mon tableau :
// Encode et decode un array pour l'insérer en base ou le lire
function Encode_Array($x)
{
return base64_encode(serialize($x));
}
function Decode_Array($x)
{
return unserialize(base64_decode($x));
}
admin novembre 19th, 2008
Dans un site ou vous désirez que le moteur de recherche soit capable de trouver des textes présent dans des fichiers uploadés ou récupérer le texte pour en faire ce que vous voulez, voici quelques fonctions déclinables à l’infini (puisqu’elles utilisent des applications Linux via la fonction exec()).
// # Pdftotext ###################################################
// # Conversion de texte du PDF en Jpeg
// # Retour :
function Pdftotext($fichier_pdf)
{
global $tmp_path;
$fichier_text=tempnam($tmp_path,'tmpPdftotext');
$commande_transformation="pdftotext -f 1 -l 1 ".$fichier_pdf."
".$fichier_text;
$log_commande=exec($commande_transformation);
if (is_file($fichier_text))
{
$text=file_get_contents($fichier_text);
}
unlink($fichier_text);
return $text;
}
// # Wordtotext ###################################################
// # Conversion de texte du fichier word en texte
// # Retour :
function Wordtotext($fichier_word)
{
global $tmp_path;
$fichier_text=tempnam($tmp_path,'tmpWordtotext');
$commande_transformation="wvText ".$fichier_word." ".$fichier_text;
exec($commande_transformation);
if (is_file($fichier_text))
{
$text=file_get_contents($fichier_text);
}
unlink($fichier_text);
return $text;
}
// # Rtftotext ###################################################
// # Conversion de texte du fichier rtf en texte
// # Retour :
function Rtftotext($fichier)
{
global $tmp_path;
$fichier_text=tempnam($tmp_path,'tmpRtftotext');
$commande_transformation="unrtf ".$fichier." >".$fichier_text;
exec($commande_transformation);
if (is_file($fichier_text))
{
$text=file_get_contents($fichier_text);
}
unlink($fichier_text);
return $text;
}
// # Ppttotext ###################################################
// # Conversion de texte du fichier Ppt en texte
// # Retour :
function Ppttotext($fichier)
{
global $tmp_path;
$fichier_text=tempnam($tmp_path,'tmpRtftotext');
$commande_transformation="catppt ".$fichier." >".$fichier_text;
exec($commande_transformation);
if (is_file($fichier_text))
{
$text=file_get_contents($fichier_text);
}
unlink($fichier_text);
return $text;
}
Voici la liste des packages à installer pour disposer de ces fonctions :
- Pdfinfo - http://linux.about.com/library/cmd/blcmdl1_pdfinfo.htm
- Pdftotext - http://www.foolabs.com/xpdf/download.html
- Unrtf lecture de fichiers rtf - http://www.gnu.org/software/unrtf/unrtf.html
- wv lecture de fichier doc - http://wvware.sourceforge.net/
- elinks nécessaire au fonctionnement de wvtext
- catdoc - http://linux.die.net/man/1/catppt
admin novembre 13th, 2008
Cette fonction vous permet de récupérer tous les urls des “médias” attachés au document html parcouru, en recherchant les balises de type href,src,url.
Si vous ne voyez pas quoi en faire, elle me permet d’encapsuler des pages html, et ses médias dans une page existante.
Cela peut aussi servir à lister les images, les liens, les css, etc présents dans un document html.
La fonction retourne les résultats avec une clé pour chaque type de lien et la liste des liens trouvés.
Cette fonction ne prend pas en compte les liens css avec @import url(”css/styles.css”);, mais cela doit se faire sans mal en modifiant un peu l’expression régulière.
// # Get_Urls ###################################################
// # Retourne toutes les url du type demandé
// # Parametres :
// $texte, type d'url
// # Retour : urls
function Get_Urls($string,$lestypes=array())
{
$types = array("href", "src", "url");
if (count($lestypes)>0)
{
$types=$lestypes;
}
while(list(,$type) = each($types)) {
preg_match_all
("|$type\s?\=?\(?\"?'?`?\s?([[:alnum:]:?=&@/#._\-éèàöôa\'\s]+)\s?\)?\"?'?`?|i",
$string, &$matches);
$ret[$type] = $matches[1];
}
return $ret;
}