<?xml version="1.0" encoding="UTF-8"?> <rss
version="2.0"
xmlns:content="http://purl.org/rss/1.0/modules/content/"
xmlns:wfw="http://wellformedweb.org/CommentAPI/"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:atom="http://www.w3.org/2005/Atom"
xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
> <channel><title>Ange Chierchia &#187; PHP/MySQL</title> <atom:link href="http://blog.angechierchia.com/php-mysql/feed/" rel="self" type="application/rss+xml" /><link>http://blog.angechierchia.com</link> <description>Front &#38; Back end Web Designer</description> <lastBuildDate>Thu, 05 Jan 2012 21:15:43 +0000</lastBuildDate> <language>en</language> <sy:updatePeriod>hourly</sy:updatePeriod> <sy:updateFrequency>1</sy:updateFrequency> <generator>http://wordpress.org/?v=</generator> <xhtml:meta xmlns:xhtml="http://www.w3.org/1999/xhtml" name="robots" content="noindex" /> <item><title>Créer son propre &#171;&#160;framework&#160;&#187; PHP, pourquoi ?</title><link>http://blog.angechierchia.com/php-mysql/creer-son-framework-php/</link> <comments>http://blog.angechierchia.com/php-mysql/creer-son-framework-php/#comments</comments> <pubDate>Mon, 12 Dec 2011 07:15:50 +0000</pubDate> <dc:creator>Ange Chierchia</dc:creator> <category><![CDATA[PHP/MySQL]]></category> <category><![CDATA[framework]]></category> <category><![CDATA[PHP]]></category> <guid
isPermaLink="false">http://blog.angechierchia.com/?p=1372</guid> <description><![CDATA[<p><img
width="633" height="120" src="http://blog.angechierchia.com/wp-content/uploads/framework-perso-php.jpg" class="attachment-post-thumbnail wp-post-image" alt="framework-perso-php" title="framework-perso-php" /></p>Cela fait maintenant presque deux ans que je suis entré dans la vie active en tant que développeur et designer Web. Et en tant que tel, je suis souvent (comprenez : tout le temps) amené à faire quasiment les mêmes choses, bien que chaque projet soit différent.
Personnellement j'aime passer du temps à peaufiner un design. je déteste réécrire les mêmes fonctions pour chaque projet. Alors oui, il a les framework, mais pourquoi utiliser un bazooka lorsqu'on doit abattre une mouche ?<span
id="more-1372"></span><p
class="author_note">Attention, l'article est un chouilla trop long (beaucoup de lignes de code).</p> Oui utiliser une CMS déjà tout fait c'est bien, oui utiliser un framework en PHP Objet c'est bien. Seulement parfois, utiliser une arme de destruction massive n'est pas la bonne méthode à appliquer pour régler les choses les plus simples.
Ces dernier mois, au fil des projets qui le permettaient, j'ai pu me construire ma propre bibliothèque de fonctions, en essayant de l'améliorer à chaque itérations, tout en restant le plus générique possible pour permettre une très bonne portabilité de projet en projet. Bien sûr je n'ai pas hésité à piquer des idées dans les frameworks PHP, mais plutôt que de me trimballer toute la clique, j'ai maintenant un petit "framework" qui me permet de faire juste ce dont j'ai besoin. Cela m'a aussi permis de monter facilement notre propre CMS, lui aussi très basique.
Aujourd'hui j'ai donc envie de partager avec vous quelques unes de mes fonctions, car ça fait un petit moment que je n'ai pas publié un peut de code PHP dans mes pages.<h2>Mes fonctions de <abbr
title="Create, Read, Update, Delete">CRUD</abbr></h2> Etape obligatoire lorsqu'on souhaite agir sur des informations stockées en base de données, les célèbres fonctions INSERT, SELECT, UPDATE et DELETE. Après plusieurs itérations je suis arrivé à des fonctions quasiment utilisable par n'importe quel projet, même si je pense qu'elles ne sont pas encore parfaites, pour le moment elles me suffisent. Cependant, si vous avez de quoi les améliorer n'hésitez pas à me donner votre avis !<h3>Ajouter un enregistrement dans une table</h3> Après pas mal de projet dans lesquels j'avais une fonction d'ajout pour chaque type de contenu (page, article, etc.) enregistrés dans des tables différentes, j'ai essayé de trouver un moyen simple d'ajouter n'importe quelle données dans n'importe quelle table. Je suis donc passé de plusieurs fonction plus ou moins lourde à une bête fonction d'une quinzaine de ligne avec laquelle je peux faire ce que je veux, simplement en lui passant un tableau des données à ajouter, et le nom de la table dans laquelle faire cet INSERT.<pre>/***
 *	insert des données dans la table en paramètre
 *	@datas	tableau des données à insérer dont la clé et le nom du champs dans la table
 *	@table	table dans laquelle insérer les données
 */
function add($datas, $table){
	$bdd = db(); //on ouvre la connexion à la base de données
	foreach($datas as $key =&gt; $value){
		$keys[] = $key;
		$values[] = $value;
	}
	$strSQL = "INSERT INTO ".$table." (";
	foreach($keys as $ky =&gt; $k){ $strSQL .= $k . ","; }
	$strSQL = substr($strSQL,0,-1) . ") VALUES(";
	foreach($values as $vl =&gt; $v){ $strSQL .= "?,"; }
	$strSQL = substr($strSQL,0,-1) . ")";
	$query = $bdd-&gt;prepare($strSQL);
	if($query-&gt;execute($values)) return $bdd-&gt;lastInsertId();
	else return false;
}</pre><strong>Comment utiliser la fonction ?</strong> Après avoir vérifiées, échappées, etc., les informations soumisent à mon formulaire, il me suffit de créer un tableau dont les clés seront les noms des champs que je veux renseigner pendant mon INSERT. <em><span
style="text-decoration: underline;">Exemple :</span> je veux renseigner le nom, l'adresse email et le commentaire dans la table "comments".</em><pre>$datas = array(
	'nom' =&gt; $nom,
	'email' =&gt; $email,
	'commentaire' =&gt; $commentaire
);
if(add($datas,'comments')) {
	return "cool";
} else return "pas cool";</pre>Si tout c'est bien passé, la fonction <code>add()</code> me renvoie l'ID de l'enregistrement créé.<h3>Mettre à jour les informations d'un enregistrement</h3> Là aussi, c'est une fonction vraiment très simple. comme ma fonction add(), ma fonction update() requiert un tableau des données et le nom de la table à modifier. Seul petit changement, on doit aussi fournir l'ID de l'enregistrement à modifier.<pre>/***
 *	met à jour les données de l'ID dans la table en paramètre
 *	@id	identifiant de la ligne à modifier
 *	@datas 	tableau des données à insérer dont la clé et le nom du champs dans la table
 *	@table 	table dans laquelle insérer les données
 */
function update($id, $datas, $table){
	$bdd = db();
	foreach($datas as $key =&gt; $value){
		$keys[] = $key;
		$values[] = $value;
	}
	$strSQL = "UPDATE ".$table." SET ";
	foreach($datas as $key =&gt; $value){
		$strSQL .= $key . " = ?,";
	} $strSQL = substr($strSQL,0,-1) . " WHERE id = ?";
	$values[] = $id;
	$query = $bdd-&gt;prepare($strSQL);
	if($query-&gt;execute($values)) return true;
	else return false;
}</pre><h3>Supprimer un enregistrement</h3> Rien de bien compliqué là non plus, on supprime l'enregistrement dont l'ID est passé en paramètre dans la table elle aussi en paramètre.<pre>/***
 *	supprime les données correspondant à l'ID dans la table en paramètre
 *	@id		identifiant de la ligne à supprimer
 *	@table	table sur laquelle on applique la suppression
 */
function delete($id, $table){
	$bdd = db();
	$strSQL = "DELETE FROM ".$table." WHERE id = ?";
	$query = $bdd-&gt;prepare($strSQL);
	//print_r(array($id));
	if($query-&gt;execute(array($id))) return true;
	else return false;
}</pre><h3>Retourner une liste d'enregistrements</h3> Cette dernière est l'une des fonctions que j'ai eu le plus de mal à rendre générique tout en me permettant de faire beaucoup de choses avec, comme par exemple préparer le terrain pour l'utiliser dans le cadre des données scindées sur plusieurs pages.
Ici ma fonction me permet de récupérer à la fois les enregistrements de ma requête, le total d'enregistrements que retournerai ma requête si aucun paramètre LIMIT n'était renseigné, la requête exécutée (pour les tests en phase de développement) ou les erreurs possibles quant à l'exécution de cette requête.<pre>/***
 * 	retourne le resultat d'un select
 *	@columns 	colonnes à selectionner pour la requête (ex: array('champ1','champ2') ou '*')
 *	@table 		nom de la table sur laquelle faire la requête
 *	@where 		champs sur lequels appliquer des conditions ( ex: array( 'champ1 =' =&gt; 'valeur', 'champ2 LIKE' =&gt; 'valeur%') )
 *	@concats 	[ AND | OR ]
 *	@order 		champs sur lequels appliquer le tri, et l'ordre pour chaque champs (ex: array('champ1' =&gt; 'ASC','champ2' =&gt; 'DESC') )
 *	@limit 		limit[0] =&gt; debut de la liste, limit[1] =&gt; nombre d'éléments dans la liste retournée (ex: array('0','20') )
 *
 *	return @retour	: tableau contenant la requête executée, les éventuelles erreurs et le resultat de la requête
 */
function get($columns = null, $table = null, $where = null, $concats = "AND", $order = null, $limit = null){
	$bdd = db();
	$retour = array(); //variable de type tableau, retournée par la fonction
	$rows = "";
	$clause = "";
	$sort = "";
	$limitStr = "";
	if(!is_null($columns) &amp;&amp; !is_null($table)){
		// si $rows est un tableau ou égale à * tout va bien.
		if(is_array($columns)){
			foreach($columns as $column) { $rows .= $column .', '; }
			$rows = substr($rows,0,-2);
		} elseif($columns == '*'){
			$rows = '*';
		} else {
			$retour['erreur'] = "Les champs selectionné doivent être appelé depuis une variable Tableau";
		}
		if(!in_array(strtolower($concats),array('and','or'))){
			$retour['erreur'] = "&lt;strong&gt;".$concats."&lt;/strong&gt; n'est pas une valeur autorisée pour concaténer des conditions. Utilisez 'OR' ou 'AND'.";
		}
		/*
		si @where est renseigné, on filtre les résultats grâce au tableau @where construit comme suit :
			array ('colname operateur' =&gt; 'valeur');
			ex: array('page_id =' =&gt; 5);
		sinon, on ne filtre pas les résultats
		*/
		if(!is_null($where) &amp;&amp; is_array($where)){
			foreach($where as $k =&gt; $v){
				$clause .= $k." ? ".$concats." ";
				$values[] = $v;
			}
			$clause = " WHERE ".substr($clause,0,(-(strlen($concats)+2)));
		} elseif(!is_null($where) &amp;&amp; !is_array($where)){
			$retour['erreur'] = "La clause WHERE doit être construite via une variable Tableau";
		} else {
			$clause = "";
		}
		//si $order est un tableau et n'est pas null
		if(!is_null($order) &amp;&amp; is_array($order)){
			foreach($order as $k =&gt; $v){ $sort .= $k." ".$v.", "; }
			$sort = " ORDER BY ".substr($sort,0,-2);
		} elseif(!is_null($order) &amp;&amp; !is_array($order)) {
			$retour['erreur'] = "ORDER BY doit être construit via une variable Tableau";
		} else {
			$sort = "";
		}
		if(!is_null($limit) &amp;&amp; is_array($limit) &amp;&amp; is_numeric($limit[0]) &amp;&amp; is_numeric($limit[1])){
			$debut = $limit[0];
			$nbRows = $limit[1];
			$limitStr = " LIMIT " . $debut . "," . $nbRows;
		} elseif(!is_null($limit) &amp;&amp; !is_array($limit)){
			$retour['erreur'] = "LIMIT doit être construit via un tableau de deux entiers";
		} else {
			$limitStr = "";
		}
		// on construit la requête
		$strSQL = "SELECT ".$rows." FROM ".$table.$clause.$sort.$limitStr;
		if(empty($retour['erreur'])){
			$query = $bdd-&gt;prepare($strSQL);
			$query-&gt;execute(@$values);
			$retour['requete'] = $strSQL;
			$retour['reponse'] = $query-&gt;fetchAll(PDO::FETCH_ASSOC);
			$sqlTotal = "SELECT COUNT(*) as total FROM ".$table.$clause.$sort;
			$q = $bdd-&gt;prepare($sqlTotal);
			$q-&gt;execute(@$values);
			$tot = $q-&gt;fetchAll(PDO::FETCH_ASSOC);
			$retour['total'] = $tot[0]['total'];
		}
	} else {
		$retour['erreur'] = "Impossible de créer la requete, les champs à selectionner et la table sont vide";
	}
	return $retour;
}</pre><strong>Comment utiliser la fonction ?</strong> <em><span
style="text-decoration: underline;">Exemple :</span> Je veux récupérer les cinq articles les plus récents écrits par nighcrawl dont le titre contient le mot "framework" publié depuis la date à laquelle la requête est exécutée.</em><pre>$champs = array('id','titre','nom','contenu');
$conditions = array(
	'nom =' =&gt; 'nighcrawl',
	'date &lt; =' =&gt; date('Y-m-d H:i:s'),
	'titre LIKE' =&gt; '%framework%'
);
$trier = array('date' =&gt; 'DESC');
$limite = array(0, 5);
$resultat = get($champs,'articles',$conditions,"AND",$trier,$limite);
if(isset($resultat['reponse'])){
	foreach($resultat['reponse'] as $row){
		echo "&lt;article&gt;
		&lt;header&gt;
			&lt;h1&gt;".$row['titre']."&lt;/h1&gt;
		&lt;/header&gt;
		&lt;div&gt;".$row['contenu']."&lt;/div&gt;
		&lt;footer&gt;Auteur : ".$row['nom']."&lt;/footer&gt;
		&lt;/article&gt;";
	}
}
else echo $resultat['erreur'];</pre><h2>Mettre en place un système de pagination</h2> Je m'arrêterai ici parce que l'article est déjà pas mal long, et si vous êtes arrivé jusqu'ici je vous dis chapeau. Personnellement je me serai déjà arrêté :). On fini donc avec une fonction très utile pour générer rapidement des liens de pagination afin de répartir les données d'une requête sur plusieurs pages. Voici donc la belle fonction :<pre>/***
 *	génère des liens de pagination : numeros de pages, 'suivants', 'précédents'
 *	@total	nombre total d'enregistremnts à paginer
 *	@nbpp	nombre d'enregistrements à afficher par page
 *	@link	chaine qui servira à construire les liens vers les différentes pages
 */
function pagination($total, $nbpp, $link){
	echo"&lt;div class='pagination'&gt;";
		/** Pagination **/
		//calcul du nombre de pages
		$nbLiens = ceil($total/$nbpp);
		if($nbLiens &gt; 1){
			/** précédents **/
			if(isset($_GET['d']) &amp;&amp; $_GET['d'] &gt; 0){
				echo "&lt;a href='".$link.($_GET['d']-$nbpp)."'&gt;« Précédents&lt;/a&gt;";
			} else {
				echo "&lt;span&gt;« Précédents&lt;/span&gt;";
			}
			/** pages ***/
			for($i = 0; $i &lt; $nbLiens; $i++){
				if($_GET['d'] == ($i*$nbpp)){
					echo "&lt;span class='active_pagi'&gt;".($i+1)."";
				} else {
					echo "&lt;a href='".$link.($i*$nbpp)."'&gt;".($i+1)."&lt;/a&gt;";
				}
			}
			/** suivants **/
			if(isset($_GET['d']) &amp;&amp; $_GET['d'] &gt;= 0 &amp;&amp; $_GET['d'] &lt; ($total-$nbpp)){
				echo "&lt;a href='".$link.($_GET['d']+$nbpp)."'&gt;Suivants »&lt;/a&gt;";
			} else {
				echo "&lt;span&gt;Suivants »&lt;/span&gt;";
			}
		}
	echo "&lt;/div&gt;";
}</pre>La pagination va s'effectuée en deux temps, d'abord l'appel de la fonction get(), puis l'appel de la fonction pagination(). Si on réutilise l'exemple précédent :<pre>$nbpp = 5; //5 articles par page
$limite = array(intval($_GET['d']),$nbpp);
$resultat = get($champs,'articles',$conditions,"AND",$trier,$limite);
if(isset($resultat['reponse'])){
	foreach ($resultat as $row) {
		//affichage des articles
		...
	}
	pagination($resultat['total'],$nbpp,'index.php?parametre=valeur&amp;d=');
} else echo $resultat['erreur'];</pre><h2>Fin !</h2> Merci de m'avoir lu jusqu'au bout. Je vous libère ici ! En espérant que ces quelques fonctions puissent vous être utiles. Elles ne sont pas parfaites et certaines pourraient être encore améliorées, alors si vous avez des idées, n'hésitez pas à les partager dans les commentaires.]]></description> <content:encoded><![CDATA[<p><img
width="633" height="120" src="http://blog.angechierchia.com/wp-content/uploads/framework-perso-php.jpg" class="attachment-post-thumbnail wp-post-image" alt="framework-perso-php" title="framework-perso-php" /></p>Cela fait maintenant presque deux ans que je suis entré dans la vie active en tant que développeur et designer Web. Et en tant que tel, je suis souvent (comprenez : tout le temps) amené à faire quasiment les mêmes choses, bien que chaque projet soit différent.
Personnellement j'aime passer du temps à peaufiner un design. je déteste réécrire les mêmes fonctions pour chaque projet. Alors oui, il a les framework, mais pourquoi utiliser un bazooka lorsqu'on doit abattre une mouche ?<span
id="more-1372"></span><p
class="author_note">Attention, l'article est un chouilla trop long (beaucoup de lignes de code).</p> Oui utiliser une CMS déjà tout fait c'est bien, oui utiliser un framework en PHP Objet c'est bien. Seulement parfois, utiliser une arme de destruction massive n'est pas la bonne méthode à appliquer pour régler les choses les plus simples.
Ces dernier mois, au fil des projets qui le permettaient, j'ai pu me construire ma propre bibliothèque de fonctions, en essayant de l'améliorer à chaque itérations, tout en restant le plus générique possible pour permettre une très bonne portabilité de projet en projet. Bien sûr je n'ai pas hésité à piquer des idées dans les frameworks PHP, mais plutôt que de me trimballer toute la clique, j'ai maintenant un petit "framework" qui me permet de faire juste ce dont j'ai besoin. Cela m'a aussi permis de monter facilement notre propre CMS, lui aussi très basique.
Aujourd'hui j'ai donc envie de partager avec vous quelques unes de mes fonctions, car ça fait un petit moment que je n'ai pas publié un peut de code PHP dans mes pages.<h2>Mes fonctions de <abbr
title="Create, Read, Update, Delete">CRUD</abbr></h2> Etape obligatoire lorsqu'on souhaite agir sur des informations stockées en base de données, les célèbres fonctions INSERT, SELECT, UPDATE et DELETE. Après plusieurs itérations je suis arrivé à des fonctions quasiment utilisable par n'importe quel projet, même si je pense qu'elles ne sont pas encore parfaites, pour le moment elles me suffisent. Cependant, si vous avez de quoi les améliorer n'hésitez pas à me donner votre avis !<h3>Ajouter un enregistrement dans une table</h3> Après pas mal de projet dans lesquels j'avais une fonction d'ajout pour chaque type de contenu (page, article, etc.) enregistrés dans des tables différentes, j'ai essayé de trouver un moyen simple d'ajouter n'importe quelle données dans n'importe quelle table. Je suis donc passé de plusieurs fonction plus ou moins lourde à une bête fonction d'une quinzaine de ligne avec laquelle je peux faire ce que je veux, simplement en lui passant un tableau des données à ajouter, et le nom de la table dans laquelle faire cet INSERT.<pre>/***
 *	insert des données dans la table en paramètre
 *	@datas	tableau des données à insérer dont la clé et le nom du champs dans la table
 *	@table	table dans laquelle insérer les données
 */
