Trucs et astuces PHP
Extraits (snippets) de code PHP pour effectuer diverses tâches plus ou moins courantes.
Calculer le chemin relatif entre deux emplacements
La fonction qui suit permet de calculer le chemin relatif entre deux emplacements. Cela peut être utile pour calculer l'emplacement relatif d'un fichier css ou image.
function relativePath($from_path, $to_path, $path_separator = DIRECTORY_SEPARATOR)
{
$exploded_from = explode($path_separator, rtrim($from_path, $path_separator));
$exploded_to = explode($path_separator, rtrim($to_path, $path_separator));
while(count($exploded_from) && count($exploded_to) && ($exploded_from[0] == $exploded_to[0]))
{
array_shift($exploded_from);
array_shift($exploded_to);
}
return str_pad("", count($exploded_from) * 3, '..'.$path_separator).implode($path_separator, $exploded_to);
}
Source: Merci à imagiro pour son commentaire sur realpath.
Autoloader universel
Un autoloader est un code gérant l'inclusion automatique des fichiers PHP déclarant des classes. La difficulté consiste à coupler performance et souplesse. Gerald's Blog propose deux articles très intéressant sur la mise en place efficiente de cette mécanique:
Téléchargez le:
command wget 'https://raw.github.com/biapy/howto.biapy.com/master/php5/DirectoriesAutoloader.php' \ --quiet --no-check-certificate --output-document='DirectoriesAutoloader.php'
Son utilisation est très simple:
require(dirname(__FILE__) . '/DirectoriesAutoloader.php');
DirectoriesAutoloader::instance('/tmp/')
->addDirectory(realpath(dirname(__FILE__) . '/../../classes'))
->addDirectory(realpath(dirname(__FILE__) . '/../framework'))
->addDirectory(realpath(dirname(__FILE__) . '/locasyst'))
->addDirectory(realpath(dirname(__FILE__) . '/lib/vendor'))
->register();
Note: Il existe aussi Open Power Autoloader (https://github.com/OPL/opl3-autoloader) qui est très efficace si le projet utilise la convention PSR-0 (merci à The Zyxist Diaries pour Efficient autoloaders for PHP).
file_get_contents et timeout
Il est impossible de contrôler le timeout utilisé par file_get_contents lorsque la ressource ouverte est une URL. Si vous rencontrez l'erreur qui suit, vous êtes confronté à ce problème:
PHP Warning: file_get_contents(http://www.url.com/): failed to open stream: HTTP request failed! in /path/to/file.php on line 8
Voici une fonction conçue pour ajouter une notion de timeout à la fonctionnalité de file_get_contents (nécessite l'extension php5-curl):
/**
* Get URL contents
*
* @param string $url A URL.
* @param integer $timeout timeout for fetching the URL.
* @return mixed string with URL contents if success, False if failure.
*/
function url_get_contents($url, $timeout = 10)
{
$curl_handle = curl_init($url);
curl_setopt($curl_handle, CURLOPT_HEADER, 0);
curl_setopt($curl_handle, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl_handle, CURLOPT_USERAGENT, "PHP script");
curl_setopt($curl_handle, CURLOPT_TIMEOUT, $timeout);
$contents = curl_exec($curl_handle);
$curl_error = curl_error($curl_handle);
curl_close($curl_handle);
if ($curl_error)
{
// echo $CurlErr;
return false;
}
return $contents;
}
Source: Merci à Ripat pour file_get_contents pour fichiers distants avec timeout.