PHP le mal-aimé

J’ai suivi une conf de Frédéric Bouchery au BreizhCamp la semaine dernière dont l’intitulé était « Pourquoi PHP ?« . Frédéric Bouchery n’est pas le dernier des manchots, puisqu’il est quand même lead dev chez CCM-Benchmark. Il était là pour défendre le langage PHP, qui s’en prend un peu plein la gueule dans le monde de l’informatique : largement critiqué, il est perçu comme un pseudo-langage fait pour les débutants ; les grandes personnes, elles, codent dans les vrais langages comme Java ou Ruby.

Les principales critiques portent sur deux points.

Le langage lui-même

Les fonctions en elles-mêmes manquent parfois de cohérence dans leur nommage (str_replace vs strpos), semblent plutôt useless (nl2br) ou sont très permissives (implode qui prend ses arguments dans les deux sens).

En outre pendant longtemps quelques mauvaises pratiques étaient possibles avec PHP, par exemple les super globales, qui permettaient des failles de sécurité grosses comme l’étoile de la mort (et si les super globales sont désormais derrière nous, il y en a d’autres).

Sa facilité d’utilisation

Sa force, sa prise en main très facile, est aussi son point faible. PHP est très simple à utiliser, donc les débutants l’utilisent beaucoup et font de la merde en barre avec. On trouve BEAUCOUP de petits scripts sur internet, des bouts de code « pour aider », qui sont juste horribles, pas optimisés, pas sécurisés, etc. Forcément, ça donne pas envie.

Mais comme je le disais à mes étudiants, si PHP permet de coder n’importe comment, on n’est pas obligé de coder n’importe comment, et en plus des standards de nommage, de code, etc, il existe plusieurs sites qui reprennent les bonnes pratiques, dont ces deux-là :
http://www.phptherightway.com/
http://www.php-fig.org/
Je ne les connaissais pas, je pense que je vais me plonger dedans avec plaisir.

J’étais heureuse d’entendre ses arguments, qui rejoignent et complètent les miens. En plus d’être fière d’être développeuse, je suis désormais fière d’être développeuse PHP 😉

Merci à Thomas Gratier et à Frédéric Bouchery pour les liens.

 

page blanche sur une erreur php

Je viens d’expérimenter un problème vraiment désagréable : les erreurs PHP ne s’affichaient plus.

Mon environnement : LAMP avec PHP5.3, error_reporting = E_ALL | E_STRICT, display_error = On, bref tout bon comme il faut, mais rien, page blanche sur les erreurs.

J’ai suivi les différentes solutions proposées, j’ai ajouté un .htaccess, un ini_set, j’ai redémarré Apache, puis le PC, rien à faire. Et puis j’ai trouvé : j’avais ajouté un error_reporting(7) dans mon code, suite à une page blanche du même acabit. Je l’ai enlevé et TADAAA ! mon code a recommencé à m’insulter.

Fatal error: Call to undefined method

Voilà, si ça peut servir à quelqu’un…

 

Renvoyer une image avec php sous code igniter

Si, pour une raison ou pour une autre, vous ne souhaitez pas que les medias sur votre site soient récupérables, vous pouvez les renvoyer avec PHP et la fonction readfile.

Un bon tutoriel est disponible à cette adresse :
http://www.editeurjavascript.com/trucs/14,afficher_une_image_avec_du_php.php

Le double avantage de cette méthode est que l’image n’est pas enregistrable facilement (une capture d’écran est toujours possible, bien sûr), et que le visiteur ne peut pas savoir dans quel répertoire vous l’avez stockée.
Une autre raison pour laquelle vous voudriez utiliser cette méthode, pourrait être de vérifier l’identité de votre visiteur avant d’afficher l’image. J’y reviendrai plus bas.

J’ai voulu intégrer cette fonctionnalité sous Code Igniter, certains aménagements sont nécessaires pour arriver au même résultat.

Je pars du principe que $_GET est désactivé, ce qui est le schéma par défaut (et recommandé) sur CI. Mes medias sont enregistrés en base, j’ai donc un ID pour chacun. C’est avec cet ID que je vais les manipuler : je vais passer en paramètre l’ID du media à afficher.

Si vos medias ne sont pas enregistrés en base, vous devrez alors passer le nom de l’image en paramètre, sans les dossiers. En effet, si vous passez un dossier, vous aurez une url du genre
controller/methode/mon_dossier/monimage.gif, ce qui vous oblige à récupérer votre dossier d’un côté, le nom de l’image de l’autre.
Cette méthode vous fait perdre l’intérêt premier de la manoeuvre, à savoir cacher le dossier et le nom de l’image.

Méthode

Mon contrôleur (ou controller) s’appelle Files et ma méthode, returnFiles.

Dans votre vue, pour afficher le media, indiquez le code suivant (où 45 est l’id de l’image à afficher) :

<img src="<?php echo site_url('files/returnFile/45); ?>" alt="votre image" />

Passons à la création du contrôleur :

class Files extends Controller {
/**
* constructeur
*
*/
function __contruct() {
parent::Controller();
}
/**
* la méthode qui va retourner le media
*
* @param int $image_id, l'ID de votre image
*
*/
function returnFile ($image_id) {
// on va cherche les infos sur l'image
// utilisez ici un model à vous pour récupérer l'url complète
// dans mon exemple, je vais récupérer quelque chose comme :
// http://www.mondomaine.com/images/image45.png
$path_to_file = Mon_model::getUrl($image_id);
// on cherche le type mime du fichier
// on charge le helper qui va nous permettre de faire ça rapidement
$this->load->helper('file');
// puis on cherche le type mime avec la fonction get_mime_by_extension, chargée avec le helper ci-dessus
$mime = get_mime_by_extension($path_to_file);
// il n'y a plus qu'à renvoyer le fichier
// on définit le content-type
header("Content-type:" . $mime);
// puis on renvoie le fichier
readfile($path_to_file);
}
}

Pour plus d’info sur le chemin du fichier (chemin absolu ou URL), je vous renvoie vers la doc de readfile sur php.net :
http://fr2.php.net/manual/fr/function.readfile.php

Vérifier l’identité de la personne qui veut afficher le media

Je le disais plus haut, on pourrait vouloir vérifier l’identité du visiteur avant d’afficher l’image.
On ajoute alors un bout de code au début de la méthode returnFiles. Vous pouvez également utiliser un pré-contrôleur.

Dans l’exemple suivant, on va simplement vérifier que l’utilisateur est connecté avec une variable de session.

/**
* la méthode qui va retourner le media
*
* @param int $image_id, l'ID de votre image
*
*/
function returnFile ($image_id) {
// vérifie que le visiteur est connecté
$is_connected = $this->session->userdata('is_connected');
if($is_connected != TRUE) {
exit;
}
// suite du script...

Dans cet exemple, on récupère une variable de session qui est initialisée à TRUE lorsque le visiteur se connecte. Si cette variable n’existe pas, ou si elle n’est pas égale à TRUE, on sort du script avec exit. On peut également renvoyer un message d’erreur, rediriger vers une page de connexion…

Compléments

Bon à savoir, cette méthode fonctionne avec les images (testée avec les gif, jpg et png), les sons (mp3) et les animations flash (swf).
J’ai eu quelques soucis pour la faire fonctionner avec les FLV. Le type mime n’était pas reconnu par mon serveur local (EasyPHP) et j’ai dû ajouter les types mimes correspondants dans le fichier httpd.conf.

AddType video/x-flv .flv
AddType video/flv .flv
AddType flv-application/octet-stream .flv

Pour autant que je sache, on peut faire la même chose avec un .htaccess.