function add($datas, $table){
	$bdd = db(); //on ouvre la connexion à la base de données
	foreach($datas as $key =&gt; $value){
		$keys[] = $key;
		$values[] = $value;
	}
	$strSQL = "INSERT INTO ".$table." (";
	foreach($keys as $ky =&gt; $k){ $strSQL .= $k . ","; }
	$strSQL = substr($strSQL,0,-1) . ") VALUES(";
	foreach($values as $vl =&gt; $v){ $strSQL .= "?,"; }
	$strSQL = substr($strSQL,0,-1) . ")";
	$query = $bdd-&gt;prepare($strSQL);
	if($query-&gt;execute($values)) return $bdd-&gt;lastInsertId();
	else return false;
}</pre><strong>Comment utiliser la fonction ?</strong> Après avoir vérifiées, échappées, etc., les informations soumisent à mon formulaire, il me suffit de créer un tableau dont les clés seront les noms des champs que je veux renseigner pendant mon INSERT. <em><span
style="text-decoration: underline;">Exemple :</span> je veux renseigner le nom, l'adresse email et le commentaire dans la table "comments".</em><pre>$datas = array(
	'nom' =&gt; $nom,
	'email' =&gt; $email,
	'commentaire' =&gt; $commentaire
);
if(add($datas,'comments')) {
	return "cool";
} else return "pas cool";</pre>Si tout c'est bien passé, la fonction <code>add()</code> me renvoie l'ID de l'enregistrement créé.<h3>Mettre à jour les informations d'un enregistrement</h3> Là aussi, c'est une fonction vraiment très simple. comme ma fonction add(), ma fonction update() requiert un tableau des données et le nom de la table à modifier. Seul petit changement, on doit aussi fournir l'ID de l'enregistrement à modifier.<pre>/***
 *	met à jour les données de l'ID dans la table en paramètre
 *	@id	identifiant de la ligne à modifier
 *	@datas 	tableau des données à insérer dont la clé et le nom du champs dans la table
 *	@table 	table dans laquelle insérer les données
 */
function update($id, $datas, $table){
	$bdd = db();
	foreach($datas as $key =&gt; $value){
		$keys[] = $key;
		$values[] = $value;
	}
	$strSQL = "UPDATE ".$table." SET ";
	foreach($datas as $key =&gt; $value){
		$strSQL .= $key . " = ?,";
	} $strSQL = substr($strSQL,0,-1) . " WHERE id = ?";
	$values[] = $id;
	$query = $bdd-&gt;prepare($strSQL);
	if($query-&gt;execute($values)) return true;
	else return false;
}</pre><h3>Supprimer un enregistrement</h3> Rien de bien compliqué là non plus, on supprime l'enregistrement dont l'ID est passé en paramètre dans la table elle aussi en paramètre.<pre>/***
 *	supprime les données correspondant à l'ID dans la table en paramètre
 *	@id		identifiant de la ligne à supprimer
 *	@table	table sur laquelle on applique la suppression
 */
function delete($id, $table){
	$bdd = db();
	$strSQL = "DELETE FROM ".$table." WHERE id = ?";
	$query = $bdd-&gt;prepare($strSQL);
	//print_r(array($id));
	if($query-&gt;execute(array($id))) return true;
	else return false;
}</pre><h3>Retourner une liste d'enregistrements</h3> Cette dernière est l'une des fonctions que j'ai eu le plus de mal à rendre générique tout en me permettant de faire beaucoup de choses avec, comme par exemple préparer le terrain pour l'utiliser dans le cadre des données scindées sur plusieurs pages.
Ici ma fonction me permet de récupérer à la fois les enregistrements de ma requête, le total d'enregistrements que retournerai ma requête si aucun paramètre LIMIT n'était renseigné, la requête exécutée (pour les tests en phase de développement) ou les erreurs possibles quant à l'exécution de cette requête.<pre>/***
 * 	retourne le resultat d'un select
 *	@columns 	colonnes à selectionner pour la requête (ex: array('champ1','champ2') ou '*')
 *	@table 		nom de la table sur laquelle faire la requête
 *	@where 		champs sur lequels appliquer des conditions ( ex: array( 'champ1 =' =&gt; 'valeur', 'champ2 LIKE' =&gt; 'valeur%') )
 *	@concats 	[ AND | OR ]
 *	@order 		champs sur lequels appliquer le tri, et l'ordre pour chaque champs (ex: array('champ1' =&gt; 'ASC','champ2' =&gt; 'DESC') )
 *	@limit 		limit[0] =&gt; debut de la liste, limit[1] =&gt; nombre d'éléments dans la liste retournée (ex: array('0','20') )
 *
 *	return @retour	: tableau contenant la requête executée, les éventuelles erreurs et le resultat de la requête
 */
function get($columns = null, $table = null, $where = null, $concats = "AND", $order = null, $limit = null){
	$bdd = db();
	$retour = array(); //variable de type tableau, retournée par la fonction
	$rows = "";
	$clause = "";
	$sort = "";
	$limitStr = "";
	if(!is_null($columns) &amp;&amp; !is_null($table)){
		// si $rows est un tableau ou égale à * tout va bien.
		if(is_array($columns)){
			foreach($columns as $column) { $rows .= $column .', '; }
			$rows = substr($rows,0,-2);
		} elseif($columns == '*'){
			$rows = '*';
		} else {
			$retour['erreur'] = "Les champs selectionné doivent être appelé depuis une variable Tableau";
		}
		if(!in_array(strtolower($concats),array('and','or'))){
			$retour['erreur'] = "&lt;strong&gt;".$concats."&lt;/strong&gt; n'est pas une valeur autorisée pour concaténer des conditions. Utilisez 'OR' ou 'AND'.";
		}
		/*
		si @where est renseigné, on filtre les résultats grâce au tableau @where construit comme suit :
			array ('colname operateur' =&gt; 'valeur');
			ex: array('page_id =' =&gt; 5);
		sinon, on ne filtre pas les résultats
		*/
		if(!is_null($where) &amp;&amp; is_array($where)){
			foreach($where as $k =&gt; $v){
				$clause .= $k." ? ".$concats." ";
				$values[] = $v;
			}
			$clause = " WHERE ".substr($clause,0,(-(strlen($concats)+2)));
		} elseif(!is_null($where) &amp;&amp; !is_array($where)){
			$retour['erreur'] = "La clause WHERE doit être construite via une variable Tableau";
		} else {
			$clause = "";
		}
		//si $order est un tableau et n'est pas null
		if(!is_null($order) &amp;&amp; is_array($order)){
			foreach($order as $k =&gt; $v){ $sort .= $k." ".$v.", "; }
			$sort = " ORDER BY ".substr($sort,0,-2);
		} elseif(!is_null($order) &amp;&amp; !is_array($order)) {
			$retour['erreur'] = "ORDER BY doit être construit via une variable Tableau";
		} else {
			$sort = "";
		}
		if(!is_null($limit) &amp;&amp; is_array($limit) &amp;&amp; is_numeric($limit[0]) &amp;&amp; is_numeric($limit[1])){
			$debut = $limit[0];
			$nbRows = $limit[1];
			$limitStr = " LIMIT " . $debut . "," . $nbRows;
		} elseif(!is_null($limit) &amp;&amp; !is_array($limit)){
			$retour['erreur'] = "LIMIT doit être construit via un tableau de deux entiers";
		} else {
			$limitStr = "";
		}
		// on construit la requête
		$strSQL = "SELECT ".$rows." FROM ".$table.$clause.$sort.$limitStr;
		if(empty($retour['erreur'])){
			$query = $bdd-&gt;prepare($strSQL);
			$query-&gt;execute(@$values);
			$retour['requete'] = $strSQL;
			$retour['reponse'] = $query-&gt;fetchAll(PDO::FETCH_ASSOC);
			$sqlTotal = "SELECT COUNT(*) as total FROM ".$table.$clause.$sort;
			$q = $bdd-&gt;prepare($sqlTotal);
			$q-&gt;execute(@$values);
			$tot = $q-&gt;fetchAll(PDO::FETCH_ASSOC);
			$retour['total'] = $tot[0]['total'];
		}
	} else {
		$retour['erreur'] = "Impossible de créer la requete, les champs à selectionner et la table sont vide";
	}
	return $retour;
}</pre><strong>Comment utiliser la fonction ?</strong> <em><span
style="text-decoration: underline;">Exemple :</span> Je veux récupérer les cinq articles les plus récents écrits par nighcrawl dont le titre contient le mot "framework" publié depuis la date à laquelle la requête est exécutée.</em><pre>$champs = array('id','titre','nom','contenu');
$conditions = array(
	'nom =' =&gt; 'nighcrawl',
	'date &lt; =' =&gt; date('Y-m-d H:i:s'),
	'titre LIKE' =&gt; '%framework%'
);
$trier = array('date' =&gt; 'DESC');
$limite = array(0, 5);
$resultat = get($champs,'articles',$conditions,"AND",$trier,$limite);
if(isset($resultat['reponse'])){
	foreach($resultat['reponse'] as $row){
		echo "&lt;article&gt;
		&lt;header&gt;
			&lt;h1&gt;".$row['titre']."&lt;/h1&gt;
		&lt;/header&gt;
		&lt;div&gt;".$row['contenu']."&lt;/div&gt;
		&lt;footer&gt;Auteur : ".$row['nom']."&lt;/footer&gt;
		&lt;/article&gt;";
	}
}
else echo $resultat['erreur'];</pre><h2>Mettre en place un système de pagination</h2> Je m'arrêterai ici parce que l'article est déjà pas mal long, et si vous êtes arrivé jusqu'ici je vous dis chapeau. Personnellement je me serai déjà arrêté :). On fini donc avec une fonction très utile pour générer rapidement des liens de pagination afin de répartir les données d'une requête sur plusieurs pages. Voici donc la belle fonction :<pre>/***
 *	génère des liens de pagination : numeros de pages, 'suivants', 'précédents'
 *	@total	nombre total d'enregistremnts à paginer
 *	@nbpp	nombre d'enregistrements à afficher par page
 *	@link	chaine qui servira à construire les liens vers les différentes pages
 */
function pagination($total, $nbpp, $link){
	echo"&lt;div class='pagination'&gt;";
		/** Pagination **/
		//calcul du nombre de pages
		$nbLiens = ceil($total/$nbpp);
		if($nbLiens &gt; 1){
			/** précédents **/
			if(isset($_GET['d']) &amp;&amp; $_GET['d'] &gt; 0){
				echo "&lt;a href='".$link.($_GET['d']-$nbpp)."'&gt;« Précédents&lt;/a&gt;";
			} else {
				echo "&lt;span&gt;« Précédents&lt;/span&gt;";
			}
			/** pages ***/
			for($i = 0; $i &lt; $nbLiens; $i++){
				if($_GET['d'] == ($i*$nbpp)){
					echo "&lt;span class='active_pagi'&gt;".($i+1)."";
				} else {
					echo "&lt;a href='".$link.($i*$nbpp)."'&gt;".($i+1)."&lt;/a&gt;";
				}
			}
			/** suivants **/
			if(isset($_GET['d']) &amp;&amp; $_GET['d'] &gt;= 0 &amp;&amp; $_GET['d'] &lt; ($total-$nbpp)){
				echo "&lt;a href='".$link.($_GET['d']+$nbpp)."'&gt;Suivants »&lt;/a&gt;";
			} else {
				echo "&lt;span&gt;Suivants »&lt;/span&gt;";
			}
		}
	echo "&lt;/div&gt;";
}</pre>La pagination va s'effectuée en deux temps, d'abord l'appel de la fonction get(), puis l'appel de la fonction pagination(). Si on réutilise l'exemple précédent :<pre>$nbpp = 5; //5 articles par page
$limite = array(intval($_GET['d']),$nbpp);
$resultat = get($champs,'articles',$conditions,"AND",$trier,$limite);
if(isset($resultat['reponse'])){
	foreach ($resultat as $row) {
		//affichage des articles
		...
	}
	pagination($resultat['total'],$nbpp,'index.php?parametre=valeur&amp;d=');
} else echo $resultat['erreur'];</pre><h2>Fin !</h2> Merci de m'avoir lu jusqu'au bout. Je vous libère ici ! En espérant que ces quelques fonctions puissent vous être utiles. Elles ne sont pas parfaites et certaines pourraient être encore améliorées, alors si vous avez des idées, n'hésitez pas à les partager dans les commentaires.]]></content:encoded> <wfw:commentRss>http://blog.angechierchia.com/php-mysql/creer-son-framework-php/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Moteurs de templates : fausse bonne idée ?</title><link>http://blog.angechierchia.com/php-mysql/reflexion-sur-les-moteurs-de-templates/</link> <comments>http://blog.angechierchia.com/php-mysql/reflexion-sur-les-moteurs-de-templates/#comments</comments> <pubDate>Mon, 31 Oct 2011 08:24:56 +0000</pubDate> <dc:creator>Ange Chierchia</dc:creator> <category><![CDATA[PHP/MySQL]]></category> <category><![CDATA[CodeIgniter]]></category> <category><![CDATA[framework]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[template]]></category> <guid
isPermaLink="false">http://blog.angechierchia.com/?p=1338</guid> <description><![CDATA[Aujourd&#8217;hui, j&#8217;inaugure le &#171;&#160;Guest blogging&#160;&#187; avec un article vraiment très intéressant de Nicolas Torres sur l&#8217;intérêt mais aussi et surtout les &#171;&#160;pièges&#160;&#187; à éviter lorsqu&#8217;on utilise un moteur de templates (comme Smarty par exemple). PHP se suffit à lui-même pour effectuer du templating, en déclarant toutes les variables dans un fichiers de traitement, et en les [...]]]></description> <content:encoded><![CDATA[<p><span
class="author_note">Aujourd&#8217;hui, j&#8217;inaugure le &laquo;&nbsp;Guest blogging&nbsp;&raquo; avec un article vraiment très intéressant de <a
title="Nicolas Torres, élève ingénieur passionné de Web design" href="http://ntorres.me" target="_blank">Nicolas Torres</a> sur l&#8217;intérêt mais aussi et surtout les &laquo;&nbsp;pièges&nbsp;&raquo; à éviter lorsqu&#8217;on utilise un moteur de templates (comme Smarty par exemple).</span></p><p><span
id="more-1338"></span></p><p>PHP se suffit à lui-même pour effectuer du <em>templating</em>, en déclarant toutes les variables dans un fichiers de traitement, et en les appelant dans un fichier d&#8217;affichage inclus à la fin du traitement. Pourquoi les développeurs utilisent-ils alors une surcouche ?</p><h2>Mauvaises excuses</h2><p>J&#8217;ai souvent entendu &laquo;&nbsp;pour que celui qui s&#8217;occupe de l&#8217;affichage n&#8217;aie pas besoin de connaissances en PHP&nbsp;&raquo; ou &laquo;&nbsp;pour appliquer simplement un cache par fichier &laquo;&nbsp;parsé&nbsp;&raquo; (inclus et interprété)&nbsp;&raquo;.</p><p>Effectivement la plupart de ces moteurs recréent une syntaxe simplifiée qui raccourcis le temps de codage et permettent une meilleur lisibilité du code telle que :</p><pre lang="php">{variable}</pre><p>au lieu de :</p><pre lang="php" escaped="true">&lt;?php echo $variable; ?&gt;</pre><h2>La faiblesse d&#8217;un tel procédé</h2><p>&laquo;&nbsp;Parser&nbsp;&raquo;, c&#8217;est consommer. Pour pouvoir interpréter correctement la syntaxe il faut utiliser des procédés de réécriture qui pèsent au chargement. Heureusement, lorsque le script est bien conçu, on n&#8217;effectue cette réécriture (compilation) qu&#8217;une seule fois après chaque modification du fichier <em>template</em>. Cela dit pour celui sur qui ça tombe, un mauvais &laquo;&nbsp;parseur&nbsp;&raquo; peut entraîner un lourd ralentissement pour une simple page.</p><p>Les programmeurs aimant bien s&#8217;inventer leur propre syntaxe et l&#8217;optimiser pour leur utilisation, ils sont parfois trop gourmands et confèrent à celle-ci bien plus de portée qu&#8217;elle ne devrait en posséder.</p><p>En effet certains ont tendance à vouloir appliquer des fonctions (<code>date()</code>, <code>htmlspecialchars_decode()</code>, <code>nl2br()</code>) au moment de l&#8217;appel de la variable. Hors il s&#8217;agit de traitement, et le traitement des données <strong>doit </strong>s&#8217;effectuer <strong>avant </strong>l&#8217;affichage.</p><p>Plus la syntaxe est développée, moins elle a d&#8217;intérêt, puisque son seul but est de <strong>diminuer le temps de codage</strong> et de <strong>gagner en lisibilité</strong>. J&#8217;ai souvent vu des moteurs utiliser une syntaxe XML telle que :</p><pre lang="php" escaped="true">&lt;foreach nom="nom_du_bloc"&gt;
    &lt;var nom="variable" /&gt;
&lt;/foreach&gt;</pre><p>qui possède un rapport performance/confort relativement faible par rapport à la syntaxe native :</p><pre lang="php" escaped="true">&lt;?php foreach ($nom_du_bloc as $row) : ?&gt;
    &lt;?php echo $row['variable']; ?&gt;
