Cannot represent a stream of type SSH2 Channel as a select()able descriptor

Une extension PHP nommé ssh2, que l’on peut retrouver dans le dépôt pecl permet de se connecter à un serveur SSH depuis un script PHP à l’aide de plusieurs fonctions. Plus particulièrement, la fonction ssh2_shell qui retourne un flux de données, ou stream, nous permet de mettre en place entre le script PHP et le serveur SSH un vrai échange complet. L’intérêt d’avoir un flux de données pour converser avec un serveur SSH est que l’on peut manipuler assez facilement à l’aide de toutes les fonctions stream_* ces flux. Ça, c’est la théorie.

En pratique, il s’avère que l’utilisation d’un flux SSH2 Channel (retourné par ssh2_shell) avec la fonction stream_select qui permet d’attendre que le flux “change” – c’est-à-dire qu’une donnée arrive – est impossible. En effet, pour utiliser le flux avec stream_select, il faut pouvoir transformer ce flux en une donnée utilisable par la fonction C select(). C’est ce que l’on appelle “caster un stream” en franglais et “to cast a stream” en anglais. Le problème, c’est que la librairie pecl/ssh2 (basée sur libssh2) n’implémente pas cette fonctionnalité, ce qui nous donne droit à un magnifique:

Warning: stream_select() [function.stream-select]: cannot represent a stream of type SSH2 Channel as a select()able descriptor in /path/to/file.php on line XX

Nous allons donc voir comment ajouter cette fonctionnalité simplement, à l’aide de patchs développés par mes soins. Continue reading

PHP PDO: Récupérer les notes du serveur de bases de données

Certaines bases de données comme Oracle et PostgreSQL – MySQL le fait partiellement – renvoient des notes (notices en anglais) concernant une requête ALTER, UPDATE ou DELETE. Il est même possible de renvoyer des notes sous PostgreSQL et Oracle en faisant respectivement RAISE NOTICE et DMBS_OUTPUT.PUT_LINE. Ces informations peuvent parfois être retournée depuis les drivers de base de la base de données mais pas avec PDO.

Note: Ces patchs sont créés et testés pour PHP 5.3 uniquement.

Accèder à la page du projet PDO – Notices

Continue reading

La source de PHP dans un projet avec Eclipse CDT

Si vous souhaitez écrire de nouvelles fonctionnalités, créer des patchs, corriger quelques bugs ou tout simplement aider la communauté PHP sur le code source, il vous faut l’avoir dans un éditeur de code. Eclipse est mon favori, il permet de gérer presque tous les types de codes, bref, il est génial ! Seulement, j’ai un peu de mal à mettre en place le code source (du tronc ou d’une branche, peu importe) en tant que projet C dans Eclipse CDT.

Continue reading

PHP: Utiliser le mode E_STRICT est une très bonne chose !

Depuis la version 5.0 de PHP, un nouveau mode d’erreur est apparu: E_STRICT. Il ne fait pas parti de E_ALL et est désactivé par défaut dans toute installation classique de PHP. Ce nouveau mode permet en fait de générer des conseils à partir de votre code. Testez-le, vous verez c’est sympa ! Il peut par exemple retourner ce genre d’erreur:

Strict Standards: date() [function.date]: It is not safe to rely on the system’s timezone settings. Please use the date.timezone setting, the TZ environment variable or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected ‘Europe/Berlin’ for ‘CEST/2,0/DST’ instead in /home/mon/fichier.php on line 196

Note: Si vous tombez ici par hasard et que vous souhaitez la liste des timezones disponibles dans PHP, elle est disponible à cette adresse.
Ici, PHP me fait penser que j’utilise la valeur par défaut du timezone du système d’exploitation. Étant sur mon propre serveur, il n’y a pas de problèmes mais sur un serveur mutualisé, on peut avoir des surprises ! ;-)

Activer les rapports E_STRICT

Pour activer les rapports d’erreurs E_STRICT, c’est très simple. Ajoutez en haut de votre fichier PHP cette commande:

error_reporting(E_ALL | E_STRICT);

Ou modifiez votre fichier php.ini directement !

error_reporting = E_ALL | E_STRICT

Note: Désactivez ce mode en production, c’est préférable :)

PHP 5.2.10 – PEAR est cassé

En changeant de version vers la nouvelle à cause d’un BUG, il est possible d’en trouver d’autres… C’est le cas dans PHP 5.2.10 où le package PEAR n’est pas bien installé. Les “channels” ne sont pas bien configurés… En effet, lors de la compilation, on a déjà des erreurs comme celles-ci:

Warning: Cannot use a scalar value as an array in phar://install-pear-nozlib.phar/PEAR/ChannelFile.php on line 139

