PHP
::Inverser les éléments d'un tableau avec ses clés
[Trackback]
Date : 2008-09-30@13:52:51
Rang : 0
La fonction PHP array_flip permet d'inverser les valeurs d'un tableau avec ses clés.
Par exemple un tableau
[0]=>"toto"
[1]=>"tata"
[2]=>"tila"
[3]=>"tequila"
sera transformer en :
["toto"]=>0
["tata"]=>1
["tila"]=>2
["tequila"]=>3
PHP
::Benchmark lecture et ecriture dans un fichier
[Trackback]
Date : 2008-09-18@17:42:57
Rang : 0
$time = time() + microtime();
for ($i = 0; $i < 100000; $i ++)
{
$handle = fopen($filename, 'r+');
$str = fread($handle, filesize($filename));
rewind($handle);
ftruncate($handle,0);
fwrite($handle, $string);
fclose($handle);
}
var_dump(time() + microtime() - $time);
$time = time() + microtime();
for ($i = 0; $i < 100000; $i ++)
{
$content = file_get_contents($filename);
file_put_contents($filename,$content);
}
var_dump(time() + microtime() - $time);
Résultats :
float 10.173743963242
float 10.913619995117
Conclusion :
C'est bien plus rapide d'ouvrir un fichier en lecture écriture et que de faire une lecture puis une ecriture
Application directe :
Dans le cache de nos objets, nous projetons de sauvegarder nos disques en evitant de mettre en cache disque les objets n'ayant pas changer. Pour cela il faut bien comparer l'objet frai et l'objet caché et donc lire puis écrire le cache si celui ci a effectivement changer.
PHP
::Benchmark touch vs file_put_contents
[Trackback]
Date : 2008-05-28@14:54:59
Rang : 0
Dans la série question existentielle :
touch vs file_put_contents
le code de test :
<?php
$time = time() + microtime();
for ($i = 0 ; $i < 10000; $i++)
{
file_put_contents('test.txt','www.deezer.com Tu peux te
créer ta propre
playlist en tinscrivant. Tu ne veux pas tinscrire? Pas gra
ve, tu peux quand meme écouter de la musique.
Simple dutilisation,
lit toutes les musiques de
la dernière recherche
les unes après les autres.');
}
var_dump(time() + microtime() - $time);
$time = time() + microtime();
for ($i = 0 ; $i < 10000; $i++)
{
touch('test.txt');
}
var_dump(time() + microtime() - $time);
?>
Les résultats :
file_put_contents 0.41347002983093
touch 0.071331977844238
Soit 6 fois plus rapide, l'application directe de ce test est que l'on évite l'écriture en cache d'un objet si celui ci n'a pas changer et on le revalide par un touch.
Pour vérifier que le cache n'a pas changer il faut bien sur lire le cache même quand il n'est plus valide.
Ce qui donne le code de bench suivant :
<?php
$time = time() + microtime();
for ($i = 0 ; $i < 10000; $i++)
{
file_put_contents('test.txt','www.deezer.com Tu peux te
créer ta propre
playlist en tinscrivant. Tu ne veux pas tinscrire? Pas gra
ve, tu peux quand meme écouter de la musique.
Simple dutilisation,
lit toutes les musiques de
la dernière recherche
les unes après les autres.');
}
var_dump(time() + microtime() - $time);
$time = time() + microtime();
for ($i = 0 ; $i < 10000; $i++)
{
file_get_contents('test.txt');
touch('test.txt');
}
var_dump(time() + microtime() - $time);
?>
Les résultats :
file_put_contents 0.51197385787964
touch + file_get_contents 0.3950469493866
Le gain est minime cette fois mais c'est toujours ça de pris :D
PHP
::Point ou virgule : Question existentielle
[Trackback]
Date : 2008-03-14@15:02:55
Rang : 0
Super question existentielle du vendredi :D est ce plus rapide de faire :
echo ' '.$i;
ou
echo ' ',$i;
Le code de test :
ob_start();
$time = microtime(true);
for ($i = 0; $i < 1000000; $i++)
{
echo ' ', $i;
}
ob_clean();
echo microtime(true) - $time, "\\n";
ob_start();
$time = microtime(true);
for ($i = 0; $i < 1000000; $i++)
{
echo ' '.$i;
}
ob_clean();
echo microtime(true) - $time, "\\n";
La réponse de ce test super important dont on connaît la réponse par avance :
1.5555839538574
1.7078490257263
Donc ',' est notre champion du super benchmark youpi :D
PHP
::API Seeqpod
[Trackback]
Date : 2008-02-04@16:36:01
Rang : 0
Non content d'être un moteur de recherche de MP3 fort sympathique
Désormais Seeqpod propose une api pour utiliser ses résultats.
Et dire que je me suis fait chier a disséqué leur site pour mon jukebox.
PHP
::Envoyer un fichier sans recharger la page
[Trackback]
Date : 2008-01-30@10:39:30
Rang : 0
Pour envoyer un fichier en attachement avec php il faut envoyer les headers suivants au navigateur:
header('Content-type: application/zip;');
header('Content-Disposition: attachment; filename="'.basename($file).'"');
header('Content-Length: '.filesize($file));
readfile($file);
Cela permet par exemple de faire télécharger un fichier (zip changer le content type en fonction de vos besoin) a l'utilisateur lorsqu'il clique sur un lien sans faire changer la page. Le href du lien est alors un script contenant les lignes précédentes.
PHP
::Requete SQL pour les liens en relations
[Trackback]
Date : 2008-01-15@11:36:08
Rang : 0
Cette requete permet de trouver pour un article donné des articles similaires en se basant sur les tags. Elle retourne les articles qui ont 50% des tags qui correspondent dans les deux sens.
Dans l'exemple suivant on traite l'article avec pour ID 100.
SELECT
ART_ID,
COUNT(*) AS MATCHES,
(
SELECT COUNT( * )
FROM ARTICLES_TAGS
WHERE t1.ART_ID = ART_ID
GROUP BY ART_ID
) AS TAG_COUNT
FROM ARTICLES_TAGS t1
WHERE TAG_ID
IN
(
SELECT TAG_ID
FROM ARTICLES_TAGS
WHERE ART_ID =100
)
AND ART_ID !=100
GROUP BY ART_ID
HAVING
(MATCHES /(SELECT greatest(COUNT(*),1) FROM ARTICLES_TAGS WHERE ART_ID =100 GROUP BY ART_ID ) >= 0.5)
AND MATCHES >=TAG_COUNT/(1/0.5)
PHP
::Benchmark require VS include
[Trackback]
Date : 2008-01-11@11:39:36
Rang : 0
Bon comme on est vendredi et que l'on m'a gentillement posé la question de savoir si le require était plus rapide que l'include je me suis fait un petit benchmark pour trouver la réponse.
Petit rappel : Les deux fonctions n'ont pas le même comportement require déclenche une erreur php qui stop donc l'exécution du code alors que include déclenche un warning et continu l'exécution.
le bench est fait sous php5
J'ai généré 2000 fichiers (1000 pour le require et 1000 pour include) avec le code suivant :
<?php
set_time_limit();
for($i = 0;$i<1000;$i++)
{
file_put_contents('/data/projects/test/include'.$i.'.php',"<?php\\necho 'coucou je suis content ".$i."';\\n?>");
file_put_contents('/data/projects/test/require'.$i.'.php',"<?php\\necho 'coucou je suis content ".$i."';\\n?>");
}
?>
Chaque fichier a un code différent je ne pense pas que cela joue mais bon comme on a apc sur les serveurs on sait jamais.
Maintenant que tout est prés on peur lancer le code de benchmark à proprement parler.
<?php
set_time_limit(0);
$start = time()+microtime();
for($i = 0;$i<1000;$i++)
{
include('/data/projects/test/include'.$i.'.php');
}
error_log('Benchmark include '.(time()+microtime()-$start),E_USER_WARNING);
$start = time()+microtime();
for($i = 0;$i<1000;$i++)
{
require('/data/projects/test/require'.$i.'.php');
}
error_log('Benchmark require '.(time()+microtime()-$start),E_USER_WARNING);
?>
Et voilà le résultat dans mon log
[11-Jan-2008 11:31:57] Benchmark include 0.039840936660767
[11-Jan-2008 11:31:57] Benchmark require 0.05462384223938
Donc include est 38% plus rapide que require.
PHP
::pagination à l'aide d'une fonction
[Trackback]
Date : 2007-11-21@15:44:55
Rang : 0
Ce petit bout de code bien pratique permet d'avoir une fonction de pagination universelle. Du moins elle fonctionne sur tous les sites permettant l'utilisation du $_GET dans les urls.
/**
* Retourne un tableau contenant les liens pour une pagination
*
* Ex: getPagination($_SERVER['REQUEST_URI'],55,10)
*
* Avec comme appel http://www.monsite.com/index.php?dummy1=4508654&dummy2=1&edit=1&p=2
*
* array
* 0 => string '<a href="/index.php?dummy1=4508654&dummy2=1&edit=1&p=0"><<</a>'
* 1 => string '<a href="/index.php?dummy1=4508654&dummy2=1&edit=1&p=1"><</a>'
* 2 => string '<a href="/index.php?dummy1=4508654&dummy2=1&edit=1&p=1">2</a>'
* 3 => string '<a href="/index.php?dummy1=4508654&dummy2=1&edit=1&p=0">1</a>'
* 4 => string '<span>3</span>'
* 5 => string '<a href="/index.php?dummy1=4508654&dummy2=1&edit=1&p=3">4</a>'
* 6 => string '<a href="/index.php?dummy1=4508654&dummy2=1&edit=1&p=4">5</a>'
* 7 => string '<a href="/index.php?dummy1=4508654&dummy2=1&edit=1&p=3">></a>'
* 8 => string '<a href="/index.php?dummy1=4508654&dummy2=1&edit=1&p=5">>></a>'
*
* @param string $url url de base pour la pagination (ex: $_SERVER['REQUEST_URI'])
* @param int $foundRows nombre de ligne total (SQL_CALC_FOUND_ROWS)
* @param int $limitPerPage nombre limite d'element par pages
* @param int $displayPages nombre de pages afficher a droite (ou a gauche) de la page courante
* @param string $pageArg index du $_GET pour cette pagination
* @param string $firstLabel texte (ou balise img ...) pour la première page
* @param string $previousLabel texte (ou balise img ...) pour la page précédente
* @param string $nextLabel texte (ou balise img ...) pour la page suivante
* @param string $lastLabel texte (ou balise img ...) pour la dernière page
* @return array
*/
function getPagination($url,$foundRows,$limitPerPage,$displayPages = 2,$pageArg = 'p', $firstLabel = '<<',$previousLabel = '<',$nextLabel = '>',$lastLabel = '>>')
{
$pages = array();
parse_str(parse_url($url,PHP_URL_QUERY),$arg);
$currentPage = isset($arg[$pageArg]) ? (int)$arg[$pageArg] : 0;
unset($arg[$pageArg]);
$strpos = strpos($url,'?');
if($strpos !== false)
{
$url = substr($url,0,$strpos);
}
$url .= '?'.http_build_query($arg,null,'&');
$lastPage = ceil($foundRows / $limitPerPage) - 1;
if($lastPage > 0)
{
if($currentPage > 0)
{
$pages[] = '<a href="'.$url.'&'.$pageArg.'=0">'.$firstLabel.'</a>';
$pages[] = '<a href="'.$url.'&'.$pageArg.'='.($currentPage-1).'">'.$previousLabel.'</a>';
for($i = 1,$max = $displayPages+1; $i<$max;$i++)
{
$p = $currentPage - $i;
if($p >= 0)
{
$pages[] = '<a href="'.$url.'&'.$pageArg.'='.$p.'">'.($p+1).'</a>';
}
else
{
$p = $max;
}
}
}
$pages[] = '<span>'.($currentPage+1).'</span>';
if($currentPage < $lastPage)
{
for($i = 1,$max = $displayPages+1; $i<$max;$i++)
{
$p = $currentPage + $i;
if($p <= $lastPage)
{
$pages[] = '<a href="'.$url.'&'.$pageArg.'='.$p.'">'.($p+1).'</a>';
}
else
{
$p = $max;
}
}
$pages[] = '<a href="'.$url.'&'.$pageArg.'='.($currentPage+1).'">'.$nextLabel.'</a>';
$pages[] = '<a href="'.$url.'&'.$pageArg.'='.($lastPage).'">'.$lastLabel.'</a>';
}
}
return $pages;
}
PHP
::Génération d'un dégradé
[Trackback]
Date : 2007-10-01@15:54:45
Rang : 0
Cette fonction retourne un tableau contenant $stepNumber couleurs nécessaire au dégradé de $startColor vers $endColor
function gradient($startColor,$endColor, $stepNumber)
{
$colors = array($startColor);
$sColor = str_split($startColor,2);
$eColor = str_split($endColor,2);
for($i = 0 ;$i< 3 ;$i++)
{
$diff [$i] = (hexdec($sColor[$i])-hexdec($eColor[$i]))/($stepNumber-2);
}
for ($i = 1;$i<$stepNumber-1;$i++)
{
$c = str_split($colors[$i-1],2);
$colors[$i] = sprintf('%02X',max(0,min(255,(hexdec($c[0])-$diff[0])))).
sprintf('%02X',max(0,min(255,(hexdec($c[1])-$diff[1])))).
sprintf('%02X',max(0,min(255,(hexdec($c[2])-$diff[2]))));
}
$colors[$i] = $endColor;
return $colors;
}
Exemple :
$colors = gradient('FF0000','00EE00',7);
Affiche :
0 => string 'FF0000' (length=6)
1 => string 'CC2F00' (length=6)
2 => string '995E00' (length=6)
3 => string '668D00' (length=6)
4 => string '33BC00' (length=6)
5 => string '00EB00' (length=6)
6 => string '00EE00' (length=6)
PHP
::Couper une chaine sans couper les mots
[Trackback]
Date : 2007-09-27@18:01:08
Rang : 0
Cette fonction coupe la chaîne $string à la longueur $length si nécessaire sans couper le dernier mot et y ajoute la chaine $cutString si il y a eu une troncature.
function cleanCut($string,$length,$cutString = '...')
{
if(strlen($string) <= $length)
{
return $string;
}
$str = substr($string,0,$length-strlen($cutString)+1);
return substr($str,0,strrpos($str,' ')).$cutString;
}
PHP
::Problème de header 301 OK au lieu de 301 Moved Permanently
[Trackback]
Date : 2007-07-05@17:30:38
Rang : 0
Petit problème avec PHP, Lors ce que j'effectue une redirection 301 avec le code suivant :
header ('HTTP/1.1 301 Moved Permanently');
Le header envoyé correspond à HTTP/1.x 301 OK
Afin de corriger se petit détail il suffit de remplacer le code précédent par :
header ('Status: 301 Moved Permanently');
Ce problème semble uniquement être valable sur la version CGI de PHP.
PHP
::Tester rapidement l'existence d'un élément dans un tableau plus rapidement que in_array
[Trackback]
Date : 2007-06-13@11:18:03
Rang : 0
Bien sur en php tout le monde utilise la fonction in_array mais une petite astuce permet de le faire plus rapidement via les index des tableau.
Normal car la fonction in_array parcourt le tableau alors que le test de l'existence de l'index accède directement à l'élément.
$arrIndex = array('1'=>true,'2'=>true,'3'=>true,'4'=>true);
$arr = array('1','2','3','4');
$start = time()+microtime();
for ($i=0;$i<10000;$i++)
{
isset($arrIndex['1']);
}
var_dump(time()+microtime()-$start);
$start = time()+microtime();
for ($i=0;$i<10000;$i++)
{
in_array('1',$arr);
}
var_dump(time()+microtime()-$start);
Résultat du benchmark :
0.009213924407959 secondes pour le isset
0.15566611289978 secondes pour le in_array
Soit 17 fois plus rapide Enjoy ;-)
Remarques :
- Cette astuce ne convient pas à tous les tableaux, vous noterez que le tableau arrIndex est spécial.
- Isset est plus rapide que array_key_exist mais ne se comporte pas de la même manière sur des tableaux ayant des valeurs null ce qui est normal.
PHP
::Openid utilisant les fonctions ssl de php
[Trackback]
Date : 2007-05-29@18:21:09
Rang : 0
Wez Furlong et oui encore lui nous présente comment faire une authentification OpenId avec SSL
http://netevil.org/node.php?nid=949
PHP
::Requêtes Asynchrones en php
[Trackback]
Date : 2007-05-29@18:17:07
Rang : 0
Wez Furlong nous présente ici comment faire des requètes asynchrones en php.
http://netevil.org/node.php?uuid=427d6d12-c107-9816-7428-27d6d128f5e5
PHP
::Effacer le premier élément ajouté d'un tableau indéxé
[Trackback]
Date : 2007-05-18@12:54:18
Rang : 0
list($id, ) = each($urls_id);
unset($urls_id[$id]);
PHP
::Easter Egg php
[Trackback]
Date : 2007-04-13@12:27:38
Rang : 0
Voilà quelques chaines à rajouter sur n'importe quelle url de site tournant sur php pour découvrir les easter eggs (petite blague de développeur) du moteur php. Tout le monde connait les fonctions documentées :
php_logo_guid() et zend_logo_guid() qui permettent d'obtenir :
Logo zend
http://petitchevalroux.net/?=PHPE9568F35-D428-11d2-A769-00AA001ACF42
Logo php
http://petitchevalroux.net/?=PHPE9568F34-D428-11d2-A769-00AA001ACF42
La fonction non documentée
php_egg_logo_guid()
permet d'obtenir :
Logo php version Easter Egg
http://petitchevalroux.net/?=PHPE9568F36-D428-11d2-A769-00AA001ACF42
PHP
::PHP benchmark foreach for
[Trackback]
Date : 2007-04-13@11:42:46
Rang : 0
Chose Bizarre en php le foreach est plus rapide que le for.
1.709 ms Pour le foreach 1.944 ms et pour le for.
Trés bizarre.
<?php
$arr=Array(
'cacazcacz',
'cacazezcacz',
'cazcazaeacz',
'cazcaczca',
'cazcaczca',
'cazcaczcaz',
'cazcaccazz',
'cazcaeazcz',
'cazcaceazz',
'cazcaazecz',
'cazcacz',
'cazcdazdacz'
);
$start=time()+microtime();
for ($j=0;$j<1000;$j++)
{
foreach ($arr as $v)
{
$v;
}
}
var_dump(time()+microtime()-$start);
$start=time()+microtime();
$countArr=count($arr);
for ($j=0;$j<1000;$j++)
{
for($i=0;$i<$countArr;$i++)
{
$arr[$i];
}
}
var_dump(time()+microtime()-$start);
?>
PHP
::Flash et php via AMF
[Trackback]
Date : 2007-04-11@22:06:33
Rang : 0
Librairie AMFPHP ou SabreAMF
AMFPHP est la librairie la plus utilisée
SabreAMF version php5
http://www.osflash.org/sabreamf
PHP
::Example de cache en shmop
[Trackback]
Date : 2006-09-27@18:01:20
Rang : 0
http://www.adamstevenson.net/mycached.phps