&lt;?php endforeach; ?&gt;</pre><p>A noter que la syntaxe PHP permet bien plus de souplesse dans la déclaration d&#8217;une boucle (concaténation, et &laquo;&nbsp;variable double&nbsp;&raquo; (<code>$$variable</code>) autorisées).</p><p>De plus, le cache peut être totalement indépendant. Il n&#8217;est donc pas nécessaire de passer par un moteur de <em>templates </em>pour pouvoir en appliquer un.</p><h2>Les bonnes pratiques</h2><p>On utilise un tel outil pour <strong>séparer le traitement de l&#8217;affichage</strong>, et optionnellement pour <strong>minimiser son code</strong> et le rendre <strong>plus clair</strong>.</p><p>Plusieurs approches sont alors pertinentes face à la question des performances. C&#8217;est certain, regrouper ses variables dans une &laquo;&nbsp;boîte noire&nbsp;&raquo;, loin des variables servant uniquement au traitement, est dans une certaine mesure très agréable. Mais avant de se jeter sur un moteur de <em>templates</em>, rélféchissez<em> </em>à quelle quantité de performance vous êtes prêt à céder.</p><h3>Un moteur sans syntaxe personnalisée</h3><p>C&#8217;est la solution la moins onéreuse. Le fameux framework <a
style="color: #ff1493;" href="http://codeigniter.com/">CodeIgniter</a> y a établi son camp. Pour gagner en confort, il est conseillé de trouver une solution pour séparer ses variables d&#8217;affichage à celles de traitement. L&#8217;une d&#8217;entre elles est de stocker ses variables dans un objet et inclure le fichier <em>template </em>dans une méthode en utilisant la fonction <a
style="color: #ff1493;" href="http://php.net/manual/fr/function.extract.php"><em>extract()</em></a>.</p><h3>Un moteur à syntaxe</h3><p>Prudence. Assurez-vous d&#8217;avoir une syntaxe suffisamment légère, et peu de fonctionnalités. Un moteur mettant à disposition l&#8217;appel de fonctions dans sa syntaxe doit être scrupuleusement analysé avant d&#8217;être employé. Le minimum nécessaire ? Appel de variables, boucles (appel de blocs) et conditions. Vérifiez que <code>preg_replace()</code>, <code>preg_replace_callback()</code> et <code>preg_match_all()</code> sont utilisées avec parcimonie car ils consomment des quantités astronomiques de performances.</p><h2>Conclusion</h2><p>Je ne me veux pas exhaustif sinon <strong>préventif </strong>quant à l&#8217;optimisation des performances. Avouez qu&#8217;écrire autant de code aussi complexe et moins souple que PHP pour perdre en performance est dénué de sens. Il est préconisé de chercher l&#8217;équilibre entre la performance et le confort, et enfin de garder en tête que le traitement n&#8217;est pas du ressort de l&#8217;affichage.</p> ]]></content:encoded> <wfw:commentRss>http://blog.angechierchia.com/php-mysql/reflexion-sur-les-moteurs-de-templates/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Expressions régulières avec MySQL</title><link>http://blog.angechierchia.com/php-mysql/expressions-regulieres-avec-mysql/</link> <comments>http://blog.angechierchia.com/php-mysql/expressions-regulieres-avec-mysql/#comments</comments> <pubDate>Fri, 22 Jul 2011 19:08:08 +0000</pubDate> <dc:creator>Ange Chierchia</dc:creator> <category><![CDATA[PHP/MySQL]]></category> <category><![CDATA[astuce]]></category> <category><![CDATA[expression reguliere]]></category> <category><![CDATA[MySQL]]></category> <category><![CDATA[regexp]]></category> <guid
isPermaLink="false">http://blog.angechierchia.com/?p=1252</guid> <description><![CDATA[<p><img
width="633" height="120" src="http://blog.angechierchia.com/wp-content/uploads/thumb-sql-regex.jpg" class="attachment-post-thumbnail wp-post-image" alt="thumb-sql-regex" title="thumb-sql-regex" /></p>Petite trouvaille du vendredi: Exécuter des requêtes MySQL pleine d'expressions régulières. Cette après midi, en faisant un petit tour dans la base de données des inscrits à la newsletter de CBC qui avait bien besoin d'un clean up afin de supprimer les adresses e-mails invalides <del>qu'on se trimbale à cause d'un formulaire d'inscription vraiment mal géré développé avant mon arrivé dans la boîte</del>.<span
id="more-1252"></span> Du coup, je cherchais un moyen de supprimer les adresses mails mal formatées qu'on trimbale, et par la même occasion, récupérer seulement les adresses mails bien formatées lors de l'envoi de la newsletter, en attendant que l'on fasse un beau remodeling du site actuel<del>, qui en a vraiment besoin, c'est carrément une question de bon sens, il est tellement affreux... (gros fail quoi, pour une boîte "à la pointe")</del>.
Du coup, je m'suis demandé tout bêtement, si MySQL prenait en compte les expressions régulières, ce qui m'aurai facilité le travail. Et bien sachez le, c'est carrément possible (youpi!) et super simple à mettre en oeuvre en plus. Voilà comment :<h3>Dans un SELECT</h3> Utile si vous voulez récupérer tous les champs validant l'expression régulière<pre>SELECT 'fofo' REGEXP '^fo' FROM table;</pre><h3>Dans une clause WHERE</h3> En fait, ça ne change pas grand chose<pre>SELECT champ FROM table WHERE champ REGEXP '^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$' AND champ2 REGEXP '(chouette|cool|super)'</pre>Alors, heureux? ;)]]></description> <content:encoded><![CDATA[<p><img
width="633" height="120" src="http://blog.angechierchia.com/wp-content/uploads/thumb-sql-regex.jpg" class="attachment-post-thumbnail wp-post-image" alt="thumb-sql-regex" title="thumb-sql-regex" /></p>Petite trouvaille du vendredi: Exécuter des requêtes MySQL pleine d'expressions régulières. Cette après midi, en faisant un petit tour dans la base de données des inscrits à la newsletter de CBC qui avait bien besoin d'un clean up afin de supprimer les adresses e-mails invalides <del>qu'on se trimbale à cause d'un formulaire d'inscription vraiment mal géré développé avant mon arrivé dans la boîte</del>.<span
id="more-1252"></span> Du coup, je cherchais un moyen de supprimer les adresses mails mal formatées qu'on trimbale, et par la même occasion, récupérer seulement les adresses mails bien formatées lors de l'envoi de la newsletter, en attendant que l'on fasse un beau remodeling du site actuel<del>, qui en a vraiment besoin, c'est carrément une question de bon sens, il est tellement affreux... (gros fail quoi, pour une boîte "à la pointe")</del>.
Du coup, je m'suis demandé tout bêtement, si MySQL prenait en compte les expressions régulières, ce qui m'aurai facilité le travail. Et bien sachez le, c'est carrément possible (youpi!) et super simple à mettre en oeuvre en plus. Voilà comment :<h3>Dans un SELECT</h3> Utile si vous voulez récupérer tous les champs validant l'expression régulière<pre>SELECT 'fofo' REGEXP '^fo' FROM table;</pre><h3>Dans une clause WHERE</h3> En fait, ça ne change pas grand chose<pre>SELECT champ FROM table WHERE champ REGEXP '^([a-z0-9_\\.-]+)@([\\da-z\\.-]+)\\.([a-z\\.]{2,6})$' AND champ2 REGEXP '(chouette|cool|super)'</pre>Alors, heureux? ;)]]></content:encoded> <wfw:commentRss>http://blog.angechierchia.com/php-mysql/expressions-regulieres-avec-mysql/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Générer un mot de passe aléatoirement</title><link>http://blog.angechierchia.com/php-mysql/generer-un-mot-de-passe-aleatoirement/</link> <comments>http://blog.angechierchia.com/php-mysql/generer-un-mot-de-passe-aleatoirement/#comments</comments> <pubDate>Fri, 08 Jul 2011 16:47:47 +0000</pubDate> <dc:creator>Ange Chierchia</dc:creator> <category><![CDATA[PHP/MySQL]]></category> <category><![CDATA[chaine aléatoire]]></category> <category><![CDATA[function]]></category> <category><![CDATA[mot de passe]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[rand()]]></category> <category><![CDATA[sécurité]]></category> <category><![CDATA[shuffle()]]></category> <guid
isPermaLink="false">http://blog.angechierchia.com/?p=1240</guid> <description><![CDATA[<p><img
width="2480" height="3508" src="http://blog.angechierchia.com/wp-content/uploads/1159613_851208571.jpg" class="attachment-post-thumbnail wp-post-image" alt="1159613_85120857" title="1159613_85120857" /></p>Pour commencer le week-end (ou les vacances pour certains), voici une petite fonction, très simple permettant de générer un mot de passe aléatoire, par exemple pour un accès à une zone de gestion. C'est d'ailleurs ce à quoi ce petit bout de code fait maison m'a servi. <span
id="more-1240"></span> Le principe ici était, pour moi, de générer une chaine de 8 caractères alphanumériques choisis aléatoirement. J'ai volontairement choisi de ne pas inclure de caractères accentués ni caractères spéciaux afin que les mots de passes générés soit relativement simple à retenir, tout en étant "difficile" à cracker. Bien sûr, les mot de passes sont cryptés en base, mais ça n'est pas la question.
Voici donc notre petite fonction :<pre>function generatePwd(){
	$chars = "azertyuiopqsdfghjklmwxcvbn0123456789";
	$lenght = strlen($chars);
	$chars = str_split($chars,1);
	$pwd = "";
	for($i=0;$i&lt;9;$i++){
		shuffle($chars);
		$pwd .= $chars[rand(0,($lenght-1))];
	}
	return $pwd;
}</pre>Ici, je définis les caractères que je souhaite utiliser pour mon mot de passe. Je range ensuite chaque caractères dans un tableau grâce à str_split(). Vient ensuite la génération de la chaîne aléatoire dans une boucle for() qui s'executera 8 fois ( je veux 8 caractères). Pour augmenter sensiblement la difficulté du mot de passe, je mélange mon tableau de caractères à chaque passage dans la boucle, et choisi un caractère  du tableau au hasard.
Fonction super simple, je vous l'accorde, mais ça pourra toujours servir, libre à vous de le modifier et l'utiliser comme bon vous semble ;)]]></description> <content:encoded><![CDATA[<p><img
width="2480" height="3508" src="http://blog.angechierchia.com/wp-content/uploads/1159613_851208571.jpg" class="attachment-post-thumbnail wp-post-image" alt="1159613_85120857" title="1159613_85120857" /></p>Pour commencer le week-end (ou les vacances pour certains), voici une petite fonction, très simple permettant de générer un mot de passe aléatoire, par exemple pour un accès à une zone de gestion. C'est d'ailleurs ce à quoi ce petit bout de code fait maison m'a servi. <span
id="more-1240"></span> Le principe ici était, pour moi, de générer une chaine de 8 caractères alphanumériques choisis aléatoirement. J'ai volontairement choisi de ne pas inclure de caractères accentués ni caractères spéciaux afin que les mots de passes générés soit relativement simple à retenir, tout en étant "difficile" à cracker. Bien sûr, les mot de passes sont cryptés en base, mais ça n'est pas la question.
Voici donc notre petite fonction :<pre>function generatePwd(){
	$chars = "azertyuiopqsdfghjklmwxcvbn0123456789";
	$lenght = strlen($chars);
	$chars = str_split($chars,1);
	$pwd = "";
	for($i=0;$i&lt;9;$i++){
		shuffle($chars);
		$pwd .= $chars[rand(0,($lenght-1))];
	}
	return $pwd;
}</pre>Ici, je définis les caractères que je souhaite utiliser pour mon mot de passe. Je range ensuite chaque caractères dans un tableau grâce à str_split(). Vient ensuite la génération de la chaîne aléatoire dans une boucle for() qui s'executera 8 fois ( je veux 8 caractères). Pour augmenter sensiblement la difficulté du mot de passe, je mélange mon tableau de caractères à chaque passage dans la boucle, et choisi un caractère  du tableau au hasard.
Fonction super simple, je vous l'accorde, mais ça pourra toujours servir, libre à vous de le modifier et l'utiliser comme bon vous semble ;)]]></content:encoded> <wfw:commentRss>http://blog.angechierchia.com/php-mysql/generer-un-mot-de-passe-aleatoirement/feed/</wfw:commentRss> <slash:comments>0</slash:comments> </item> <item><title>Exécuter des requêtes SQL avec CodeIgniter</title><link>http://blog.angechierchia.com/php-mysql/requetes-sql-avec-codeigniter/</link> <comments>http://blog.angechierchia.com/php-mysql/requetes-sql-avec-codeigniter/#comments</comments> <pubDate>Fri, 14 Jan 2011 21:36:57 +0000</pubDate> <dc:creator>Ange Chierchia</dc:creator> <category><![CDATA[PHP/MySQL]]></category> <category><![CDATA[CodeIgniter]]></category> <category><![CDATA[MySQL]]></category> <guid
isPermaLink="false">http://blog.angechierchia.com/?p=1090</guid> <description><![CDATA[<p><img
width="200" height="200" src="http://blog.angechierchia.com/wp-content/uploads/ci_cms.jpg" class="attachment-post-thumbnail wp-post-image" alt="ci_cms" title="ci_cms" /></p>Pour continuer à parler CodeIgniter, on va aujourd'hui s'intéresser à la construction de requêtes SQL via les fonctions disponibles avec CodeIgniter et voir l'intêret d'utiliser ces fonctions lorsqu'on interroge une base de données.<span
id="more-1090"></span> Ok, avant de voir comment utiliser CodeIgniter pour exécuter des requêtes SQL, on va voir comment déclarer plusieurs configuration de base de données, pour par exemple avoir une configuration différente selon si l'on travaille en local ou bien sur serveur.<h2>Configurer la classe Database</h2> Afin de permettre à CodeIgniter de "discutailler" avec notre base de données, il faut lui donner les infos pour y accéder. Ouvrez le fichier database.php se trouvant dans le dossier config de l'application (application/config/database.php), vous trouverez les réglages de la base de données stockés dans un  tableau multidirectionnel <code>$db</code> comme ci-dessous.<pre class="brush:php">$dbconf['default']['hostname'] = "localhost";
$dbconf['default']['username'] = "root";
$dbconf['default']['password'] = "";
$dbconf['default']['database'] = "database_name";
$dbconf['default']['dbdriver'] = "mysql";
$dbconf['default']['dbprefix'] = "";
$dbconf['default']['pconnect'] = TRUE;
$dbconf['default']['db_debug'] = FALSE;
$dbconf['default']['cache_on'] = FALSE;
$dbconf['default']['cachedir'] = "";
$dbconf['default']['char_set'] = "utf8";
$dbconf['default']['dbcollat'] = "utf8_general_ci";</pre>L'intérêt d'utiliser un tableau multidirectionnel pour enregistrer les infos relatives à la base de données, c'est de pouvoir définir un autre tableau  avec des informations différentes, pour ensuite choisir lequel de ces tableaux utiliser. Ainsi, si l'on souhaite déclarer deux configurations différentes, rien de plus simple :<pre class="brush:php">//config par défaut
$db['default']['hostname'] = "localhost";
$dbconf['default']['username'] = "root";
$dbconf['default']['password'] = "";
$dbconf['default']['database'] = "database_name";
$dbconf['default']['dbdriver'] = "mysql";
$dbconf['default']['dbprefix'] = "";
$dbconf['default']['pconnect'] = TRUE;
$dbconf['default']['db_debug'] = FALSE;
$dbconf['default']['cache_on'] = FALSE;
$dbconf['default']['cachedir'] = "";
$dbconf['default']['char_set'] = "utf8";
$dbconf['default']['dbcollat'] = "utf8_general_ci";
//config secondaire
$dbconf['test']['hostname'] = "host_name";
$dbconf['test']['username'] = "db_user";
$dbconf['test']['password'] = "db_pass";
$dbconf['test']['database'] = "database_name";
$dbconf['test']['dbdriver'] = "mysql";
$dbconf['test']['dbprefix'] = "";
$dbconf['test']['pconnect'] = TRUE;
$dbconf['test']['db_debug'] = FALSE;
$dbconf['test']['cache_on'] = FALSE;
$dbconf['test']['cachedir'] = "";
$dbconf['test']['char_set'] = "utf8";
$dbconf['test']['dbcollat'] = "utf8_general_ci";</pre>Il suffira ensuite de définir la valeur de la variable $active_group à "test" pour utiliser notre configuration secondaire. Easy!
Pour établir la connexion à la base de données il faudra alors faire appelle à la librairie Database dans votre classe, grâce à la ligne suivante :<pre class="brush:php">$this-&gt;load-&gt;database($dbconf);</pre>Il est aussi possible d'instancier deux connexion en faisant comme suit :<pre class="brush:php">$db1 = $this-&gt;load-&gt;database('default');
$db2 = $this-&gt;load-&gt;database('test');</pre><h2>Ma première requête SQL avec CodeIgniter</h2> On y est, notre connexion à la base est active, on va pouvoir manipuler les données (j'adore ça, manipuler des données)!
Avec CodeIgniter, ce qu'il y a de bien c'est qu'on a vraiment le choix des armes pour construire nos requêtes : soit on les construit comme au bon vieux temps des <code>mysql_*()</code> soit on utilise la <a
title="Utiliser PDO pour les connexions à une base de données" href="http://blog.angechierchia.com/php-mysql/utiliser-pdo-pour-les-connexion-a-une-bdd/">méthode objet (PDO)</a>, ou encore mieux on utilise les nombreuses fonctions du Framework!
Comme il y a toute une flopée de fonctions préexistantes je vais volontairement ne présenter que les plus courantes.<h3>mysql_query() à la sauce CI</h3> C'est la fonction <code>query()</code> de la classe Database qui permet d'exécuter simplement des requêtes <code>SELECT</code> simple. La fonction s'utilise très simplement : <code>$this-&gt;db-&gt;query('SELECT * FROM table');</code> Si l'on souhaite construire des requêtes avec paramètres, il sera obligatoire de les échapper avec les fonction <code>escape()</code>, <code>escape_str()</code> ou <code>escape_like_str()</code>, équivalents de la fonction <code>mysql_real_escape_string()</code>.
La fonction <code>escape()</code> permet d'échapper les données quelque soit leur type (<code>string, int, float</code>, etc…), tandis que <code>escape_str()</code> n'accepte que des données de type <code>string</code>. <code>escape_like_str()</code> quant à elle, permet d'échapper des requêtes avec des conditions <code>LIKE</code>.
Query() peut aussi être utilisé avec des requêtes préparées, comme avec l'objet PDO. Ainsi pour exécuter une requête, rien de bien compliqué:<pre class="brush:php">$sql = "SELECT * FROM some_table WHERE id = ? AND status = ? AND author = ?";
$this-&gt;db-&gt;query($sql, array(3, 'live', 'Rick'));</pre>L'intérêt ici, comme avec PDO c'est que les valeurs passées en paramètre sont automatiquement échappées.
CodeIgniter pourrait s'arrêter là, mais dans ce cas qu'aurait-il de plus que le simple objet PDO ? La réponse : l'Active Record!<h2>La classe Active Record</h2> Utiliser l'Active Record, c'est hype, branché et trop in the move!
Pourquoi? Parce que cela permet entre autre de laisser de côté l'histoire "Ma base est en MySQL, SQL Server, Postgre, … ?", en clair on ne s'occupe pas du SGBD utilisé, on lui pose juste les questions. Conséquence, notre appli a une meilleure portabilité.
CodeIgniter propose pas mal de fonctions permettant de construire des requêtes sans se fouler, j'irai même jusqu'à dire "sans même en connaître un radis en SQL". Regardons ce qui nous est proposé.<h3>$this-&gt;db-&gt;get()</h3> <code>get()</code> permet d'exécuter en un rien de temps un <code>SELECT</code> sur une table et ainsi retourner tout ses enregistrements<pre class="brush:php">$query = $this-&gt;db-&gt;get('mytable');
// équivalent: SELECT * FROM mytable</pre>Si l'on veut limiter le nombre de résultats retournés, par exemple dans le cadre d'une pagination, rien de plus simple il suffit juste de passer deux autres paramètres à <code>get()</code> en plus de la table sur laquelle on travaille.<pre class="brush:php">$query = $this-&gt;db-&gt;get('mytable', 10, 20);
// équivalent : SELECT * FROM mytable LIMIT 20, 10</pre><h3>$this-&gt;db-&gt;get_where()</h3> Vraiment besoin d'explications? <code>get_where()</code> permet tout simplement de faire un <code>get()</code> avec des conditions.
Les différentes condition seront à présenter sous forme d'un tableau (on vera ça ensuite dans la fonction <code>where()</code>) .<pre class="brush:php">$query = $this-&gt;db-&gt;get_where('mytable', $where, $limit, $offset);</pre>Avec ces deux fonctions, c'est le Framework qui s'occupe de construire nos requêtes. Si l'on veut les générer nous même tout en utilisant l'Active Directory, c'est maintenant qu'on va retrouver une pelletée  de méthodes.<h3>SELECT, FROM, WHERE</h3> Ok, admettons que l'on veuille retourner le titre, le contenu et la date d'un article dans notre base.
Clairement ici <code>get_where()</code> boufferai de la ressource inutilement puisqu'il nous retournerai d'autres champs dont on aurait pu se passer. <code>select()</code> est là pour nous ravir les amis!<pre class="brush:php">$this-&gt;db-&gt;select('title, content, date');
$query = $this-&gt;db-&gt;get('articles');
// équivalent: SELECT title, content, date FROM articles</pre>Attends voir, là on récupère le titre, le contenu et la date de tout les articles dans la base… Quel œil vif! C'est ici qu'interviennent nos amis <code>from()</code> et <code>where()</code> :<pre class="brush:php">$this-&gt;db-&gt;select('title, content, date');
$this-&gt;db-&gt;from('articles');
$this-&gt;db-&gt;where(array('id' =&gt; 7));
$query = $this-&gt;db-&gt;get();</pre>C'est pas beautiful ? CodeIgniter a un sac plein de fonctions équivalentes aux fonction SQL comme <code>SUM()</code>, <code>AVG()</code>, <code>COUNT()</code>, etc.  Je ne les traiterai pas ici mais vous pourrez les retrouver sur dans le <a
href="http://www.codeigniter.fr/user_guide/database/" target="_blank">Guide Utilisateur de CodeIgniter</a>.
Chose pratique, on peut concaténer toutes ses fonctions, pour économiser en ligne de code. Ainsi, notre requête précédente pourrait s'écrire :<pre class="brush:php">$this-&gt;db-&gt;select('title, content, date')-&gt;from('articles')-&gt;where(array('id' =&gt; 7));
$query = $this-&gt;db-&gt;get();</pre><h3>Affichage des résultats</h3> On finira ce billet très rapidement sur la façon d'afficher le résultat de nos différentes requêtes.
Ici on fera un simple <code>foreach()</code> comme on a l'habitude d'en faire quand on utilise PDO (pour moi en tout cas).<pre class="brush:php">$query = $this-&gt;db-&gt;get('mytable');
foreach ($query-&gt;result() as $row){
             echo $row-&gt;title;
}</pre><h2>Conclusion</h2> Ici on a donc vu pas mal de méthodes bien utile lorsqu'il s'agit d'interroger une base de donnée lorsqu'on développe dans le cadre d'une application Web sous CodeIgniter.
Petite parenthèse, je tiens à m'excuser pour l'attente interminable entre le moment ou j'ai annoncé faire cet article, et sa publication. J'ai eu deux bons gros mois de taff bien chargés, autant au boulot, qu'au niveau perso (notamment le site du WDFR sur lequel je travail avec <a
href="http://twitter.com/Fran6">@Fran6</a>, <a
href="http://twitter.com/Twikito">@Twikito</a>, <a
href="http://twitter.com/ClementRoy">@ClementRoy</a> et <a
href="http://twitter.com/C_Beghin">@C_Beghin</a>, et tout le workgroup WDFR), ce qui explique en partie ce petit retard.
J'en profite aussi pour souhaité avec du retard, une très bonne année 2011, pleine de bonnes choses et d'argent (surtout) ^^]]></description> <content:encoded><![CDATA[<p><img
width="200" height="200" src="http://blog.angechierchia.com/wp-content/uploads/ci_cms.jpg" class="attachment-post-thumbnail wp-post-image" alt="ci_cms" title="ci_cms" /></p>Pour continuer à parler CodeIgniter, on va aujourd'hui s'intéresser à la construction de requêtes SQL via les fonctions disponibles avec CodeIgniter et voir l'intêret d'utiliser ces fonctions lorsqu'on interroge une base de données.<span
id="more-1090"></span> Ok, avant de voir comment utiliser CodeIgniter pour exécuter des requêtes SQL, on va voir comment déclarer plusieurs configuration de base de données, pour par exemple avoir une configuration différente selon si l'on travaille en local ou bien sur serveur.<h2>Configurer la classe Database</h2> Afin de permettre à CodeIgniter de "discutailler" avec notre base de données, il faut lui donner les infos pour y accéder. Ouvrez le fichier database.php se trouvant dans le dossier config de l'application (application/config/database.php), vous trouverez les réglages de la base de données stockés dans un  tableau multidirectionnel <code>$db</code> comme ci-dessous.<pre class="brush:php">$dbconf['default']['hostname'] = "localhost";
$dbconf['default']['username'] = "root";
$dbconf['default']['password'] = "";
$dbconf['default']['database'] = "database_name";
$dbconf['default']['dbdriver'] = "mysql";
$dbconf['default']['dbprefix'] = "";
$dbconf['default']['pconnect'] = TRUE;
$dbconf['default']['db_debug'] = FALSE;
$dbconf['default']['cache_on'] = FALSE;
$dbconf['default']['cachedir'] = "";
$dbconf['default']['char_set'] = "utf8";
$dbconf['default']['dbcollat'] = "utf8_general_ci";</pre>L'intérêt d'utiliser un tableau multidirectionnel pour enregistrer les infos relatives à la base de données, c'est de pouvoir définir un autre tableau  avec des informations différentes, pour ensuite choisir lequel de ces tableaux utiliser. Ainsi, si l'on souhaite déclarer deux configurations différentes, rien de plus simple :<pre class="brush:php">//config par défaut
$db['default']['hostname'] = "localhost";
$dbconf['default']['username'] = "root";
$dbconf['default']['password'] = "";
$dbconf['default']['database'] = "database_name";
$dbconf['default']['dbdriver'] = "mysql";
$dbconf['default']['dbprefix'] = "";
$dbconf['default']['pconnect'] = TRUE;
$dbconf['default']['db_debug'] = FALSE;
$dbconf['default']['cache_on'] = FALSE;
$dbconf['default']['cachedir'] = "";
$dbconf['default']['char_set'] = "utf8";
$dbconf['default']['dbcollat'] = "utf8_general_ci";
//config secondaire
$dbconf['test']['hostname'] = "host_name";
$dbconf['test']['username'] = "db_user";
$dbconf['test']['password'] = "db_pass";
$dbconf['test']['database'] = "database_name";
$dbconf['test']['dbdriver'] = "mysql";
$dbconf['test']['dbprefix'] = "";
$dbconf['test']['pconnect'] = TRUE;
$dbconf['test']['db_debug'] = FALSE;
$dbconf['test']['cache_on'] = FALSE;
$dbconf['test']['cachedir'] = "";
$dbconf['test']['char_set'] = "utf8";
$dbconf['test']['dbcollat'] = "utf8_general_ci";</pre>Il suffira ensuite de définir la valeur de la variable $active_group à "test" pour utiliser notre configuration secondaire. Easy!
Pour établir la connexion à la base de données il faudra alors faire appelle à la librairie Database dans votre classe, grâce à la ligne suivante :<pre class="brush:php">$this-&gt;load-&gt;database($dbconf);</pre>Il est aussi possible d'instancier deux connexion en faisant comme suit :<pre class="brush:php">$db1 = $this-&gt;load-&gt;database('default');
$db2 = $this-&gt;load-&gt;database('test');</pre><h2>Ma première requête SQL avec CodeIgniter</h2> On y est, notre connexion à la base est active, on va pouvoir manipuler les données (j'adore ça, manipuler des données)!
Avec CodeIgniter, ce qu'il y a de bien c'est qu'on a vraiment le choix des armes pour construire nos requêtes : soit on les construit comme au bon vieux temps des <code>mysql_*()</code> soit on utilise la <a
title="Utiliser PDO pour les connexions à une base de données" href="http://blog.angechierchia.com/php-mysql/utiliser-pdo-pour-les-connexion-a-une-bdd/">méthode objet (PDO)</a>, ou encore mieux on utilise les nombreuses fonctions du Framework!
Comme il y a toute une flopée de fonctions préexistantes je vais volontairement ne présenter que les plus courantes.<h3>mysql_query() à la sauce CI</h3> C'est la fonction <code>query()</code> de la classe Database qui permet d'exécuter simplement des requêtes <code>SELECT</code> simple. La fonction s'utilise très simplement : <code>$this-&gt;db-&gt;query('SELECT * FROM table');</code> Si l'on souhaite construire des requêtes avec paramètres, il sera obligatoire de les échapper avec les fonction <code>escape()</code>, <code>escape_str()</code> ou <code>escape_like_str()</code>, équivalents de la fonction <code>mysql_real_escape_string()</code>.
La fonction <code>escape()</code> permet d'échapper les données quelque soit leur type (<code>string, int, float</code>, etc…), tandis que <code>escape_str()</code> n'accepte que des données de type <code>string</code>. <code>escape_like_str()</code> quant à elle, permet d'échapper des requêtes avec des conditions <code>LIKE</code>.
Query() peut aussi être utilisé avec des requêtes préparées, comme avec l'objet PDO. Ainsi pour exécuter une requête, rien de bien compliqué:<pre class="brush:php">$sql = "SELECT * FROM some_table WHERE id = ? AND status = ? AND author = ?";
$this-&gt;db-&gt;query($sql, array(3, 'live', 'Rick'));</pre>L'intérêt ici, comme avec PDO c'est que les valeurs passées en paramètre sont automatiquement échappées.
CodeIgniter pourrait s'arrêter là, mais dans ce cas qu'aurait-il de plus que le simple objet PDO ? La réponse : l'Active Record!<h2>La classe Active Record</h2> Utiliser l'Active Record, c'est hype, branché et trop in the move!
Pourquoi? Parce que cela permet entre autre de laisser de côté l'histoire "Ma base est en MySQL, SQL Server, Postgre, … ?", en clair on ne s'occupe pas du SGBD utilisé, on lui pose juste les questions. Conséquence, notre appli a une meilleure portabilité.
CodeIgniter propose pas mal de fonctions permettant de construire des requêtes sans se fouler, j'irai même jusqu'à dire "sans même en connaître un radis en SQL". Regardons ce qui nous est proposé.<h3>$this-&gt;db-&gt;get()</h3> <code>get()</code> permet d'exécuter en un rien de temps un <code>SELECT</code> sur une table et ainsi retourner tout ses enregistrements<pre class="brush:php">$query = $this-&gt;db-&gt;get('mytable');
// équivalent: SELECT * FROM mytable</pre>Si l'on veut limiter le nombre de résultats retournés, par exemple dans le cadre d'une pagination, rien de plus simple il suffit juste de passer deux autres paramètres à <code>get()</code> en plus de la table sur laquelle on travaille.<pre class="brush:php">$query = $this-&gt;db-&gt;get('mytable', 10, 20);
// équivalent : SELECT * FROM mytable LIMIT 20, 10</pre><h3>$this-&gt;db-&gt;get_where()</h3> Vraiment besoin d'explications? <code>get_where()</code> permet tout simplement de faire un <code>get()</code> avec des conditions.
Les différentes condition seront à présenter sous forme d'un tableau (on vera ça ensuite dans la fonction <code>where()</code>) .<pre class="brush:php">$query = $this-&gt;db-&gt;get_where('mytable', $where, $limit, $offset);</pre>Avec ces deux fonctions, c'est le Framework qui s'occupe de construire nos requêtes. Si l'on veut les générer nous même tout en utilisant l'Active Directory, c'est maintenant qu'on va retrouver une pelletée  de méthodes.<h3>SELECT, FROM, WHERE</h3> Ok, admettons que l'on veuille retourner le titre, le contenu et la date d'un article dans notre base.
Clairement ici <code>get_where()</code> boufferai de la ressource inutilement puisqu'il nous retournerai d'autres champs dont on aurait pu se passer. <code>select()</code> est là pour nous ravir les amis!<pre class="brush:php">$this-&gt;db-&gt;select('title, content, date');
$query = $this-&gt;db-&gt;get('articles');
// équivalent: SELECT title, content, date FROM articles</pre>Attends voir, là on récupère le titre, le contenu et la date de tout les articles dans la base… Quel œil vif! C'est ici qu'interviennent nos amis <code>from()</code> et <code>where()</code> :<pre class="brush:php">$this-&gt;db-&gt;select('title, content, date');
$this-&gt;db-&gt;from('articles');
$this-&gt;db-&gt;where(array('id' =&gt; 7));
$query = $this-&gt;db-&gt;get();</pre>C'est pas beautiful ? CodeIgniter a un sac plein de fonctions équivalentes aux fonction SQL comme <code>SUM()</code>, <code>AVG()</code>, <code>COUNT()</code>, etc.  Je ne les traiterai pas ici mais vous pourrez les retrouver sur dans le <a
href="http://www.codeigniter.fr/user_guide/database/" target="_blank">Guide Utilisateur de CodeIgniter</a>.
Chose pratique, on peut concaténer toutes ses fonctions, pour économiser en ligne de code. Ainsi, notre requête précédente pourrait s'écrire :<pre class="brush:php">$this-&gt;db-&gt;select('title, content, date')-&gt;from('articles')-&gt;where(array('id' =&gt; 7));
$query = $this-&gt;db-&gt;get();</pre><h3>Affichage des résultats</h3> On finira ce billet très rapidement sur la façon d'afficher le résultat de nos différentes requêtes.
Ici on fera un simple <code>foreach()</code> comme on a l'habitude d'en faire quand on utilise PDO (pour moi en tout cas).<pre class="brush:php">$query = $this-&gt;db-&gt;get('mytable');
foreach ($query-&gt;result() as $row){
             echo $row-&gt;title;
}</pre><h2>Conclusion</h2> Ici on a donc vu pas mal de méthodes bien utile lorsqu'il s'agit d'interroger une base de donnée lorsqu'on développe dans le cadre d'une application Web sous CodeIgniter.
Petite parenthèse, je tiens à m'excuser pour l'attente interminable entre le moment ou j'ai annoncé faire cet article, et sa publication. J'ai eu deux bons gros mois de taff bien chargés, autant au boulot, qu'au niveau perso (notamment le site du WDFR sur lequel je travail avec <a
href="http://twitter.com/Fran6">@Fran6</a>, <a
href="http://twitter.com/Twikito">@Twikito</a>, <a
href="http://twitter.com/ClementRoy">@ClementRoy</a> et <a
href="http://twitter.com/C_Beghin">@C_Beghin</a>, et tout le workgroup WDFR), ce qui explique en partie ce petit retard.
J'en profite aussi pour souhaité avec du retard, une très bonne année 2011, pleine de bonnes choses et d'argent (surtout) ^^]]></content:encoded> <wfw:commentRss>http://blog.angechierchia.com/php-mysql/requetes-sql-avec-codeigniter/feed/</wfw:commentRss> <slash:comments>2</slash:comments> </item> <item><title>Développer un CMS avec CodeIgniter #3 : la gestion des pages</title><link>http://blog.angechierchia.com/php-mysql/developper-cms-codeigniter-la-gestion-des-pages/</link> <comments>http://blog.angechierchia.com/php-mysql/developper-cms-codeigniter-la-gestion-des-pages/#comments</comments> <pubDate>Sat, 07 Aug 2010 15:09:15 +0000</pubDate> <dc:creator>Ange Chierchia</dc:creator> <category><![CDATA[PHP/MySQL]]></category> <category><![CDATA[CMS]]></category> <category><![CDATA[CodeIgniter]]></category> <category><![CDATA[MySQL]]></category> <category><![CDATA[PHP]]></category> <guid
isPermaLink="false">http://blog.angechierchia.com/?p=984</guid> <description><![CDATA[<p><img
width="200" height="200" src="http://blog.angechierchia.com/wp-content/uploads/ci_cms.jpg" class="attachment-post-thumbnail wp-post-image" alt="ci_cms" title="ci_cms" /></p>Dans ce nouvel article qui fait suite à "<a
href="http://blog.angechierchia.com/php-mysql/moteur-site-web-developper-cms-codeigniter/">Développer un moteur de site Web avec CodeIgniter</a>" et "<a
href="http://blog.angechierchia.com/php-mysql/login-securise-cms-codeigniter-partie-2/">Système de login sécurisé -- CMS CodeIgniter, partie 2</a>" nous allons nous intéresser au module de gestion des pages de contenu, le coeur du moteur de site web en somme.<span
id="more-984"></span><h2>Introduction</h2> La semaine le mois dernier (désolé) on avait vu comment CodeIgniter construisait les pages de notre site en utilisant le modèle MVC, c'est à dire la séparation du code source en trois couches qui ont chacune une "mission" : accéder aux données stockées dans la base (couche Modèles) traiter les données (couche Contrôleurs), afficher les données (couche Vues).
Nous avions donc créé un contrôleur Admin qui se chargeait de traiter les données renvoyées par notre modèle User_model qui s'occupait de voir si pour les infos de connexion passées via notre vue loginform.php on avait un résultat dans la base, auquel cas, on donnait accès à l'administration du site. Et on s'était arrêté là. Aujourd'hui… la suite!<h2>L'accès aux données relatives aux pages du site</h2> Ayant pris l'habitude de bien séparer les différentes parties des sites que je développe, et parce que c'est plus pratique pour s'y retrouver par la suite, je vous propose de créer un nouveau modèle qui ne s'intéressera qu'à nos données stockées dans notre table pages.
Dans le dossier <em>application/models</em>, créez un nouveau fichier que vous appellerez <em>page_model.php</em> contenant le code suivant:<pre class="brush:php">class Page_model extends Model {
	function Page_model(){
		parent::Model();
	}
}</pre>Qui nous permet de  définir notre classe Page_model comme étant un Model. Ensuite, nous allons ajouter différentes méthodes à l'intérieur de cette classe qui nous permettront de modifier les données présentent dans notre table pages. C'est ce qu'on appelle les fonctions CRUD (Create, Read, Update, Delete).
Okay, premièrement on va s'occuper de la fonction d'ajout dans la base.<pre class="brush:php">function add($data){
	return $this-&gt;db-&gt;insert('pages',$data);
}</pre>Ici, c'est allé super vite n'est-ce pas? En effet dans notre modèle on ne s'occupe que de l'insertion des données dans la base, leur traitement pour savoir si oui ou non les données sont conformes se fera avant ça, dans notre contrôleur.
Pour ce qui est des fonctions de modification, et de suppression, c'est aussi rapide, donc les voici toutes les deux:<pre class="brush:php">function update($id,$data){
	$this-&gt;db-&gt;where('id',$id);
	return $this-&gt;db-&gt;update('pages',$data);
}
function delete($id){
	return $this-&gt;db-&gt;delete('pages',array('id'=&gt;$id));
}</pre>Passons maintenant à nos fonction de "lecture" ici, on a deux fonctions, la première servira pour retourner toutes les pages présentent dans la base, alors que la seconde ne retournera qu'une seule page.<pre class="brush:php">//retourne la liste des pages
function getListe(){
	//SELECT * FROM pages
	$query = $this-&gt;db-&gt;get('pages');
	if($query-&gt;num_rows() &gt; 0){
		$rows = $query-&gt;result();
		return $rows;
	}
}
//retourne l'enregistrement dans la
//base de données correspondant à l'id
//passée en paramètre
function get($id){
	//SELECT * FROM pages WHERE id = '$id'
	$query = $this-&gt;db-&gt;get_where('pages',array('id'=&gt;$id));
	if($query-&gt;num_rows()&gt;0){
		$rows = $query-&gt;result();
		return $rows[0];
	}
}</pre><h2>Le traitement des données</h2> Nous en avons fini avec notre modèle, passons à notre contrôleur. Ici on va reprendre notre contrôleur Admin et y ajouter une méthode appelée page… Originale n'est-ce pas ^^.
C'est dans cette méthode que nous allons traiter les données passées à nos formulaires d'ajout/modification des pages, que nous renverrons au modèle rédigé juste avant.
Pour rappel, voilà notre contrôleur Admin là où on s'est arrêté le mois dernier:<pre class="brush:php">class Admin extends Controller {
	//constructeur de la classe
	function Admin() {
		parent::Controller();
		$this-&gt;load-&gt;model('user_model');
		$this-&gt;load-&gt;library('form_validation');
	}
	//affiche l'admin si la session existe, sinon le formulaire de login
	function index(){
		if($this-&gt;user_model-&gt;isLoggedIn()){
			redirect('admin/dashboard','refresh');
		} else {
			redirect('admin/login','refresh');
		}
	}
	//traitement du formulaire de login
	function login(){
		if($this-&gt;user_model-&gt;isLoggedIn()){
			redirect('admin','refresh');
		} else {
			//on charge la validation de formulaires
			$this-&gt;load-&gt;library('form_validation');
			//on définit les règles de succès
			$this-&gt;form_validation-&gt;set_rules('username','Login','required');
			$this-&gt;form_validation-&gt;set_rules('password','Mot de passe','required');
			//si la validation a échouée on redirige vers le formulaire de login
			if(!$this-&gt;form_validation-&gt;run()){
				$this-&gt;load-&gt;view('loginform');
			} else {
				$username = $this-&gt;input-&gt;post('username');
				$password = $this-&gt;input-&gt;post('password');
				$validCredentials = $this-&gt;user_model-&gt;validCredentials($username,$password);
				if($validCredentials){
					redirect('admin/dashboard','refresh');
				} else {
					$data['error_credentials'] = 'Wrong Username/Password';
					$this-&gt;load-&gt;view('loginform',$data);
				}
			}
		}
	}
	//affichage de l'adminstration
	function dashboard(){
		if($this-&gt;user_model-&gt;isLoggedIn())
			$this-&gt;load-&gt;view('admin');
	}
	//deconnexion
	function logout(){
		$this-&gt;user_model-&gt;logout();
		redirect('admin','refresh');
	}
}</pre>Ajoutons maintenant notre fonction page. Elle prendra en paramètres deux variables : $action qui nous permettra de savoir qu'est-ce que l'on doit faire lorsqu'on appelle cette fonction, et $id qui donnera l'identifiant de la page à modifier/supprimer dans la base. Voici la structure générale de notre méthode, je détaillerai les différentes étapes par la suite.<pre class="brush:php">function page($action = 'list', $id = null){
		if($this-&gt;user_model-&gt;isLoggedIn()):
			$this-&gt;load-&gt;model('page_model');
			switch($action){
				case 'list':
					//affichage de la liste des pages
				break;
				case 'edit':
					//affichage du formulaire de modification d'une page
				break;
				case 'update': //mise a jour de la page
					//modification d'une page
				break;
				case 'add': //ajout d'une page
					//création d'un page
				break;
				case 'delete':
					//suppression de la page
				break;
			}
		else:
			redirect('admin/login');
		endif;
	}</pre>Ici on attend donc les deux paramètres $action et $id qui ont par défaut les valeurs respectives 'list' et null, ainsi si la fonction est appelée sans aucun paramètre, on affichera l'action list, donc la liste des pages, tandis que l'identifiant de page sera nul. Aussi, avant de traiter les données, on s'assure que l'utilisateur est bien loggué en administrateur via la commande $this-&gt;user_model-&gt;isLoggedIn().
