Archives de catégorie : PHP

Le PHP (PHP: Hypertext Preprocessor) est un langage de scripts libre principalement utilisé pour produire des pages Web dynamiques via un serveur HTTP, mais pouvant également fonctionner comme n’importe quel langage interprété de façon locale, en exécutant les programmes en ligne de commande. PHP est un langage impératif disposant depuis la version 5 de fonctionnalités de modèle objet complètes. En raison de la richesse de sa bibliothèque, on désigne parfois PHP comme une plate-forme plus qu’un simple langage.
Le PHP est un langage que j’utilise assez souvent et il m’arrive donc de découvrir de nouvelles choses à son sujet. Du coup, rien de tel pour se fixer les idées que d’essayer de résumer ça dans un billet.

Singleton(s) !

Publié dans PHP objet | Commentaires fermés sur Singleton(s) !

Voilà bien longtemps que je n’avais pas fait de billets sur le PHP Objet. A vrai dire, je suis en train d’apprendre la programmation orientée objet en cours (au travers du Java et du C++), donc ça fixe vraiment les idées et permet de comprendre pas mal de petites choses, notamment l’utilité de certaines notions, comme les singletons, qui me paraissait bien douteuse auparavant. Un singleton, c’est une classe que l’on ne peut instancier qu’une seule fois. Par exemple, en cours on a créé une classe liste dont hérite la classe liste vide, et la classe listeNonVide. Clairement, il n’existe qu’une et une seule liste vide (sinon, on ne s’en sort pas), donc cette classe ne peut être instanciée qu’une seule fois, donc c’est un singleton. Je n’ai pas encore trouvé d’exemples plus parlant, par contre sur Apprendre-PHP, l’exemple est celui d’une classe PresidentDeLaRepublique qui, en effet, ne peut être instanciée qu’une seule fois)

Comment faire ?

L’idée est la suivante : le constructeur de la classe est private, on ne peut donc instancier la classe en passant directement par lui. Par contre, une variable static possède un accessor (getMachin()) qui est public et qui appelle le constructeur si la classe n’est pas encore instanciée (variable static == null), ou retourne l’instance sinon. En somme, voilà ce que ça donne :
Continuer la lecture

Taille d’une image avec getimagesize

Publié dans PHP | Laisser un commentaire

Ouhahou, ça faisait longtemps ! Il faut dire que je suis parti en vacances tout une semaine, que c’est un peu le rush au boulot ces derniers temps, et accessoirement que j’ai de moins en moins Internet chez moi. Bref, j’ai reussi cahin caha à apprendre de nouvelles choses pendant au moins 30 minutes chaque jour, mais pour mettre ces découvertes à l’écrit, il m’aurait fallu un peu plus de temps. Hier, je cherchais à connaitre les dimensions (largeur et hauteur) d’une image. J’ai d’abord pensé à imagesx() et imagesy() que j’avais déjà utilisé et qui renvoie respectivement la largeur et la hauteur de l’image dont le descripteur est passé en argument. C’est justement là le problème, puisque pour ce servir de ces fonctions il faut d’abord utiliser imagecreatefromjpeg('nom du fichier image') ce qui n’est quand même pas très pratique. Surtout quand on tombe sur getimagesize(‘nom du fichier image’) ! Cette fonction retourne non seulement la largeur et la hauteur de l’image étudiée, mais aussi son format (notamment au format mime), son type de coloration (RGB ou CMYK) ! C’est plutôt beau, non ? Voyons un petit exemple :

<?php
echo '<pre>';
print_r(getimagesize('test.gif'));
echo '</pre>';

Ce qui retourne :

Array (
    [0] => 45
    [1] => 45
    [2] => 1
    [3] => width="45" height="45"
    [bits] => 7
    [channels] => 3
    [mime] => image/gif ) 

Voilà ce qui peut être utile :

  • Le champ 0 retourne la largeur en pixel. On retrouve cette largeur dans le champ 3 dans une chaine de caractères directement utilisable dans du code HTML
  • Le champ 1 retourne la hauteur en pixel. On retrouve cette hauteur dans le champ 3 dans une chaine de caractères directement utilisable dans du code HTML
  • Le champ 2 et mime retournent le format de l’image. Le champ 2 par son numéro, le champ mime au format mime utilisable directement dans les entêtes HTTP.

C’est quelque chose que je cherchais depuis quelque temps, le problème c’est que j’ai oublié dans quel projet j’en avais besoin…
Au passage, 2 autres informations dont je pense ne jamais me servir :

  • Le champ bits retourne le nombre de bits par couleur. ça peut boguer avec le format Gif. J’ai pas trop compris ce que cela voulait signifier
  • Le champ channels retourne le type de coloration (3 pour RGB, 4 pour CMYK)

