Extension PHP intl non chargée / non trouvée


Le problème

J’ai eu un problème sous Windows de librairie « intl » non chargée (php_intl.dll), alors que cette librairie était activée dans le php.ini, et était présente dans le répertoire des extensions ( c:...\wamp2-4\bin\php\php5.4.16\ext).

Cause et résolution

php_intl.dll utilise des librairies icu.dll.
Il faut ajouter dans le PATH système de Windows le répertoire qui contient les librairies icu
.dll (( c:...\wamp2-4\bin\php\php5.4.16), afin que ces dernières  soient trouvées. Inutile de redémarrer la machine.

 

Créer un module avec Zftool


Installation via Composer

Ouvrir un terminal (ici console Windows) et se positionner à la racine du projet (ici C:\www\librairie)

 C:\www\librairie>php composer.phar require zendframework/zftool:dev-master

Cette commande réalise les opérations suivantes :

  • Installation du module zendframework/zftool sous ./vendor.

  • Installation des commandes à utiliser en mode console sous ./vendor/bin.

Modifier application.config.php pour charger le module

return array(

// This should be an array of module namespaces used in the application.

‘modules’ => array(

‘Application’,

. . .

‘ZFTool’,

),

Créer un module

Nous allons créer un module nommé « Admin ». Il faut se positionner à la racine du projet, sous peine de voir s’afficher le message : « Error: I cannot find the autoloader of the application ».

> cd c:\www\librairie

.\vendor\bin\zf.php.bat     create  module   Admin

The module Admin has been created

Le module « Admin » est créé sous le répertoire module.

PHPExcel / directive open_basedir / fonction sys_get_temp_dir()


Message d’erreur
PHP Warning: realpath() [<a href='function.realpath'>function.realpath</a>]: open_basedir restriction in effect. File(/tmp) is not within the allowed path(s): .... in /PHPExcel/PHPExcel/Shared/File.php on line 141

Configuration

PHP 5.3.9
PHPExcel 1.7.6
Même problème sous Unix et  Windows.

Le problème

La librairie PHPExcel échoue lorsqu’elle essaie de créer des fichiers sous le répertoire temporaire d’Unix (ou windows) et que ces 2 conditions sont réunies :
– la directive open_basedir est activée (Cette directive contient la liste des répertoires accessibles par le programme PHP),
– le répertoire temporaire de l’OS n’est pas cité dans la directive open_basedir.

Pour récupérer la valeur du répertoire temporaire de l’OS, PHPExcel utilise la fonction PHP sys_get_temp_dir(), qui lui retourne /tmp (et c:\windows\temp pour windows). Si il n’est pas possible de rajouter /tmp dans open_basedir (peut être interdit sur des machines de production), vous trouverez ci-dessous les solutions que j’ai mises en oeuvre. Voici le code de la librairie PHPExcel qui pose problème :

Fichier PHPExcel/PHPExcel/Shared/File.php (1.7.6)

class PHPExcel_Shared_File {
. . .
public static function sys_get_temp_dir() {
// sys_get_temp_dir is only available since PHP 5.2.1
// http://php.net/manual/en/function.sys-get-temp-dir.php#94119
if ( !function_exists('sys_get_temp_dir')) {
if ($temp = getenv('TMP') ) {
if (file_exists($temp)) { return realpath($temp); }
}
if ($temp = getenv('TEMP') ) {
if (file_exists($temp)) { return realpath($temp); }
}
if ($temp = getenv('TMPDIR') ) {
if (file_exists($temp)) { return realpath($temp); }
}
// trick for creating a file in system's temporary dir
// without knowing the path of the system's temporary dir
$temp = tempnam(FILE, '');
if (file_exists($temp)) {
unlink($temp);
return realpath(dirname($temp));
}
return null;
}
// use ordinary built-in PHP function
// There should be no problem with the 5.2.4 Suhosin realpath() bug, because this line should only
// be called if we're running 5.2.1 or earlier return realpath(sys_get_temp_dir());                             // Erreur PHP ICI (ligne 141)
}

Solutions possibles

1ère solution 

Mettre à jour la librairie avec la version PHPExcel 1.8 : Les concepteurs ont ajouté une portion de code permettant d’utiliser la valeur de la directive PHP upload_tmp_dir, à la place du répertoire temporaire de l’OS. Le répertoire upload_tmp_dir devra être cité dans open_basedir, si il n’y est pas déjà.

Fichier PHPExcel/PHPExcel/Shared/File.php (1.8)

public static function sys_get_temp_dir()
{
if (self::$_useUploadTempDirectory) {
// use upload-directory when defined to allow
// running on environments having very restricted
// open_basedir configs
if (ini_get('upload_tmp_dir') !== FALSE) {
if ($temp = ini_get('upload_tmp_dir')) {
if (file_exists($temp))
return realpath($temp);
}
}

}
// sys_get_temp_dir is only available since PHP 5.2.1
// http://php.net/manual/en/function.sys-get-temp-dir.php#94119
if ( !function_exists('sys_get_temp_dir')) {
if ($temp = getenv('TMP') ) {
if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); }
}
if ($temp = getenv('TEMP') ) {
if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); }
}
if ($temp = getenv('TMPDIR') ) {
if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); }
}
// trick for creating a file in system's temporary dir
// without knowing the path of the system's temporary dir
$temp = tempnam(FILE, '');
if (file_exists($temp)) {
unlink($temp);
return realpath(dirname($temp));
}
return null;
}
// use ordinary built-in PHP function
// There should be no problem with the 5.2.4 Suhosin realpath() bug,
// because this line should only
// be called if we're running 5.2.1 or earlier
return realpath(sys_get_temp_dir());
}