Passons à l'écriture des actions possible. Je vais faire les actions list, edit et delete en même temps car elle sont simple et ne nécessites pas vraiment qu'on s'y attarde.<pre class="brush:php">case 'list': //affichage de la liste des pages
	$data['liste'] = $this-&gt;page_model-&gt;getListe();
	$this-&gt;load-&gt;view('list_page',$data);
break;
case 'edit': //affichage du formulaire de modification d'une page
	if(isset($id) &amp;&amp; $id != 0){
		$data['page'] = $this-&gt;page_model-&gt;get($id);
		$this-&gt;load-&gt;view('edit_page',$data);
	}
break;
case 'delete':
	if(isset($id) &amp;&amp; $id != 0){
		if($this-&gt;page_model-&gt;delete($id)){
			echo "page supprimé";
		}
	}
break;</pre>Ici rien de bien compliqué, si $action est égale à 'list', on appelle la méthode getListe() de notre modèle Page que l'on stocke dans la variable $data, de type array, et dont l'identifiant sera 'liste'. Ensuite on charge la vue list_page en lui passant les données stockées dans la variable $data, ce qui nous permettra, lorsqu'on rédigera cette vue, de récupérer les données de la méthode getListe via la variable $liste. Vous suivez toujours?
Si l'on passe la valeur 'edit' à notre variable $action, on vérifie que notre variable $id ne soit pas nulle, et on envoi les données retournées par la méthode get() à notre vue edit_page.
Enfin, si $action vaut 'delete' et que $id n'est pas nulle, on appelle la méthode delete() de notre modèle Page.
Okay, maintenant on passe à la modification d'une page, via l'action update. Ici, le principe c'est que via l'action edit on a récupéré les données stockées dans la base et on a peuplé le formulaire de la vue edit_page. Ce formulaire renvoi les données à l'action update, via une URL du style /admin/page/update/$id. On doit donc vérifier si les données renvoyées sont bonne avant de modifier leur valeur dans la base.<pre class="brush:php">case 'update': //mise a jour de la page
	if(isset($id) &amp;&amp; $id != 0){
		//définition des règles de validation
		//$this-&gt;load-&gt;helper('form_validation');
		$this-&gt;form_validation-&gt;set_rules('titre_page','Titre','required');
		$this-&gt;form_validation-&gt;set_rules('contenu_page','Contenu','required');
		if($this-&gt;form_validation-&gt;run()){
			//les champs obligatoires sont fournis
			//on créé un tableau dans lequel on passe les infos du formulaire
			$data = array(
				'title' =&gt; $this-&gt;input-&gt;post('titre_page'),
				'content' =&gt; $this-&gt;input-&gt;post('contenu_page'),
			);
			//on regarde si le champs keywords est renseigné
			if($this-&gt;input-&gt;post('keywords_page')){
				$data['keywords'] = $this-&gt;input-&gt;post('keywords_page');
			}
			//on fait la même chose pour le champs description
			if($this-&gt;input-&gt;post('description_page')){
				$data['description'] = $this-&gt;input-&gt;post('description_page');
			}
			//enregistrement dans la base de données
			if($this-&gt;page_model-&gt;update($id,$data)){
				echo "Page mis à jour";
			}
		} else {
			//certains champs obligatoires sont manquants
			redirect('admin/page/edit/'.$id);
		}
	}