C’est donc bien que le phar des channels n’est pas correct. Après l’installation, lorsque l’on essaye d’installer le packet Net_IPv6 par exemple, on a ce message:

pear.php.net is using a unsupported protocal – This should never happen.
install failed

Continue reading

[notice] child pid XXXXX exit signal Segmentation fault (11)

L’erreur de Segmentation fault arrive – parfois – sans prévenir, elle est le témoin d’un bug ou d’une erreur dans le script PHP. La double assignation de variables peut faire ça ($var1 = $var2 = 'oups';) mais c’est souvent une erreur non-humaine… Elle est visible du côté utilisateur car le processus lui même de la page contenant cette erreur est “killé”, ce qui en résulte une réponse vide du serveur Apache, ce qui fait que Firefox présente une jolie fenêtre “Ouverture fichier.php”.

Capture-Ouverture de tests.php

En effet, j’était avec Apache 2.2.9 et PHP 5.2.6-1+lenny3 (installé via apt-get) et il m’est arrivé quelque chose d’assez surprenant, c’est une erreur de segmentation lors de l’assignation à une variable quelconque du résultat PDOStatement d’une requête faite avec PDO::query. Une heure ou deux à chercher d’où pouvait venir le problème pour enfin arriver à la conclusion que c’est un bug de PHP.

Dans ce cas, une seule solution, la mise à jour. J’ai donc décider de mettre à jour Apache en compilant la nouvelle version moi-même, idem pour PHP, que j’ai compiler. Je suis passé à Apache 2.2.13 avec PHP 5.2.10 pur. C’est parfait, ça marche ! :)

PHP: include_path, comment faciliter les inclusions

Dans PHP, il est très fréquent de devoir faire des inclusions de librairies, functions, classes en incluant des fichiers. Le seul “problème” c’est que ces fichiers à inclure ne sont pas toujours dans le même répertoire que le fichier incluant. On peut donc utiliser des chemins relatifs comme ../../dossier/fichier.php. Seulement, si notre fichier incluant changes… il faudras changer tous les chemins des inclusions !

On peux donc utiliser les chemins absolus comme /home/projet/lib/fichier.php. C’est parfait, on peut changer de place le fichier incluant et ça marche toujours ! Seulement, si le dossier contenant les librairies changes, il faudras à nouveau tout modifier.

Dans ce cas, pourquoi le pas créer une constante PATH_LIB par exemple, qui contient le chemin du dossier contenant toutes les librairies ? Si le dossier changes, on changes juste la constante. Certes, c’est une solution pratique.

Néanmoins, il y a encore plus simple ! Continue reading

SoapFault exception: [HTTP] Error Fetching http headers

Lors d’une utilisation longue de SOAP (des miliers de commandes ou des commandes très longues côté serveur), il arrive souvent que SOAP Client retourne une exception comme celle-ci:

Fatal error:  Uncaught SoapFault exception: [HTTP] Error Fetching http headers in /path/to/php/file.php:100
Stack trace:
[...]

Continue reading

Performances PHP: Serialize ou Implode – Unserialize ou Explode

Pour le stockage de tableaux “simple”, c’est-à-dire sur un niveau, sans clés particuliéres, la question est souvent celle de quelle méthode vais-je utiliser pour transformer ce tableau en chaine de caractère et inversement. Deux solutions viennent tout de suite à l’esprit, serialize/unserialize et implode/explode. Voici un petit benchmark que j’ai réaliser, avec un million d’itération de chaque commande, sur un tableau très simple de dix éléments, 5 chaines de caractères (entre 6 et 1 caractère) et 5 entiers inférieurs à 10 :
Continue reading

PHP: mb_substr à la place de substr pour l’UTF-8

Si vous utilisez un hébergement mutualisé pour quelconque site ou service, lors du développement, tout doit être encodé de la même manière. Comme je le conseil dans l’article concernant les problèmes d’encodage, utiliser UTF-8 avec PHP n’est pas toujours facile, surtout quand c’est PHP lui-même qui vous transforme vos chaines de caractère UTF-8 en ISO-8859-1 (si c’est l’encodage de caractère utilisé sur le serveur…).

C’est en effet le cas de la fonction substr qui converti les chaines de caractères. Comprendre d’où vient l’erreur d’encodage sans penser que ça pourrait être PHP lui-même, c’est dur… Donc, pour spécifier l’encodage à utiliser pour substr, il faut utiliser la fonction mb_substr et lui ajouter un argument comme ceci:

$new_string = mb_substr($string, $start, $end, 'UTF-8');

Que cet article aide de nombreuses personnes à ne pas chercher pendant des heures un problème qui n’est pas réellement de le ressort…