dimanche 14 avril 2013

Trucs pour feuille de style CSS3

Voici quelques trucs compatible CSS3 (bientôt tout les navigateurs en date de février 2013) pour vous facilité la vie.

Trucs retour à la ligne avec mot insécable.

Exemple pour l'affichage sur mobile avec largeur réduite on veux écrire une adresse URL au complet qui dépasse en caractère la largeur disponible.
Solution ajouter le code CSS: word-wrap:break-word;

Menu déroulant en CSS

L'utilisation du Javascript pour les menu déroulant n'est pas toujour requis. Par exemple pour une fonctionnalité de base de menu déroulant le code ce fait très bien via CSS2 et est compatible sur tout les navigateur et ne nécessite pas d'avoir Javascript.

Voici le principe de base :

Faire un menu dans une balise <nav> avec une liste <ul>

  • menu1
    • menu 1.1
    • menu 1.2
  • menu 2
  • menu3
    • menu 3.1
    • menu 3.2
    • menu 3.3
En CSS vous devez cacher les menus déroulant avec : nav ul li ul { display:none; }
Et pour afficher le menu déroulant rien de plus simple : nav ul li:hover ul { display:block;}

Par la suite on rajoute un peu de CSS pour afficher le tout de façon plus estétique, mettre les menu déroulant en position absolut et fixer la largeur du menu déroulant. Enlever les puce des listes, géré les marge et padding.

Ce site fonctionne avec ce principe
Exemple de code CSS pour menu déroulant:
nav ul {list-style:none; padding:0px; margin:0px; } 
nav ul li { float:left;  padding:0px; margin:0px; padding-right:20px; } 
nav ul li ul{  margin:0px;  padding:0px;  position:absolute;    float:none; display:none;  }  
nav ul li:hover ul {display:block; }  
nav ul li ul li { margin:0px; padding:0px; float:none;} 
nav ul li ul li a {width:150px; display:block;}

Toutes les façons de mettre du style dans une page HTML

Voici les différentes façons d'ajouter un style à une balise HTML

1 Méthode standard avec fichier CSS externe

Code source de la page web



<link href="css/style.css" media="all" rel="stylesheet" />
<h1>Titre de la page</h1>

code source du fichier css/style.css

h1 {color:red; font-size:24px; text-align:center; }

2 Avec code CSS dans le fichier directement

Code source de la page web
source code



<style media="all" type="text/css">
h1 {color:red; font-size:24px; text-align:center; }
</style>

3 Avec style directement sur l'élément

Code source de la page web
source code

<h1 style="color:red; font-size:24px; text-align:center;">Titre de la page</h1>

Feuille de style pour IE

<!-- patch IE  -->
    <!--[if IE]>
    <link href="css/ie_patch.css" media="all" rel="stylesheet">
    <![endif]-->


Et remplacer css/ie_patch.css par l'emplacement de votre CSS.

Plusieurs feuilles de style différentes

Voici comment permettre a vos visiteurs de choisir parmi différents habillage css pour votre site.

Premièrement il faut avoir différents css qui permettre d'habiller différemment votre site web. Par exemple pour ce site il y a plusieurs css pour chaque couleur d'habillage différent (bleu, orange, mauve, rouge , ...).