break;</pre>Pour l'insertion d'une nouvelle page dans la base de données le principe est le même, sauf que j'ai choisi de réunir les deux étapes de l'appel du formulaire et celle de la vérification des données. Voici ce que ça donne:<pre class="brush:php">case 'add': //ajout d'une page
	$this-&gt;form_validation-&gt;set_rules('titre_page','Titre','required');
	$this-&gt;form_validation-&gt;set_rules('contenu_page','Contenu','required');
	if($this-&gt;form_validation-&gt;run()){
		//les champs obligatoires sont fournis
		//on créé un tableau dans lequel on passe les infos du formulaire
		$data = array(
			'title' =&gt; $this-&gt;input-&gt;post('titre_page'),
			'content' =&gt; $this-&gt;input-&gt;post('contenu_page'),
		);
		//on regarde si le champs keywords est renseigné
		if($this-&gt;input-&gt;post('keywords_page')){
			$data['keywords'] = $this-&gt;input-&gt;post('keywords_page');
		}
		//on fait la même chose pour le champs description
		if($this-&gt;input-&gt;post('description_page')){
			$data['description'] = $this-&gt;input-&gt;post('description_page');
		}
		//enregistrement dans la base de données
		if($this-&gt;page_model-&gt;add($data)){
			echo "page ajouté";
		}
	} else {
		//certains champs obligatoires sont manquants
		$this-&gt;load-&gt;view('add_page');
	}
break;</pre><h2>Le troisième tiers de notre application: les vues</h2> On en a enfin fini avec notre contrôleur! On passe maintenant au troisième tiers de notre application, les vues. Ici je ne vais pas vous donner plus d'explications, les trois vues sont relativement simples a comprendre même en ne connaissant pas trop bien la syntaxe utilisée par CodeIgniter. Voici donc les trois vues list_page.php, add_page.php et edit_page.php.<h4>La liste des pages présentes dans la base</h4><pre class="brush:php">foreach($liste as $page):
	echo "&lt;h2&gt;".anchor('admin/page/edit/'.$page-&gt;id,$page-&gt;title)."&lt;/h2&gt;
	".$page-&gt;content."&lt;div&gt;&lt;small&gt;&lt;strong&gt;Tags:&lt;/strong&gt; ".$page-&gt;keywords."&lt;/small&gt;&lt;/div&gt;
endforeach;</pre><h4>Le formulaire d'ajout d'une page</h4><pre class="brush:php">echo form_open('admin/page/add/');
echo validation_errors();
echo form_input('titre_page',set_value('titre_page'));
echo form_textarea('contenu_page',set_value('contenu_page'));
echo form_submit('','Ajouter');
echo form_close();</pre><h4>Le formulaire de modification</h4><pre class="brush:php">echo form_open('admin/page/update/'.$page-&gt;id);
echo form_input('titre_page',$page-&gt;title);
echo form_textarea('contenu_page',$page-&gt;content);
echo form_submit('','Modifier');
echo form_close();</pre><h2>Conclusion</h2> Après avoir développé notre système de login sécurisé, on a vu ici comment construire simplement et rapidement un module de gestion pour les pages que contiendra notre futur site Web.
Avec ce nouvel article, notre système pourrait très bien s'arrêter là, il est fonctionnel et relativement sécurisé tant au niveau de l'accès par login/mot de passe, qu'au niveau de la vérification des valeurs saisies dans les différents formulaires, du fait que c'est le framework lui-même qui s'occupe de vérifier les données et d'échapper les données avant de les enregistrer dans la base.
La prochaine fois, on vera comment intégrer un éditeur de texte comme TinyMCE à notre CMS afin de pouvoir mettre en forme notre texte facilement, et puis surement d'autre petites choses. Par contre, je ne sais pas encore quand est-ce que je vous pondrait çà ;)]]></description> <content:encoded><![CDATA[<p><img
width="200" height="200" src="http://blog.angechierchia.com/wp-content/uploads/ci_cms.jpg" class="attachment-post-thumbnail wp-post-image" alt="ci_cms" title="ci_cms" /></p>Dans ce nouvel article qui fait suite à "<a
href="http://blog.angechierchia.com/php-mysql/moteur-site-web-developper-cms-codeigniter/">Développer un moteur de site Web avec CodeIgniter</a>" et "<a
href="http://blog.angechierchia.com/php-mysql/login-securise-cms-codeigniter-partie-2/">Système de login sécurisé -- CMS CodeIgniter, partie 2</a>" nous allons nous intéresser au module de gestion des pages de contenu, le coeur du moteur de site web en somme.<span
id="more-984"></span><h2>Introduction</h2> La semaine le mois dernier (désolé) on avait vu comment CodeIgniter construisait les pages de notre site en utilisant le modèle MVC, c'est à dire la séparation du code source en trois couches qui ont chacune une "mission" : accéder aux données stockées dans la base (couche Modèles) traiter les données (couche Contrôleurs), afficher les données (couche Vues).
Nous avions donc créé un contrôleur Admin qui se chargeait de traiter les données renvoyées par notre modèle User_model qui s'occupait de voir si pour les infos de connexion passées via notre vue loginform.php on avait un résultat dans la base, auquel cas, on donnait accès à l'administration du site. Et on s'était arrêté là. Aujourd'hui… la suite!<h2>L'accès aux données relatives aux pages du site</h2> Ayant pris l'habitude de bien séparer les différentes parties des sites que je développe, et parce que c'est plus pratique pour s'y retrouver par la suite, je vous propose de créer un nouveau modèle qui ne s'intéressera qu'à nos données stockées dans notre table pages.
Dans le dossier <em>application/models</em>, créez un nouveau fichier que vous appellerez <em>page_model.php</em> contenant le code suivant:<pre class="brush:php">class Page_model extends Model {
	function Page_model(){
		parent::Model();
	}
}</pre>Qui nous permet de  définir notre classe Page_model comme étant un Model. Ensuite, nous allons ajouter différentes méthodes à l'intérieur de cette classe qui nous permettront de modifier les données présentent dans notre table pages. C'est ce qu'on appelle les fonctions CRUD (Create, Read, Update, Delete).
Okay, premièrement on va s'occuper de la fonction d'ajout dans la base.<pre class="brush:php">function add($data){
	return $this-&gt;db-&gt;insert('pages',$data);
}</pre>Ici, c'est allé super vite n'est-ce pas? En effet dans notre modèle on ne s'occupe que de l'insertion des données dans la base, leur traitement pour savoir si oui ou non les données sont conformes se fera avant ça, dans notre contrôleur.
Pour ce qui est des fonctions de modification, et de suppression, c'est aussi rapide, donc les voici toutes les deux:<pre class="brush:php">function update($id,$data){
	$this-&gt;db-&gt;where('id',$id);
	return $this-&gt;db-&gt;update('pages',$data);
}
function delete($id){
	return $this-&gt;db-&gt;delete('pages',array('id'=&gt;$id));
}</pre>Passons maintenant à nos fonction de "lecture" ici, on a deux fonctions, la première servira pour retourner toutes les pages présentent dans la base, alors que la seconde ne retournera qu'une seule page.<pre class="brush:php">//retourne la liste des pages
function getListe(){
	//SELECT * FROM pages
	$query = $this-&gt;db-&gt;get('pages');
	if($query-&gt;num_rows() &gt; 0){
		$rows = $query-&gt;result();
		return $rows;
	}
}
//retourne l'enregistrement dans la
//base de données correspondant à l'id
//passée en paramètre
function get($id){
	//SELECT * FROM pages WHERE id = '$id'
	$query = $this-&gt;db-&gt;get_where('pages',array('id'=&gt;$id));
	if($query-&gt;num_rows()&gt;0){
		$rows = $query-&gt;result();
		return $rows[0];
	}
}</pre><h2>Le traitement des données</h2> Nous en avons fini avec notre modèle, passons à notre contrôleur. Ici on va reprendre notre contrôleur Admin et y ajouter une méthode appelée page… Originale n'est-ce pas ^^.
C'est dans cette méthode que nous allons traiter les données passées à nos formulaires d'ajout/modification des pages, que nous renverrons au modèle rédigé juste avant.
Pour rappel, voilà notre contrôleur Admin là où on s'est arrêté le mois dernier:<pre class="brush:php">class Admin extends Controller {
	//constructeur de la classe
	function Admin() {
		parent::Controller();
		$this-&gt;load-&gt;model('user_model');
		$this-&gt;load-&gt;library('form_validation');
	}
	//affiche l'admin si la session existe, sinon le formulaire de login
	function index(){
		if($this-&gt;user_model-&gt;isLoggedIn()){
			redirect('admin/dashboard','refresh');
		} else {
			redirect('admin/login','refresh');
		}
	}
	//traitement du formulaire de login
	function login(){
		if($this-&gt;user_model-&gt;isLoggedIn()){
			redirect('admin','refresh');
		} else {
			//on charge la validation de formulaires
			$this-&gt;load-&gt;library('form_validation');
			//on définit les règles de succès
			$this-&gt;form_validation-&gt;set_rules('username','Login','required');
			$this-&gt;form_validation-&gt;set_rules('password','Mot de passe','required');
			//si la validation a échouée on redirige vers le formulaire de login
			if(!$this-&gt;form_validation-&gt;run()){
				$this-&gt;load-&gt;view('loginform');
			} else {
				$username = $this-&gt;input-&gt;post('username');
				$password = $this-&gt;input-&gt;post('password');
				$validCredentials = $this-&gt;user_model-&gt;validCredentials($username,$password);
				if($validCredentials){
					redirect('admin/dashboard','refresh');
				} else {
					$data['error_credentials'] = 'Wrong Username/Password';
					$this-&gt;load-&gt;view('loginform',$data);
				}
			}
		}
	}
	//affichage de l'adminstration
	function dashboard(){
		if($this-&gt;user_model-&gt;isLoggedIn())
			$this-&gt;load-&gt;view('admin');
	}
	//deconnexion
	function logout(){
		$this-&gt;user_model-&gt;logout();
		redirect('admin','refresh');
	}
}</pre>Ajoutons maintenant notre fonction page. Elle prendra en paramètres deux variables : $action qui nous permettra de savoir qu'est-ce que l'on doit faire lorsqu'on appelle cette fonction, et $id qui donnera l'identifiant de la page à modifier/supprimer dans la base. Voici la structure générale de notre méthode, je détaillerai les différentes étapes par la suite.<pre class="brush:php">function page($action = 'list', $id = null){
		if($this-&gt;user_model-&gt;isLoggedIn()):
			$this-&gt;load-&gt;model('page_model');
			switch($action){
				case 'list':
					//affichage de la liste des pages
				break;
				case 'edit':
					//affichage du formulaire de modification d'une page
				break;
				case 'update': //mise a jour de la page
					//modification d'une page
				break;
				case 'add': //ajout d'une page
					//création d'un page
				break;
				case 'delete':
					//suppression de la page
				break;
			}
		else:
			redirect('admin/login');
		endif;
	}</pre>Ici on attend donc les deux paramètres $action et $id qui ont par défaut les valeurs respectives 'list' et null, ainsi si la fonction est appelée sans aucun paramètre, on affichera l'action list, donc la liste des pages, tandis que l'identifiant de page sera nul. Aussi, avant de traiter les données, on s'assure que l'utilisateur est bien loggué en administrateur via la commande $this-&gt;user_model-&gt;isLoggedIn().
