Woodymood / Conseil, étude, développement, formation Web logo

Blog développement

5 février 09 - attention à in_array avec les types mixés

Regardez les deux codes suivants, la présence du 0 va "perturber" le comportement de in_array si on ne met pas le flag stric. Plus d'info sur ce bug sur http://bugs.php.net/bug.php?id=45526

$val = 'foo';
$arr = array('bar', 0);
if ( in_array($val, $arr) ) echo 'yes';
else echo 'no';
// va afficher yes

$val = 'foo';
$arr = array('bar', 0);
if ( in_array($val, $arr, true) ) echo 'yes';
else echo 'no';
// va afficher no

27 octobre 08 - calculer la différence entre deux dates exprimée en nombre de mois.

J'ai eu besoin il y quelques temps d'obtenir le nombre de mois qui séparent deux dates. Après avoir essayé quelques magouilles du genre
$monthshift = floor( ($time - $now) / (30.5*24*3600)); qui ne marchent pas à tous les coups (à tous les mois), je m'attaquais à écrire cette fonction qui ne fut pas si compliquée que ça:

/*

retourne la différence de mois entre time1 et time2

$time1 et $time2 sont les temps unix des deux dates à comparer.

*/

function mois_diff($time1, $time2) {



$mois1 = intval(date('m', $time1));
$annee1 = intval(date('Y', $time1));

$mois2 = intval(date('m', $time2));
$annee2 = intval(date('Y', $time2));

if ( $annee1 == $annee2 ) {

return $mois1 - $mois2;
}

else if ( $annee1 > $annee2 ) {

// la différence est positive

// nombre de mois restant dans l'année 2
$mois_annee2 = 12 - $mois2;

// nombre de mois pendant les années de différences
$mois_entre = ($annee1 - $annee2 - 1) * 12;

// total
return $mois_annee2 + $mois_entre + $mois1;


}
else {

// la différence est négative

// nombre de mois restant dans l'année 1
$mois_annee1 = 12 - $mois1;

// nombre de mois pendant les années de différences
$mois_entre = ($annee2 - $annee1 - 1) * 12;

// total
return -1 * ($mois_annee1 + $mois_entre + $mois2);


}

}

29 novembre 07 - Mots réservés en Mysql 5 !

