Zend Framework : Attention aux erreurs

Me revoilà, je fais pas mal de veille en ce moment pour le développement de la nouvelle version de Wanarun.

J’ai décidé de me baser sur le Zend Framework et j’ai créé une sur-couche pour placer mes objets.

J’ai donc crée un Load pour Wanarun :

class Wanarun_Loader extends Zend_Loader
{
}

que je charge en début de page :

set_include_path(dirname(__FILE__).'/../framework/wanarun/library/'.PATH_SEPARATOR.get_include_path());
require_once "Wanarun/Loader.php";
Wanarun_Loader::registerAutoload();

Je travaillais sur la version 1.7.4 jusqu’a récemment ou je me suis retrouvé complétement bloqué sur un bug assez bizarre : plus aucune erreur, uniquement une page blanche…

Il se trouve que dans le Loader Zend sur la version 1.7.4 on avait droit à (ligne 82-83) :

...
self::_securityCheck($file);
@include_once $file;
...

Donc bien sur, aucun probleme d’erreur dans le Zend Framework (le @ ne pose pas de problème) mais comme j’héritais du Zend Loader et que j’avais fait une erreur… je ne la voyais pas…

Deux solutions :

  • Upgrader au Zend Framework 1.7.5 qui n’a pas de @
  • Supprimer le @

Encore une fois du temps perdu à cause de ce satané @…personnelement je serais pour le retirer dans la version 6…

Astuces rewrite….

Avant je ne faisais pas attention au moteur de recherche et a l’optimisation des pages. Mais c’est vrai que ca permet quand même de récupérer pas mal d’utilisateurs parfois. Voila le cas des parcours sur Wanarun.

avant j’avais des urls du genre :

http://www.wanarun.net/index.php?content=/view/parcours.php&parcours=2251

et j’ai décidé d’activer le mode rewrite pour obtenir ca :

http://www.wanarun.net/carte/2251/le-long-du-canal-thaon-les-vosges.html

Je ne vous cache pas que Google adore ce genre d’URL

Voila le code que j’ai mis dans mon fichier .htaccess :

RewriteEngine On
RewriteRule ^carte/([0-9]+)/(.*).html$ index.php?content=/view/parcours.php&parcours=$1

Ensuite pour rediriger proprement les anciennes pages j’ai ajouté ce code dans ma page

if ($_SERVER["SCRIPT_NAME"]=="/index.php" && urlParcours($parc_d)!=$_SERVER["REDIRECT_URL"])
    {
      header('HTTP/1.1 301 Moved Permanently');
      header("location: ".urlParcours($parc_d));
      exit;
    }

ma fonction urlParcours renvoit l’url propre tout simplement.

mysql / mysqli / mysqlnd : les extensions PHP pour MySQL

Le couple PHP / MySQL est devenu inséparable depuis quelques années maintenant… Mais la vie de couple n’est pas toujours facile. Il existe 3 façons d’unir ce couple :

  • ext/mysql : l’extension mysql classique (old school) que nous avons tous utilisés
  • ext/mysqli : l’extension mysql « improved » (sous entendu amélioré) interface object / prepared statement et autres nouveautés

Mais voilà, le hic c’est les fameuses connexions persistentes, depuis toujours on a tous désactiver cette possibilité allant même jusqu’à oublier qu’elle existait.

Mais voila MySQL AB a décidé de prendre le taureau par les cornes et de développer une libriairie de remplacement pour résoudre ces problèmes. c’est chose faite avec mysqlnd (Mysql native driver). cette librairies remplace la librairie libmysql qui se trouve dans PHP et elle est écrit directement par les équipes de MySQL.

pour en savoir plus

A tester !

Modification javascript pour les tables