La fonction teste la variable statique self::$_useUploadTempDirectory qui est initialisée à False par défaut. Nous devons initialiser cette statique à true, quelque part dans notre code (avant d’utiliser PHPExcel).

. . .
PHPExcel_Shared_File::setUseUploadTempDirectory(true);
...

2ème solution

Si vous ne pouvez pas mettre à jour tout de suite la librairie, vous pouvez juste modifier la fonction pour qu’elle utilise systématiquement upload_tmp_dir sur le modèle ci-dessous . J’ai repris le même code que ci-dessus, mais sans le test.

Fichier PHPExcel/PHPExcel/Shared/File.php (1.7.6 MODIFIE)
public static function sys_get_temp_dir()
{

// use upload-directory when defined to allow running
// on environments having very restricted
// open_basedir configs
if (ini_get('upload_tmp_dir') !== FALSE) {
if ($temp = ini_get('upload_tmp_dir')) {
if (file_exists($temp))
return realpath($temp);
}

}
// sys_get_temp_dir is only available since PHP 5.2.1
// http://php.net/manual/en/function.sys-get-temp-dir.php#94119
if ( !function_exists('sys_get_temp_dir')) {
if ($temp = getenv('TMP') ) {
if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); }
}
if ($temp = getenv('TEMP') ) {
if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); }
}
if ($temp = getenv('TMPDIR') ) {
if ((!empty($temp)) && (file_exists($temp))) { return realpath($temp); }
}
// trick for creating a file in system's temporary dir
// without knowing the path of the system's temporary dir
$temp = tempnam(FILE, '');
if (file_exists($temp)) {
unlink($temp);
return realpath(dirname($temp));
}
return null;
}
// use ordinary built-in PHP function
// There should be no problem with the 5.2.4 Suhosin realpath() bug, because this line should only
// be called if we're running 5.2.1 or earlier
return realpath(sys_get_temp_dir());
}

Autres solutions (PHP < 5.2.1 ou PHP >= 5.4)

  • Si vous utilisez PHP < 5.2.1, la fonction sys_get_temp_dir() n’existe pas encore, PHPExcel se sert (comme on le voit dans le code de la fonction) de la valeur d’une variable d’environnement TMP, TEMP ou TMPDIR. Cette variable peut donc être initialisée au préalable dans l’environnement. Par exemple :
    Dans httpd.conf ou .htaccess :
    SetEnv           TMPDIR      chemin_mon_rep_temporaire

Dans les sources PHP :
putenv("TMPDIR", chemin_mon_rep_temporaire) ;

  • si vous utilisez PHP >= 5.4, vous pouvez paramétrer le répertoire temporaire du SE dans la directive PHP sys_temp_dir. Cette valeur sera retournée par la fonction PHP sys_get_temp_dir().

Apache/php : php_value versus php_admin_value


Principe

– Si une directive est définie dans le httpd.conf par l’intermédiaire de admin_value, elle peut être redéfinie en local (php.ini, .htaccess, dans le programme PHP via ini_set()).
Cela ne fonctionne que si la directive est PHP_INI_ALL (modifiable au niveau système, dans fichiers locaux et programme PHP) ou PHP_INI_PERDIR (modifiable  au niveau système et dans fichiers locaux). Liste des directives sur le site de php.net

– Si une directive est définie dans le httpd.conf par l’intermédiaire de php_admin_value, elle ne peut pas être redéfinie en local.

Exemple 1

– httpd.conf :
php_admin_value memory_limit 16M
– Programme PHP :
ini_set("memory_limit","64M");
phpinfo() ;
– Résultat du phpinfo() : memory_limit 16M

Exemple 2

– httpd.conf :
php_value memory_limit 16M
– Programme PHP :
ini_set("memory_limit","64M");
– phpinfo() ;
Résultat du phpinfo() : memory_limit 64M

Dans la pratique (serveurs de production) memory_limit est fixé par les administateurs dans le httpd.conf avec php_admin_value, tout l’intérêt étant d’empécher les utilisateurs de décider chacun de leurs propres limites.

Parution de mon ouvrage « Programmation shell sous Unix/Linux » aux éditions ENI


La 4ème édition de mon ouvrage sur le shell Unix/Linux est sorti en Août 2014. J’ai enrichi cet ouvrage avec des exercices corrigés, et complété avec les principales spécificités du ksh93. Les shells Bourne, ksh 88 et 93, et bash sont traités. J’ai voulu cet ouvrage aussi pédagogique que possible. J’y explique un certain nombre de mécanismes du shell. Vous trouverez plus d’informations sur le site des Editions ENI : http://www.editions-eni.fr/livres/programmation-shell-sous-unix-linux-sh-ksh-bash-avec-exercices-corriges-4ieme-edition/.78fb4ff18c634260219f847edb0d3f4a.html

Programmation shell sous Unix / Linux