Passons à l'écriture des actions possible. Je vais faire les actions list, edit et delete en même temps car elle sont simple et ne nécessites pas vraiment qu'on s'y attarde.<pre class="brush:php">case 'list': //affichage de la liste des pages
	$data['liste'] = $this-&gt;page_model-&gt;getListe();
	$this-&gt;load-&gt;view('list_page',$data);
break;
case 'edit': //affichage du formulaire de modification d'une page
	if(isset($id) &amp;&amp; $id != 0){
		$data['page'] = $this-&gt;page_model-&gt;get($id);
		$this-&gt;load-&gt;view('edit_page',$data);
	}
break;
case 'delete':
	if(isset($id) &amp;&amp; $id != 0){
		if($this-&gt;page_model-&gt;delete($id)){
			echo "page supprimé";
		}
	}
break;</pre>Ici rien de bien compliqué, si $action est égale à 'list', on appelle la méthode getListe() de notre modèle Page que l'on stocke dans la variable $data, de type array, et dont l'identifiant sera 'liste'. Ensuite on charge la vue list_page en lui passant les données stockées dans la variable $data, ce qui nous permettra, lorsqu'on rédigera cette vue, de récupérer les données de la méthode getListe via la variable $liste. Vous suivez toujours?
Si l'on passe la valeur 'edit' à notre variable $action, on vérifie que notre variable $id ne soit pas nulle, et on envoi les données retournées par la méthode get() à notre vue edit_page.
Enfin, si $action vaut 'delete' et que $id n'est pas nulle, on appelle la méthode delete() de notre modèle Page.
Okay, maintenant on passe à la modification d'une page, via l'action update. Ici, le principe c'est que via l'action edit on a récupéré les données stockées dans la base et on a peuplé le formulaire de la vue edit_page. Ce formulaire renvoi les données à l'action update, via une URL du style /admin/page/update/$id. On doit donc vérifier si les données renvoyées sont bonne avant de modifier leur valeur dans la base.<pre class="brush:php">case 'update': //mise a jour de la page
	if(isset($id) &amp;&amp; $id != 0){
		//définition des règles de validation
		//$this-&gt;load-&gt;helper('form_validation');
		$this-&gt;form_validation-&gt;set_rules('titre_page','Titre','required');
		$this-&gt;form_validation-&gt;set_rules('contenu_page','Contenu','required');
		if($this-&gt;form_validation-&gt;run()){
			//les champs obligatoires sont fournis
			//on créé un tableau dans lequel on passe les infos du formulaire
			$data = array(
				'title' =&gt; $this-&gt;input-&gt;post('titre_page'),
				'content' =&gt; $this-&gt;input-&gt;post('contenu_page'),
			);
			//on regarde si le champs keywords est renseigné
			if($this-&gt;input-&gt;post('keywords_page')){
				$data['keywords'] = $this-&gt;input-&gt;post('keywords_page');
			}
			//on fait la même chose pour le champs description
			if($this-&gt;input-&gt;post('description_page')){
				$data['description'] = $this-&gt;input-&gt;post('description_page');
			}
			//enregistrement dans la base de données
			if($this-&gt;page_model-&gt;update($id,$data)){
				echo "Page mis à jour";
			}
		} else {
			//certains champs obligatoires sont manquants
			redirect('admin/page/edit/'.$id);
		}
	}
break;</pre>Pour l'insertion d'une nouvelle page dans la base de données le principe est le même, sauf que j'ai choisi de réunir les deux étapes de l'appel du formulaire et celle de la vérification des données. Voici ce que ça donne:<pre class="brush:php">case 'add': //ajout d'une page
	$this-&gt;form_validation-&gt;set_rules('titre_page','Titre','required');
	$this-&gt;form_validation-&gt;set_rules('contenu_page','Contenu','required');
	if($this-&gt;form_validation-&gt;run()){
		//les champs obligatoires sont fournis
		//on créé un tableau dans lequel on passe les infos du formulaire
		$data = array(
			'title' =&gt; $this-&gt;input-&gt;post('titre_page'),
			'content' =&gt; $this-&gt;input-&gt;post('contenu_page'),
		);
		//on regarde si le champs keywords est renseigné
		if($this-&gt;input-&gt;post('keywords_page')){
			$data['keywords'] = $this-&gt;input-&gt;post('keywords_page');
		}
		//on fait la même chose pour le champs description
		if($this-&gt;input-&gt;post('description_page')){
			$data['description'] = $this-&gt;input-&gt;post('description_page');
		}
		//enregistrement dans la base de données
		if($this-&gt;page_model-&gt;add($data)){
			echo "page ajouté";
		}
	} else {
		//certains champs obligatoires sont manquants
		$this-&gt;load-&gt;view('add_page');
	}
break;</pre><h2>Le troisième tiers de notre application: les vues</h2> On en a enfin fini avec notre contrôleur! On passe maintenant au troisième tiers de notre application, les vues. Ici je ne vais pas vous donner plus d'explications, les trois vues sont relativement simples a comprendre même en ne connaissant pas trop bien la syntaxe utilisée par CodeIgniter. Voici donc les trois vues list_page.php, add_page.php et edit_page.php.<h4>La liste des pages présentes dans la base</h4><pre class="brush:php">foreach($liste as $page):
	echo "&lt;h2&gt;".anchor('admin/page/edit/'.$page-&gt;id,$page-&gt;title)."&lt;/h2&gt;
	".$page-&gt;content."&lt;div&gt;&lt;small&gt;&lt;strong&gt;Tags:&lt;/strong&gt; ".$page-&gt;keywords."&lt;/small&gt;&lt;/div&gt;
endforeach;</pre><h4>Le formulaire d'ajout d'une page</h4><pre class="brush:php">echo form_open('admin/page/add/');
echo validation_errors();
echo form_input('titre_page',set_value('titre_page'));
echo form_textarea('contenu_page',set_value('contenu_page'));
echo form_submit('','Ajouter');
echo form_close();</pre><h4>Le formulaire de modification</h4><pre class="brush:php">echo form_open('admin/page/update/'.$page-&gt;id);
echo form_input('titre_page',$page-&gt;title);
echo form_textarea('contenu_page',$page-&gt;content);
echo form_submit('','Modifier');
echo form_close();</pre><h2>Conclusion</h2> Après avoir développé notre système de login sécurisé, on a vu ici comment construire simplement et rapidement un module de gestion pour les pages que contiendra notre futur site Web.
Avec ce nouvel article, notre système pourrait très bien s'arrêter là, il est fonctionnel et relativement sécurisé tant au niveau de l'accès par login/mot de passe, qu'au niveau de la vérification des valeurs saisies dans les différents formulaires, du fait que c'est le framework lui-même qui s'occupe de vérifier les données et d'échapper les données avant de les enregistrer dans la base.
La prochaine fois, on vera comment intégrer un éditeur de texte comme TinyMCE à notre CMS afin de pouvoir mettre en forme notre texte facilement, et puis surement d'autre petites choses. Par contre, je ne sais pas encore quand est-ce que je vous pondrait çà ;)]]></content:encoded> <wfw:commentRss>http://blog.angechierchia.com/php-mysql/developper-cms-codeigniter-la-gestion-des-pages/feed/</wfw:commentRss> <slash:comments>16</slash:comments> </item> <item><title>Système de login sécurisé &#8211; CMS CodeIgniter, partie 2</title><link>http://blog.angechierchia.com/php-mysql/login-securise-cms-codeigniter-partie-2/</link> <comments>http://blog.angechierchia.com/php-mysql/login-securise-cms-codeigniter-partie-2/#comments</comments> <pubDate>Sat, 19 Jun 2010 11:58:15 +0000</pubDate> <dc:creator>Ange Chierchia</dc:creator> <category><![CDATA[PHP/MySQL]]></category> <category><![CDATA[CMS]]></category> <category><![CDATA[CodeIgniter]]></category> <category><![CDATA[MySQL]]></category> <category><![CDATA[PHP]]></category> <guid
isPermaLink="false">http://blog.angechierchia.com/?p=912</guid> <description><![CDATA[<p><img
width="200" height="200" src="http://blog.angechierchia.com/wp-content/uploads/ci_cms.jpg" class="attachment-post-thumbnail wp-post-image" alt="ci_cms" title="ci_cms" /></p><a
title="Développer un moteur de site Web avec CodeIgniter" href="http://blog.angechierchia.com/php-mysql/moteur-site-web-developper-cms-codeigniter/">Dans mon article précédent</a>, on a vu comment installer et configurer le framework PHP CodeIgniter. Aujourd'hui, on commence le développement de notre moteur de site Web. Au programme, la base de données et le système de login sécurisé.<span
id="more-912"></span><h2>Avant de commencer</h2> Cet article est le second d'un ensemble d'article sur la création d'un système de gestion de contenu en utilisant le framework PHP CodeIgniter. Je vous invite donc à <a
title="Développer un système de gestion de contenu avec CodeIgniter" href="http://blog.angechierchia.com/php-mysql/moteur-site-web-developper-cms-codeigniter/">lire le précédent article</a> pour partir sur de bonnes bases et avoir une installation saine de CodeIgniter pour l'article actuel.
Okay, on a donc convenu mercredi que l'on partira sur un simple CMS pour l'instant, donc ici pas de gestion de catalogue produit, pas de blog, juste un gestionnaire de pages (bien qu'intégrer un blog ne soit pas franchement différent de ce dernier). Allez, on se lance!<h2>Création de la base de données</h2> Comme notre CMS sera très simple, on aura pas beaucoup de tables dans notre base de données, et quand je dis pas beaucoup, c'est déjà trop. On aura donc une table users qui nous permettra d'enregistrer les infos de connexion des différents utilisateurs de notre CMS. Ici rien de très compliqué:<pre class="brush:sql">CREATE TABLE users (
  id int NOT NULL AUTO_INCREMENT,
  username varchar(50) UNIQUE NOT NULL,
  password varchar(255) NOT NULL,
  PRIMARY KEY (id)
);</pre>On a donc ici un champ <code>username</code> qui devra être unique, un champ <code>password</code> pour le mot de passe que l'on cryptera en <code>SHA1</code>, je n'aime pas trop <code>MD5</code> même si ça peut faire l'affaire ici.
Ensuite, la dernière table de notre base sera une table dans laquelle on enregistrera le contenu des pages présentent sur le site. La encore rien de compliqué, j'ai même choisi de disposé de champs afin de renseigner les balises meta pour l'indexation des pages dans Google (un peu de SEO ne fait pas de mal).<pre class="brush:sql">CREATE TABLE pages (
  id int NOT NULL AUTO_INCREMENT,
  title varchar(100) NOT NULL,
  content longtext NOT NULL,
  keywords text NOT NULL,
  description text NOT NULL,
  PRIMARY KEY (id)
);</pre>J'ai vraiment besoin d'expliquer?
Okay, on va maintenant créer le fichier qui permettra de récupérer les données présentes dans la base de données.<h2>Création du Modèle Users_model.php</h2> Qu'est-ce que ça veut bien dire? Vous vous rappelez dans le précédent article on a parlé de Modèle MVC, et bien Users_model.php c'est le 'M' de 'MVC'. C'est ici qu'on va écrire nos fonctions "CRUD" (Create, Read, Update, Delete), on utilisera ensuite ces fonction dans notre <strong>C</strong>ontrôleur, qui traitera les données retournées par notre <strong>M</strong>odèle, et les affichera dans la <strong>V</strong>ue.
Allez on se lance, ce sera plus clair quand on aura mit les pieds dans le code. Donc, dans le dossier <em>application/models</em> on créé le fichier u<em>sers_model.php</em> qui contiendra ceci :<pre class="brush:php">&lt;?php
class User_model extends Model {
     function User_model(){
          parent::Model();
     }
}
?&gt;</pre>Ici on créé la classe <code>User_model</code> qui hérite de la classe <code>Model</code>, puis on instancie  la classe avec le constructeur <code>User_model</code> (on aurai pu aussi utiliser <code>__constructor</code> pour l'instancier).
On va maintenant créer notre fonction qui vérifiera les infos de login passées au formulaire qu'on verra plus tard. Dans la classe User_model, sous notre constructeur du même nom, ajoutez la fonction suivante :<pre class="brush:php">function validCredentials($username,$password){
     $this-&gt;load-&gt;library('encrypt');
     $password = $this-&gt;encrypt-&gt;sha1($password);
     //requête préparée, beaucoup plus sécurisé
     $q = "SELECT * FROM users WHERE username = ? AND password = ?";
     $data = array($username,$password);
     $q = $this-&gt;db-&gt;query($q,$data);
     if($q-&gt;num_rows() &gt; 0){
          $r = $q-&gt;result();
          $session_data = array('username' =&gt; $r[0]-&gt;username,'logged_in' =&gt; true);
          $this-&gt;session-&gt;set_userdata($session_data);
          return true;
     } else { return false; }
}</pre><h4>Que ce passe-t-il ici?</h4> D'abord on charge la librairie encrypt avec la commande <code>$this-&gt;load-&gt;library('encrypt')</code> ce qui nous permet d'utiliser les fonctions de cette librairie dans notre modèle. Ensuite on crypte en SHA1 le mot de passe passé en paramètre à la fonction. Enfin, on exécute la requête stockée dans la variable $q avec <code>$this-&gt;db-&gt;query()</code> en lui passant le tableau $data pour remplacer les points d'interrogation dans notre requête ; c'est une requête préparée, <a
title="Connexion à une base de données avec PDO" href="http://blog.angechierchia.com/php-mysql/utiliser-pdo-pour-les-connexion-a-une-bdd/">j'en avais parlé l'an dernier dans un article sur l'Objet PDO</a>.
Si la requête nous renvoi un résultat, on créé deux variable de sessions username et logged_in qui permettra de savoir si on a accès ou non à notre admin. Sinon validCredentials nous retourne false.
On va ajouter aussi une autre fonction pour savoir si on est bien loggué. On pourrait s'en passer mais ça nous évitera quelques lignes de code dans notre contrôleur. Celle ci est simple, ajoutez la fonction suivante à l'intérieur de votre Modèle:<pre class="brush:php">function isLoggedIn(){
     if($this-&gt;session-&gt;userdata('logged_in'))
     { return true; } else { return false; }
}</pre><h2>Il reste encore du monde? On passe au Contrôleur</h2> Maintenant qu'on a notre Modèle pour l'accès à la base de données, il est temps de les manipuler ces petites données! Créez un fichier  <em>admin.php</em> dans le dossier a<em>pplication/controllers</em> et mettez y le code suivant:<pre class="brush:php">class Admin extends Controller {
     //constructeur de la classe
     function Admin() {
          parent::Controller();
          $this-&gt;load-&gt;model('user_model');
     }
}</pre>Ici comme notre avec notre User_model, on crée une classe Admin qui hérite de la classe Controller, et on l'initialise grace à son constructeur, dans lequel on charger notre modèle User_model, ce qui nous permettra d'utiliser ses fonctions dans notre contrôleur Admin.
Maintenant que notre contrôleur est instancié, on va ajouter les fonctions (ou méthodes) qui nous permettrons d'envoyer les données du formulaire de login à notre Modèle et ainsi définir si on a accès ou non à notre backoffice.
La première fonction qu'on va inclure dans notre classe Admin, et la fonction index() qui nous servira de page d'accueil. En gros lorsqu'on accédera à l'adresse http://localhost:8888/cms/index.php/admin, c'est notre fonction iindex() qui sera appelée.<pre class="brush:php">function index(){
     if($this-&gt;user_model-&gt;isLoggedIn()){
          redirect('admin/dashboard','refresh');
     } else {
          redirect('admin/login','refresh');
     }
}</pre>Ici on vérifie si on est bien loggué, dans ce cas on redirige à l'adresse http://localhost:8888/index.php/admin/dashboard qui est le tableau de bord de notre CMS, sinon on redirige au formulaire de login.
Parlons du formulaire de login. Pour traiter les données soumises au formulaire, on va créer une méthode login() dans notre contrôleur.<pre class="brush:php">function login(){
     if($this-&gt;user_model-&gt;isLoggedIn()){
          redirect('admin','refresh');
     } else {
          //on charge la validation de formulaires
          $this-&gt;load-&gt;library('form_validation');
          //on définit les règles de succès
          $this-&gt;form_validation-&gt;set_rules('username','Login','required');
          $this-&gt;form_validation-&gt;set_rules('password','Mot de passe','required');
          //si la validation a échouée on redirige vers le formulaire de login
          if(!$this-&gt;form_validation-&gt;run()){
               $this-&gt;load-&gt;view('loginform');
          } else {
               $username = $this-&gt;input-&gt;post('username');
               $password = $this-&gt;input-&gt;post('password');
               $validCredentials = $this-&gt;user_model-&gt;validCredentials($username,$password);
               if($validCredentials){
                    redirect('admin/dashboard','refresh');
               } else {
                    $data['error_credentials'] = 'Wrong Username/Password';
                    $this-&gt;load-&gt;view('loginform',$data);
               }
          }
     }
}</pre>Ici on vérifie d'abord si on est loggué, dans ce cas on redirige vers l'admin, sinon on traite le formulaire. On charge la librairie <code>form_validation</code>, qui va nous permettre d'accéder à des fonctions de validation de champs déjà toute prête, notamment la fonction <code>set_rules</code> qui nous permettra de définir quels champs sont obligatoire, quel type de données accepter, etc. Lorsque nos règles d'acceptation sont validées, on vérifie que les login/mot de passe passés en paramètres retournent un résultant dans la base de données, via notre fonction <code>validCredentials()</code> qu'on a définit dans notre modèle <em>User_model</em>. Si un résultat est retourné, la fonction <code>validCredentials</code> créée la variable de session <code>logged_in</code> et nous redirige vers le dashboard.
Dernière méthode de notre contrôleur, la fonction dashboard() qui se chargera d'afficher notre tableau de bord.<pre class="brush:php">function dashboard(){
     if($this-&gt;user_model-&gt;isLoggedIn())
          $this-&gt;load-&gt;view('admin');
}</pre>Passons maintenant à nos deux "vues", loginform et admin. Ce sont les deux fichiers que l'on appelle avec la fonction $this-&gt;load-&gt;view() dans notre contrôleur. Dans le dossier <em>application/views</em> créez les fichier <em>loginform.php </em>et <em>admin.php</em>. La vue admin n'ayant pas trop d'intérêt pour l'instant, on va juste voir la vue loginform, qui nous permettra de voir comment créer facilement un formulaire avec CodeIgniter.<pre class="brush:php">&lt;?php
echo form_open('admin/login');
     echo form_label('Login','username');
     echo form_input('username',set_value('username'));
     echo form_label('Mot de passe','password');
     echo form_password('password');
     echo form_submit('submit','Connexion');