On en apprend tous les jours avec ces migrations php5 / mysql5. Dernièrement les requêtes SQl plantaient apparemment sans raison. C'était du au nom d'un champ (le mot condition) qui était devenu sous mysql 5 un nom reservé. Il faudrait toujours échapper les noms de champs avec des ` de cette forme:

INSERT INTO

table

(`condition`)

VALUES

('bla bla bla')

09 octobre 07 - Migrer spip de 1.7 ou 1.8 à >= 1.9

De nombreux changements sont apparus dans spip depuis la génération 1.9. Le but de cette liste est de donner des pistes sur les modifications à faire dans nos squelettes, une fois bien sûr que la 1.9 est installée et fonctionnelle. A lire en premier : http://www.spip.net/fr_article3370.html

- mettre tous ses fichiers propres dans un sous dossier /squelettes
- mettre à jour la syntaxe des INCLURE sous la forme {fond=}
- revoir éventuellement les include() php suite au déplacement dans le sous dossier /squelettes
- renommer les autres fichiers php3 en php, comme mes_fonctions
- virer tous les fichiers .php3 qui servaient anciennement à fixer le delais et les remplacer par la balise #CACHE{} dans les fichiers .html
- les liens vers un squelette article se font comme spip.php?article120 ou spip.php?page=article&id_article=120
- remplacer tous les liens en dur vers des article.php3 ou rubrique.php3 par des spip.php
- voir eventuellement si des fichiers du noyau de spip avait été modifiés et refaire ces modifications en surcharge de code dans /squelettes/
- dans les formulaires les appels se font plutot comme ça :
<form action="spip.php" method="get">
<input type="hidden" name="page" value="article">
<input type="hidden" name="id_article" value="47">
- utiliser la balise #CHEMIN pour les images et les fichiers css
- eventuellement remplacer les <?= par des <?php echo si le serveur php passe en 5.

25 septembre 07 - Debuguer ses scripts php

Le but est d'être informé quand le script plante, sans que le site affiche une insulte. On peut fabriquer une message d'erreur et le tracer dans un fichier de log, et/ou s'envoyer un mail avec le message d'erreur ou un lien vers le fichier d'erreurs. Maintenant, on a besoin que le message d'erreur soit le plus explicite possible pour corriger le bug. Il existe quelques fonctions de ce genre dans php, qui, combinée à print_r($t, true) nous explicite le message en nous informant sur les variables d'environnements et la pile d'appels des fonctions. Exemple :

$message_erreur =

mysql_error() . "\n\n" .

print_r(get_defined_vars(), true) . "\n\n" .

print_r(debug_backtrace(), true);

20 mars 07 - Un menu spip arborescent avec que des articles

Nous avons mis en place cette technique pour notre dernier site en spip pour Jean-Marie Wenger. Les avantages de mettre tous les contenus des pages du site dans des articles exclusivement, et pas dans des rubriques, sont :

  • plus de confort pour le client qui doit mettre à jour son site (le formulaire des articles comporte plus de champs ainsi que les très utiles boutons typographiques)
  • offrir une traduction vraiment de page à page pour toutes les pages du site (les rubriques n'ayant pas de lien de traduction)

L'astuce consiste à garder une structure arborescente dans spip avec des rubriques et des articles, et de rajouter dans chaque rubrique un article supplémentaire qui s'appelle strictement comme sa rubrique mère. Voici la boucle pour un menu à deux niveaux, en admettant que les contenus de votre menu se trouvent dans la rubrique 1 :

<table>

<BOUCLE_menu(RUBRIQUES){id_parent=1}{par num titre}{tout}>

<BOUCLE_premierarticle(ARTICLES){id_rubrique}{titre = #_menu:TITRE}{0,1}>
<tr>
<th><a href="#URL_ARTICLE">[(#TITRE|supprimer_numero)]</a></th>
</tr>
</BOUCLE_premierarticle>

<BOUCLE_sous_articles(ARTICLES){id_rubrique}{titre != #_menu:TITRE}{par num titre}>
<tr>
<td><a href="#URL_ARTICLE">[(#TITRE|supprimer_numero)]</a></td>
</tr>
</BOUCLE_sous_articles>

</BOUCLE_menu>

</table>

13 mars 07 - Ajouter la contrainte Foreign Key dans Mysql

Le moteur de stockage InnoDB permet donc de gérer la contrainte d'integrité Foreign Key, ou clé etrangère. Malheureusement on ne trouve pas encore d'outil WYSIWYG dans phpmyadmin pour réaliser cela. Il faut donc écrire à la main la requête SQL alter table adequate. Voici un exemple où un film possède un genre et un genre peut s'accocier à plusieurs films. film.id_genre est la clé etrangère de genre.id. Notez que c'est conseillé de mettre un nom à la contrainte (ici ref_id_genre) pour pouvoir eventuellement la supprimer par la suite. Pour approfondir le sujet.

ALTER TABLE film ADD CONSTRAINT ref_id_genre FOREIGN KEY ( id_genre ) REFERENCES genre ( id )

7 mars 07 - Redirection php en fonction du domaine demandé

Il arrive parfois qu'on ait plusieurs noms de domaines synonymes pour un seul site hebergé. ET en plus, on pourrait avoir envie de rediriger l'internaute sur telle ou telle page en fonction du domaine qu'il a demandé.

L'information du nom de domaine peut être récupérée via le tableau $_SERVER, par exemple dans la clé HTTP_HOST. Méfiance quand même, ce champ peut être vide ou être écrit sans les 'www', donc prévoir un cas par défaut et ne pas faire une comparaison stricte de deux chaînes.

Voici un exemple à placer dans votre index.php avec la fonction strpos(), remarquez le !== false pour ne pas se faire avoir par la valeur de retour 0.

<?php
if ( strpos($_SERVER['HTTP_HOST'], 'domaine1.ch') !== false ) {
     header("Location:index1.php");
}
else if ( strpos($_SERVER['HTTP_HOST'], 'domaine2.ch') !== false ) {
     header("Location:index2.php");
}
else {
     header("Location:index_defaut.php");
}
?>