Forcer le téléchargement d’un fichier

Publié dans PHP | Laisser un commentaire

Lorsque j’ai conçu la Bnbox v.3 j’aurais bien aimé savoir ce que j’ai découvert il y a peu. Comment forcer le téléchargement d’un fichier sur un site Web ? Par exemple un fichier PDF (so beautiful!) ou un fichier mp3 sont en général directement lus par les navigateurs récents. Mais il peut être pratique, parfois, d’éviter au visiteur la manipulation Clic droit > Enregistrer la cible du lien sous….

<?php
/**
 * Force le téléchargement d'un fichier
 * 
 * @param string $filePath Emplacement du fichier sur le serveur web
 * @param string $fileNameToDl=<em> Nom du fichier que l'utilisateur va télécharger (si on souhaite le rendre différent de celui d'origine)
 * @post Ouvre une fenêtre permettant le téléchargement du fichier
 * /
function forcerTelechargement($filePath, $fileNameToDl=</em>)
{
    header('Content-Description: Téléchargement le fichier '.$fileName);
    header('Content-Type: application/octet-stream'); // On peut mettre text/gif, etc...
    header('Content-Length: '.filesize($path.'/'.$fileName));
    header('Content-disposition: attachment; filename='.($fileNameToDl != NULL ? $fileNameToDl : basename($filePath))); // Nom du fichier téléchargé par l'utilisateur. On peut donc mettre ce qu'on veut.
    header('Pragma: no-cache');
    header('Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0');
    header("Expires: Sat, 26 Jul 1997 05:00:00 GMT"); // Date dans le passé pour ne vraiment pas avoir de cache
    readfile($filePath); // Ouvre le fichier dans le buffer : d'après le geader, ce sera une fenêtre de téléchargement
    exit();
}

forcerTelechargement('./document/exemple.pdf');

Continuer la lecture

Lire un fichier CSV (Excel) avec PHP

Publié dans PHP | Un commentaire

Je viens de découvrir 2 petites fonctions PHP bien utiles pour s’occuper d’un fichier Excel. (ou équivalent) Si vous avez déjà essayé de traiter un fichier Excel avec PHP, vous savez sûrement qu’il faut préalablement enregistrer ce fichier au format CSV (Comma-Separated Values), vos colonnes sont alors séparées par des points virgules ( ; ) et vos lignes par un retour à la ligne. Donc un fichier CSV ressemble à ceci :
case1;case2;"case 3 avec des espaces";case4
case5;case6;"case 7 avec des espaces";case8

A partir de la, au premier abord, on s’apprête à utiliser des regex (preg_match_all par exemple) pour lire le fichier, mais ce serait perdre un peu de temps pour pas grand chose. En effet, il existe 2 fonctions pour lire et écrire un fichier CSV en PHP : fgetcsv et fputcsv.
Continuer la lecture

Tout ce qu’il faut savoir pour crawler tranquilement

Publié dans PHP | Laisser un commentaire

Ah, avant toute chose qu’est-ce que j’entends par le mot « crawler » ? On pourrait appeler ça « scrapper », « looter », voir même « pirater ». En fait l’idée est de créer un petit programme dont le but va être de récupérer des informations sur un site Web qui se trouve en ligne (ou pas). Exactement comme fait le GoogleBot ou les autres robots de moteurs de recherche. Et comme font aussi les robots qui cherchent des adresses e-mails pour faire du spam… Bref, on voit qu’il peut y avoir un petit problème éthique derrière le scrolling, mais c’est une discipline qui peut être tout à fait noble et utile autant pour le crawleur que pour le crawlé. Mais je ne vais pas faire de débat philosophique, plutôt parler technique.
Durant le stage que j’effectue actuellement, j’ai pas mal l’occasion de crawler des sites Web, voici donc un résumé de fonctions ou de techniques qui peuvent être utiles.

Le crawling en résumé

L’idée principale est de faire automatiquement rapidement ce que l’on aurait dû faire à la main en mettant beaucoup de temps. Pour cela, on fait une petite étude des urls du site que l’on souhaite crawler. Par exemple, si c’est une liste d’article, les pages de chaque article auront peut-être un url avec quelque chose du genre : article.php?id=1452112. A partir de la :

 $url = 'article.php?id={id}'; for($i=1; $i<=$nbArticle; $i++) {
	$urlAScroller = str_replace('{id}', $i, $url);
	$content = file_get_contents($urlAScroller);
	// Regex et explode sur $content pour récupérer les informations souhaitées }

Continuer la lecture

Une fonction regex bien utile : preg_match_all

Publié dans PHP | 2 commentaires

J’avais utilisé cette fonction il y quelques temps et je n’arrivais à mettre la main dessus. preg_match_all() est très pratique lorsque l’on souhaite récupèrer plusieurs données d’un seul coup. Que fait-elle en gros ? On lui fournit un pattern (comme pour une regex classique, c’est le patron de ce que l’on cherche), une chaine de caractères dans laquelle effectuer la recherche, un array dans lequel on mettra les données et des options si besoin.

  • Dans la case 0 de l’array de retour, on aura un array avec toutes les chaines de caractères correspondant au pattern. (ce qui correspond au $0)
  • Dans la case 1 de l’array de retour, on aura un array avec tous les $1 de chaque chaines de caractères correspondant au pattern.
  • Dans la case 2, de l’array de retour, on aura un array avec tous les $2, … et ainsi de suite.

Exemple

Dans ma variable $content, j’ai le contenu suivant :

Nom : Duck, Prénom : Donald;
Nom : Mouse, Prénom : Mickey;
Nom : Duck, Prénom : Daisy;

Pour récupèrer les noms et prénoms de chacun des personnages, je peux donc utiliser la regex suivante :

preg_match_all('!Nom : ([^,]+), Prénom : ([^,]+);\n!isU', $content, $out, PREG_PATTERN_ORDER);

Affichons l’array de retour à l’arrache pour voir le résultat :

echo '<pre>'; print_r($out); echo '<pre><br />';

On voit bien que l’on un array avec des sous array content $0, $1, etc. On peut donc afficher noms et prénoms (ou les enregistrer dans une base de données si l’on préfère) de la manière suivante :

$nb = count($out[0]); for($i=0; $i<$nb; $i++) { 
	echo 'Patron : '.$out[0][$i].'<br />'; 
	echo $out[1][$i].' '; 
	echo $out[2][$i].'<br />';
}

Tout ceci nous évite d’utiliser plein de preg_replace() couplés avec un petit explode(). Quand c’est possible, c’est tout de même bien plus simple avec preg_match_all(). Bon, comme ça, je suis sûr de ne plus oublier cette petite fonction bien pratique.

Classes abstraites et finales

Publié dans PHP objet | 2 commentaires

Les notions de classes abstraites et classes finales permettent de sécuriser notre programmation PHP, dans le sens qu’elles permettent d’éviter qu’un programmeur, reprenant notre code, n’en contourne la logique et s’égare ainsi sur une fausse piste.
En effet :

  • Class abstraite : class qui ne peut être instanciée, il est donc OBLIGATOIRE de créer une class héritante de cette class pour s’en servir. Utile lorsque l’on créé une class générique qui ne servira qu’à créer des sous class et non à être instanciée. Une telle class ne contient donc pas de __construct() puisqu’elle n’est pas instanciée. Mot clef : abstract.
  • Class finale : class qui NE PEUT PLUS avoir de sous-class, c’est-à-dire de class héritante. Les méthodes de cette class ne pourront être surchargées (réécrites, redéfinies). Mot clef : final. De la même manière, on peut aussi déclarer des méthodes abstraites et finales.
  • Méthode abstraite : méthode qui doit OBLIGATOIREMENT être surchargée (réécrite, ou redéfinie). Une class contenant une méthode abstraite doit aussi être abstraite. Mot clef : abstract.
  • Méthode finale : méthode qui NE PEUT ÊTRE surchargée (réécrite, redéfinie). Une class finale s’applique sur toutes les méthodes ou attributs de la classe, alors qu’ici on ne touche qu’à une seule méthode. Mot clef : final. Pour bien comprendre ces 2 notions et en saisir mieux l’intérêt voici plusieurs exemples, un pour chaque cas.

Class et méthodes abstraites

 abstract class Site {
	protected $type;
	protected $name;
	public function getType()
	{
		return $this->type;
	}
	public function getName()
	{
		return $this->name;
	}
}
$monSite = new Site();
echo $monSite->getType(); // Erreur : on tente d'instancier une classe abstraite

Continuer la lecture

Générer un array de plus de 2 400 000 éléments

Publié dans PHP | Un commentaire

Peut-être avez-vous déjà essayé de créer un array très très grand. Moi oui. Mon problème c’est que les valeurs que contenaient mon array étaient aussi très grande. En fait j’ai essayé de générer un array contenant 2 600 000 éléments allant de 1 à 2 600 000.

Naïvement avec une boucle for

 $a_cle = array();
for($i=1;$i<=2600000;$i++) {
   $a_cle[] = $i;
}

Mais là… erreur : Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 16 bytes) in /var/agence.php on line 52

Un peu plus malin avec range()

$a_cle = range(1, 2600000);

Mais là… erreur : Fatal error: Allowed memory size of 268435456 bytes exhausted (tried to allocate 16 bytes) in /var/agence.php on line 52

Futé avec array_flip

En fait, je me suis aperçu que ce dont j’avais besoin c’était des numéros que je pouvais prendre au hasard (mais jamais les mêmes) allant de 1 à 2600000, mais pas forcément d’un array avec les clés allant de 1 à 2600000 et les valeurs allant de 1 à 260000. Donc j’ai créé avec array avec des clés allant de 1 à 2600000 et des valeurs toutes à 1.

$a_cle = array_flip($a_cle);
$cle = array_rand($a_cle);
echo $cle; unset($a_cle[$cle]);

Vous me direz que j’aurai pu modifier le php.ini pour augmenter l’espace mémoire utilisable par PHP, mais :

  • je n’y avais pas accès
  • je ne savais comment faire à l’époque :p

Du BBcode en PHP sans regex

Publié dans PHP | Laisser un commentaire

Alors parait-il que l’on pourrait faire du BBcode en PHP sans utiliser du tout de regex, et ce grâce à une l’extension PECL nommée BBcode et qui ferait partie (en théorie) du module PHP standart depuis PHP 5.2.0. Bon en pratique j’ai PHP 5.2.8 (en local avec Easy PHP, eh oui j’suis sous Windows en ce moment) et je n’ai pas du tout cette extension. Et puis sur le site de téléchargement du package il n’y a que des packages pour Linux (et pour des raisons diverses et variées je n’ai pas accès à Linux pour l’instant. Misère…).
Bref, je suis un peu déçu, j’aurai bien aimé tester. Mais le manuel nous dit tout ce qu’il faut faire : Extension PHP BBcode. Y parait que c’est beaucoup plus rapide que de coder son BBcode avec des regex, et en plus ça à l’air très simple à mettre en place. Bon par contre, je suppose qu’on ne peut pas configurer tout comme on le souhaite, mais passons pour l’instant. En théorie :

  • On créé une structure de BBcode avec bbcode_create() et on peut ensuite ajouter des balises avec bbcode_add_element() si on en a oublié, ou même des smilies avec bbcode_add_smiey().
  • Reste à utiliser bbcode_parse() pour parser une chaine de caractère en transformant par exemple [b]test[/b] par test, et donc pour mettre le mot « test » en gras.
  • Puis bbcode_destroy() pour libérer proprement notre structure de BBcode.

Voilà pour la théorie ! Dès que j’ai réussi à tester la bête, j’essaierai de voir ce que ça peut donner en pratique !

Quelques méthodes et constantes magiques ou prédéfinies

Publié dans PHP objet | Laisser un commentaire

Attributs ou méthodes qui n’existent pas ?

Avant de faire un petit récapitulatif magique ou déjà défini (mouahaha), voyons une petite notion importante du PHP objet : il est possible de modifier et de lire la valeur d’un attribut qui n’existe pas (ah horreur), par contre, on ne peut utiliser une méthode qui n’existe pas (ah bah ça tombe bien alors !). Je m’explique en codant :

class Chat { }
$unChat = new Chat();
$unChat->couleur = 'noir';
$unChat->etat = 'sorti ses griffes';
echo 'Mon chat '.$unChat->couleur.' a '.$unChat->etat.'.';

Eh oui, ce petit exemple affichera bien : « Mon chat noir a sorti ses griffes . ». C’est horrible, n’est-ce-pas ? Heureusement avec __set() et __get(), on va pouvoir empêcher ce types d’actions et en profiter pour vérifier le type des valeurs que l’on assigne à nos attributs.
Par contre :

class Chat { } 
$unChat = new Chat();
$unChat->etreGentils();

Nous renverra une jolie petite erreur ! (heu, oui, je n’aime pas tellement les chats. Enfin, cela dit, je n’ai rien contre eux non plus) Heureusement la méthode magique __call() va nous permettre de rattraper ce petit bémol. Mais tout cela est très bien expliqué sur Apprendre PHP, alors sans plus tarder voilà une liste des méthodes et des constantes magiques, ainsi que des fonctions prédéfinies avec à chaque fois une explique, ou des exemples tiré du manuel PHP, de tutoriels sur le Web ou de mes propres mot.
Continuer la lecture