Comme plusieurs d’entre vous veulent connaitre les modifications que j’ai fait pour les tableaux javascript (suite des commentaires sur l’article « Economisez votre serveur : Triez en javascript »

Pour rappel, la page d’exemple se trouve ici : la page des entrainements de MARC78 sur Wanarun

Les modifications de la librairies sortable.js
Ajout d’une variable pour la taille des pages

var maxRows=20;

Ajout de la fonction showPageTable()

function showPageTable(table,number)
{
  for (j=1;j<table>{
    if (j=(maxRows*(number)+1))
    {
      table.rows[j].style.display='none';
    }
    else
    {
      table.rows[j].style.display='';
    }
  }
}

Modification de sortables_init()

//après la ligne
ts_makeSortable(thisTbl);
//j'initiliase mon tableau sur la premiere page
showPageTable(thisTbl,'1');

Dans le php

//il faut définir une variable commune avec le javascript
define("NB_LIGNE_TABLEAU",20);
 
$list=$data["performance"];
$page_str="";
$separator=" | ";
$nb_page=floor(sizeof($list)/NB_LIGNE_TABLEAU)+1;
if ($nb_page&gt;1)
{
        for($i=1;$i&lt;=$nb_page;$i++)
        {
                $page_str.="<a href="#">".$i."</a>";
                $page_str.=$separator;
        }
        echo substr($page_str,0,-strlen($separator));
}

Astuces pour les scripts Shell

Vous êtes peut être comme moi, vous utilisez PHP pour faire des scripts shell. J’utilise une petite astuce pour mettre en place des variables dans mes scripts en reprennant la syntaxe qu’on utilise sous linux avec « –var value »

un petit include que vous pouvez transformez en fonction comme bon vous semble.

for($i=1;$i&lt;sizeof($argv);$i++)
{
 if (substr($argv[$i],0,2)==&quot;--&quot;)
 {
 		$_REQUEST[substr($argv[$i],2)]=$argv[$i+1];
 		$i++;
 }
}
 
extract($_REQUEST);

Comme ca quand je lance « mon_script.php –code TE –mode debug »

c’est comme si je faisais :

$code="TE";
$mode="debug";

Ca n’interessera peut être pas tout le monde mais c’est bien pratique !

Créer une table temporaire

Parfois, il est préférable ou nécessaire de passer par une table temporaire pour insérer / mettre a jour des données.
Ca vous permet d’insérer les données et eventuellement de vérifier la table temporaire avant de permutter les 2 tables.
Par exemple, vérifier que votre table comporte au moins 10 éléments ou n’est pas vide.

//j'efface la table temporaire si elle existe :
$res=mysql_query("drop table if exists my_table_tmp");
if ($res==false) die("Erreur mysql ".mysql_error());
 
//je récupére la structure de la table maitre
$res=mysql_query("show create table my_table");
if ($res==false) die("Erreur mysql ".mysql_error());
$row=mysql_fetch_row($res);
$create=$row[1];
 
//je substitue le nom de ma table maitre pour créer ma table temporaire
$create=str_replace("my_table","my_table_tmp",$create);
//je crée ma table temporaire.
$res=mysql_query($create);
if (!$res) die("Erreur mysql ".mysql_error());

La requete utilisant RENAME TABLE est pratique pour ce cas :

RENAME TABLE my_table TO my_table_backup, my_table_tmp TO my_table;

en PHP ca donne :

//Je permutte les tables 
$res=mysql_query("RENAME TABLE my_table TO my_table_backup, my_table_tmp TO my_table");
if (!$res) die("Erreur mysql ".mysql_error());

Filtrons les entrées

Afin de sécuriser au maximum vos sites, la première règle est de bien faire attention aux entrées utilisateurs. Cette partie peut être un peu fastidieuse mais c’est une des règles à respecter.

Les 3 règles les plus importantes :

  1. Initialiser vos variables utilisées dans la page.
  2. Vérifiez les variables rentrées par l’utilisateur.
  3. Vérifiez l’entrée des fonctions include / require fichiers.

La question c’est donc comment verifier vos variables simplement et efficacement.

Avant PHP 5.2, chacun avait sa propre recette de cuisine car il n’y avait aucune veritable solution dans PHP alors que tout le monde disait que c’était très important surtout suite aux nombreuses alertes qu’on voyait fleurir sur des logiciels Open Source.

Depuis PHP 5.2, l’extension filter (disponible jusqu’alors via PECL) a été inclus dans la distribution standard.

Cette extension est très pratique, elle permet par exemple de valider une adresse email sans se prendre la tête avec les dizaines d’expressions regulières que vous verez ici ou là sur Internet.

$email='nimportequoiyahoo.fr';
  $email=filter_var($email, FILTER_VALIDATE_EMAIL);
//$email est à null car l'adresse est incorrecte
$email='bonneadresse@bondomaine.com';
$email=filter_var($email, FILTER_VALIDATE_EMAIL);
//$email vaut "bonneadresse@bondomaine.com"

A retenir, on met la variable en premier argument et le filtre qu’on veut appliquer en deuxième.
Si cela retourne « null », la variable n’est pas correcte sinon elle est correcte.

Aprés on peut faire des choses plus complexe, l’utilisateur doit rentrer un entier entre 1 et 10

$categorie=filter_var($_GET['categorie'],
  array(
            //je veux uniquement un entier
            'filter'    =&gt; FILTER_VALIDATE_INT,
            //il doit etre compris dans un tableau
            'flags'     =&gt; FILTER_REQUIRE_ARRAY,
            //entre 1 et 10
            'options'   =&gt; array(
						   'min_range' =&gt; 1,
							 'max_range' =&gt; 10
							 )
           ));

Aprés dans la vie de tous les jours, vous aimeriez filtrer l’ensemble de votre formulaire en une seule fois :

// je decris mon formulaire sous forme de tableau
// avec les format attendu
$config_form = array(
    'produit'   =&gt; FILTER_VALIDATE_INT,
    'categorie'    =&gt; array('filter'    =&gt; FILTER_VALIDATE_INT,
                            'flags'     =&gt;FILTER_REQUIRE_ARRAY,
                            'options'   =&gt; array('min_range' =&gt; 1, 'max_range' =&gt; 10)
                           )
);
 
$_POST_CLEAN = filter_input_array(INPUT_POST, $config_form);
//je recupére ainsi dans $_POST_CLEAN tout ce qui était
//dans $_POST mais maintenant les données sont
//filtrées.

A vous de jouer !

Et si MySQL était mort ?

Une chose assez importante auquel les développeurs ne pensent pas tout le temps : Avez vous verifié si votre serveur MySQL fonctionne correctement ? Est-ce que la fonction mysql_connect / mysqli_connect ne renvoit pas false ?

Je pense que beaucoup oublie cet étape, c’est comprehensible dans l’euphorie du développement. J’ai fait une petite requète sur Google et je vois tout simplement 734000 pages avec une erreur qui découle de ce problème…

C’est pas bien compliqué, il faut juste y penser !

$my=mysql_connect(...,...,...);
if ($my===false)
{
  header("location: /mysql_out.php");
  // a la rigueur on envoie un petit mail au webmaster pour le mettre au courant
  mail(...,...,...,...);
  exit;
}

Allez je referai un petit point de temps en temps pour voir si ce nombre (734 000 pages sur Google) baisse un peu !

Opération booléenne en PHP

PHP est un language non typé, et c’est parfois le casse-tête en particulier pour les tests booléens, j’avoue que je prefère parfois utilisé le === en particulier sur la fonction strpos. Qui ne c’est pas fait avoir sur un « if (strpos) » !

Pour vous tester sur la logique booléenne voilà un test pour remettre à jour vos neurones.

Vous avez un trou de mémoire concernant toutes ses opérations élementaires (isset, is_null, ==false,…), voici les tableaux de corrrespondance de tous les tests.

Bon courage

Objet PHP : attention au __destruct

Dans la bible des erreurs à éviter car elles peuvent prendre la tête : la fonction __destruct sur un objet PHP.

Il faut être trés vigilent, en effet, cette fonction est appellé même après un exit, donc on peut avoir un état en base de donnée juste avant exit qu’on vient de verifier par un dump.

Et se retrouver après exit  avec un état différent, effectivement la fonction exit appelle tous les destructeurs des objets en mémoire.



Check out our best movie collection. Latest CD, DVD, HQ DVD movie downloads. Buy and download movies instantly.