<?xml version="1.0" encoding="UTF-8"?><?xml-stylesheet href="https://chierchia.fr/wp-content/plugins/pretty-rss-feeds/xslt/pretty-feed.xsl" type="text/xsl" media="screen" ?><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>php - Ange Chierchia</title>
	<atom:link href="https://chierchia.fr/tag/php/feed/" rel="self" type="application/rss+xml" />
	<link>https://chierchia.fr/tag/php/</link>
	<description>Développeur Web full-stack</description>
	<lastBuildDate>Sat, 22 Mar 2025 19:37:02 +0000</lastBuildDate>
	<language>fr-FR</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	

<image>
	<url>https://chierchia.fr/wp-content/uploads/cropped-16350293-SSDKVqo3-32x32.jpg</url>
	<title>php - Ange Chierchia</title>
	<link>https://chierchia.fr/tag/php/</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
					<title>Tous les éditeurs de code que j’ai utilisé</title>
					<link>https://chierchia.fr/2025/03/tous-les-editeurs-de-code-que-jai-utilise/</link>
					<comments>https://chierchia.fr/2025/03/tous-les-editeurs-de-code-que-jai-utilise/#comments</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Sat, 22 Mar 2025 18:48:45 +0000</pubDate>
				<category><![CDATA[Journal]]></category>
		<category><![CDATA[atom]]></category>
		<category><![CDATA[coda]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[personnel]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[vscode]]></category>
		<guid isPermaLink="false">https://chierchia.fr/?p=4429</guid>

					<description><![CDATA[Ceci est un post que j’ai eu envie d’écrire pour aucune autre raison que celle d’être tombé sur l’un des premiers article du blog de Paweł Gryzbek. Je ne vais pas partager mon «&#160;setup&#160;» mais plutôt tous les IDE, au sens large, que j’ai utilisé jusqu’à maintenant pour le développement Web. J’ai adoré utiliser Espresso [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class='e-content'>
<p>Ceci est un post que j’ai eu envie d’écrire pour aucune autre raison que celle d’être tombé sur <a href="https://pawelgrzybek.com/my-web-development-setup/" target="_blank" rel="noreferrer noopener">l’un des premiers article</a> du blog de Paweł Gryzbek. Je ne vais pas partager mon «&nbsp;setup&nbsp;» mais plutôt tous les IDE, au sens large, que j’ai utilisé jusqu’à maintenant pour le développement Web.</p>



<ul class="wp-block-list">
<li>Microsoft FrontPage <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f922.png" alt="🤢" class="wp-smiley" style="height: 1em; max-height: 1em;" /></li>



<li>Dreamweaver MX</li>



<li>Komodo Edit</li>



<li>Espresso</li>



<li>Coda</li>



<li>Adobe Brackets</li>



<li>Sublime Text 2</li>



<li>Sublime Text 3</li>



<li>Atom</li>



<li>Visual Studio Code</li>
</ul>



<p>J’ai adoré utiliser Espresso pour le CSS et Coda pour le PHP, mais j’avoue que mon préféré jusqu’ici c’est VSCode. Déjà avant que GitHub soit racheté par Microsoft j’adorais coder dans Atom. Ça fait maintenant plus de 6 ans que je code dans VSCode et je ne compte pas changer !</p>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2025/03/tous-les-editeurs-de-code-que-jai-utilise/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
			</item>
		<item>
					<title>dimanche 17 novembre 2024 @ 13:00:25</title>
					<link>https://chierchia.fr/2024/11/dimanche-17-novembre-2024-130025/</link>
					<comments>https://chierchia.fr/2024/11/dimanche-17-novembre-2024-130025/#respond</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Sun, 17 Nov 2024 12:00:25 +0000</pubDate>
				<category><![CDATA[Notes]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[wordpress]]></category>
		<guid isPermaLink="false">https://chierchia.fr/?p=3562</guid>

					<description><![CDATA[Je viens de modifier mon script dans le functions.php de mon thème WordPress pour utiliser automatiquement la date et l&#8217;heure du jour, pour mes notes auxquelles je ne donne pas de titre, plutôt qu&#8217;un morceau du contenu. Si jamais ça vous intéresse, voilà comment j&#8217;ai fait. C&#8217;est très basique :]]></description>
										<content:encoded><![CDATA[<div class='e-content'>
<div class="wp-block-indieblocks-reply"><div class="u-in-reply-to h-cite"><p><i>In reply to <a class="u-url" href="https://chierchia.fr/2024/03/generer-automatiquement-le-titre-dun-post-dans-wordpress/">https://chierchia.fr/2024/03/generer-automatiquement-le-titre-dun-post-dans-wordpress/</a>.</i></p></div><div class="e-content">
<p>Je viens de modifier mon script dans le <code>functions.php</code> de mon thème WordPress pour utiliser automatiquement la date et l&rsquo;heure du jour, pour mes notes auxquelles je ne donne pas de titre, plutôt qu&rsquo;un morceau du contenu.<br></p>



<p>Si jamais ça vous intéresse, voilà comment j&rsquo;ai fait. C&rsquo;est très basique :</p>



<pre class="wp-block-code"><code>add_filter( 'wp_insert_post_data' , 'generate_post_title' , '99', 1 ); 
function generate_post_title($data) {
  if(empty($data&#91;'post_title'])) {

    $date = $data&#91;'post_date'];
    $timestamp = strtotime($date);
    $data&#91;'post_title'] = date_i18n('l d F Y @ H:i:s', $timestamp);
    
  }
  return $data; // Returns the modified data.
}</code></pre>
</div></div>
</div>]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2024/11/dimanche-17-novembre-2024-130025/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
					<title>Nettoyer une chaîne de caractères avec PHP</title>
					<link>https://chierchia.fr/2016/03/nettoyer-une-chaine-de-caracteres-php-permalien/</link>
					<comments>https://chierchia.fr/2016/03/nettoyer-une-chaine-de-caracteres-php-permalien/#respond</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Sun, 27 Mar 2016 13:10:26 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[back-end]]></category>
		<category><![CDATA[php]]></category>
		<guid isPermaLink="false">https://nighcrawl.com/blog/2016/03/nettoyer-une-chaine-de-caracteres-php-permalien</guid>

					<description><![CDATA[Quoi de plus simple que de nettoyer une chaîne de caractères pour l’utiliser comme URL vers une page, un article ou tout autre contenu publié sur Internet en général ? Et pourtant… Bien que très simple à mettre en place dans les faits, quand vient l’heure de nettoyer une chaîne de caractères pleine d’accents, de [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class='e-content'>Quoi de plus simple que de nettoyer une chaîne de caractères pour l’utiliser comme URL vers une page, un article ou tout autre contenu publié sur Internet en général ? Et pourtant…</p>
<p>Bien que très simple à mettre en place dans les faits, quand vient l’heure de nettoyer une chaîne de caractères pleine d’accents, de signes de ponctuation et autres caractères spéciaux, c’est la galère.<span id="more-1339"></span></p>
<p>Voici la fonction que j’utilise pour nettoyer mes chaînes de caractères et les utiliser comme <a href="https://fr.wikipedia.org/wiki/Permalien" target="_blank" rel="noopener">permalien</a></p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>function clean($string) {
	$string = html_entity_decode(preg_replace('/&amp;([a-zA-Z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);/i', '$1', htmlentities($string, ENT_QUOTES, 'UTF-8')), ENT_QUOTES, 'UTF-8');
	$string = strtolower(trim(preg_replace('/[^0-9a-z]+/i', '-', $string), '-'));

	return $string;
}
</code></pre>
</div>
</div>
<p>Le principe ici est très simple. D’abord on converti tout les caractères qui peuvent l’être en entités HTML à l’aide de la fonction <code class="language-plaintext highlighter-rouge">htmlentities()</code>, ensuite on remplace chaque caractère par son équivalent sans accent, cédille, etc.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>preg_replace('/&amp;([a-zA-Z]{1,2})(?:acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);/i', '$1', htmlentities($string, ENT_QUOTES, 'UTF-8')), ENT_QUOTES, 'UTF-8');
</code></pre>
</div>
</div>
<p>En appliquant la fonction <code class="language-plaintext highlighter-rouge">html_entity_decode()</code> sur la chaîne nettoyée de tout caractère accentué, on transforme à nouveau les entités HTML restantes en caractères normaux.</p>
<p>Enfin, on remplace tous les caractères n’étant pas des lettres ou des chiffres par un tiret, puis on supprime les tirets en trop à l’aide de la fonction <code class="language-plaintext highlighter-rouge">trim()</code>.</p>
<p>J’espère que ce petit morceau de code vous aura été utile :).</p>
<p>N’hésitez pas à partager votre solution, ou vos remarques dans les commentaires.</p>
<p>Tchô !</p></div>
]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2016/03/nettoyer-une-chaine-de-caracteres-php-permalien/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
					<title>Créer un pixel de suivi</title>
					<link>https://chierchia.fr/2016/03/creer-un-pixel-de-suivi/</link>
					<comments>https://chierchia.fr/2016/03/creer-un-pixel-de-suivi/#respond</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Tue, 08 Mar 2016 18:10:44 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[analytics]]></category>
		<category><![CDATA[back-end]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[pixel]]></category>
		<guid isPermaLink="false">https://nighcrawl.com/blog/2016/03/creer-un-pixel-de-suivi</guid>

					<description><![CDATA[Ces dernières semaines, j’ai essentiellement travaillé sur la conception d’un cookie/pixel de suivi et le traitement des informations récupérées, pour en faire des tableaux statistiques et autres graphiques de fréquentation par la suite. Je vous parlerai peut-être de mon expérience avec la librairie JavaScript C3.js dans un prochain article. L’intérêt d’un tel dispositif est de pouvoir [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class='e-content'>Ces dernières semaines, j’ai essentiellement travaillé sur la conception d’un cookie/pixel de suivi et le traitement des informations récupérées, pour en faire des tableaux statistiques et autres graphiques de fréquentation par la suite. Je vous parlerai peut-être de mon expérience avec <a href="http://c3js.org/" target="_blank" rel="noopener">la librairie JavaScript C3.js</a> dans un prochain article.</p>
<p>L’intérêt d’un tel dispositif est de pouvoir « tracker » ce qu’un visiteur fait lorsqu’il parcours votre site Web, ou encore de savoir si une campagne emailing a bien été ouverte.<span id="more-1341"></span></p>
<h2 id="pixel-de-suivi">Pixel de suivi</h2>
<p>Le code partagé ici est un exemple basique est ne reflète pas exactement la solution que j’ai utilisé pour tracker les visiteurs de nos sites Internet, mais le principe reste le même.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>&lt;?php
// On récupère d'abord l'adresse IP du visiteur
$ip = !empty($_SERVER['HTTP_CLIENT_IP']) ? $_SERVER['HTTP_CLIENT_IP'] : (!empty($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']);

// Navigateur utilisé
$browser = $_SERVER['HTTP_USER_AGENT'];

// URL de la page visité
$url = $_SERVER['REQUEST_URI'];

// Enregistrement dans un fichier de log
$handle = fopen('log.txt', 'a+');
$log_data = date('Y-m-d H:i:s') . ' -- ' . $ip . ' -- ' . $brower . ' -- '. $url . "\r\n";
fwrite($handle, $log_data);
fclose($handle);

// Création du pixel de suivi
$pixel = imagecreate(1,1);
$pixel = imagecolorallocatealpha($pixel, 255, 255, 255, 0);

// Enfin, on affiche le pixel de suivi
header('Content-Type: image/png');
imagepng($pixel);
imagedestroy($pixel)
?&gt;
</code></pre>
</div>
</div>
<h2 id="intégrer-le-pixel-de-suivi">Intégrer le pixel de suivi</h2>
<p>Maintenant que notre image de 1 pixel sur 1 pixel est créée, il ne reste plus qu’à l’insérer dans le code HTML des pages que l’on souhaite suivre. Une simple balise <code class="language-plaintext highlighter-rouge">img</code> juste avant la balise <code class="language-plaintext highlighter-rouge">&lt;/body&gt;</code> suffira !</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>&lt;img src="pixel.php" width="1" height="1" /&gt;
</code></pre>
</div>
</div>
<p>Eh voilà ! J’espère que ce petit bout de code vous aura plu. Si vous avez d’autres solutions, n’hésitez pas à les partager dans les commentaires.</p>
<p>Tchô !</p>
<p>&nbsp;</p></div>
]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2016/03/creer-un-pixel-de-suivi/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
					<title>Créer son framework PHP Objet</title>
					<link>https://chierchia.fr/2016/01/creer-son-framework-php-objet/</link>
					<comments>https://chierchia.fr/2016/01/creer-son-framework-php-objet/#respond</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Mon, 11 Jan 2016 07:40:21 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[back-end]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programmation objet]]></category>
		<guid isPermaLink="false">https://nighcrawl.com/blog/2016/01/creer-son-framework-php-objet</guid>

					<description><![CDATA[Pour faire suite à un article que j’avais écrit il y a un peu plus de quatre ans maintenant sur la création d’un framework PHP, je vous propose de créer un framework PHP Objet en utilisant les principes MVC. Lorsque je travaillais encore chez CBC Informatique, nous n’utilisions pas les principes de la programmation orientée [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class='e-content'>Pour faire suite à un article que j’avais écrit il y a un peu plus de quatre ans maintenant sur la <a href="http://chierchia.fr/blog/creer-son-framework-php/">création d’un framework PHP</a>, je vous propose de créer un framework PHP Objet en utilisant les principes MVC.<span id="more-1344"></span></p>
<p>Lorsque je travaillais encore chez CBC Informatique, nous n’utilisions pas les principes de la programmation orientée Objet et nous préférions développer nous même les sites Web de nos clients plutôt que de s’appuyer sur des solutions toutes faites, afin de garder la maitrise de notre code. C’est dans cette optique que j’avais développé <a href="https://github.com/nighcrawl/custom-cms" target="_blank" rel="noopener">notre mini-framework/CMS</a>.</p>
<p>Depuis presque 1 an maintenant,  je travaille chez Ibakus Europe et à nouvelle équipe nouvelle façon de travailler. Pour concevoir les nouvelles applications Web IBAKUS, nous utilisons la programmation orientée Objet et les principes du MVC. Nos applications gérant des données plutôt sensibles, il a été décidé de développer notre propre framework PHP Objet, afin de garder au maximum la main sur le code et pouvoir le modifier plus facilement.</p>
<h2 id="les-bases-du-framework-php-objet">Les bases du framework PHP Objet</h2>
<p>D’abord, nous avons écrit une classe maîtresse que l’on a appelée <em>Container</em>. Elle nous permet entre autre d’initialiser le framework avec un fichier de configuration, de définir les différentes routes et de charger les différents Modèles et Contrôleurs.</p>
<p>Une <strong>classe abstraite</strong> <em>Model</em> définit les méthodes utilisées pour agir sur la base de données puis chacun de nos modèles étendent cette classe afin de gérer les spécificités qui leur sont propres.</p>
<p>Mon but n’étant pas de publier le code source de notre framework, je m’intéresserai uniquement aux méthodes CRUD de notre classe abstraite <em>Model</em>.</p>
<h2 id="structure-de-la-classe-abstraite-model">Structure de la classe abstraite <em>Model</em></h2>
<p>La classe abstraite <em>Model</em> est définie par deux propriétés <code class="language-plaintext highlighter-rouge">$db</code> et <code class="language-plaintext highlighter-rouge">$table</code> et cinq méthodes : <code class="language-plaintext highlighter-rouge">get()</code>, <code class="language-plaintext highlighter-rouge">getDatas()</code>, <code class="language-plaintext highlighter-rouge">set()</code>, <code class="language-plaintext highlighter-rouge">delete()</code> et <code class="language-plaintext highlighter-rouge">save()</code>.</p>
<p>La propriété <code class="language-plaintext highlighter-rouge">$db</code> est une instance de la classe PDO établissant la connexion à notre base de données, <code class="language-plaintext highlighter-rouge">$table</code> quand à elle contient le nom de la table sur laquelle les opérations des méthodes <code class="language-plaintext highlighter-rouge">save()</code> et <code class="language-plaintext highlighter-rouge">delete()</code> vont être faites. Voici la structure de notre classe :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>abstract class Model {
  protected $db;
  protected $table;
  
  public function __construct() {
    $this -&gt; db = Container::getDb();
    $this -&gt; table = $this; 
  }
  
  /**
   * Un echo de $this retournera le nom de la table associée au modèle.
   * Par exemple 'pages' pour le modèle 'PagesModel'
   */
  public function __toString() {
    return strtolower(substr(get_class($this), 0, -5));
  }
  
  // GETTERS
  public function get($attr) {
    return $this -&gt; $attr;
  }
  
  /**
   * Retourne tous les attributs de l'objet
   */
  public function getDatas() {
    $datas = array();
    foreach (get_object_vars($this) as $key =&gt; $value)
        $datas[$key] = $value;
    
    return $datas;
  }
  
  // SETTER
  public function set($attr, $data) {
    if (property_exists($this, $attr)
        $this -&gt; $attr = $data;
  }
  
  // METHODES
  public function delete() {}
  
  public function save() {}
}
</code></pre>
</div>
</div>
<h3 id="la-méthode-save">La méthode <code class="language-plaintext highlighter-rouge">save()</code></h3>
<p>cette méthode permet d’enregistrer l’objet dans la base de données, que ce soit pour son insertion ou lors de sa modification. Pour définir si l’on va faire un <code class="language-plaintext highlighter-rouge">INSERT</code> ou un <code class="language-plaintext highlighter-rouge">UPDATE</code>, on testera la valeur de l’attribut <code class="language-plaintext highlighter-rouge">id</code> de l’objet courant. Si elle n’est pas nulle on souhaite modifier l’objet, sinon on crée une nouvelle entrée dans la base.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>public function save($type = null) {
  if ($this -&gt; get('id') == null) {
    $query = 'INSERT INTO ' . $this -&gt; get('table') . ' SET';
    $nbDatas = count($this -&gt; getDatas());

    $i = 0;
    foreach ($this -&gt; getDatas() as $key =&gt; $value) {
      $i++;
      $query .= ' ' . $key . ' = :' . $key;
      if ($i &lt; $nbDatas) $query .= ','; else $query .= ';'; } } else { $query = 'UPDATE ' . $this -&gt; get('table') . ' SET';
    $nbDatas = count($this -&gt; getDatas());

    $i = 0;
    foreach ($this -&gt; getDatas() as $key =&gt; $value) {
      $i++;
      if ($key != 'id') {
        $query .= ' ' . $key . ' = :' . $key;
        if ($i &lt; $nbDatas) $query .= ','; } } $query .= ' WHERE id = :id;'; } $query = $this -&gt; get('db') -&gt; prepare($query);

  foreach ($this -&gt; getDatas() as $key =&gt; $value)
    $query -&gt; bindValue(':' . $key, $value);

  $executed = $query -&gt; execute();

  if ($executed &amp;&amp; $this -&gt; get('id') == null)
    $this -&gt; set('id', $this -&gt; get('db') -&gt; lastInsertId());

  return $executed;
}
</code></pre>
</div>
</div>
<h3 id="la-méthode-delete">La méthode <code class="language-plaintext highlighter-rouge">delete()</code></h3>
<p>Pour supprimer les données de l’objet enregistré, rien de vraiment compliqué, on execute simplement une requête préparée avec la classe PDO et on supprime l’enregistrement dont <code class="language-plaintext highlighter-rouge">id</code> correspond à l’attribut <code class="language-plaintext highlighter-rouge">id</code> de l’objet courant.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>public function delete() {
  $query = $this -&gt; get('db') -&gt; prepare('DELETE FROM ' . $this -&gt; get('table') . ' WHERE id = :id;');
  $query -&gt; bindValue(':id', $this -&gt; get('id'));
  
  return $query -&gt; execute();
}
</code></pre>
</div>
</div>
<h2 id="pour-finir--construire-un-cms">Pour finir : construire un CMS</h2>
<p>Construire un CMS sur base d’une classe abstraite comme celle-ci permet d’écrire très simplement les différents modules dont on aura besoin.</p>
<p>Si l’on souhaite gérer des pages de contenu, il suffira d’écrire un modèle héritant de la classe <em>Model</em>, par exemple <em>pagesModel</em> et d’y définir les attributs de l’objet en regard de la structure de la table <em>pages</em> de la base de données.</p>
<p>Cette classe héritant de la classe abstraite, nous n’auront pas besoin de réécrire nos méthodes <code class="language-plaintext highlighter-rouge">save()</code> et <code class="language-plaintext highlighter-rouge">delete()</code> et l’on pourra se concentrer sur des méthodes permettant par exemple, de retourner un menu de navigation, des méta-tags pour le référencement naturel, etc.</p>
<p>Bien sûr, il faudra écrire un contrôleur permettant de traiter les données à passer au modèle, qui se chargera ensuite de les enregistrer en base de données, mais ça se fait rapidement  .</p>
<p>Là dessus, bonne semaine (et bonne année) !</p></div>
]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2016/01/creer-son-framework-php-objet/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
					<title>Créer son propre framework PHP, pourquoi ?</title>
					<link>https://chierchia.fr/2011/12/creer-son-framework-php/</link>
					<comments>https://chierchia.fr/2011/12/creer-son-framework-php/#respond</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Mon, 12 Dec 2011 07:15:50 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[back-end]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[php]]></category>
		<guid isPermaLink="false">https://nighcrawl.com/blog/2011/12/creer-son-framework-php</guid>

					<description><![CDATA[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 [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class='e-content'>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.</p>
<p>Personnellement j’aime passer du temps à peaufiner un design. je déteste réécrire les mêmes fonctions pour chaque projet. Alors oui, il des frameworks PHP, mais pourquoi utiliser un bazooka lorsqu’on doit abattre une mouche ?<span id="more-1364"></span></p>
<p class="author_note"><strong>MAJ 11/01/2016 : Si le PHP Objet vous parle, vous pouvez lire <a href="http://chierchia.fr/blog/creer-son-framework-php-objet/">Créer son framework PHP Objet</a> qui est <em>un peu</em> plus récent </strong></p>
<p class="author_note">Attention, l’article est un chouilla trop long (beaucoup de lignes de code).</p>
<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.</p>
<p>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.</p>
<p>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.</p>
<h2 id="mes-fonctions-de-crud">Mes fonctions de CRUD</h2>
<p>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 !</p>
<h3 id="ajouter-un-enregistrement-dans-une-table">Ajouter un enregistrement dans une table</h3>
<p>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.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>/***
 *  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;
}
</code></pre>
</div>
</div>
<p><strong>Comment utiliser la fonction ?</strong></p>
<p>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.</p>
<p><em><span style="text-decoration: underline;">Exemple :</span> je veux renseigner le nom, l’adresse email et le commentaire dans la table « comments ».</em></p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>$datas = array(
  'nom' =&gt; $nom,
  'email' =&gt; $email,
  'commentaire' =&gt; $commentaire
);

if(add($datas,'comments')) {
  return "cool";
} else return "pas cool";
</code></pre>
</div>
</div>
<p>Si tout c’est bien passé, la fonction <code class="language-plaintext highlighter-rouge">add()</code> me renvoie l’ID de l’enregistrement créé.</p>
<h3 id="mettre-à-jour-les-informations-dun-enregistrement">Mettre à jour les informations d’un enregistrement</h3>
<p>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.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>/***
 *  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;
}
</code></pre>
</div>
</div>
<h3 id="supprimer-un-enregistrement">Supprimer un enregistrement</h3>
<p>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.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>/***
 *  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;
}
</code></pre>
</div>
</div>
<h3 id="retourner-une-liste-denregistrements">Retourner une liste d’enregistrements</h3>
<p>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.</p>
<p>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.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>/***
 *  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;
}
</code></pre>
</div>
</div>
<p><strong>Comment utiliser la fonction ?</strong></p>
<p><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></p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>$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'];
</code></pre>
</div>
</div>
<h2 id="mettre-en-place-un-système-de-pagination">Mettre en place un système de pagination</h2>
<p>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 :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>/***
 *  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;";
}
</code></pre>
</div>
</div>
<p>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 :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>$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'];
</code></pre>
</div>
</div>
<h2 id="fin-">Fin !</h2>
<p>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.</p></div>
]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2011/12/creer-son-framework-php/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
					<title>Générer un mot de passe aléatoirement</title>
					<link>https://chierchia.fr/2011/07/generer-un-mot-de-passe-aleatoirement/</link>
					<comments>https://chierchia.fr/2011/07/generer-un-mot-de-passe-aleatoirement/#respond</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Fri, 08 Jul 2011 16:47:47 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[back-end]]></category>
		<category><![CDATA[password]]></category>
		<category><![CDATA[php]]></category>
		<guid isPermaLink="false">https://nighcrawl.com/blog/2011/07/generer-un-mot-de-passe-aleatoirement</guid>

					<description><![CDATA[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.  Le principe ici était, pour moi, de générer [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class='e-content'>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-1375"></span></p>
<p>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.</p>
<p>Voici donc notre petite fonction :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>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;
}
</code></pre>
</div>
</div>
<p>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.</p>
<p>Fonction super simple, je vous l’accorde, mais ça pourra toujours servir, libre à vous de le modifier et l’utiliser comme bon vous semble </p></div>
]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2011/07/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>https://chierchia.fr/2011/01/requetes-sql-avec-codeigniter/</link>
					<comments>https://chierchia.fr/2011/01/requetes-sql-avec-codeigniter/#respond</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Fri, 14 Jan 2011 21:36:57 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[back-end]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[mysql]]></category>
		<category><![CDATA[php]]></category>
		<guid isPermaLink="false">https://nighcrawl.com/blog/2011/01/requetes-sql-avec-codeigniter</guid>

					<description><![CDATA[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. 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 [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class='e-content'>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-1384"></span></p>
<p>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.</p>
<h2 id="configurer-la-classe-database">Configurer la classe Database</h2>
<p>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 class="language-plaintext highlighter-rouge">$db</code> comme ci-dessous.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>$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";
</code></pre>
</div>
</div>
<p>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 :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>//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";
</code></pre>
</div>
</div>
<p>Il suffira ensuite de définir la valeur de la variable $active_group à « test » pour utiliser notre configuration secondaire. Easy!</p>
<p>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 :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>$this-&gt;load-&gt;database($dbconf);
</code></pre>
</div>
</div>
<p>Il est aussi possible d’instancier deux connexion en faisant comme suit :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>$db1 = $this-&gt;load-&gt;database('default');
$db2 = $this-&gt;load-&gt;database('test');
</code></pre>
</div>
</div>
<h2 id="ma-première-requête-sql-avec-codeigniter">Ma première requête SQL avec CodeIgniter</h2>
<p>On y est, notre connexion à la base est active, on va pouvoir manipuler les données (j’adore ça, manipuler des données)!</p>
<p>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 class="language-plaintext highlighter-rouge">mysql_*()</code> soit on utilise la <a title="Utiliser PDO pour les connexions à une base de données" href="http://chierchia.fr/blog/utiliser-pdo-pour-les-connexion-a-une-bdd/">méthode objet (PDO)</a>, ou encore mieux on utilise les nombreuses fonctions du Framework!</p>
<p>Comme il y a toute une flopée de fonctions préexistantes je vais volontairement ne présenter que les plus courantes.</p>
<h3 id="mysql_query-à-la-sauce-ci">mysql_query() à la sauce CI</h3>
<p>C’est la fonction <code class="language-plaintext highlighter-rouge">query()</code> de la classe Database qui permet d’exécuter simplement des requêtes <code class="language-plaintext highlighter-rouge">SELECT</code> simple. La fonction s’utilise très simplement : <code class="language-plaintext highlighter-rouge">$this-&gt;db-&gt;query('SELECT * FROM table');</code></p>
<p>Si l’on souhaite construire des requêtes avec paramètres, il sera obligatoire de les échapper avec les fonction <code class="language-plaintext highlighter-rouge">escape()</code>, <code class="language-plaintext highlighter-rouge">escape_str()</code> ou <code class="language-plaintext highlighter-rouge">escape_like_str()</code>, équivalents de la fonction <code class="language-plaintext highlighter-rouge">mysql_real_escape_string()</code>.</p>
<p>La fonction <code class="language-plaintext highlighter-rouge">escape()</code> permet d’échapper les données quelque soit leur type (<code class="language-plaintext highlighter-rouge">string, int, float</code>, etc…), tandis que <code class="language-plaintext highlighter-rouge">escape_str()</code> n’accepte que des données de type <code class="language-plaintext highlighter-rouge">string</code>. <code class="language-plaintext highlighter-rouge">escape_like_str()</code> quant à elle, permet d’échapper des requêtes avec des conditions <code class="language-plaintext highlighter-rouge">LIKE</code>.</p>
<p>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é:</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>$sql = "SELECT * FROM some_table WHERE id = ? AND status = ? AND author = ?";
$this-&gt;db-&gt;query($sql, array(3, 'live', 'Rick'));
</code></pre>
</div>
</div>
<p>L’intérêt ici, comme avec PDO c’est que les valeurs passées en paramètre sont automatiquement échappées.</p>
<p>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!</p>
<h2 id="la-classe-active-record">La classe Active Record</h2>
<p>Utiliser l’Active Record, c’est hype, branché et trop in the move!</p>
<p>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é.</p>
<p>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é.</p>
<h3 id="this-db-get">$this-&gt;db-&gt;get()</h3>
<p><code class="language-plaintext highlighter-rouge">get()</code> permet d’exécuter en un rien de temps un <code class="language-plaintext highlighter-rouge">SELECT</code> sur une table et ainsi retourner tout ses enregistrements</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>$query = $this-&gt;db-&gt;get('mytable');
// équivalent: SELECT * FROM mytable
</code></pre>
</div>
</div>
<p>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 class="language-plaintext highlighter-rouge">get()</code> en plus de la table sur laquelle on travaille.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>$query = $this-&gt;db-&gt;get('mytable', 10, 20);
// équivalent : SELECT * FROM mytable LIMIT 20, 10
</code></pre>
</div>
</div>
<h3 id="this-db-get_where">$this-&gt;db-&gt;get_where()</h3>
<p>Vraiment besoin d’explications? <code class="language-plaintext highlighter-rouge">get_where()</code> permet tout simplement de faire un <code class="language-plaintext highlighter-rouge">get()</code> avec des conditions.</p>
<p>Les différentes condition seront à présenter sous forme d’un tableau (on vera ça ensuite dans la fonction <code class="language-plaintext highlighter-rouge">where()</code>) .</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>$query = $this-&gt;db-&gt;get_where('mytable', $where, $limit, $offset);
</code></pre>
</div>
</div>
<p>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.</p>
<h3 id="select-from-where">SELECT, FROM, WHERE</h3>
<p>Ok, admettons que l’on veuille retourner le titre, le contenu et la date d’un article dans notre base.</p>
<p>Clairement ici <code class="language-plaintext highlighter-rouge">get_where()</code> boufferai de la ressource inutilement puisqu’il nous retournerai d’autres champs dont on aurait pu se passer. <code class="language-plaintext highlighter-rouge">select()</code> est là pour nous ravir les amis!</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>$this-&gt;db-&gt;select('title, content, date');
$query = $this-&gt;db-&gt;get('articles');
// équivalent: SELECT title, content, date FROM articles
</code></pre>
</div>
</div>
<p>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 class="language-plaintext highlighter-rouge">from()</code> et <code class="language-plaintext highlighter-rouge">where()</code> :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>$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();
</code></pre>
</div>
</div>
<p>C’est pas beautiful ? CodeIgniter a un sac plein de fonctions équivalentes aux fonction SQL comme <code class="language-plaintext highlighter-rouge">SUM()</code>, <code class="language-plaintext highlighter-rouge">AVG()</code>, <code class="language-plaintext highlighter-rouge">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" rel="noopener">Guide Utilisateur de CodeIgniter</a>.</p>
<p>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 :</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>$this-&gt;db-&gt;select('title, content, date')-&gt;from('articles')-&gt;where(array('id' =&gt; 7));
$query = $this-&gt;db-&gt;get();
</code></pre>
</div>
</div>
<h3 id="affichage-des-résultats">Affichage des résultats</h3>
<p>On finira ce billet très rapidement sur la façon d’afficher le résultat de nos différentes requêtes.</p>
<p>Ici on fera un simple <code class="language-plaintext highlighter-rouge">foreach()</code> comme on a l’habitude d’en faire quand on utilise PDO (pour moi en tout cas).</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>$query = $this-&gt;db-&gt;get('mytable');
foreach ($query-&gt;result() as $row){
  echo $row-&gt;title;
}
</code></pre>
</div>
</div>
<h2 id="conclusion">Conclusion</h2>
<p>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.</p>
<p>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.</p>
<p>J’en profite aussi pour souhaité avec du retard, une très bonne année 2011, pleine de bonnes choses et d’argent (surtout) ^^</p></div>
]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2011/01/requetes-sql-avec-codeigniter/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
					<title>Développer un CMS avec CodeIgniter #3 : la gestion des pages</title>
					<link>https://chierchia.fr/2010/08/developper-cms-codeigniter-la-gestion-des-pages/</link>
					<comments>https://chierchia.fr/2010/08/developper-cms-codeigniter-la-gestion-des-pages/#respond</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Sat, 07 Aug 2010 15:09:15 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[back-end]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[php]]></category>
		<guid isPermaLink="false">https://nighcrawl.com/blog/2010/08/developper-cms-codeigniter-la-gestion-des-pages</guid>

					<description><![CDATA[Dans ce nouvel article qui fait suite à « Développer un moteur de site Web avec CodeIgniter » et « Système de login sécurisé — CMS CodeIgniter, partie 2 » nous allons nous intéresser au module de gestion des pages de contenu, le coeur du moteur de site web en somme. Introduction La semaine le mois dernier (désolé) on [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class='e-content'>Dans ce nouvel article qui fait suite à « <a href="http://chierchia.fr/php-mysql/moteur-site-web-developper-cms-codeigniter/">Développer un moteur de site Web avec CodeIgniter</a> » et « <a href="http://chierchia.fr/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-1386"></span></p>
<h2 id="introduction">Introduction</h2>
<p>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).</p>
<p>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!</p>
<h2 id="laccès-aux-données-relatives-aux-pages-du-site">L’accès aux données relatives aux pages du site</h2>
<p>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.</p>
<p>Dans le dossier <em>application/models</em>, créez un nouveau fichier que vous appellerez <em>page_model.php</em> contenant le code suivant:</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>class Page_model extends Model {
  function Page_model(){
    parent::Model();
  }
}
</code></pre>
</div>
</div>
<p>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).</p>
<p>Okay, premièrement on va s’occuper de la fonction d’ajout dans la base.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>function add($data){
  return $this-&gt;db-&gt;insert('pages',$data);
}
</code></pre>
</div>
</div>
<p>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.</p>
<p>Pour ce qui est des fonctions de modification, et de suppression, c’est aussi rapide, donc les voici toutes les deux:</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>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));
}
</code></pre>
</div>
</div>
<p>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.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>//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];
  }
}
</code></pre>
</div>
</div>
<h2 id="le-traitement-des-données">Le traitement des données</h2>
<p>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 ^^.</p>
<p>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.</p>
<p>Pour rappel, voilà notre contrôleur Admin là où on s’est arrêté le mois dernier:</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>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');
  }
}
</code></pre>
</div>
</div>
<p>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.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>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;
}
</code></pre>
</div>
</div>
<p>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().</p>
<p>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.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>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;
</code></pre>
</div>
</div>
<p>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?</p>
<p>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.</p>
<p>Enfin, si $action vaut ‘delete’ et que $id n’est pas nulle, on appelle la méthode delete() de notre modèle Page.</p>
<p>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.</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>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;
</code></pre>
</div>
</div>
<p>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:</p>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>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;
</code></pre>
</div>
</div>
<h2 id="le-troisième-tiers-de-notre-application-les-vues">Le troisième tiers de notre application: les vues</h2>
<p>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.</p>
<h4 id="la-liste-des-pages-présentes-dans-la-base">La liste des pages présentes dans la base</h4>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>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;
</code></pre>
</div>
</div>
<h4 id="le-formulaire-dajout-dune-page">Le formulaire d’ajout d’une page</h4>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>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();
</code></pre>
</div>
</div>
<h4 id="le-formulaire-de-modification">Le formulaire de modification</h4>
<div class="language-plaintext highlighter-rouge">
<div class="highlight">
<pre class="highlight"><code>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();
</code></pre>
</div>
</div>
<h2 id="conclusion">Conclusion</h2>
<p>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.</p>
<p>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.</p>
<p>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 çà </p></div>
]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2010/08/developper-cms-codeigniter-la-gestion-des-pages/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
		<item>
					<title>Système de login sécurisé – CMS CodeIgniter, partie 2</title>
					<link>https://chierchia.fr/2010/06/login-securise-cms-codeigniter-partie-2/</link>
					<comments>https://chierchia.fr/2010/06/login-securise-cms-codeigniter-partie-2/#respond</comments>
		
		<dc:creator><![CDATA[<span class='p-author h-card'>Ange Chierchia</span>]]></dc:creator>
		<pubDate>Sat, 19 Jun 2010 11:58:15 +0000</pubDate>
				<category><![CDATA[Articles]]></category>
		<category><![CDATA[back-end]]></category>
		<category><![CDATA[cms]]></category>
		<category><![CDATA[codeigniter]]></category>
		<category><![CDATA[framework]]></category>
		<category><![CDATA[php]]></category>
		<guid isPermaLink="false">https://nighcrawl.com/blog/2010/06/login-securise-cms-codeigniter-partie-2</guid>

					<description><![CDATA[Dans mon article précédent, 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é. Avant de commencer Cet article est le second d’un ensemble d’article sur la création d’un système de [&#8230;]]]></description>
										<content:encoded><![CDATA[<div class='e-content'><a title="Développer un moteur de site Web avec CodeIgniter" href="http://chierchia.fr/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-1388"></span></p>
<h2 id="avant-de-commencer">Avant de commencer</h2>
<p>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://chierchia.fr/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.</p>
<p>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!</p>
<h2 id="création-de-la-base-de-données">Création de la base de données</h2>
<p>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é:</p>
<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>
<p>On a donc ici un champ <code class="language-plaintext highlighter-rouge">username</code> qui devra être unique, un champ <code class="language-plaintext highlighter-rouge">password</code> pour le mot de passe que l’on cryptera en <code class="language-plaintext highlighter-rouge">SHA1</code>, je n’aime pas trop <code class="language-plaintext highlighter-rouge">MD5</code> même si ça peut faire l’affaire ici.</p>
<p>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).</p>
<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>
<p>J’ai vraiment besoin d’expliquer?</p>
<p>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.</p>
<h2 id="création-du-modèle-users_modelphp">Création du Modèle Users_model.php</h2>
<p>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.</p>
<p>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_sers_model.php_ qui contiendra ceci :</p>
<pre class="brush:php">&lt;?php
class User_model extends Model {
     function User_model(){
          parent::Model();
     }
}
?&gt;</pre>
<p>Ici on créé la classe <code class="language-plaintext highlighter-rouge">User_model</code> qui hérite de la classe <code class="language-plaintext highlighter-rouge">Model</code>, puis on instancie la classe avec le constructeur <code class="language-plaintext highlighter-rouge">User_model</code> (on aurai pu aussi utiliser <code class="language-plaintext highlighter-rouge">__constructor</code> pour l’instancier).</p>
<p>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 :</p>
<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 id="que-ce-passe-t-il-ici">Que ce passe-t-il ici?</h4>
<p>D’abord on charge la librairie encrypt avec la commande <code class="language-plaintext highlighter-rouge">$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 class="language-plaintext highlighter-rouge">$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://chierchia.fr/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>.</p>
<p>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.</p>
<p>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:</p>
<pre class="brush:php">function isLoggedIn(){
     if($this-&gt;session-&gt;userdata('logged_in'))
     { return true; } else { return false; }
}</pre>
<h2 id="il-reste-encore-du-monde-on-passe-au-contrôleur">Il reste encore du monde? On passe au Contrôleur</h2>
<p>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_pplication/controllers_ et mettez y le code suivant:</p>
<pre class="brush:php">class Admin extends Controller {

     //constructeur de la classe
     function Admin() {
          parent::Controller();
          $this-&gt;load-&gt;model('user_model');
     }
}</pre>
<p>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.</p>
<p>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.</p>
<p>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.</p>
<pre class="brush:php">function index(){
     if($this-&gt;user_model-&gt;isLoggedIn()){
          redirect('admin/dashboard','refresh');
     } else {
          redirect('admin/login','refresh');
     }
}</pre>
<p>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.</p>
<p>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.</p>
<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>
<p>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 class="language-plaintext highlighter-rouge">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 class="language-plaintext highlighter-rouge">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 class="language-plaintext highlighter-rouge">validCredentials()</code> qu’on a définit dans notre modèle <em>User_model</em>. Si un résultat est retourné, la fonction <code class="language-plaintext highlighter-rouge">validCredentials</code> créée la variable de session <code class="language-plaintext highlighter-rouge">logged_in</code> et nous redirige vers le dashboard.</p>
<p>Dernière méthode de notre contrôleur, la fonction dashboard() qui se chargera d’afficher notre tableau de bord.</p>
<pre class="brush:php">function dashboard(){
     if($this-&gt;user_model-&gt;isLoggedIn())
          $this-&gt;load-&gt;view('admin');
}</pre>
<p>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.</p>
<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>
<p>Ici on ouvre un tag <code class="language-plaintext highlighter-rouge">&lt;form&gt;</code> qui enverra le formulaire à la méthode <code class="language-plaintext highlighter-rouge">login()</code> du contrôleur <code class="language-plaintext highlighter-rouge">Admin</code>. Puis on affiche les erreurs de validation si il y a lieu avec la fonction <code class="language-plaintext highlighter-rouge">validation_errors()</code> et les erreurs de login/mot de passe avec notre variable <code class="language-plaintext highlighter-rouge">$error_credentials</code>.</p>
<p>Eh voilà, votre formulaire de login sécurisé est terminé!</p>
<h2 id="conclusion">Conclusion</h2>
<p>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.</p>
<p>Dans le prochain article, on s’attardera sur LE coeur de notre système, à savoir la gestion des pages. Allez, bon week-end!</p></div>
]]></content:encoded>
					
					<wfw:commentRss>https://chierchia.fr/2010/06/login-securise-cms-codeigniter-partie-2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