echo form_close();
echo validation_errors();
echo @$error_credentials;
?&gt;</pre>Ici on ouvre un tag <code>&lt;form&gt;</code> qui enverra le formulaire à la méthode <code>login()</code> du contrôleur <code>Admin</code>. Puis on affiche les erreurs de validation si il y a lieu avec la fonction <code>validation_errors()</code> et les erreurs de login/mot de passe avec notre variable <code>$error_credentials</code>.
Eh voilà, votre formulaire de login sécurisé est terminé!<h2>Conclusion</h2> Ici on a vue comment bien utiliser l'architecture trois tiers qui permet de séparer la couche présentation (nos Views), de la couche métier (notre Controller) et de la couche réseau (notre Model). Ainsi, si l'on veut changer de système de gestion de base de données et passer sur une base Oracle plutôt que MySQL, nous n'aurons qu'a changer les méthodes écrient dans notre modèle User_model.
Dans le prochain article, on s'attardera sur LE coeur de notre système, à savoir la gestion des pages. Allez, bon week-end!]]></description> <content:encoded><![CDATA[<p><img
width="200" height="200" src="http://blog.angechierchia.com/wp-content/uploads/ci_cms.jpg" class="attachment-post-thumbnail wp-post-image" alt="ci_cms" title="ci_cms" /></p><a
title="Développer un moteur de site Web avec CodeIgniter" href="http://blog.angechierchia.com/php-mysql/moteur-site-web-developper-cms-codeigniter/">Dans mon article précédent</a>, on a vu comment installer et configurer le framework PHP CodeIgniter. Aujourd'hui, on commence le développement de notre moteur de site Web. Au programme, la base de données et le système de login sécurisé.<span
id="more-912"></span><h2>Avant de commencer</h2> Cet article est le second d'un ensemble d'article sur la création d'un système de gestion de contenu en utilisant le framework PHP CodeIgniter. Je vous invite donc à <a
title="Développer un système de gestion de contenu avec CodeIgniter" href="http://blog.angechierchia.com/php-mysql/moteur-site-web-developper-cms-codeigniter/">lire le précédent article</a> pour partir sur de bonnes bases et avoir une installation saine de CodeIgniter pour l'article actuel.
Okay, on a donc convenu mercredi que l'on partira sur un simple CMS pour l'instant, donc ici pas de gestion de catalogue produit, pas de blog, juste un gestionnaire de pages (bien qu'intégrer un blog ne soit pas franchement différent de ce dernier). Allez, on se lance!<h2>Création de la base de données</h2> Comme notre CMS sera très simple, on aura pas beaucoup de tables dans notre base de données, et quand je dis pas beaucoup, c'est déjà trop. On aura donc une table users qui nous permettra d'enregistrer les infos de connexion des différents utilisateurs de notre CMS. Ici rien de très compliqué:<pre class="brush:sql">CREATE TABLE users (
  id int NOT NULL AUTO_INCREMENT,
  username varchar(50) UNIQUE NOT NULL,
  password varchar(255) NOT NULL,
  PRIMARY KEY (id)
);</pre>On a donc ici un champ <code>username</code> qui devra être unique, un champ <code>password</code> pour le mot de passe que l'on cryptera en <code>SHA1</code>, je n'aime pas trop <code>MD5</code> même si ça peut faire l'affaire ici.
Ensuite, la dernière table de notre base sera une table dans laquelle on enregistrera le contenu des pages présentent sur le site. La encore rien de compliqué, j'ai même choisi de disposé de champs afin de renseigner les balises meta pour l'indexation des pages dans Google (un peu de SEO ne fait pas de mal).<pre class="brush:sql">CREATE TABLE pages (
  id int NOT NULL AUTO_INCREMENT,
  title varchar(100) NOT NULL,
  content longtext NOT NULL,
  keywords text NOT NULL,
  description text NOT NULL,
  PRIMARY KEY (id)
);</pre>J'ai vraiment besoin d'expliquer?
Okay, on va maintenant créer le fichier qui permettra de récupérer les données présentes dans la base de données.<h2>Création du Modèle Users_model.php</h2> Qu'est-ce que ça veut bien dire? Vous vous rappelez dans le précédent article on a parlé de Modèle MVC, et bien Users_model.php c'est le 'M' de 'MVC'. C'est ici qu'on va écrire nos fonctions "CRUD" (Create, Read, Update, Delete), on utilisera ensuite ces fonction dans notre <strong>C</strong>ontrôleur, qui traitera les données retournées par notre <strong>M</strong>odèle, et les affichera dans la <strong>V</strong>ue.
Allez on se lance, ce sera plus clair quand on aura mit les pieds dans le code. Donc, dans le dossier <em>application/models</em> on créé le fichier u<em>sers_model.php</em> qui contiendra ceci :<pre class="brush:php">&lt;?php
class User_model extends Model {
     function User_model(){
          parent::Model();
     }
}
?&gt;</pre>Ici on créé la classe <code>User_model</code> qui hérite de la classe <code>Model</code>, puis on instancie  la classe avec le constructeur <code>User_model</code> (on aurai pu aussi utiliser <code>__constructor</code> pour l'instancier).
On va maintenant créer notre fonction qui vérifiera les infos de login passées au formulaire qu'on verra plus tard. Dans la classe User_model, sous notre constructeur du même nom, ajoutez la fonction suivante :<pre class="brush:php">function validCredentials($username,$password){
     $this-&gt;load-&gt;library('encrypt');
     $password = $this-&gt;encrypt-&gt;sha1($password);
     //requête préparée, beaucoup plus sécurisé
     $q = "SELECT * FROM users WHERE username = ? AND password = ?";
     $data = array($username,$password);
     $q = $this-&gt;db-&gt;query($q,$data);
     if($q-&gt;num_rows() &gt; 0){
          $r = $q-&gt;result();
          $session_data = array('username' =&gt; $r[0]-&gt;username,'logged_in' =&gt; true);
          $this-&gt;session-&gt;set_userdata($session_data);
          return true;
     } else { return false; }
}</pre><h4>Que ce passe-t-il ici?</h4> D'abord on charge la librairie encrypt avec la commande <code>$this-&gt;load-&gt;library('encrypt')</code> ce qui nous permet d'utiliser les fonctions de cette librairie dans notre modèle. Ensuite on crypte en SHA1 le mot de passe passé en paramètre à la fonction. Enfin, on exécute la requête stockée dans la variable $q avec <code>$this-&gt;db-&gt;query()</code> en lui passant le tableau $data pour remplacer les points d'interrogation dans notre requête ; c'est une requête préparée, <a
title="Connexion à une base de données avec PDO" href="http://blog.angechierchia.com/php-mysql/utiliser-pdo-pour-les-connexion-a-une-bdd/">j'en avais parlé l'an dernier dans un article sur l'Objet PDO</a>.
Si la requête nous renvoi un résultat, on créé deux variable de sessions username et logged_in qui permettra de savoir si on a accès ou non à notre admin. Sinon validCredentials nous retourne false.
On va ajouter aussi une autre fonction pour savoir si on est bien loggué. On pourrait s'en passer mais ça nous évitera quelques lignes de code dans notre contrôleur. Celle ci est simple, ajoutez la fonction suivante à l'intérieur de votre Modèle:<pre class="brush:php">function isLoggedIn(){
     if($this-&gt;session-&gt;userdata('logged_in'))
     { return true; } else { return false; }
}</pre><h2>Il reste encore du monde? On passe au Contrôleur</h2> Maintenant qu'on a notre Modèle pour l'accès à la base de données, il est temps de les manipuler ces petites données! Créez un fichier  <em>admin.php</em> dans le dossier a<em>pplication/controllers</em> et mettez y le code suivant:<pre class="brush:php">class Admin extends Controller {
     //constructeur de la classe
     function Admin() {
          parent::Controller();
          $this-&gt;load-&gt;model('user_model');
     }
}</pre>Ici comme notre avec notre User_model, on crée une classe Admin qui hérite de la classe Controller, et on l'initialise grace à son constructeur, dans lequel on charger notre modèle User_model, ce qui nous permettra d'utiliser ses fonctions dans notre contrôleur Admin.
Maintenant que notre contrôleur est instancié, on va ajouter les fonctions (ou méthodes) qui nous permettrons d'envoyer les données du formulaire de login à notre Modèle et ainsi définir si on a accès ou non à notre backoffice.
La première fonction qu'on va inclure dans notre classe Admin, et la fonction index() qui nous servira de page d'accueil. En gros lorsqu'on accédera à l'adresse http://localhost:8888/cms/index.php/admin, c'est notre fonction iindex() qui sera appelée.<pre class="brush:php">function index(){
     if($this-&gt;user_model-&gt;isLoggedIn()){
          redirect('admin/dashboard','refresh');
     } else {
          redirect('admin/login','refresh');
     }
}</pre>Ici on vérifie si on est bien loggué, dans ce cas on redirige à l'adresse http://localhost:8888/index.php/admin/dashboard qui est le tableau de bord de notre CMS, sinon on redirige au formulaire de login.
Parlons du formulaire de login. Pour traiter les données soumises au formulaire, on va créer une méthode login() dans notre contrôleur.<pre class="brush:php">function login(){
     if($this-&gt;user_model-&gt;isLoggedIn()){
          redirect('admin','refresh');
     } else {
          //on charge la validation de formulaires
          $this-&gt;load-&gt;library('form_validation');
          //on définit les règles de succès
          $this-&gt;form_validation-&gt;set_rules('username','Login','required');
          $this-&gt;form_validation-&gt;set_rules('password','Mot de passe','required');
          //si la validation a échouée on redirige vers le formulaire de login
          if(!$this-&gt;form_validation-&gt;run()){
               $this-&gt;load-&gt;view('loginform');
          } else {
               $username = $this-&gt;input-&gt;post('username');
               $password = $this-&gt;input-&gt;post('password');
               $validCredentials = $this-&gt;user_model-&gt;validCredentials($username,$password);
               if($validCredentials){
                    redirect('admin/dashboard','refresh');
               } else {
                    $data['error_credentials'] = 'Wrong Username/Password';
                    $this-&gt;load-&gt;view('loginform',$data);
               }
          }
     }
}</pre>Ici on vérifie d'abord si on est loggué, dans ce cas on redirige vers l'admin, sinon on traite le formulaire. On charge la librairie <code>form_validation</code>, qui va nous permettre d'accéder à des fonctions de validation de champs déjà toute prête, notamment la fonction <code>set_rules</code> qui nous permettra de définir quels champs sont obligatoire, quel type de données accepter, etc. Lorsque nos règles d'acceptation sont validées, on vérifie que les login/mot de passe passés en paramètres retournent un résultant dans la base de données, via notre fonction <code>validCredentials()</code> qu'on a définit dans notre modèle <em>User_model</em>. Si un résultat est retourné, la fonction <code>validCredentials</code> créée la variable de session <code>logged_in</code> et nous redirige vers le dashboard.
Dernière méthode de notre contrôleur, la fonction dashboard() qui se chargera d'afficher notre tableau de bord.<pre class="brush:php">function dashboard(){
     if($this-&gt;user_model-&gt;isLoggedIn())
          $this-&gt;load-&gt;view('admin');
}</pre>Passons maintenant à nos deux "vues", loginform et admin. Ce sont les deux fichiers que l'on appelle avec la fonction $this-&gt;load-&gt;view() dans notre contrôleur. Dans le dossier <em>application/views</em> créez les fichier <em>loginform.php </em>et <em>admin.php</em>. La vue admin n'ayant pas trop d'intérêt pour l'instant, on va juste voir la vue loginform, qui nous permettra de voir comment créer facilement un formulaire avec CodeIgniter.<pre class="brush:php">&lt;?php
echo form_open('admin/login');
     echo form_label('Login','username');
     echo form_input('username',set_value('username'));
     echo form_label('Mot de passe','password');
     echo form_password('password');
     echo form_submit('submit','Connexion');