Pour ce site j'utilise un CSS global et des css pour chaque couleur d'habillage différent :

  • CSS Global ( http://www.phpascal.com/css/style_global.css)
  • CSS orange : http://www.phpascal.com/css/orange.css
  • CSS mauve http://www.phpascal.com/css/mauve.css
Une fois que vous avez plusieurs css de disponible il vous suffit de permettre aux visiteurs d'en choisir un en particulier.

Il y a plusieurs façon de procédé, une façon est d'utiliser une variable de session pour sauvegarder le choix du visiteur.

Pour ce faire il faut :
  1. Débuter une session au début de chacune des page su site
  2. Avoir une page qui recoie en paramètre le style a changé
  3. Enregistrer le choix du visiteur dans une variable PHP
  4. Avoir un haut de page qui affiche le bon fichier css selon la variable de session
Exemple du traitement pour faire marcher le tout :
Lien pour changer de css : index.php?style=mauve
Code source de l'include du haut des pages :
<?php
/* haut des pages du site */

if (!isset($_SESSION['debuter']))
{
session_start();
$_SESSION['debuter'] = 'oui';
}

// recuperer information et mettre dans variable de session
if (isset($_GET['style'])) $_SESSION['style'] = $_GET['style'];

// mettre dans la variable $style le style choisie et indiquer un style par defaut
if (isset($_SESSION['style'])) $style = $_SESSION['style'];
else $style = "bleu";
?>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
.....
<link href="http://www.phpascal.com/css/<?php print  $style; ?>.css" media="all" rel="stylesheet" />
....
</head>
<body>
....


Ceci permet d'avoir une feuille de style qui a le nom de la variable envoyer en GET. Exemple : index.php?style=rouge va mettre la feuille de style rouge.css sur le site.

Gestion global des CSS

Pour utiliser de façon intelligente les css, il faut ce donné des standards d'affichage dans notre page.

Par exemple quelle police on va utiliser pour la page, quelle taille vont avoir nos différent texte dans la page, quel couleur va être le texte, ...

Une bonne feuille de style css commence par un bon code HTML avec l'utilisation des balise sémantique.
Exemple de balise sémantique:

  • <body>
  • <h1>, <h2>, <h3>, <h4>, <h5>, <h6>
  • <p>
  • <img>
  • <strong>
  • <ul>, <ol>, <li>
  • <i>, <u>, <sup>, <em>
Pour un site web avec un design graphique simple, on ne devrait avoir plusieurs classe css à créé. Toutes les balise html existantes nous permet un vaste choix d'habillage avec les css.

Par exemple le code source de cette page j'utilise seulement 10 classes CSS. Ceci permet d'avoir une feuille de style simple et facile à modifier.

Exemple de base pour un CSS Global pour un site web utilisant uniquement les balise sémantique HTML:

body { background-color:#005BA3; margin:0px; font-family:Arial, Helvetica, sans-serif;}
a:link, a:hover, a:visited { text-decoration:none;}
a:visited:hover, a:hover { text-decoration:underline;}
img { border:0px; }
h1 {font-size:24px; }
h2 {font-size:20px; margin-bottom:2px; padding-bottom:0px; }
h3 {font-size:16px; margin:0px; padding:0px; margin-top:10px; margin-bottom:0px; }
li {margin-left:20px; }

Les couleurs des liens en CSS

Il y a 4 différents affichages des liens sur une page selon son état

  1. Liens inactif ( a:link )
  2. Liens déjà visité (a:visited)
  3. Liens quand on clique dessus (a:active)
  4. Liens quand on passe la souris dessus (a:hover)
On peut choisir si on veux que les liens soient souligner ou non. Dans mon exemple le lien ce souligne quand on est au dessus du lien.

Voici comment en CSS affecter les mêmes couleurs et style pour toutes les sorte de liens :

a:link, a:hover, a:visited, a:visited:hover, a:hover
{
text-decoration:none;
color:red;
}

a:visited:hover, a:hover { text-decoration:underline;}

Comme vous pouvez le voir dans l'exemple, le style a:hover à été assigner en premier avec text-decoration:none puis par la suit

Feuilles de style pour l'impression

Avant d'expliquer en détail il faut savoir que si on fait une feuille de style spécifique pour l'impression cela suppose qu'on à déjà une feuille de style de faire pour l'affichage web (sreen).

Le principal but d'avoir une feuille de style différente pour l'impression c'est pour avoir le contenue de la page qui s'affiche correctement lorsqu'on l'imprime. Cela nous permet aussi d'enlever des bouts de site qui ne sont pas utile lors de l'impression d'une page: par exemple des menus, des publicité.

Par exemple la page web actuel:   à une feuille de style pour l'impression qui permet d'imprimer seulement le texte de l'article. (pour le voir faite aperçu avant impression).

Voici maintenant comment faire pour avoir 2 feuilles de style pour une page web: une pour l'écran et une pour l'impression:

À mettre dans la balise
:

<link href="style_ecran.css" rel="stylesheet"   type="text/css" media="screen" />
<link href="style_imprimer.css" rel="stylesheet" type="text/css"  media="print">
Exemple CSS d'impression :


/* CSS pour l'impression seulement */

.enlever_imp {display:none; }

Avec ce simple code il est possible d'ajouter la classe enlever_imp dans notre page pour les section que vous ne voulez pas imprimer.

Compatibilité du HTML5- est-ce que les navigateurs sont compatibles

Voici les statistiques de compatibilité des navigateurs avec les nouvelles options disponible avec le HTML5.
Premièrement avant de vous montré ce qui est compatible avec le HTML5 et ce qui n'est pas encore supporté il faut savoir que les navigateurs évolue rapidement et que dans le futur, de plus en plus de fonctionalité serrons supporté.  Cette explication ce base sur ce qui est fonctionnel au mois de février 2013 au Canada et en France.

Créé une image pour les favoris

Pour ajouter un icône a votre site il faut :

  1. Créé une image jpg de 16 pixel par 16 pixel

  2. Renomer cette image en icone (nom_image.jpg -> nom_image.ico)

  3. Mettre cette image sur votre site web

  4. Ajouter à l'intérieur de la balise <head> de votre site la ligne <link rel="Shortcut Icon" href="lien_icone.ico" type="image/x-icon" />

Exemple de l'icône de ce site : http://www.phpascal.com/images/icone_site.ico

Ce tout petit geste permet de bien identifier votre site dans une liste de favoris.

PS: Ce code : <link rel="Shortcut Icon" href="http://www.phpascal.com/images/icone_site.ico" type="image/x-icon" /> est valide avec XHTML 1.1 Strict

Banir l'utilisation des tableaux

Il faut bannir les tableaux dans une page web (sauf si on à un chiffrier Excel).

Les tableaux rendent laborieux la maintenance d'un site web et sa facilité à le modifier. Il rend aussi l'habillage en css plus difficile et moins malléable.

Les tableaux ont été très pratique pour la mise en page web avant l'arriver des feuille de style CSS. Il reste encore utile pour l'envoie de courriel à différent système de courriel qui ne fonctionne pas bien avec les CSS.

Maintenant que les feuilles de style en cascade sont implanter il faut les utiliser, c'est plus vraiment un choix!

Utilisation des balises sémantiques

Voici les différentes balises sémantique à utiliser dans une page html avec son utilisation spécifique.

Voici les balises de type bloc, qui par défaut est un espace séparer du reste par un espacement en haut et en bas et qui prend toute la largeur.

  • BLOCKQUOTE - pour indiquer une citation
  • CENTER - pour centrer
  • DEL - pour indiquer du texte supprimer
  • DIV - balise générique sans but précis
  • H1 - Titre de page le plus important, niveau 1
  • H2 - Titre de page de niveau 2
  • H3 - Titre de page de niveau 3
  • H4 - Titre de page de niveau 4
  • H5 - Titre de page de niveau 5
  • H6 - Titre de page le moins important, niveau 6
  • HR - Ligne de séparation
  • P - Un paragraphe de texte
  • PRE - texte déjà formater dans le code source
Balise pour faire des listes :
  • OL - Liste ordoner avec numéro 1,2,3,...
  • UL - Liste sans ordre avec des bullets
  • LI - Élément de la liste
Style pour du textes dans un paragraphe:
  • EM - Mettre de l'importance
  • STRONG - Mettre de l'importance
  • B - Mettre en gras
  • BIG - Mettre en gros
  • I - Mettre en italique
  • S - Faire un trait sur le texte (exemple)
  • SMALL -Mettre en petit

Voici en gros toutes les balise importante a utiliser dans une page HTML ce qui permet d'éviter beaucoup de balise du type : <span class="style_12"> et <div class=millieu> pour des balise qui coresponde à la fonction du texte dans la page.

Htacces et urlRewrite

RewriteEngine On
RewriteBase /site_web/www/

Faire la redirection d'un url avec paramêtre exemple :
http://localhost/site_web/www/aaaaa/bbbbb.html?param1=1&param2=2
RewriteCond %{QUERY_STRING} ^param1=([A-Za-z0-9-_]+)&param2=([A-Za-z0-9-_]+)$
RewriteRule ^[a-z0]/([A-Za-z0-9-_]+).html$ test1.php?param1=%1&param2=%2 [L]


Ajouter une restriction sur un répertoire en particulier que l'on ne veux pas effectuer le URL rewrite :

RewriteCond %{REQUEST_URI} !(FCKeditor) [NC]
RewriteRule ^([A-Za-z0-9-_]+)/([A-Za-z0-9-_]+)/([A-Za-z0-9-_]+).html?$  page.php?url=$3&lang=fr [QSA,L]


Redirection permanante d'une page vers une autre :
Redirect permanent  /page_vielle.php                 /nouvelle_emplacement/page_nouvelle.html

Commandes SSH pour gestion des permissions de fichier

Modifier l'auteur et le group d'un fichier :

chown nom_auteur:nom_group fichier


Modifier la permission sur un fichier
chmod 777 fichier

Liste des commandes CVS SSH

Voici une liste de commandes CVS :

CVS CO

cvs co fichier : aller chercher la dernière version et l'importer localement

CVS CI

cvs ci fichier : enregistrer notre version
cvs ci -m 'ajouter commentaire' fichier : enregistrer fichier avec un message d'information sauvegarder dans les logs

CVS LOG

cvs log fichier : voir l'historique des version du fichier

Options supplémentaires pour l'historique des fichiers 
(d = nombre de jour, format de date YYY-MM-DD)
cvs log -d "d" fichier
cvs log -d ">d" fichier
cvs log -d "<d" fichier 
cvs log -d "d1<d2" fichier : trouver log entre 2 date d1 et d2

CVS UPDATE

cvs update -p -r 1.7 fichier > fichier 
cvs commit -m “blab la” fichier

CVS DIFF

Voir la différence entre 2 versions
cvs diff -r 1.4 -r 1.5 fichier

Liste de comandes simple SSH

Avec une configuration de site web LAMP (Linux, Apache, MySQL, PHP). Un des aspets à conaître est l'utilisation de linux pour faire la gestion du serveur sur lequel s'exécute vos site web dynamque.

Avec une console SSH (disponible via un petit logiciel exemple : putty) vous avez accès directement au serveur et pouver ainsi le paramétrer a votre guise.

Voici une liste rapide de commandes SSH :
  • locate fichier1.html  : recherche tout les fichier qui on fichier1.html dedans
  • ls : liste les fichier d'un répertoire
  • du -sh : affiche la taille d'un répertoire
  • ls | wc -l : affiche le nombre de fichier dans un répertoire
  • mkdir nom_repertoire : crée un répertoire
  • rmdir nom_repertoire: supprime un répertoire
  • clear : efface l'écran
  • cp fichier.html fichier_copier.html : copier un fichier
  • cd nom_repertoire : aller dans le répertoire
  • pwd : afficher l'arboresence ou on ce trouve sur le serveur
  • exit : quitter, ce déconnecter du serveur
  • su - : se connecter en tant que super utilisateur (root)
  • man ls : afficher les insctruction pour la commande ls
  • cd .. : reculer d'un répertoire dans l'arboresence
  • rm fichier*.html supprimer les fichier qui débute par fichier et qui finisse par .html
  • rm -rf repertoire supprimer sans confirmation tout les fichiers d'un répertoire de façon récursive (supprimer tout les sous répertoires et sous fichiers)
  • tail -50 nom_du_fichier  affiche les derni`re ligne d'un fichier (-f voir modif en temp réel)
  • head -50 nom_fichier voir début d'un fichier
  • passwd le_nom_du_compte : Changer mot de pass
Ajouter accès SSH a un site :
Modifier fichier /etc/passwd et enlever nologin et remplacer par shell
PS: Si aucun accès n'existe encore en SSH sur le serveur pour en ajouter vous devez vous connecter directement sur le serveur et faire la modification dans la salle de serveur. Si il y a déjà un ou plusieurs membre qui ont activer leur compte SSH c'est possible en root d'ajouter la connexion SSH a un membre spécifique.

Ajouter une clé secondaire (FOREIGN KEY)

Pour pouvoir utilisé les clé secondaire (FOREIGN KEY) vous devez d'abord avoir des tables de type : InnoDB.

Attention les clé secondaire ne marche pas avec les table de type : MyISAM.

ALTER TABLE `table_1` ADD FOREIGN KEY ( `id_table_2` )
REFERENCES `bd_database`.`table_2` (`id`)
ON DELETE RESTRICT ;


Ceci permet d'associer un clé secondaire à la table_1 pour le champ id_table_2 vers la table table_2.id.
L'option ON DELETE RESTRICT permet de garder l'intégrité des donné en empêchant de supprimer un enregistrement de la table table_2 qui serrais utilisé dans un ou plusieurs enregistrement de la table table_1.

Sauvegarde SQL dans un fichier text

Ce script crée un fichier txt de toutes votre base de données.  Vous pouvez utiliser ce script pour faire la sauvegarde automatique de vos base de données. Dans mon exemple je vais exécuter ce script une fois par jour et ainsi créé un différents fichier par jour.

Exemple en partant du 14 avril 2009 :

  • bd_2009-04-14.txt
  • bd_2009-04-15.txt
  • bd_2009-04-16.txt
  • bd_2009-04-17.txt
  • (...)
Et mon script va automatiquement supprimer les vieux save de plus de 3 mois.

Voici le script

<?php
/*
* Sauvegarde de la BD dans un fichier .txt
* et suppression de vieux sauvegarde + de 3 mois
*
* fichier a appeler dans un CRON a tout les jours
* ce script fait un fichier de sauvegarde sous le format bd_2009-04-14.txt
* un dump sql qui permet de refaire ne entier la base de données
*/


$repertoire_sav = "/votre/repertoire/de/sauvegarde";
$nom_bd = "Nom de votre BD";

include ("votre/repertoire/connexion.php"); // fichier de connexion PHP



//////// Supprimer vieux save /////////////////////////////////////////////////////
// trouver date d'il y a 3 mois
$date_vieux = mktime(0,0, 0, date('m') - 3, date('j') ,  date('Y'));

$date_vieux_trv = date('Y-m-d',$date_vieux);
$nom_vieux_save = "bd_$date_vieux_trv".".txt";
$vieux_save = "$repertoire_sav/$nom_vieux_save";

if (is_file($vieux_save))
    {
    unlink($vieux_save);
    }
// fin supprimer vieux sauvegarde
///////////////////////////////////////////////////////////////////////////////


// faire sauvegarde
// ouverture du buffer
ob_start();


$table =""; $tb ="";
$date_sauvegarde = date('Y-m-d H:i:s');

$nom_save = "bd_";
$nom_save .= date('Y-m-d');
$nom_save .= ".txt";


$crlf="\n";

$strTableStructure      = "Table structure for table";
$strDumpingData         = "Dumping data for table";

print "# ---- BD: $nom_bd  ------------------------------$crlf";
print "# ---- Date de la sauvegarde : $date_sauvegarde   ----------------$crlf";





$tables = mysql_query("SHOW TABLES FROM YOUR_DATABASE");

$num_tables = @mysql_numrows($tables);

$i = 0;
// boucle toute les tables
while($i < $num_tables)
{
    $table = mysql_tablename($tables, $i);
    if ($tb) {
        if ($table == $tb) {
            print $crlf;
            print "# --------------------------------------------------------$crlf";
            print "#$crlf";
            print "# $strTableStructure '$table'$crlf";
            print "#$crlf";
            print $crlf;

            echo get_table_def($db, $table, $crlf).";$crlf$crlf";

            print "#$crlf";
            print "# $strDumpingData '$table'$crlf";
            print "#$crlf";
            print $crlf;

            get_table_content($db, $table, "my_handler");

            exit ;
        }
    }
    else {
        print $crlf;
        print "# --------------------------------------------------------$crlf";
        print "#$crlf";
        print "# $strTableStructure '$table'$crlf";
        print "#$crlf";
        print $crlf;

        echo get_table_def($db, $table, $crlf).";$crlf$crlf";

        print "#$crlf";
        print "# $strDumpingData '$table'$crlf";
        print "#$crlf";
        print $crlf;

        get_table_content($db, $table, "my_handler");
    }

    $i++;
}


// enregistrer le save
$sauvegarde = ob_get_clean();

// patch bug CURENT_TIMESTAMP
$sauvegarde = str_replace("DEFAULT 'CURRENT_TIMESTAMP'","DEFAULT CURRENT_TIMESTAMP",$sauvegarde);

$nom_fichier = "$repertoire_sav/$nom_save";
$fd = fopen($nom_fichier,"w+");
fwrite ($fd,$sauvegarde);
fclose($fd);




mysql_close();



/*
* Functions
*/
function get_table_def($db, $table, $crlf)
{
    global $drop;

    $schema_create = "";
    if(!empty($drop))
        $schema_create .= "DROP TABLE IF EXISTS $table;$crlf";

    $schema_create .= "CREATE TABLE $table ($crlf";

    $result = mysql_db_query($db, "SHOW FIELDS FROM $table") or mysql_die();
    while($row = mysql_fetch_array($result))
    {
        $schema_create .= "   $row[Field] $row[Type]";

        if(isset($row["Default"])
           && (!empty($row["Default"]) || $row["Default"] == "0"))
            $schema_create .= " DEFAULT '$row[Default]'";
        if($row["Null"] != "YES")
            $schema_create .= " NOT NULL";
        if($row["Extra"] != "")
            $schema_create .= " $row[Extra]";
        $schema_create .= ",$crlf";
    }
    $schema_create = ereg_replace(",".$crlf."$", "", $schema_create);
    $result = mysql_db_query($db, "SHOW KEYS FROM $table") or mysql_die();
    while($row = mysql_fetch_array($result))
    {
        $kname=$row['Key_name'];
        if(($kname != "PRIMARY") && ($row['Non_unique'] == 0))
            $kname="UNIQUE|$kname";
        if(!isset($index[$kname]))
            $index[$kname] = array();
        $index[$kname][] = $row['Column_name'];
    }

    while(list($x, $columns) = @each($index))
    {
        $schema_create .= ",$crlf";
        if($x == "PRIMARY")
            $schema_create .= " PRIMARY KEY (" . implode($columns, ", ") . ")";
        elseif (substr($x,0,6) == "UNIQUE")
            $schema_create .= " UNIQUE ".substr($x,7)." (".implode($columns,", ").")";
        else
            $schema_create .= " KEY $x (" . implode($columns, ", ") . ")";
    }

    $schema_create .= "$crlf)";
    return (stripslashes($schema_create));
}

function get_table_content($db, $table, $handler)
{
    $result = mysql_db_query($db, "SELECT * FROM $table") or mysql_die();
    $i = 0;
    while($row = mysql_fetch_row($result))
    {
        $table_list = "(";

        for($j=0; $j<mysql_num_fields($result);$j++)
            $table_list .= mysql_field_name($result,$j).", ";

        $table_list = substr($table_list,0,-2);
        $table_list .= ")";

        if(isset($GLOBALS["showcolumns"]))
            $schema_insert = "INSERT INTO $table $table_list VALUES (";
        else
            $schema_insert = "INSERT INTO $table VALUES (";

        for($j=0; $j<mysql_num_fields($result);$j++)
        {
            if(!isset($row[$j]))
                $schema_insert .= " NULL,";
            elseif($row[$j] != "")
                $schema_insert .= " '".addslashes($row[$j])."',";
            else
            $schema_insert .= " '',";
        }
        $schema_insert = ereg_replace(",$", "", $schema_insert);
        $schema_insert .= ")";
        $handler(trim($schema_insert));
        $i++;
    }
    return (true);
}

function my_handler($sql_insert)
{
    global $crlf, $asfile;

    echo "$sql_insert;$crlf";
}

?>

Utilisation de PHPMyAdmin

Sur les différents serveur web fonctionnant avec LAMP (Linux, Apache, MySQL, PHP) il est très souvent disponible l'outil web pour géré sa base de données: PHPMyAdmin.

Si il n'est pas installer je vous suggère fortement de l'installer.

Ce petit site web est très pratique pour faire toutes les opérations sur sa base de données sans avoir recours à des opération en ligne de commande.

Je vous recommande d'utiliser cette interface pour faire l'importation ou l'exportation de votre base de données.

Vous pouvez aussi tester vos commande SQL et les optimiser en regardant combien de temps il ont pris à s'exécuter.

Une autre chose que je trouve très pratique de PHPMyAdim c'est que vous pouvez imprimer un shéma relationnel de votre base de données avec les relations entre vos tables.  Pour ce faire aller dans la page d'accueil d'une base de données et cliquer sur un lien en bas de la page : Préparer le schéma en PDF

Gestions des erreurs SQL dans une page PHP

Dans la gestion des erreurs SQL dans une page web PHP il est pratique d'arrêter le traitement de la page quand on rencontre une erreur SQL.

Pour la conception et le test d'un nouveau site web il faut afficher l'erreur SQL pour pouvoir la corrier.

Exemple d'affichage en cas d'erreur SQL :
<?php
$liste = "select  *
           from page
           order by nom";
       
$reponse = mysql_query($liste) or die ("Erreur : liste = $liste <br>".mysql_error());
?>

Dans cette exemple, si il y a une erreur avec la requête SQL le script s'arrête et une message d'erreur s'affiche.

Le message d'erreur comprend le code source de la requête SQL ainsi que le message d'erreur de MYSQL qui indique ou se trouve l'erreur dans votre requête.

Introduction à Jquery

Voici quelque instruction pour débuter avec l'utilisation de Jquery


Il y a trois façon d'accéder aux éléments d'une page avec Jquery

  1. $('h1') : Avec la balise web directement, plusieurs résultats possibles, exemple <h1>
  2. $('.h1') : Avec le nom de la classe d'un élément, plusieurs résultats possible, exemple <div class='h1'>
  3. $('#h1') : avec le id d'un élément, un résultat possible, exemple <div id='h1'>

Voici 5 façon de récupérer de l'information dans la page avec Jquery

  1. .html()
  2. .text()
  3. .attr()
  4. .val()
  5. .each()

L'option text resemble à html mais ne retourne pas du code html, pas de balise html juste le texte.

L'option val sert pour les champs dans un formulaire.

L'option attr sert a trouver la valeur d'un attribut par exemmple pour une image alt, title, src et on a aussi la possibilité d'inventer des attributs et d'y accéder via Jquery par contre l'utilisation d'attribut personalisé n'est pas valide avec le W3C.

L'option each() sert a parcourir un par un les élément de la page par exemple $('a').each va parcourir un a un tout les lien de la page.

Code source exemple

<script>
    // attendre chargement du DOM avant de faire le js Jquery
    $(function() {
       

    var info1 = $('h1').html();
    var info2 = $('h1').text();
    var info3 = $('#id').attr('info_extra');
    var info4 = $('.class').attr('href');
    var info5 = $('#hidden').val();
    var info6 = $('p:first').text();
   
    var info7 = '';
    $( "p" ).each(function( index )
    {
        info7 = info7 + $(this).text() + ' --- ';
       
    });
   
    alert('info1 = ' + info1 + '\ninfo2 = ' + info2 + '\ninfo3 = ' + info3
                + '\ninfo4 = ' + info4 + '\ninfo5 = ' + info5 + '\ninfo6 = ' + info6
                + '\ninfo7 = ' + info7  );
   

    $('h1').html('Nouveau titre');
    $('.class').attr('href','#nouveau_lien');
    $('#hidden').val('valeur modifier via JQUERY');
    $('p:first').text('nouveau text pour le paragraphe');
   
    var num = 1;
    $( "p" ).each(function( index )
    {
        $(this).html('<h1>paragraphe #' + num + '</h1><ul><li>liste ajouter</li></ul>Avec code HTML');
        num++;
    });   
   
   
    });
    </script>

<h1><strong>jQuery</strong> trouver info</h1>

<a href="#lien" id="id" class="class" info_extra='attribu ajouter'>Lien test</a>

<input type="hidden" name="cacher" id="hidden" value="valeur test" />

<p>Paragraphe 1</p>
<p>Paragraphe 2</p>

Empêcher fermeture dialog modal de JqueryUI

Avec JQUERYUI il y a la possibilité d'avoir des belle boite de dialog avec du style qui remplace parfaitement la fonction alert() de javascript.  Par contre pour pouvoir l'utilisé sans que l'internaute puisse fermer la fenêtre on doit utilisé quelques astuces.


Voici le code javascript pour empêcher la fermeture d'un popup modal :


<script type='text/javascript'>
   $( "#boite_modal" ).dialog({
       autoOpen: false,
       width: 300,
       modal: true,
       closeOnEscape: false,
       open: function(event, ui) {  $(".ui-dialog-titlebar-close", $(this).parent()).hide(); }
    });

$('.lien_boite').click(function(event){
    $( "#boite_modal" ).dialog("open");
    event.preventDefault();
        });
</script>

Voici le code HTML

<div style='display:none;' id='boite_modal' title='Boite impossible à fermer!'>Désoler vous êtes coincé ici <p>Bouton escape désactiver</p><p>Bouton X -close cacher en CSS</p><p>Essayer F5</p></div>
<a href='#modal' id='lien_boite'>Ouvrir popup modal</a>

Bien sur pour que ça fonctionne vous dever avoir Jquery et JqueryUI sur votre site.

Calculer l'age d'une personne avec requete SQL et PHP

Option de SQL assez simple pour récupérer l'age d'une personne en jour par la suite on divise par 365 et le tour est joué :

Exemple avec une table enfant qui a un champ date_naissance de format date dans une BD MySQL


    $enfant = "select *, DATEDIFF(CURDATE(),date_naissance)  as nb_jour
                                from enfant   ";
   
    $rb = mysql_query($enfant) or die ("<B>enfant = $enfant</b>".mysql_error());
       
    while($List2 = mysql_fetch_array($rb))
    {
    extract($List2);
   
    $age = floor($nb_jour / 365);
 print "age = $age<br/>\n";
}

Mettre en place la notification instantané avec Paypal

Voici comment faire pour obtenir la notification instantané avec Paypal. (IPN en anglais instant payment notification).

L'installation de l'IPN permet a un site marchand de savoir quand une commande est payé et permet de faire les étapes relative qui suit le payement d'une commande.

Il y a deux étapes pour mettre en place ce système de confirmation en temps réel des achat sur PayPal:

  1. Créé un script qui va être appeler par PayPal lors d'un achat
  2. Donner a paypal l'url du fichier a appeler sur votre site


Voici le code source d'un script qui permet la récupération des information sur un achat d'une commande:
<?php

// read the post from PayPal system and add 'cmd'
$req = 'cmd=_notify-validate';

foreach ($_POST as $key => $value) {
$value = urlencode(stripslashes($value));
$req .= "&$key=$value";
}

// post back to PayPal system to validate
$header .= "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) . "\r\n\r\n";
$fp = fsockopen ('www.paypal.com', 80, $errno, $errstr, 30);

// assign posted variables to local variables
$item_name = $_POST['item_name'];
$item_number = $_POST['item_number']; // id commande
$payment_status = $_POST['payment_status']; // Completed,
$payment_amount = $_POST['mc_gross']; //0.01
$payment_currency = $_POST['mc_currency']; //CAD
$txn_id = $_POST['txn_id'];
$receiver_email = $_POST['receiver_email'];
$payer_email = $_POST['payer_email'];

if (!$fp) {
// HTTP ERROR
} else {
fputs ($fp, $header . $req);
while (!feof($fp)) {
$res = fgets ($fp, 1024);
if (strcmp ($res, "VERIFIED") == 0) {

// check the payment_status is Completed
// check that txn_id has not been previously processed
// check that receiver_email is your Primary PayPal email
// check that payment_amount/payment_currency are correct
// process payment


if ($payment_status == "Completed")
    {
    // si le payment est accepter  traitement de l'information
   
   
    }


}
else if (strcmp ($res, "INVALID") == 0) {
// log for manual investigation
}
}
fclose ($fp);
}
?>


Vous n'avez qu'a rajouter votre programmation si la transaction est complété ("Completed")


Une fois ce fichier créé il ne reste plus qu'a indiquer son url à Paypal. Pour ce faire il existe 2 méthodes différentes a utiliser la façon simple ou la façon compliquer :

Installation IPN Version Simple

Pour indiquer à Paypal quel fichier a appeler à chaque transaction effectuer, il suffit de rajouter dans le formulaire du bouton Paypal l'url de votre script dans un champ cacher du nom de notify_url
Exemple :
<form action=https://www.paypal.com/cgi-bin/webscr method=post target=new>
<input type=hidden name=cmd value=_xclick>
<input type=hidden name=business value=votre@courriel.com>
<input type=hidden name=undefined_quantity value=1>
<input type=hidden name=item_name value='Nom du produit'>
<input type=hidden name=item_number value='204'><input type=hidden name=amount value=99.00>
<input type=hidden name=currency_code value=USD>
<input type=hidden name=shipping value=0.00>
<input type=hidden name=image_url value=http://www.images.jpg>
<input type=hidden name=return value=http://www.site-web.com>
<input type=hidden name=cancel_return value=http://www.site-web.com>
<input type=hidden name=no_note value=0>
<input type=hidden name=notify_url value=http://www.site-web.com/payment_paypal.php>
<input type=submit value="Paypal">
</form> 

Cette méthode pour activer la notification instantané avec Paypal est rapide à mettre en place et pratique puisque l'on a pas besoin des accès au compte Paypals pour l'installer (si on ne peux pas l'avoir). Et permet aussi d'assigner différents fichiers de script à différentes sections de note site web au besoin.


Installation IPN Vesrsion compliquer


Voici la façon compliquer d'installer l'IPN (instant notification payment) mais qui a l'avantage d'être appeler a toutes les transaction de votre compte paypals puisque c'est configurer au niveau de votre compte paypal directement :
  • Ouvrer votre compte paypal et cliquer dans le menu du haut sur 'Solution e-commerce'
  • Cliquer dans le menu de côté sur 'Paiements sur site marchand' puis sur 'Liste de fonctions'
  • Dans cette page trouver 'Notification instantanée de paiement' puis cliquez sur configuration.

Par la suite: cocher la case, entrer l'url de votre page script et cliquer sur enregistrer.

L'installation est maintenant terminer et votre script va être automatiquement appeler à chaque transaction Paypal.

Ré-écriture des url avec une page dynamique php avec paramètres

Voici comment faire pour utilisé la ré-écriture des url par le serveur pour avoir des url simple à partir de page php avec des paramètres.

Exemple pour cette page : Ré-écriture des url
Cette page est afficher a l'aide de l'url suivant avec des variables

  •  index.php?cat=programmation-web&sous_cat=php&page=re-ecriture-url

La ré-écriture par le serveur de cette page me permet d'utiliser l'adresse :
  • /programmation-web/php/re-ecriture-url.html
Voici comment ça marche :
Il y a un fichier .htaccess a la racine du site avec les informations suivantes :
RewriteEngine On
RewriteBase /
RewriteRule ^programmation-web/([A-Za-z0-9-_]+)/([A-Za-z0-9-_]+).html$ index.php?cat=programmation-web&sous_cat=$1&page=$2  [L]

Avec ces 3 lignes de code, une redirection serveur
ce fait automatiquement quand le serveur reçoit un url du genre :
  • programmation-web/premier_parametre/deuxieme_parametre/troisieme_parametre.html
et fait l'appel au fichier index.php avec les 3 paramètres dans l'ordre.
Dans mon cas ces paramètres sont ceux de la catégorie de la page, de la sous catégories et de la page(cat, sous_cat et page).

Page réellement appeler : index.php?cat=programmation-web&sous_cat=php&page=re-ecriture-url

Le but d'utiliser ce type de modification est d'améliorer le référencement de vos page par les moteur de recherche et permet d'avoir de meilleur statistique avec Google Analitics.

ATTENTION
Ceci fonctionne avec des paramêtres qui sont composé de chiffre 0 è 9 et des lettres minuscule ou majuscule, un tiret (-), un underscore(_). Ces caractères son définie par ([A-Za-z0-9-_]+)  et tout autre caractère utiliser en paramêtre ne fonctionnera pas. Exemple : programmation-web/premier_paramètre/deuxième_paramètre/troisième_paramètre.html contient des accent et ne marchera pas. Évidemment éviter aussi les espaces. 

Script pour téléchargé un fichier

Avec un fichier avec ce code :


<?php
// fichier script.php
//date actuelle
$date = gmdate('D, d M Y H:i:s');

header("Content-Type: $mime"); //Ici par exemple c'est pour un fichier XML, a changer en fonction du type mime du fichier voulu.
header("Content-Disposition: attachment; filename=$fichier");
header('Last-Modified: '. $date . ' GMT');
header('Expires: ' . $date);
//header specifique IE :s parce que sinon il aime pas
if(preg_match('/msie|(microsoft internet explorer)/i', $_SERVER['HTTP_USER_AGENT'])){
  header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
  header('Pragma: public');
}else{
  header('Pragma: no-cache');
}

readfile($fichier);
exit();
?>


Vous pouvez créé différentes page php avec les codes suivant :


<?php
// http://fr.wikipedia.org/wiki/Type_MIME
$fichier = "fichier.wav";
$mime = 'audio/x-wav';
include("script.php");
?>

Appeler une page en php (include)

Voici les différentes façon d'inclure des page en PHP :

Voici les 4 fonctions php possibles :

  1. include ( inclusion standar)
  2. include_once ( inclusion du fichier seulement s'il n'a pas déjà été inclu)
  3. require ( fichier a inclure obligatoirement)
  4. require_once (fichier a inclure obligatoirement, si n'est pas déjà inclu)

Si on inclu un fichier qui n'existe pas, les fonctions require et require_once vont faire arrêter le script avec une erreur fatal. L'utilisation des fonction include et include_once ne ferra pas planter le script même (juste un warning).

Exemple d'utilisation avec l'url au complet:
<?php include("http://www.mon_du_site_web.com"); ?>

Exemple d'utilisation avec emplacement relatif
<?php include("mon_du_fichier.html"); ?>
<?php include("../../../fichier.html"); ?>


L'utilisation du code:  ../   permet de remonter dans les répertoires.

Fonction pour formater une date en français

Fonction pour formater une date en français en PHP.

Voici la fonction tout simple a prendre tel quel permet de convertir la date.  Pour l'affichage en format texte en français ou en anglais.

De : 2010-12-21 14:40:15 vers -> mardi 21 décembre 2010 à 14:40:15


/**
 * formater une date en français ou en anglais
 *
 * affichage date en francais ou en anglais
 * recois une date au format : 2008-12-01 11:16:53
 * et le renvoie au format : 1 décembre 2008 à 11:16:53
 *
 * Exemple %A %d %B %Y à %H:%M:%S  -> Monday 13 June 2011 à 16:13:26
 *
 * http://www.phpascal.com/programmation-web/PHP/date_formater_en_francais.html
 *
 * @param $date = date au format Y-m-d H:i:s
 * @author PHPascal.com
 * @since 2011-06-28 à 16:17:29
 * @return string
 */
function aff_date($date,$lang = 'fr',$format_fr="%d %B %Y", $format_en ="%B %d, %Y")
{
    $date_formatee = "";
   
    $format = $format_fr;
    if ($lang == 'en') $format = $format_en;
               
               
    if ($lang == 'fr') setlocale(LC_TIME, "fr_FR");
           
    $date_strtotime = strtotime($date);
    $date_formatee = strftime ($format,$date_strtotime);
    return $date_formatee;

}

lundi 1 avril 2013

Programmer avec register_globals à off

Quand on apprend à programmer, on ne sais pas tout de suite ce qu'il faut faire, ou, ne pas faire. Les choses qui sont indispensables, les choses superflues... Ce petit récapitulatif n'est pas exhaustif, mais, j'espère qu'elle vous aidera pour débuter sans faire les même erreurs que moi :) Ici, je suppose que vous avez néanmoins déjà un minimum d'expérience en programmation PHP.

Les variables
Depuis PHP plus récent que la version 4.1.0, les serveur sont générale configurer avec les variables globales à OFF. Ça veut dire quoi?
 En gros, vous devez précisez la provenance de chaque variables.
exemple :

* Dans l'url : index.php?page=truc , $page est récupéré avec $_GET[page]
* Par un formulaire : <form type="input" name="page"> , $page est récupéré avec $_POST[page]
* D'une sessions : Les sessions sont particulière, on déclare une sessions grace au tableau $_SESSION[].
Ex : <?php sessions_start(); $_SESSION[page]="accueil"; ?>

Il en existe d'autre comme $_SERVER[] et $_ENV[], mais, elle sont moins importante au début. Du moins, je trouve. Pour une liste des variables, voir : les types de variables PHP .

Tout cela pour dire que vous avez peut être appris que l'on pouvais faire ceci :
<?php
echo $page;
?>

pour afficher la variable qui provient de l'url index.php?page=accueil.
On PEUT le faire sur certain serveur encore, MAIS, imaginer que vous avez un formulaire avec un champs qui s'appelle "page".
Le code le voici :
<form type="input" name="page" value="accueil">

Sur la page (recup.php), qui récupère les donnée du formulaire, on écrirai :
<?php
echo $page;
?>


Et, si maintenant, je fais ceci :
recup.php?page=coucou

La page recup.php va afficher la variable $page de l'url, et non celle du formulaire.

Ce n'est qu'un exemple tout bête, mais il faut TOUJOURS programmer en utilisant les bonnes variable pour chaque type !
$_GET pour l'url
$_POST pour les formulaire
$_SESSION pour les sessions
$_COOKIE pour les cookies

Erreurs de requêtes MySQL en PHP

Erreurs de requêtes MySQL en PHP
La configuration du serveur doit être avec les Magic_quotes=Off pour que cette exemple fonctionne.

Le problèmes de mettre des variables dans une requête MySQL c'est la possibilité de pouvoir exploiter une faille par injection. Par contre, si votre serveur a les magic_quotes à On, vous ne risquez pas grand chose, enfin, moins. (à voir dans php.ini)

Un exemple de requête mysql pour une identification par login et mot de passe :

SELECT * FROM Table WHERE login='$login' AND password='$mdp'

Le formulaire pour être de ce genre :
Login :
<input name="mdp" id="mdp" type="text">
Mot de passe :
<input name="textfield2" type="text">


Le code qui récupèrera les données du formulaire :

<?php
$login = $_POST['login'];
$pass = $_POST['mdp'];
$req = "SELECT * FROM Table WHERE login='$login' AND password='$pass'";
?>


C'est un code que pas mal de débutants (plus haut aussi des fois :)) utilisent, bon, la suite ne marche pas sur tous les serveur, ça dépend de la configuration.
Aller maintenant sur la page du page formulaire et taper ceci :
Login : test1' or '1=1
Mot de passe : test2' or '1=1

Cliquer sur valider ...
et, surprise, vous est loguez !
Suffit ensuite de choisir mieux votre login pour tomber sur le compte de l'admin, ou root. ex :
Login : root' or '1=1
Mot de passe : test2' or '1=1


Explications
Voici à quoi ressemble votre requête avec les informations fourni par le formulaire :
$req="select * from Table where login='root' or '1=1' and password='test2' or '1=1'";

je pense que vous avez maintenant compris. En utilisant le OR '1=1, on est sur de toujours avoir une réponse affirmative.

Si vous ne pouvez changer la configuration de votre serveur, il suffit d'utiliser la function addslashes() pour ajouter des slash devant tous les ' ou "...
Le code sécurisé :
<?php
$login = mysql_real_escape_string($_POST['login']);
$pass = mysql_real_escape_string($_POST['mdp']);
$req = "SELECT * FROM Table WHERE login='$login' AND password='$pass'";
?>


Qui vous donnera cette requête :
$req = "SELECT * FROM Table WHERE login='root' OR '1=1' AND password='test2' OR '1=1'";

Si vous pouvez changer la configuration, editer le fichier php.ini, chercher la ligne magic_quotes=Off, et mettez On à la place de Off.

Si vous rencontrez des erreurs, des chose que je dit complètement fausses, merci de me prévenir.
Si vous utilisez EasyPhp 1.7, php.ini est déjà configurer avec les magic_quotes à On, donc, pas de soucis à ce faire !

Regexp les classes de regex

Les regex
Il peut également être utile de vérifier si une chaîne contient des caractères d'un certain type (numérique, alphanumérique, ...) sans avoir à les énumérer. Pour cela les expressions régulières définissent des classes de caractères, dont la syntaxe est:

[:classe:]

Les classes de caractères sont celles définies par UNIX. Voici un tableau récapitulant certaines de ces classes:

Nom de la classe Description
[:alnum:] caractères alphanumériques (équivalent à [A-Za-z0-9] )
[:alpha:] caractères alphabétiques ( [A-Za-z] )
[:blank:] caractères blanc (espace, tabulation)
[:ctrl:] caractères de contrôe (les premiers du code ASCII
[:digit:] chiffre ( [0-9] )
[:graph:] caractère d'imprimerie (qui fait une marque sur l'écran en quelque sorte)
[:print:] caractère imprimable (qui passe à l'imprimante ... tout sauf les caractères de contrôle)
[:punct:] caractère de ponctuation
[:space:] caractère d'espacement
[:upper:] caractère majuscule
[:xdigit:] caractère hexadécimal

Voici quelques exemples d'utilisation des classes de caractère dans une expression régulière :

chaine composée d'un ou plusieurs caractère(s) alphanumérique(s) "^[:alnum:]+$" chaine contenant un caractère de ponctuation ou un caractère d'espacement "[:punct:]|[:space:]" Un nombre "^[:digit:]+$"


Les fonctions de manipulation d'expressions régulières

PHP fournit quelques fonctions de bases permettant de manipuler des chaînes à l'aide d'expressions régulières.


Ce document issu de CommentCaMarche.net est soumis à la licence GNU FDL . Vous pouvez copier, modifier des copies de cette page tant que cette note apparaît clairement.

Les regex avec ereg eregi eregi_replace ereg_replace

ereg
La fonction ereg() dont la signature est la suivante :
Booleen ereg( chaine modèle,chaine texte[,tableau occurrences] )
permet d'évaluer le texte passer en argument grâce au modèle (qui est une expression régulière) et stocke toutes les occurrences dans un tableau passé optionnellement en paramètre. Lorsque la fonction trouve des occurrences, elle renvoie true , sinon elle retourne false .

eregi
La fonction eregi() dont la signature est la suivante :
Booleen eregi( chaine modele,chaine texte[,tableau occurrences] )
effectue le même travail que sa consœur ereg() , à la différence près qu'elle n'est pas sensible à la casse (pas de différenciation minuscules/majuscules)


<?

$fp = fopen("http://www.com%6dentcamarche%2enet","r"); //lecture du fichier
while (!feof($fp))
{ //on parcoure toutes les lignes
$page .= fgets($fp, 4096); // lecture du contenu de la ligne
}

$titre = eregi("<title>(.*)</title>",$page,$regs); //on isole le titre

/* Le titre commence par <title>, puis contient n'importe quelle chaine, et se termine par </title> */

echo $regs[1];
// on retourne la premiere occurence trouvée
// Les occurences se trouvent entre parenthèses
// $regs[0] renvoie toute la chaine

fclose($fp);

?>




Les fonctions ereg_replace et eregi_replace

La fonction ereg_replace() dont la signature est la suivante :
chaine ereg_replace( chaine modèle,chaine remplacement,chaine texte )
Permet de retourner la chaine texte passée en arguments avec les occurences trouvees remplacées par la chaine de remplacement.
Pour utiliser les occurrences correspondant au modèle dans la chaine de remplacement, il suffit d'utiliser des parenthèses dans la chaine modèle, puis de faire référence à ces éléments dans la chaine de remplacement en utilisant deux signes antislash suivi d'un numéro identifiant l'élément entre 0 et 9 (les numéros sont donnés par ordre imbriqués, puis de gauche à droite, le zéro représente la chaine entière).
Le code suivant remplace Toto par <b>Toti Toto</b>... inutile mais formateur.

$Texte = "Bienvenue a Toto dans le mondes des expressions régulières";
$Texte = ereg_replace("To(to)","<b>\1ti \0</b>",$Texte);

Le code suivant (utilisation avancée des expressions régulières) remplace un URL par un hypertexte HTML (il remplace toute suite de caractères de ponctuations et alphanum&eacuyte;riques commençant par http:// , ou ftp:// par le même texte (sans le http://) entre balises HTML hypertexte...):

$Texte = "Bienvenue sur http://www.commentcamarche.net cher ami";
$Texte = ereg_replace("(http://)(([[:punct:]]|[[:alnum:]])*)","<a href="\0">\2</a>",$Texte);

La fonction eregi_replace() dont la signature est la suivante :
chaine eregi_replace( chaine modèle,chaine remplacement,chaine texte )
effectue le même travail que sa consœur ereg_replace() , à la différence près qu'elle n'est pas sensible à la casse (pas de différenciation minuscules/majuscules).


La fonction split()

La fonction split() possède la syntaxe suivante:

tableau split (chaîne expression, chaîne texte [, entier limite])
La fonction split() retourne un tableau à partir d'une chaine et d'une expression régulière. La limite, optionnelle permet de limiter la taille du tableau retourné. Dans ce cas le dernier élément du tableau contient le reste de la chaine. Si une erreur se produit, split retourne 0.

<?

// découpe une phrase en un tableau de mots
// on utilise split au cas ou plusieurs espaces séparent les mots
$phrase = "Ceci est une phrase avec trois espaces ici";
$tableau_mots = split(" +",trim($phrase)); // un espace ou plus

?>



La fonction sql_regcase()

La fonction sql_regcase() possède la syntaxe suivante:

chaine sql_regcase (chaine texte)

Elle retourne une expression régulière qui représente la chaine passée en paramètre sans tenir compte de la case. Chaque caractère de la chaine est représenté entre crochets, avec deux caractères à l'intérieur un en majuscule et l'autre en minuscule, ou le cas échéant deux fois le même caractères. Aucune explication ne vaut un bon exemple ;)

<?

echo sql_regcase("un test"); // affiche [Uu][Nn][ ][Tt][Ee][Ss][Tt]

?>


Cette fonction permet de générer une chaine non sensible à la casse, pour les expressions régulières dans les bases de données par exemple. Dans MySQL lorsque vous utilisez la fonction REGEXP (au lieu de LIKE) la recherche est sensible à la casse. La solution est donc de générer une chaine non sensible à la casse à l'aide de sql_regcase.

<?

$motclef = sql_regcase("motclef");
$sql = "SELECT * from table WHERE champ REGEXP "[[:<:]]$motclef[[:>:]]"";
// selectionne tous les enregistrements de la table table, contenant le MOT motclef

?>



Ce document issu de CommentCaMarche.net est soumis à la licence GNU FDL . Vous pouvez copier, modifier des copies de cette page tant que cette note apparaît clairement.

Introduction aux expressions régulieres regex

Qu'est-ce qu'une expression régulière?

Les expressions régulières sont des modèles créés à l'aide de caractères ASCII permettant de manipuler des chaînes de caractères, c'est-à-dire permettant de trouver les portions de la chaîne correspondant au modèle. Ce système est emprunté au système POSIX (un système d'exploitation). De nombreux scripts sous UNIX les utilisent (notamment Perl ).

En réalité il s'agit d'un système fort ingénieux (et aussi très puissant) permettant de retrouver un mot, ou une phrase (et même beaucoup d'autres choses en réalité) dans un texte, ressemblant au modèle que l'on a construit...


Construire une expression régulière

Les expressions régulières permettent de rechercher des occurrences (c'est-à-dire une suite de caractères correspondant à ce que l'on recherche) grâce à une série de caractères spéciaux. L'expression régulière en elle-même est donc une chaîne de caractère contenant des caractères spéciaux et des caractères standards...

Les symboles ^ et $ indiquent le début ou la fin d'une chaine, et permettent donc de la délimiter. "^debut": chaine qui commence par "debut" "fin$": chaine qui se termine par "fin" "^chaine$": chaine qui commence et se termine par "chaine" "abc": chaine contenant la chaine "abc" Les symboles *, + et ?, respectivement "zero ou plusieurs", "un ou plusieurs", "un ou aucun", permettent de donner une notions de nombre. "abc+": chaine qui contient "ab" suivie de un ou plusieurs "c" ("abc", "abcc" etc..) "abc*": chaine qui contient "ab" suivie de zero ou plusieurs "c" ("ab", "abc" etc..) "abc?": chaine qui contient "ab" suivie de zero ou un "c" ("ab" ou "abc") "^abc+": chaine qui commence par "ab" suivie de un ou plusieurs "c" ("abc", "abcc" etc..)

Les accolades {X,Y} permettent de donner des limites de nombre. "abc{2}": chaine qui contient "ab" suivie de deux "c" ("abcc") "abc{2,}": chaine qui contient "ab" suivie de deux "c" ou plus ("abcc" etc..) "abc{2,4}": chaine qui contient "ab" suivie 2, 3 ou 4 "c" ("abcc" .. "abcccc") A noter que le premier nombre de la limite ("{0,2}", mais pas "{,2}") est obligatoire. Les symboles vu précedemment ('*', '+', and '?') sont équivalents à "{0,}", "{1,}", et "{0,1}".

Les parenthèses ( ) permettent de représenter une séquence de caractères. "a(bc)*": chaine qui contient "a" suivie de zero "bc" ou plus La barre verticale | se comporte en tant qu'opérateur OU "un|le": chaine qui contient "un" ou "le" "(un|le) chien": chaine qui contient "un chien" ou "le chien" "(a|b)*": chaine qui contient une suite de "a" ou de "b" Le point . indique n'importe quel caractère (une fois) "^.{3}$": chaine qui contient 3 caractères Les crochets [ ] définissent une liste de caractères autorisés (ou interdits). Le signe - permet quand à lui de définir un intervalle. Le caractère ^ après le premier crochet indique quand à lui une interdiction. "[abc]": chaine qui contient un "a", un "b", ou un "c" "[a-z]": chaine qui contient un caractère compris entre "a" et "z" "[^a-zA-Z]": chaine qui ne commence pas par une lettre



* Pour rechercher un caractère faisant partie des caractères spéciaux, il suffit de le faire précéder d'un antislash ( sauf entre crochets )
* un antislash doit donc être doublé!


En effet dans les crochets, chaque caractère représente ce qu'il est. Pour représenter un ] il faut le mettre en premier (ou après un ^ si c'est une interdiction), un - se met en premier ou en dernier. "[+?{}.]": chaine qui contient un de ces six caractères "[]-]": chaine qui contient le caractère "]" ou le caractère "-"

Voici un tableau récapitulatif des caractères spéciaux utilisés dans les expressions régulières:

Caractère Utilité
[] Les crochets définissent une liste de caractères autorisés
() Les parenthèse définissent un élément composé de l'expression régulière qu'elle contient
{} Les accolades lorsqu'elles contiennent un ou plusieurs chiffres séaprés par des virgules représente le nombre de fois que l'élément précédant les accolades peut se reproduire (par exemple p{2,5} correspond à ppp , pppp ou ppppp
- Un moins entre deux caractères dans une liste représente un intervalle (par exemple [a-d] représente [abcd] )
. Le caractère point représente un caractère unique
* Le caractère astérisque indique la répétition indéterminée de l'élément la précédant
? Le caractère "point d'interrogation indique la présence éventuelle de l'élément la précédant
| Occurence de l'élément situé à gauche de cet opérateur ou de celui situé à droite ( lard|cochon )
^

* Placé en début d'expression il signifie "chaîne commençant par .. "
* Utilisé à l'intérieur d'une liste il signifie "ne contenant pas les caractères suivants...

$ Placé en fin d'expression il signifie "chaîne finissant par .. "


Ce document issu de CommentCaMarche.net est soumis à la licence GNU FDL . Vous pouvez copier, modifier des copies de cette page tant que cette note apparaît clairement

Utiliser gzopen et gzread

gzopen -- Ouvre un fichier compressé
int gzopen(string filename, string mode);

Ouvre un fichier compressé avec gzip (.gz) pour le lire ou líécrire. Le paramètre de mode est le même que dans fopen() ("rb"
ou "wb") mais il peut aussi inclure un niveau de compression ("wb9") ou une stratégie: 'f' pour les données filtrées, comme
dans "wb6f", 'h' pour Huffman seul , comme dans "wb1h".

Gzopen peut être utilisé pour ouvrir des fichiers qui ne sont pas au format gzip; dans ce cas, gzread() lira directement le
fichier, sans appliquer de décompression.
Gzopen retourne un pointeur de fichier sur le fichier ouvert. Ce pointeur sera nécessaire pour toutes les opérations ultérieures
sur ce fichier. Les opérations de compression/décompression seront transparentes.
Si l'ouverture échoue, la fonction retourne faux (false).

Exemple :

<?php
$fp = gzopen("/tmp/file.gz", "r");
?>



gzread
gzread -- Lit un fichier compressé en mode binaire
string gzread(int zp, int length);

gzread() lis jusqu’à length octets depuis le fichier compressé référencé par zp. La lecture stoppe lorsque length octets
décompressés ont été lus, ou que la fin du fichier a été trouvée.

Exemple :
<?php
$filename = "/usr/local/something.txt.gz";
$zd = gzopen( $filename, "r" );
$contents = gzread( $zd, 10000 );
gzclose( $zd );
?>

Utilisation de continue et break

Voici un exemple pour comprendre l'utilité des fonctions continue et break


<html>
    <head><title>Continue, Break</title></head>
<body>
<p>
<?php
for ($i=0;$i<10;$i++)
{
    echo $i;  // va afficher 0,2,4,6,8
    $i++;
    echo $i;  // va afficher 1.3.5.7.9
}

echo "<br>";

for ($i=0;$i<10;$i++)
{
    echo $i;
    $i++;
   
    if ($i>4) break;
        echo $i;
}

echo "<br>";

for ($i=0;$i<10;$i++)
{
    echo $i;
    $i++;
   
    if ($i>4) continue;
        echo $i;
}
?>
</p>
</body>
</html>


Donne le résultat:

0123456789
01234
0123468

Upload PHP

L'upload en PHP est utilisé au travers du web en générale d'une façon très peux sécurisé (la plupart du temps, pas du tout sécurisé).
L'un des problèmes est le manque de mises en garde et d'exemples sécurisé d'upload PHP.
L'upload PHP n'est pas à prendre à la légère; On doit vraiment prendre en compte les risques de sécurités qu'il engendre.

Pour commencer, voici un exemple d'upload PHP très simple qui ne fais aucune vérification de sécurité.
Ne pas utiliser sur un site en production !


<form method="post" enctype="multipart/form-data" action="">
<input type="file" name="fichier" size="30">
<input type="submit" name="upload" value="Uploader">
</form>
<?php
// 1
if( isset($_POST['upload']) )
{
    $content_dir = $_SERVER['DOCUMENT_ROOT'].'/upload_dir/';

    // 2
    if( !is_uploaded_file($_FILES['fichier']['tmp_name']) )
    {
        exit("Le fichier est introuvable");
    }

    // 3
    if( !move_uploaded_file($_FILES['fichier']['tmp_name'], $content_dir . $_FILES['fichier']['name']) )
    {
        exit("Impossible de copier le fichier dans $content_dir");
    }

    echo "Le fichier a bien été uploadé";
}
?>


Explications :
1) On vérifie que le formulaire a bien été validé
2) Upload du fichier
3) déplacement du ficher de sen répertoire temporaire vers le répertoire d'upload de destination



Voyons maintenant un exemple d'upload PHP sécurisé (du moins, beaucoup plus sécurisé)

On vérifie quoi en faite ?
Ceci dépend de vous et de ce que vous voulez en faire, qui va avoir accès aux fichier, etc... Mais en règle générale :

- Extension
- Poids
- Caractères spéciales

Le code PHP d'upload sécurisé :
<form method="post" enctype="multipart/form-data" action="">
    <input type="file" name="fichier" size="30">
    <input type="submit" name="upload" value="Uploader">
</form>
<?php
if($_POST['upload'])
{
    // repertoire où vont être placé les fichiers
    $content_dir = $_SERVER['DOCUMENT_ROOT'].'/upload_dir/';
   
    // ajouter ici les autres extensions autorisé
    $extensions_OK = array('jpg', 'jpeg', 'gif', 'png', 'pdf', 'doc', 'docx', 'etc...');

    // Le nom du fichier ne peux pas être vide
    if(empty($_FILES['fichier']['name'])){
        exit("Aucun fichier sélectionné.");
    }

    // on test si le fichier est uploadé
    if( !is_uploaded_file($_FILES['fichier']['tmp_name']) ){
        exit("Le fichier n'a pas pu être uploadé.");
    }
   
    // récupération de l'extension du fichier
    $ext = strtolower( pathinfo($_FILES['fichier']['name'],  PATHINFO_EXTENSION) );
   
    // est ce que l'extension est valide ?
    if(!in_array($ext, $extensions_OK)) {
        exit("Le format de votre fichier n'est pas autorisé.");
    }

    // renommons le fichier pour plus de sécurité
    // ceci donne un nom de fichier très dur à trouver
    $name_file = md5( uniqid('H', 5) ).'.'.$ext;

    // upload
    if(!move_uploaded_file($tmp_file,$content_dir.$name_file)){
        exit("Impossible de copier le fichier !");
    }else{
        echo "Le fichier a bien été uploadé";
    }

}
?>


Dans cette exemple, on vérifie que le nom du fichier n'est pas vide, que l'extension est bien valide.
Puis, on le renomme pour avoir un nom de fichier très dur à trouver.


Et maintenant, une fonction PHP d'upload avec une utilisation très simple !
<?php
function upload($_files, $destination_rep)
{
    if(!empty($_files['fichier']['tmp_name']) && !empty($_files['fichier']['name']))
    {
        $tmp_file = $_files['fichier']['tmp_name'];

        //on test si l'upload a reussi
        if(!is_uploaded_file($tmp_file))
            exit('Erreur lors de l\'upload.');

        // on va ajouter une chaine pour rendre le nom du fichier unique et pratiquement introuvable.
        $unikifier = md5( uniqid('H', 5) );
       
        // extension du fichier
        $ext = pathinfo($_FILES['fichier']['name'],  PATHINFO_EXTENSION);

        // nettoyage du nom du fichier (on peux pas d'accents ou d'espace)
        $file_name = $unikifier.'.'.$ext;

        //on déplace le fichier vers notre répertoire de destination
        if(!move_uploaded_file($tmp_file, $destination_rep.$file_name))
            exit("Impossible de déplacer le fichier. Upload annulé.");
        else
            return $file_name;
    }
}


$file_dir = './upload_dir/';

if($_POST || $_FILES)
{
    $file = upload($_FILES, $file_dir);
    echo 'Upload terminé : '.$file;
}
else
{
    echo '
    <form method="post" enctype="multipart/form-data" action="">
        <input type="file" name="fichier" size="30">
        <input type="submit" name="upload" value="Uploader">
    </form>'
;
}
?>



On pourrait allez plus loin ? OUI !
Il faudrait définir le répertoire d'upload dans un endroit NON accessible depuis un navigateur web,
renommer complètement le fichier, vérifié que le fichier ne contient pas (DANS le fichier) du code PHP ou autre, vérifié le type MIME et faire une contre vérification avec l'extension.


Bon upload php !