echo form_close();
echo validation_errors();
echo @$error_credentials;
?&gt;</pre>Ici on ouvre un tag <code>&lt;form&gt;</code> qui enverra le formulaire à la méthode <code>login()</code> du contrôleur <code>Admin</code>. Puis on affiche les erreurs de validation si il y a lieu avec la fonction <code>validation_errors()</code> et les erreurs de login/mot de passe avec notre variable <code>$error_credentials</code>.
Eh voilà, votre formulaire de login sécurisé est terminé!<h2>Conclusion</h2> Ici on a vue comment bien utiliser l'architecture trois tiers qui permet de séparer la couche présentation (nos Views), de la couche métier (notre Controller) et de la couche réseau (notre Model). Ainsi, si l'on veut changer de système de gestion de base de données et passer sur une base Oracle plutôt que MySQL, nous n'aurons qu'a changer les méthodes écrient dans notre modèle User_model.
Dans le prochain article, on s'attardera sur LE coeur de notre système, à savoir la gestion des pages. Allez, bon week-end!]]></content:encoded> <wfw:commentRss>http://blog.angechierchia.com/php-mysql/login-securise-cms-codeigniter-partie-2/feed/</wfw:commentRss> <slash:comments>9</slash:comments> </item> <item><title>Développer un moteur de site Web avec CodeIgniter</title><link>http://blog.angechierchia.com/php-mysql/moteur-site-web-developper-cms-codeigniter/</link> <comments>http://blog.angechierchia.com/php-mysql/moteur-site-web-developper-cms-codeigniter/#comments</comments> <pubDate>Wed, 16 Jun 2010 19:09:06 +0000</pubDate> <dc:creator>Ange Chierchia</dc:creator> <category><![CDATA[PHP/MySQL]]></category> <category><![CDATA[CMS]]></category> <category><![CDATA[CodeIgniter]]></category> <category><![CDATA[PHP]]></category> <guid
isPermaLink="false">http://blog.angechierchia.com/?p=877</guid> <description><![CDATA[<p><img
width="200" height="200" src="http://blog.angechierchia.com/wp-content/uploads/ci_cms.jpg" class="attachment-post-thumbnail wp-post-image" alt="ci_cms" title="ci_cms" /></p>Aujourd'hui, on va voir comment créer un moteur de site Web, aussi appelé système de gestion de contenu, en utilisant le très bon (est facile à utiliser) Framework CodeIgniter. Comme la tâche va être longue, j'ai prévu d'étaler cet article en plusieurs parties. On commence donc aujourd'hui avec la première partie du développement de notre CMS utilisant CodeIgniter.<span
id="more-877"></span><h2>Introduction</h2> Pourquoi choisir d'utiliser un framework PHP pour développer un tel projet? La raison est simple : pourquoi perdre son temps à réinventer la roue quand on a la possibilité d'utiliser des fonctions déjà toutes prêtes? Un framework est donc fort utile dans ce type de projet, surtout pour tout le back-end du site, ce que l'utilisateur ne voit pas, et sur lequel nous les développeurs, passons pas mal de temps à développer pour rendre la vie facile à l'utilisateur du site.
Pourquoi CodeIgniter comme base de travail? Pour moi qui n'avais pas l'habitude d'utiliser des frameworks PHP (j'aime bien me compliquer la vie), j'ai trouvé que CodeIgniter était le plus simple à prendre en main pour moi qui n'avais pour dire jamais fais de PHP Objet (ouh! le nul!).
Aussi, un framework permet de passer plus de temps sur le développement pur plutôt que de perdre son temps sur des petites choses bien chiantes comme il faut (la validation de formulaire me sort par les trous de nez!).<h2>Quelles fonctionnalités pour notre CMS?</h2> Avant de se lancer à la va vite dans le développement, il faut se demander à quoi servira notre moteur de site, est-ce qu'on gère un blog, un catalogue de produit, ou bien un simple site vitrine? Étant actuellement entrain de développer un site permettant d'afficher un catalogue de produits, j'aurai tendance à vouloir vous proposer de partir sur cette idée. Pour commencer je vous propose de nous concentrer sur une simple vitrine (ce qu'il y a de plus simple), et on verra ensuite pour le catalogue de produit.
Notre système devra donc comprendre:<ul><li>un accès sécurisé au back-end.</li><li>un gestionnaire de page</li><li>on devra pouvoir uploader des images</li><li>pourquoi pas pouvoir modifier le design du site?</li></ul><h2>Installer et configurer CodeIgniter</h2> <img
class="aligncenter size-full wp-image-881" title="download_ci" src="http://blog.angechierchia.com/wp-content/uploads/download_ci.jpg" alt="" width="603" height="143" /> Aujourd'hui on va simplement préparer le terrain en téléchargeant et en installant le framework sur notre serveur Web. Rendez-vous sur le site du framework et <a
title="Télécharger CodeIgniter" href="http://codeigniter.com/downloads/" target="_blank">télécharger la version actuelle de CodeIgniter</a>, au moment ou j'écris c'est la version 1.7.2. <img
class="size-full wp-image-885 alignright" title="screenshot 2010-06-1620.33.20" src="http://blog.angechierchia.com/wp-content/uploads/screenshot-2010-06-1620.33.20.jpg" alt="" width="210" height="509" /> Dézipper le contenu de l'archive et transférez les dossiers de CodeIgniter à la racine de votre serveur. Vous devriez avoir une arborescence comme présenté à droite:
Les dossiers important ici sont le dossier <em>system</em>, qui renferme tout les fichiers nécessaires au fonctionnement de CodeIgniter, et le dossier <em>application</em>, qu'il est possible de sortir du dossier <em>system</em> pour une meilleure organisation. Aussi on pourra se passer du dossier <em>user_guide</em> qui n'est qu'une version local du guide utilisateur disponible sur le site de CodeIgniter.
Vous remarquerez aussi les dossiers <em>controllers</em>, <em>models</em> et <em>views</em>, ce sont nos trois dossiers de travail. Eh oui, CodeIgniter utilise le Modèle MVC (Modèle-Vue-Controleur) aussi appeler application trois tiers, ce qui permet de séparer les opérations d'accès à notre base de données des opérations de traitement de ces données, ainsi que l'affichage de ces même données.
Passons maintenant à la configuration de CodeIgniter.
Ici c'est très simple, il suffit de modifier la variable <code>$config['base_url']</code> du fichier <em>application/config/config.php</em> en renseigner l'adresse de notre serveur.<pre class="brush:php">$config['base_url'] = "http://localhost:8888/codeigniter/";</pre>On va ensuite configurer l'accès à la base de données. Pour cela, direction <em>application/config/database.php</em> et renseigner les lignes suivantes avec vos informations de connexion.<pre class="brush:php">$db['default']['hostname'] = "localhost";
$db['default']['username'] = "root";
$db['default']['password'] = "root";
$db['default']['database'] = "database_ci";
$db['default']['dbdriver'] = "mysql";</pre>Et voilà! Si vous vous rendez à l'adresse où vous avez installer CodeIgniter vous devriez avoir une joli page "Hello World" si vous avez bien suivi les étapes ci dessus.
Allez, je vous laisse ici pour aujourd'hui, la prochaine fois on s'intéressera à la création de la base de données et au système de login sécurisé.]]></description> <content:encoded><![CDATA[<p><img
width="200" height="200" src="http://blog.angechierchia.com/wp-content/uploads/ci_cms.jpg" class="attachment-post-thumbnail wp-post-image" alt="ci_cms" title="ci_cms" /></p>Aujourd'hui, on va voir comment créer un moteur de site Web, aussi appelé système de gestion de contenu, en utilisant le très bon (est facile à utiliser) Framework CodeIgniter. Comme la tâche va être longue, j'ai prévu d'étaler cet article en plusieurs parties. On commence donc aujourd'hui avec la première partie du développement de notre CMS utilisant CodeIgniter.<span
id="more-877"></span><h2>Introduction</h2> Pourquoi choisir d'utiliser un framework PHP pour développer un tel projet? La raison est simple : pourquoi perdre son temps à réinventer la roue quand on a la possibilité d'utiliser des fonctions déjà toutes prêtes? Un framework est donc fort utile dans ce type de projet, surtout pour tout le back-end du site, ce que l'utilisateur ne voit pas, et sur lequel nous les développeurs, passons pas mal de temps à développer pour rendre la vie facile à l'utilisateur du site.
Pourquoi CodeIgniter comme base de travail? Pour moi qui n'avais pas l'habitude d'utiliser des frameworks PHP (j'aime bien me compliquer la vie), j'ai trouvé que CodeIgniter était le plus simple à prendre en main pour moi qui n'avais pour dire jamais fais de PHP Objet (ouh! le nul!).
Aussi, un framework permet de passer plus de temps sur le développement pur plutôt que de perdre son temps sur des petites choses bien chiantes comme il faut (la validation de formulaire me sort par les trous de nez!).<h2>Quelles fonctionnalités pour notre CMS?</h2> Avant de se lancer à la va vite dans le développement, il faut se demander à quoi servira notre moteur de site, est-ce qu'on gère un blog, un catalogue de produit, ou bien un simple site vitrine? Étant actuellement entrain de développer un site permettant d'afficher un catalogue de produits, j'aurai tendance à vouloir vous proposer de partir sur cette idée. Pour commencer je vous propose de nous concentrer sur une simple vitrine (ce qu'il y a de plus simple), et on verra ensuite pour le catalogue de produit.
Notre système devra donc comprendre:<ul><li>un accès sécurisé au back-end.</li><li>un gestionnaire de page</li><li>on devra pouvoir uploader des images</li><li>pourquoi pas pouvoir modifier le design du site?</li></ul><h2>Installer et configurer CodeIgniter</h2> <img
class="aligncenter size-full wp-image-881" title="download_ci" src="http://blog.angechierchia.com/wp-content/uploads/download_ci.jpg" alt="" width="603" height="143" /> Aujourd'hui on va simplement préparer le terrain en téléchargeant et en installant le framework sur notre serveur Web. Rendez-vous sur le site du framework et <a
title="Télécharger CodeIgniter" href="http://codeigniter.com/downloads/" target="_blank">télécharger la version actuelle de CodeIgniter</a>, au moment ou j'écris c'est la version 1.7.2. <img
class="size-full wp-image-885 alignright" title="screenshot 2010-06-1620.33.20" src="http://blog.angechierchia.com/wp-content/uploads/screenshot-2010-06-1620.33.20.jpg" alt="" width="210" height="509" /> Dézipper le contenu de l'archive et transférez les dossiers de CodeIgniter à la racine de votre serveur. Vous devriez avoir une arborescence comme présenté à droite:
Les dossiers important ici sont le dossier <em>system</em>, qui renferme tout les fichiers nécessaires au fonctionnement de CodeIgniter, et le dossier <em>application</em>, qu'il est possible de sortir du dossier <em>system</em> pour une meilleure organisation. Aussi on pourra se passer du dossier <em>user_guide</em> qui n'est qu'une version local du guide utilisateur disponible sur le site de CodeIgniter.
Vous remarquerez aussi les dossiers <em>controllers</em>, <em>models</em> et <em>views</em>, ce sont nos trois dossiers de travail. Eh oui, CodeIgniter utilise le Modèle MVC (Modèle-Vue-Controleur) aussi appeler application trois tiers, ce qui permet de séparer les opérations d'accès à notre base de données des opérations de traitement de ces données, ainsi que l'affichage de ces même données.
Passons maintenant à la configuration de CodeIgniter.
Ici c'est très simple, il suffit de modifier la variable <code>$config['base_url']</code> du fichier <em>application/config/config.php</em> en renseigner l'adresse de notre serveur.<pre class="brush:php">$config['base_url'] = "http://localhost:8888/codeigniter/";</pre>On va ensuite configurer l'accès à la base de données. Pour cela, direction <em>application/config/database.php</em> et renseigner les lignes suivantes avec vos informations de connexion.<pre class="brush:php">$db['default']['hostname'] = "localhost";
$db['default']['username'] = "root";
$db['default']['password'] = "root";
$db['default']['database'] = "database_ci";
$db['default']['dbdriver'] = "mysql";</pre>Et voilà! Si vous vous rendez à l'adresse où vous avez installer CodeIgniter vous devriez avoir une joli page "Hello World" si vous avez bien suivi les étapes ci dessus.
Allez, je vous laisse ici pour aujourd'hui, la prochaine fois on s'intéressera à la création de la base de données et au système de login sécurisé.]]></content:encoded> <wfw:commentRss>http://blog.angechierchia.com/php-mysql/moteur-site-web-developper-cms-codeigniter/feed/</wfw:commentRss> <slash:comments>5</slash:comments> </item> <item><title>Afficher une date relative en PHP</title><link>http://blog.angechierchia.com/php-mysql/afficher-une-date-relative-en-php/</link> <comments>http://blog.angechierchia.com/php-mysql/afficher-une-date-relative-en-php/#comments</comments> <pubDate>Mon, 12 Apr 2010 11:28:52 +0000</pubDate> <dc:creator>Ange Chierchia</dc:creator> <category><![CDATA[PHP/MySQL]]></category> <category><![CDATA[date]]></category> <category><![CDATA[PHP]]></category> <guid
isPermaLink="false">http://www.angechierchia.com/?p=646</guid> <description><![CDATA[<p><img
width="200" height="200" src="http://blog.angechierchia.com/wp-content/uploads/phpcutetime.jpg" class="attachment-post-thumbnail wp-post-image" alt="phpcutetime" title="phpcutetime" /></p>Hier, je vous présentais le <a
title="Afficher de jolies dates en jQuery grâce à CuteTime" href="http://www.angechierchia.com/ajax-javascript/plugin-jquery-cutetime-affichez-vos-dates-comme-sur-twitter/">plugin jQuery CuteTime</a>, aujourd'hui, je vous propose de faire la même chose, mais cette fois en PHP, grâce à une fonction qu'a proposé <a
title="Temps relatif en PHP" href="http://blog.jaysalvat.com/articles/temps-relatif-en-php.php" target="_blank">Jay Salvat sur son blog</a>.<span
id="more-646"></span> Comme CuteTime, la fonction de Jay permet de retourner une date relative, comme sur Twitter. Avec la fonction de Jay Salvat, il est possible de passer plusieurs formats de dates, à la différence du plugin CuteTime ou il n'accepte que des dates formatées de la façon suivante : 2010/04/12 13:15:30. Ici on peut fournir une date du style 12 avril 2010 13:15 grâce à la fonction PHP strtotime qui permet de transformer une chaîne en timestamp.
Bon trêve de blabla, voici la fonction que propose Jay pour parvenir un résultat similaire à CuteTime, mais cette fois côté serveur:<pre class="brush:php">&lt;?php
/**
 * Fonction getRelativeTime
 * par Jay Salvat - http://blog.jaysalvat.com/
 */
function getRelativeTime($date) {
    // Déduction de la date donnée à la date actuelle
    $time = time() - strtotime($date); 
    // Calcule si le temps est passé ou à venir
    if ($time &gt; 0) {
        $when = "il y a";
    } else if ($time &lt; 0) {
        $when = "dans environ";
    } else {
        return "il y a moins d'une seconde";
    }
    $time = abs($time); 
    // Tableau des unités et de leurs valeurs en secondes
    $times = array( 31104000 =&gt;  'an{s}',       // 12 * 30 * 24 * 60 * 60 secondes
                    2592000  =&gt;  'mois',        // 30 * 24 * 60 * 60 secondes
                    86400    =&gt;  'jour{s}',     // 24 * 60 * 60 secondes
                    3600     =&gt;  'heure{s}',    // 60 * 60 secondes
                    60       =&gt;  'minute{s}',   // 60 secondes
                    1        =&gt;  'seconde{s}'); // 1 seconde         
    foreach ($times as $seconds =&gt; $unit) {
        // Calcule le delta entre le temps et l'unité donnée
        $delta = round($time / $seconds); 
        // Si le delta est supérieur à 1
        if ($delta &gt;= 1) {
            // L'unité est au singulier ou au pluriel ?
            if ($delta == 1) {
                $unit = str_replace('{s}', '', $unit);
            } else {
                $unit = str_replace('{s}', 's', $unit);
            }
            // Retourne la chaine adéquate
            return $when." ".$delta." ".$unit;
        }
    }
}
?&gt;</pre>Pour l'utiliser, il suffit ensuite d'en faire l'appel comme ça :<pre class="brush:php">&lt;?php echo getRelativeTime ('2010-03-01 13:25:00'); ?&gt;</pre>Si vous utiliser un gestionnaire de contenu comme Wordpress, vous pouvez aussi inclure cette fonction dans le fichier function.php de votre thème, vous pourrez donc l'utiliser dans votre thème Wordpress.]]></description> <content:encoded><![CDATA[<p><img
width="200" height="200" src="http://blog.angechierchia.com/wp-content/uploads/phpcutetime.jpg" class="attachment-post-thumbnail wp-post-image" alt="phpcutetime" title="phpcutetime" /></p>Hier, je vous présentais le <a
title="Afficher de jolies dates en jQuery grâce à CuteTime" href="http://www.angechierchia.com/ajax-javascript/plugin-jquery-cutetime-affichez-vos-dates-comme-sur-twitter/">plugin jQuery CuteTime</a>, aujourd'hui, je vous propose de faire la même chose, mais cette fois en PHP, grâce à une fonction qu'a proposé <a
title="Temps relatif en PHP" href="http://blog.jaysalvat.com/articles/temps-relatif-en-php.php" target="_blank">Jay Salvat sur son blog</a>.<span
id="more-646"></span> Comme CuteTime, la fonction de Jay permet de retourner une date relative, comme sur Twitter. Avec la fonction de Jay Salvat, il est possible de passer plusieurs formats de dates, à la différence du plugin CuteTime ou il n'accepte que des dates formatées de la façon suivante : 2010/04/12 13:15:30. Ici on peut fournir une date du style 12 avril 2010 13:15 grâce à la fonction PHP strtotime qui permet de transformer une chaîne en timestamp.
Bon trêve de blabla, voici la fonction que propose Jay pour parvenir un résultat similaire à CuteTime, mais cette fois côté serveur:<pre class="brush:php">&lt;?php
/**
 * Fonction getRelativeTime
 * par Jay Salvat - http://blog.jaysalvat.com/
 */
function getRelativeTime($date) {
    // Déduction de la date donnée à la date actuelle
    $time = time() - strtotime($date); 
    // Calcule si le temps est passé ou à venir
    if ($time &gt; 0) {
        $when = "il y a";
    } else if ($time &lt; 0) {
        $when = "dans environ";
    } else {
        return "il y a moins d'une seconde";
    }
    $time = abs($time); 
    // Tableau des unités et de leurs valeurs en secondes
    $times = array( 31104000 =&gt;  'an{s}',       // 12 * 30 * 24 * 60 * 60 secondes
                    2592000  =&gt;  'mois',        // 30 * 24 * 60 * 60 secondes
                    86400    =&gt;  'jour{s}',     // 24 * 60 * 60 secondes
                    3600     =&gt;  'heure{s}',    // 60 * 60 secondes
                    60       =&gt;  'minute{s}',   // 60 secondes
                    1        =&gt;  'seconde{s}'); // 1 seconde         
    foreach ($times as $seconds =&gt; $unit) {
        // Calcule le delta entre le temps et l'unité donnée
        $delta = round($time / $seconds); 
        // Si le delta est supérieur à 1
        if ($delta &gt;= 1) {
            // L'unité est au singulier ou au pluriel ?
            if ($delta == 1) {
                $unit = str_replace('{s}', '', $unit);
            } else {
                $unit = str_replace('{s}', 's', $unit);
            }
            // Retourne la chaine adéquate
            return $when." ".$delta." ".$unit;
        }
    }
}
?&gt;</pre>Pour l'utiliser, il suffit ensuite d'en faire l'appel comme ça :<pre class="brush:php">&lt;?php echo getRelativeTime ('2010-03-01 13:25:00'); ?&gt;</pre>Si vous utiliser un gestionnaire de contenu comme Wordpress, vous pouvez aussi inclure cette fonction dans le fichier function.php de votre thème, vous pourrez donc l'utiliser dans votre thème Wordpress.]]></content:encoded> <wfw:commentRss>http://blog.angechierchia.com/php-mysql/afficher-une-date-relative-en-php/feed/</wfw:commentRss> <slash:comments>4</slash:comments> </item> <item><title>Récupérer la valeur d&#8217;un champ personnalisé dans WordPress hors de la Boucle</title><link>http://blog.angechierchia.com/php-mysql/wordpress-custom-field-hors-de-la-loop/</link> <comments>http://blog.angechierchia.com/php-mysql/wordpress-custom-field-hors-de-la-loop/#comments</comments> <pubDate>Wed, 02 Sep 2009 20:26:46 +0000</pubDate> <dc:creator>Ange Chierchia</dc:creator> <category><![CDATA[PHP/MySQL]]></category> <category><![CDATA[custom field]]></category> <category><![CDATA[MySQL]]></category> <category><![CDATA[PDO]]></category> <category><![CDATA[PHP]]></category> <category><![CDATA[Wordpress]]></category> <guid
isPermaLink="false">http://www.angechierchia.com/?p=386</guid> <description><![CDATA[Aujourd&#8217;hui je vais vous faire partager une petite astuce que j&#8217;ai dut utiliser pour l&#8217;un de mes projets en cours. La problématique : Comment afficher un custom field lorsqu&#8217;on est hors de la loop wordpress? Il y a quelques jours, je travaillais sur l&#8217;intégration d&#8217;un design dans le système de blog WordPress, plateforme que j&#8217;utilise [...]]]></description> <content:encoded><![CDATA[<p>Aujourd&#8217;hui je vais vous faire partager une petite astuce que j&#8217;ai dut utiliser pour l&#8217;un de mes projets en cours. La problématique : Comment afficher un custom field lorsqu&#8217;on est hors de la loop wordpress?<span
id="more-386"></span></p><p>Il y a quelques jours, je travaillais sur l&#8217;intégration d&#8217;un design dans le système de blog WordPress, plateforme que j&#8217;utilise notamment ici. Dans ma charte graphique, chaque élément du menu de navigation est suivi d&#8217;une petite phrase expliquant ce que l&#8217;on trouvera dans la page lié. J&#8217;avais décidé d&#8217;enregistrer ces phrases dans un champ personnalisé pour pouvoir l&#8217;afficher très simplement et rapidement avec l&#8217;une des fonctions qu&#8217;intègre WordPress comme wp_page_menu() ou wp_list_page().</p><p>Malheureusement, comme me l&#8217;a confirmé mon ami @clawfire, ces deux fonctions n&#8217;entrent pas dans ce qu&#8217;on appelle la Boucle ou Loop dans le jargon WP, il me fallait donc coder moi même l&#8217;affichage du menu intégrant ce champ personnalisé. Voilà la marche à suivre</p><h2>Sur quelles tables de la base de données doit on travailler?</h2><p>D&#8217;abord il faut savoir dans quelles tables sont enregistrés les données qui nous intéresses.  On remarquera que WordPress enregistre les données d&#8217;un article dans la table wp_posts, et la table wp_postmeta enregistre d&#8217;autres informations moins primordiales comme par exemple quel modèle de page utilise l&#8217;article, ET les différents champs personnalisés attachés à l&#8217;article.</p><h2>Au boulot!</h2><p>Maintenant qu&#8217;on sait sur quoi faire notre requête SQL, il est temps de passer à la programmation!</p><pre class="brush:php">try{
$db = new PDO('mysql:dbname=database;host=localhost','root','pass');
} catch(PDOException $e){
echo "connexion echoué : ".$e-&gt;getMessage();
}
//on récupère l'ID de la page statique qui sert de page d'accueil du site
$strHomepage = "SELECT option_value FROM wp_options WHERE option_name = 'page_on_front'";
$stmt = $db-&gt;prepare($strHomepage);
$stmt-&gt;execute();
$home_id = $stmt-&gt;fetch(PDO::FETCH_OBJ)-&gt;option_value;
//on récupère la valeur de l'option siteurl
$strHomeUrl = "SELECT option_value FROM wp_options WHERE option_name = 'siteurl'";
$stmt = $db-&gt;prepare($strHomeUrl);
$stmt-&gt;execute();
$home_url = $stmt-&gt;fetch(PDO::FETCH_OBJ)-&gt;option_value;
//on récupère les infos neccessaires à l'affichage du menu avec la taglines
$strTagline = "SELECT * FROM wp_posts p, wp_postmeta m WHERE p.ID = m.post_id
AND meta_key = 'nav_tagline' AND post_parent = 0
AND post_type ='page' AND post_status = 'publish'
ORDER BY menu_order ASC";
//echo $home_id;
$stmt = $db-&gt;prepare($strTagline);
$stmt-&gt;execute();
echo "&lt;ul&gt;";
while($r = $stmt-&gt;fetch()){
if($r['ID'] == $home_id){
} else {
echo "&lt;li&gt;&lt;a href='".$home_url."/?page_id=".$r['ID']."'&gt;".$r['post_title']."&lt;span&gt;".$r['meta_value']."&lt;/span&gt;&lt;/a&gt;&lt;/li&gt;";
}
}
echo "&lt;ul&gt;";</pre><p>Et voilà, notre menu avec un custom field est terminé!</p> ]]></content:encoded> <wfw:commentRss>http://blog.angechierchia.com/php-mysql/wordpress-custom-field-hors-de-la-loop/feed/</wfw:commentRss> <slash:comments>3</slash:comments> </item> </channel> </rss>
