<?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>Blogbonzo: Matteo Magni &#187; LinkedIn</title>
	<atom:link href="http://blog.ilbonzo.org/category/linkedin/feed/" rel="self" type="application/rss+xml" />
	<link>http://blog.ilbonzo.org</link>
	<description>Consulente Informatico, Web Developer &#38; System Administrator</description>
	<lastBuildDate>Wed, 09 Dec 2009 13:07:18 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.4</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>PDO, Abstraction Layer</title>
		<link>http://blog.ilbonzo.org/2008/06/16/pdo-abstraction-layer/</link>
		<comments>http://blog.ilbonzo.org/2008/06/16/pdo-abstraction-layer/#comments</comments>
		<pubDate>Mon, 16 Jun 2008 14:19:42 +0000</pubDate>
		<dc:creator>Bonzo</dc:creator>
				<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[MySQL]]></category>
		<category><![CDATA[Pgsql]]></category>
		<category><![CDATA[Programmazione]]></category>
		<category><![CDATA[php]]></category>

		<guid isPermaLink="false">http://blog.ilbonzo.org/2008/06/16/pdo-abstraction-layer/</guid>
		<description><![CDATA[Finalmente con la versione 5.1 PHP ha un nuovo livello di astrazione per la connettività con i database veramente valido.
PDO, PHP Data Objects
Ho deciso di studiarlo un po&#8217;:
Creo un Database di prova:

DROP TABLE IF EXISTS first_table;


--CREATE TABLE first_table (
--id INT(10) NOT NULL AUTO_INCREMENT,
--name VARCHAR(255) NOT NULL,
--surname VARCHAR(255) NOT NULL,
--PRIMARY KEY (id)
--) TYPE=MyISAM;


CREATE TABLE first_table (
id [...]]]></description>
			<content:encoded><![CDATA[<p>Finalmente con la versione 5.1 PHP ha un nuovo livello di astrazione per la connettività con i database veramente valido.<br />
<strong><a href="http://it2.php.net/pdo">PDO</a>, PHP Data Objects</strong></p>
<p>Ho deciso di studiarlo un po&#8217;:</p>
<p>Creo un Database di prova:<br />
<code><br />
DROP TABLE IF EXISTS first_table;<br />
</code><br />
<code><br />
--CREATE TABLE first_table (<br />
--id INT(10) NOT NULL AUTO_INCREMENT,<br />
--name VARCHAR(255) NOT NULL,<br />
--surname VARCHAR(255) NOT NULL,<br />
--PRIMARY KEY (id)<br />
--) TYPE=MyISAM;<br />
</code><br />
<code><br />
CREATE TABLE first_table (<br />
id INT(10) NOT NULL AUTO_INCREMENT,<br />
name VARCHAR(255) NOT NULL,<br />
surname VARCHAR(255) NOT NULL,<br />
PRIMARY KEY (id)<br />
) TYPE=innoDB;<br />
</code><br />
<code><br />
INSERT INTO first_table (name,surname) VALUES ('matteo','magni');<br />
INSERT INTO first_table (name,surname) VALUES ('john','starks');<br />
INSERT INTO first_table (name,surname) VALUES ('michael','jordan');<br />
INSERT INTO first_table (name,surname) VALUES ('kobe','bryant');<br />
INSERT INTO first_table (name,surname) VALUES ('earvin','johnson');<br />
INSERT INTO first_table (name,surname) VALUES ('larry','bird');<br />
INSERT INTO first_table (name,surname) VALUES ('patrick','ewing');<br />
INSERT INTO first_table (name,surname) VALUES ('reggie','miller');<br />
INSERT INTO first_table (name,surname) VALUES ('ron','harper');<br />
INSERT INTO first_table (name,surname) VALUES ('anfernee','hardaway');<br />
INSERT INTO first_table (name,surname) VALUES ('tim','hardaway');<br />
INSERT INTO first_table (name,surname) VALUES ('mitch','richmond');<br />
INSERT INTO first_table (name,surname) VALUES ('jason','williams');<br />
INSERT INTO first_table (name,surname) VALUES ('allen','iverson');<br />
INSERT INTO first_table (name,surname) VALUES ('dwayne','wade');<br />
</code></p>
<p>Lo importo così dopo aver creato il DB pdo<br />
<code><br />
mysql -p -D pdo < pdo.sql<br />
</code><br />
Per le prove utilizzerò sia la versione con tabella MyISAM che quella con tabella InnoDB, la differenza è che per la prima non sono disponibili le transazioni.</p>
<p><strong>Usiamo le eccezioni per connetterci al DB</strong><br />
</code><code><br />
//USO le eccezioni<br />
$string_dsn = 'mysql:host=localhost;dbname=pdo'; // mysql<br />
$string_username = 'user';<br />
$string_password = 'password';<br />
try {<br />
    $mypdo = new PDO($string_dsn, $string_username, $string_password);<br />
}<br />
catch(PDOException $e) {<br />
    echo 'Errore di connessione: '.$e->getMessage();<br />
}<br />
</code></p>
<p>Query fatta con errore, mi restituisce il numero dell&#8217;errore:<br />
<code><br />
$mypdo->exec('SELECT * FROM SELECT'); // errore generato appositamente<br />
echo 'Errore N: '.$mypdo->errorCode();<br />
</code>    </p>
<p>Se la uso così è molto utile, mando io il messaggio che voglio:<br />
<code><br />
if($mypdo->errorCode() !== '' || !$mypdo->exec('SELECT * FROM SELECT'))<br />
    echo 'errore nella query SELECT * FROM SELECT';<br />
</code></p>
<p>Così mi ritorna un array di tre elementi con le notizie sull&#8217;errore:<br />
<code><br />
var_dump($mypdo->errorInfo());<br />
//array di tre elementi<br />
if(count($mypdo->errorInfo()) == 1) // ... tutto ok<br />
if(count($mypdo->errorInfo()) > 1) { // ... ci sono errori<br />
    $errorinfo = $mypdo->errorInfo();<br />
    echo $errorinfo[2]; // stringa con l' errore<br />
}<br />
</code></p>
<p><strong>QUERY</strong> semplice senza preparare niente,<br />
Mi ritorna i dati accessibili sia con il numero della colonna (partendo da 0) che con il nome della colonna<br />
Query senza parametri aggiuntivi per stabilire che Fetch usare:</p>
<p><code><br />
foreach($mypdo->query('SELECT * FROM first_table') as $row)<br />
{<br />
    echo '--------------&lt;br /&gt;';<br />
    echo '1: '.$row[0].' - 2: '.$row[1].'&lt;br /&gt;';<br />
    echo 'id: '.$row['id'].' - name: '.$row['name'].'&lt;br /&gt;';<br />
}<br />
</code><br />
mi ritorna i dati accessibili sia con il numero della colonna (partendo da 0) che con il nome della colonna.</p>
<p>Esplicito il tipo di Fetch con il parametro PDO_FETCH_*<br />
<strong>PDo::FETCH_BOTH</strong> #usatelo come mysql fetch_array, risultato duplicato, quello di default<br />
<code><br />
foreach($mypdo->query('SELECT * FROM first_table', PDO::FETCH_BOTH) as $row)<br />
{<br />
    echo '--------------&lt;br /&gt;';<br />
    echo '1: '.$row[0].' - 2: '.$row[1].'&lt;br /&gt;';<br />
    echo 'id: '.$row['id'].' - name: '.$row['name'].'&lt;br /&gt;';<br />
}<br />
</code></p>
<p><strong>PDO::FETCH_ASSOC</strong> #usatelo come mysql_fetch_assoc<br />
<code><br />
foreach($mypdo->query('SELECT * FROM first_table', PDO::FETCH_ASSOC) as $row)<br />
{<br />
    echo '--------------&lt;br /&gt;';<br />
    echo 'id: '.$row['id'].' - name: '.$row['name'].'&lt;br /&gt;';<br />
}<br />
</code></p>
<p><strong>PDO::FETCH_NUM </strong>#analogo a mysql_fetch_row<br />
<code><br />
foreach($mypdo->query('SELECT * FROM first_table', PDO::FETCH_NUM) as $row)<br />
{<br />
    echo '--------------&lt;br/&gt;';<br />
    echo '1: '.$row[0].' - 2: '.$row[1].'&lt;br/&gt;';<br />
}<br />
</code></p>
<p><strong>PDO::FETCH_OBJ </strong>#ritorna un oggetto con le proprieta&#8217; che hanno il nome dei campi<br />
<code><br />
foreach($mypdo->query('SELECT * FROM first_table', PDO::FETCH_OBJ) as $row)<br />
{<br />
    echo '--------------&lt;br /&gt;';<br />
    echo 'id->'.$row->id.' - name-> '.$row->name.'&lt;br /&gt;';<br />
}<br />
</code></p>
<p><strong>PDO::FETCH_LAZY </strong>#combina *_BOTH e *_OBJ<br />
<code><br />
foreach($mypdo->query('SELECT * FROM first_table', PDO::FETCH_LAZY) as $row)<br />
{<br />
    echo '--------------&lt;br /&gt;';<br />
    echo '1: '.$row[0].' - 2: '.$row[1].'&lt;br /&gt;';<br />
    echo 'id:  '.$row['id'].' - name: '.$row['name'].'&lt;br /&gt;';<br />
    echo 'id->'.$row->id.' - name-> '.$row->name.'&lt;br /&gt;';<br />
}<br />
</code></p>
<p><strong>PDO::FETCH_BOUND</strong> #Lo vediamo con bindColumn,<br />
restituiti come attributi alle variabili PHP</p>
<p>Per Evitare problemi con DB case sensitive e non case sensitive<br />
Setto che i nomi delle colonne siano restituiti sempre minuscoli<br />
<code><br />
$mypdo->setAttribute(PDO::CASE_LOWER);<br />
/*<br />
 * Psso usare anche<br />
 * PDO::CASE_UPPER<br />
 * PDO::CASE_NATURAL come sono fornite dal driver, metodo di default<br />
 */<br />
</code><br />
oppure si usa sempre FETCH_NUM</p>
<p><strong>Utilizzo delle Transazioni</strong></p>
<p>inizio la transazione</p>
<p>Su Mysql devo usare tabelle InnoDB perchè MyIsam non supportano le transazioni</p>
<p>Però&#8230;<br />
The following example begins a transaction and issues two statements that<br />
modify the database before rolling back the changes.<br />
On MySQL, however, the DROP TABLE statement automatically commits the<br />
transaction so that none of the changes in the transaction are rolled back.</p>
<p>Quindi niente drop per una transazione.<br />
<code><br />
$mypdo->beginTransaction();<br />
$mypdo->exec('DROP TABLE first_table');<br />
$mypdo->rollBack(); // la tabella mytable rimarra' invariata :-)<br />
</code></p>
<p>come detto su MySQL la cancella lo stesso.</p>
<p><code><br />
$mypdo->beginTransaction();<br />
$mypdo->exec("INSERT INTO first_table (name,surname) VALUES ('gianni','morandi')");<br />
$mypdo->rollBack(); // la tabella mytable rimarra' invariata :-)<br />
</code></p>
<p><code><br />
$mypdo->beginTransaction();<br />
$mypdo->exec("INSERT INTO first_table (name,surname) VALUES ('gianni','morandi')");<br />
$mypdo->commit(); // la tabella mytable rimarra' invariata :-)<br />
</code><br />
mi inserisce il nuovo valore.</p>
<h3>Prepared Statement</h3>
<p><strong>Metodo Fetch</strong><br />
Metodo implementato nello statement che è in grado di spostare il cursore dei risultati di una query in un ciclo.<br />
Gli posso passare i parametri come a query.<br />
/*<br />
 * PDO::FETCH_ASSOC, PDO::FETCH_BOTH, PDO::FETCH_BOUND, PDO::FETCH_LAZY,<br />
 * PDO::FETCH_OBJ, PDO::FETCH_NUM<br />
 */<br />
<code><br />
$mypdo->beginTransaction();<br />
// preparo la query<br />
$stpdo = $mypdo->prepare('UPDATE first_table SET name = "pippo" WHERE id = 17');<br />
// eseguo la query<br />
$stpdo->execute();<br />
$mypdo->commit();<br />
echo 'SELECT';<br />
$mypdo->beginTransaction();<br />
// preparo la query<br />
$stpdo = $mypdo->prepare('SELECT * FROM first_table');<br />
// eseguo la query<br />
$stpdo->execute();<br />
//stampo a video il contenuto dell'array che mi crea fetch<br />
while ($row=$stpdo->fetch())<br />
{<br />
     echo 'id: '.$row['id'].' - name: '.$row['name'].'&lt;br /&gt;';<br />
}<br />
$mypdo->commit();<br />
</code></p>
<p><strong>La potenza prepare e execute </strong><br />
Potenza del metodo prepare<br />
<code><br />
$mypdo->beginTransaction();<br />
$stpdo = $mypdo->prepare('UPDATE first_table SET name = ? WHERE id = ?');<br />
//i punti interrogativi saranno sostituiti da execute<br />
$stpdo->execute(array('gianni', 17));<br />
$mypdo->commit();<br />
echo 'SELECT';<br />
$mypdo->beginTransaction();<br />
// preparo la query<br />
$stpdo = $mypdo->prepare('SELECT * FROM first_table');<br />
// eseguo la query<br />
$stpdo->execute();<br />
//stampo a video il contenuto dell'array che mi crea fetch<br />
while ($row=$stpdo->fetch())<br />
{<br />
     echo 'id: '.$row['id'].' - name: '.$row['name'].'&lt;br /&gt;';<br />
}<br />
$mypdo->commit();<br />
</code><br />
Posso preparare la query una volta e fare poi i vari inserimenti.<br />
<strong>potenza prepare e execute ancora</strong><br />
<code><br />
$mypdo->beginTransaction();<br />
$stpdo = $mypdo->prepare('UPDATE first_table SET name = :name WHERE id = :id');<br />
//i punti interrogativi non sempre sono chiari, così lo è di più<br />
$stpdo->execute(array(':name'=>'marcello',':id'=>17));<br />
$mypdo->commit();<br />
echo 'SELECT';<br />
$mypdo->beginTransaction();<br />
// preparo la query<br />
$stpdo = $mypdo->prepare('SELECT * FROM first_table');<br />
// eseguo la query<br />
$stpdo->execute();<br />
//stampo a video il contenuto dell'array che mi crea fetch<br />
while ($row=$stpdo->fetch())<br />
{<br />
     echo 'id: '.$row['id'].' - name: '.$row['name'].'&lt;br /&gt;';<br />
}<br />
$mypdo->commit();<br />
</code></p>
<p><strong>Metodo fetchAll</strong><br />
ritorna un array le righe del resultset<br />
<code><br />
$mypdo->beginTransaction();<br />
// preparo la query<br />
$stpdo = $mypdo->prepare('SELECT * FROM first_table');<br />
// eseguo la query<br />
$stpdo->execute();<br />
$row=$stpdo->fetchAll();<br />
//stampo a video il contenuto dell'array che mi crea fetch<br />
var_dump($row);<br />
$mypdo->commit();<br />
</code></p>
<p><strong>Metodo fetchAll</strong><br />
<code><br />
$mypdo->beginTransaction();<br />
// preparo la query<br />
$stpdo = $mypdo->prepare('SELECT * FROM first_table');<br />
// eseguo la query<br />
$stpdo->execute();<br />
$row=$stpdo->fetchAll(PDO::FETCH_OBJ);<br />
//così ho un array di oggetti<br />
//stampo a video il contenuto dell'array che mi crea fetch<br />
var_dump($row);<br />
$mypdo->commit();<br />
</code></p>
<h3>Metodi bind</h3>
<p><strong>bindParam</strong><br />
<code><br />
$id=10;<br />
$mypdo->beginTransaction();<br />
// preparo la query<br />
$stpdo = $mypdo->prepare("SELECT * FROM first_table WHERE id = ? ");<br />
$stpdo->bindParam(1,$id, PDO::PARAM_INT);<br />
$stpdo->execute();<br />
while ($row=$stpdo->fetch())<br />
{<br />
     echo 'id: '.$row['id'].' - name: '.$row['name'].'&lt;br /&gt;';<br />
}<br />
$mypdo->commit();<br />
</code><br />
Oppure:<br />
<code><br />
$id=10;<br />
$mypdo->beginTransaction();<br />
// preparo la query<br />
$stpdo = $mypdo->prepare("SELECT * FROM first_table WHERE id = :id ");<br />
$stpdo->bindParam(':id',$id, PDO::PARAM_INT);<br />
$stpdo->execute();<br />
while ($row=$stpdo->fetch())<br />
{<br />
     echo 'id: '.$row['id'].' - name: '.$row['name'].'&lt;br /&gt;';<br />
}<br />
$id=13;<br />
$stpdo->bindParam(':id',$id, PDO::PARAM_INT);<br />
$stpdo->execute();<br />
while ($row=$stpdo->fetch())<br />
{<br />
     echo 'id: '.$row['id'].' - name: '.$row['name'].'&lt;br /&gt;';<br />
}<br />
$mypdo->commit();<br />
</code><br />
Così ho preparato la query una volta sola, ed ho legato :id al valore della variabile $id.</p>
<p><strong>bindValue</strong><br />
<code><br />
$id=10;<br />
$mypdo->beginTransaction();<br />
$stpdo = $mypdo->prepare('SELECT * FROM first_table WHERE id < ? ');<br />
$stpdo->bindValue(1, $id, PDO::PARAM_INT);<br />
$stpdo->execute();<br />
while ($row=$stpdo->fetch())<br />
{<br />
     echo 'id: '.$row['id'].' - name: '.$row['name'].'&lt;br /&gt;';<br />
}<br />
$mypdo->commit();<br />
</code></p>
<p><strong>bindColumn</strong><br />
<code><br />
$mypdo->beginTransaction();<br />
// preparo la query<br />
$stpdo = $mypdo->prepare("SELECT * FROM first_table ");<br />
$stpdo->bindColumn(1,$id);<br />
$stpdo->bindColumn(2,$name);<br />
$stpdo->bindColumn(3,$surname);<br />
$stpdo->execute();<br />
while($row = $stpdo->fetch(PDO::FETCH_BOUND))<br />
    echo $id.' '.$name.' '.$surname.'&lt;br /&gt;'; // stampo i nomi<br />
$mypdo->commit();<br />
</code><br />
In pratica specifico prima come devono chiamarsi i dati letti da una query e di che tipo devono essere.<br />
a variabile $id non l&#8217;avevo mai creata, nonostante ciò non ho avuto nessun notice o warning perche&#8217; questa viene popolata e inizializzata ( se inesistente ) automaticamente all&#8217; interno della chiamata a bindColumn.<br />
Poi la variabile viene automaticamente riassegnata ad ogni ciclo del while ,<br />
permettendoci di evitare i soliti $row[N] per il fetch_row o $row['key'] per il fetch_assoc.</p>
<p><strong>bindColumn</strong><br />
<code><br />
$mypdo->beginTransaction();<br />
// preparo la query<br />
$stpdo = $mypdo->prepare("SELECT * FROM first_table ");<br />
$stpdo->bindColumn(1,$id, PDO::PARAM_INT);<br />
$stpdo->bindColumn(2,$name, PDO::PARAM_STR);<br />
$stpdo->bindColumn(3,$surname, PDO::PARAM_STR);<br />
$stpdo->execute();<br />
while($row = $stpdo->fetch(PDO::FETCH_BOUND))<br />
    echo $id.' '.$name.' '.$surname.'&lt;br /&gt;'; // stampo i nomi<br />
$mypdo->commit();<br />
</code></p>
<p>i parametri non modificano il risultato, ma &#8220;forse&#8221; ottimizzano le query</p>
<p>così abbiamo visto anche come funizona PDO::FETCH_BOUND</p>
<p>E se volessi usare Postgres invece di Mysql?<br />
Semplice creo il DB pgsql come quello mysql e basta che cambi queste rige con i diversi parametri di connessione:<br />
<code><br />
$string_dsn = 'pgsql:host=localhost;dbname=pdo'; // pgsql<br />
$string_username = 'user';<br />
$string_password = 'password';<br />
</code></p>
<p>ed il gioco è fatto, bello no?!</p>
<p>Lo studio l&#8217;ho fatto partendo da questi link:</p>
<p><a href="http://it2.php.net/pdo">http://it2.php.net/pdo</a><br />
<a href="http://forum.html.it/forum/showthread.php?s=&#038;postid=8143487">Pillola PDO</a></p>
<p>Gabba Gabba Hey<br />
Bonzo</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ilbonzo.org/2008/06/16/pdo-abstraction-layer/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CakePHP, Blog[2]</title>
		<link>http://blog.ilbonzo.org/2008/02/11/cakephp-blog2/</link>
		<comments>http://blog.ilbonzo.org/2008/02/11/cakephp-blog2/#comments</comments>
		<pubDate>Mon, 11 Feb 2008 12:31:51 +0000</pubDate>
		<dc:creator>Bonzo</dc:creator>
				<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[cakePHP]]></category>

		<guid isPermaLink="false">http://blog.ilbonzo.org/2008/02/11/cakephp-blog2/</guid>
		<description><![CDATA[Andiamo avanti con la realizzazione del blog scritto con CakePHP.
Devo creare il meccanismo la creazione, modifica e eliminzaione dei post.
Aggiungere i Post
/app/controllers/posts_controller.php

< ?php
class PostsController extends AppController
{
    var $name = 'Posts';
    function index()
    {
        $this->set('posts', $this->Post->findAll());
    }
	function [...]]]></description>
			<content:encoded><![CDATA[<p>Andiamo avanti con la realizzazione del blog scritto con <a href="http://cakephp.org" class="Tips3" title="CakePHP framework web">CakePHP</a>.</p>
<p>Devo creare il meccanismo la creazione, modifica e eliminzaione dei post.</p>
<p><strong>Aggiungere i Post</strong><br />
<em>/app/controllers/posts_controller.php</em><br />
<code><br />
< ?php<br />
class PostsController extends AppController<br />
{<br />
    var $name = 'Posts';<br />
    function index()<br />
    {<br />
        $this->set('posts', $this->Post->findAll());<br />
    }<br />
	function view($id = null)<br />
    {<br />
        $this->Post->id = $id;<br />
        $this->set('post', $this->Post->read());<br />
    }<br />
	function add()<br />
    {<br />
        if (!empty($this->data))<br />
        {<br />
            if ($this->Post->save($this->data))<br />
            {<br />
                $this->flash('Your post has been saved.','/posts');<br />
            }<br />
        }<br />
    }<br />
}<br />
?><br />
</code></p>
<p>Il controller guarda che i dati inviati via POST non siano vuoti, se non lo sono utilizza il metodo per salvare i dati. Con il metodo flash è possibile visualizzare un messaggio che dice se i dati sono stati salvati.<br />
<strong><br />
Creo la vista add</strong><br />
<em>/app/views/posts/add.thtml</em><br />
<code><br />
< &lt;h1&gt;Add Post&lt;/h1&gt;<br />
&lt;form method="post" action="<?php echo $html->url('/posts/add')?>"&gt;<br />
    &lt;p&gt;<br />
        Title:<br />
        < ?php echo $html->input('Post/title', array('size' => '40'))?><br />
        < ?php echo $html->tagErrorMsg('Post/title', 'Title is required.') ?><br />
    &lt;/p&gt;<br />
    &lt;p&gt;<br />
        Body:<br />
        < ?php echo $html->textarea('Post/body', array('rows'=>'10')) ?><br />
        < ?php echo $html->tagErrorMsg('Post/body', 'Body is required.') ?><br />
    &lt;/p&gt;<br />
    &lt;p&gt;<br />
        < ?php echo $html->submit('Save') ?><br />
    &lt;/p&gt;<br />
&lt;/form&gt;<br />
</code></p>
<p>ecco come si visualizza la pagina:<br />
<em>http://localhost/cake/posts/add</em><br />
<a href='http://blog.ilbonzo.org/wp-content/uploads/2008/02/003_add_post.png' title='creazione post' rel='lightbox'><img src='http://blog.ilbonzo.org/wp-content/uploads/2008/02/003_add_post.thumbnail.png' alt='creazione post' /></a></p>
<p><strong>Modifico il modello Post</strong><br />
<em>/app/models/post.php</em><br />
aggiungo la validazione dei dati.</p>
<p><code><br />
< ?php<br />
class Post extends AppModel<br />
{<br />
    var $name = 'Post';<br />
    var $validate = array(<br />
        'title'  => VALID_NOT_EMPTY,<br />
        'body'   => VALID_NOT_EMPTY<br />
    );<br />
}<br />
?></code></p>
<p>L&#8217;array $validate dice a Cake come validare i dati quando è chiamato il metodo save(). I valori per queste chiave si possono vedere in  /cake/libs/validators.php.</p>
<p><code><br />
/**<br />
 * Not empty.<br />
 */<br />
	define('VALID_NOT_EMPTY', '/.+/');<br />
/**<br />
 * Numbers [0-9] only.<br />
 */<br />
	define('VALID_NUMBER', '/^[-+]?\\b[0-9]*\\.?[0-9]+\\b$/');<br />
/**<br />
 * A valid email address.<br />
 */<br />
	define('VALID_EMAIL', '/\\A(?:^([a-z0-9][a-z0-9_\\-\\.\\+]*)@([a-z0-9][a-z0-9\\.\\-]{0,63}\\.(com|org|net|biz|info|name|net|pro|aero|coop|museum|[a-z]{2,4}))$)\\z/i');<br />
/**<br />
 * A valid year (1000-2999).<br />
 */<br />
	define('VALID_YEAR', '/^[12][0-9]{3}$/');<br />
</code></p>
<p>Ecco cosa succede se si prova ad inserire un post senza il titolo:</p>
<p><a href='http://blog.ilbonzo.org/wp-content/uploads/2008/02/004_cake_title_request.png' title='title request' rel='lightbox'><img src='http://blog.ilbonzo.org/wp-content/uploads/2008/02/004_cake_title_request.thumbnail.png' alt='title request' /></a></p>
<p><strong>Cancellare i post, azione delete</strong><br />
<em>/app/controllers/posts_controller.php</em></p>
<p><code><br />
< ?php<br />
class PostsController extends AppController<br />
{<br />
    var $name = 'Posts';<br />
    function index()<br />
    {<br />
        $this->set('posts', $this->Post->findAll());<br />
    }<br />
	function view($id = null)<br />
    {<br />
        $this->Post->id = $id;<br />
        $this->set('post', $this->Post->read());<br />
    }<br />
	function add()<br />
    {<br />
        if (!empty($this->data))<br />
        {<br />
            if ($this->Post->save($this->data))<br />
            {<br />
                $this->flash('Your post has been saved.','/posts');<br />
            }<br />
        }<br />
    }<br />
	function delete($id)<br />
	{<br />
		$this->Post->del($id);<br />
		$this->flash('The post with id: '.$id.' has been deleted.', '/posts');<br />
	}<br />
}<br />
?><br />
</code></p>
<p>Aggiungo il link delete nella vista index<br />
<em>/app/views/posts/index.thtml</em></p>
<p><code><br />
< ?php<br />
echo $html->link(<br />
                'Delete',<br />
                "/posts/delete/{$post['Post']['id']}",<br />
                null,<br />
                'Are you sure?'<br />
            )<br />
?><br />
</code></p>
<p>se clicco mi si apre un alert javascript che mi chiede se sono sicuro.<br />
Se disabilito javascript nel browser il post viene cancellato senza richiesta di conferma.</p>
<p><strong>Modificare i post, azione edit</strong><br />
<em>/app/controllers/posts_controller.php</em></p>
<p><code><br />
	function edit($id = null)<br />
	{<br />
		if (empty($this->data))<br />
		{<br />
			$this->Post->id = $id;<br />
			$this->data = $this->Post->read();<br />
		}<br />
		else<br />
		{<br />
			if ($this->Post->save($this->data['Post']))<br />
			{<br />
				$this->flash('Your post has been updated.','/posts');<br />
			}<br />
		}<br />
	}<br />
</code></p>
<p><strong>Creo la vista edit</strong><br />
<em>/app/views/posts/edit.thtml</em></p>
<p><code><br />
&lt;h1&gt;Edit Post&lt;/h1&gt;<br />
&lt;form method="post" action="< ?php echo $html->url('/posts/edit')?>"&gt;<br />
    < ?php echo $html->hidden('Post/id'); ?><br />
    &lt;p&gt;<br />
        Title:<br />
        < ?php echo $html->input('Post/title', array('size' => '40'))?><br />
        < ?php echo $html->tagErrorMsg('Post/title', 'Title is required.') ?><br />
    &lt;/p&gt;<br />
    &lt;p&gt;<br />
        Body:<br />
        < ?php echo $html->textarea('Post/body', array('rows'=>'10')) ?><br />
        < ?php echo $html->tagErrorMsg('Post/body', 'Body is required.') ?><br />
    &lt;/p&gt;<br />
    &lt;p&gt;<br />
        < ?php echo $html->submit('Save') ?><br />
    &lt;/p&gt;<br />
&lt;/form&gt;<br />
</code></p>
<p>aggiungo il link edit nella vista index<br />
<em>/app/views/posts/index.thtml</em></p>
<p><code><br />
 < ?php echo $html->link('Edit', '/posts/edit/'.$post['Post']['id']);?><br />
</code></p>
<p><strong>Modifica pagina di home</strong><br />
<em>/app/config/routes.php</em></p>
<p>Nel file routes.php ci sono le configurazioni per i controller e le relative viste che si devono aprire per i vari indirizzi.</p>
<p>Modifico commentando<br />
<code><br />
	//$Route->connect('/', array('controller' => 'pages', 'action' => 'display', 'home'));<br />
</code><br />
e settando:<br />
<code><br />
/**<br />
* Collegamento alla pagina index<br />
*<br />
*/<br />
	$Route->connect ('/', array('controller'=>'posts', 'action'=>'index'));<br />
</code><br />
Così andando a http://localhost/cake mi apre direttamente la vista index del controller posts.</p>
<p>Ecco fatto, ora il sistema di gestione dei Post è finito, il prossimo obbiettivo è implementare un sistema di gestione degli utenti che possono inviare i post.</p>
<p>Gabba Gabba Hey<br />
Bonzo</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ilbonzo.org/2008/02/11/cakephp-blog2/feed/</wfw:commentRss>
		<slash:comments>2</slash:comments>
		</item>
		<item>
		<title>CakePHP, Blog [1]</title>
		<link>http://blog.ilbonzo.org/2008/02/05/cakephp-blog-1/</link>
		<comments>http://blog.ilbonzo.org/2008/02/05/cakephp-blog-1/#comments</comments>
		<pubDate>Tue, 05 Feb 2008 12:51:41 +0000</pubDate>
		<dc:creator>Bonzo</dc:creator>
				<category><![CDATA[LinkedIn]]></category>
		<category><![CDATA[cakePHP]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[blog]]></category>
		<category><![CDATA[Programmazione]]></category>

		<guid isPermaLink="false">http://blog.ilbonzo.org/2008/02/05/cakephp-blog-1/</guid>
		<description><![CDATA[Comincio a fare &#8220;sul serio&#8221; con l&#8217;uso di CAkePHP, ora proverò a creare un blog.
Creazione database

Per prima cosa
Ecco alcuni accorgimenti sulle regole che devono seguire le tabelle (naming convention):

I nomi devono essere in plurale inglese (posts ad esempio), in modo che i modelli corrispondenti abbiano nomi in singolare;
tutte le tabelle devono avere una chiave primaria [...]]]></description>
			<content:encoded><![CDATA[<p>Comincio a fare &#8220;sul serio&#8221; con l&#8217;uso di CAkePHP, ora proverò a creare un blog.</p>
<p><strong>Creazione database</strong></p>
<blockquote><p>
Per prima cosa<br />
Ecco alcuni accorgimenti sulle regole che devono seguire le tabelle (naming convention):</p>
<ul>
<li>I nomi devono essere in plurale inglese (posts ad esempio), in modo che i modelli corrispondenti abbiano nomi in singolare;</li>
<li>tutte le tabelle devono avere una chiave primaria chiamata id;
        </li>
<li>le chiavi esterne utilizzate per costruire le relazioni tra le tabelle devono essere nomiate utilizzando il singolare della tabella a cui fanno riferimento seguito da _id (post_id per esempio);</li>
<li> è possibile includere i campi created e modified che verranno automaticamente aggiornati da CakePHP quando si opererà sui record.
</li>
</ul>
<p>Cake contiente una classe <em>inflections</em> che si occupa di ottenere i plurali dei vari nomi.</p>
</blockquote>
<p>Creo il database <strong>blog_cake</strong>.</p>
<p>Creo la tabella <strong>posts</strong>.<br />
<code><br />
/* First, create our posts table: */<br />
CREATE TABLE posts (<br />
    id INT UNSIGNED AUTO_INCREMENT PRIMARY KEY,<br />
    title VARCHAR(50),<br />
    body TEXT,<br />
    created DATETIME DEFAULT NULL,<br />
    modified DATETIME DEFAULT NULL<br />
);<br />
</code><br />
<code><br />
/* Then insert some posts for testing: */<br />
INSERT INTO posts (title,body,created)<br />
    VALUES ('il titolo', 'Questo è il contenuto di un post.', NOW());<br />
INSERT INTO posts (title,body,created)<br />
    VALUES ('secondo titolo', 'Altro contenuto di un post.', NOW());<br />
INSERT INTO posts (title,body,created)<br />
    VALUES ('Divetimento', 'Divertiamoci.', NOW());<br />
</code></p>
<p>Imposto i dati di connessione al database nel file <em>/app/config/database.php</em><br />
<code><br />
var $default = array('driver'   => 'mysql',<br />
                     'connect'  => 'mysql_pconnect',<br />
                     'host'     => 'localhost',<br />
                     'login'    => '<utente>',<br />
                     'password' => '
<password>',<br />
                     'database' => 'blog_cakel' );
</password></utente></code></p>
<p>Cake contiene una Classe AppModel da cui si parte per ottenere i nuovi modelli, estendendo tale classe di partenza.</p>
<p><strong>Creo il modello Post:</strong></p>
<p><em>/app/models/post.php</em></p>
<p><code><br />
< ?php<br />
class Post extends AppModel<br />
{<br />
    var $name = 'Post';<br />
}<br />
?><br />
</code></p>
<p><strong>Creo il controller Post</strong><br />
Dato che abbiamo deciso di seguire le convenzioni sui nomi sarà possibile accedere ai modelli implementati direttamente attraverso $this->NOME_MODELLO.<br />
<em>/app/controllers/posts_controller.php</em></p>
<p><code>< ?php<br />
class PostsController extends AppController<br />
{<br />
    var $name = 'Posts';<br />
}<br />
?><br />
</code></p>
<p>Ci aggiungo l&#8217;azione index</p>
<p><code><br />
< ?php<br />
class PostsController extends AppController<br />
{<br />
    var $name = 'Posts';<br />
    function index()<br />
    {<br />
        $this->set('posts', $this->Post->findAll());<br />
    }<br />
}<br />
?></code></p>
<p>Il metodo index registra un array con tutti i post inseriti utilizzando il metodo set, che rende disponibile questo array alla vista.</p>
<p><strong>Creo la vista index</strong><br />
<em><br />
/app/views/posts/index.thtml</em></p>
<p><code><br />
&lt;h1&gt;Blog&lt;/h1&gt;<br />
    < ?php foreach ($posts as $post): ?><br />
    &lt;dl&gt;<br />
		&lt;dt&gt;<br />
		&lt;h3&gt;< ?php echo $html->link($post['Post']['title'], "/posts/view/".$post['Post']['id']); ?>&lt;/h3&gt;<br />
        < ?php<br />
			echo $post['Post']['id'];<br />
			echo '&lt;br/&gt;';<br />
			echo $post['Post']['created'];<br />
			echo '&lt;br/&#038;gt';<br />
			echo '&lt;br/&gt;';<br />
		?><br />
		&lt;/dt&gt;<br />
		&lt;dd&gt;<br />
		< ?php<br />
			echo $post['Post']['body'];<br />
		?><br />
		&lt;/dd&gt;<br />
	&lt;/dl&gt;<br />
   < ?php endforeach; ?><br />
</code></p>
<p>Vado con il browser all&#8217;indirizzo:<br />
<em>http://localhost/cake/posts/</em><br />
ed ecco il risultato:</p>
<p><a href='http://blog.ilbonzo.org/wp-content/uploads/2008/01/001_post.PNG' title='cakePHP blog' rel='lightbox'><img src='http://blog.ilbonzo.org/wp-content/uploads/2008/01/001_post.thumbnail.PNG' alt='cakePHP blog' /></a></p>
<p>Ora aggiungo l&#8217;azione view al controller, per gestire la visualizzazione di un singolo post.</p>
<p><code><br />
< ?php<br />
class PostsController extends AppController<br />
{<br />
    var $name = 'Posts';<br />
    function index()<br />
    {<br />
        $this->set('posts', $this->Post->findAll());<br />
    }<br />
	function view($id = null)<br />
    {<br />
        $this->Post->id = $id;<br />
        $this->set('post', $this->Post->read());<br />
    }<br />
}<br />
?><br />
</code></p>
<p><strong>Creo la vista view</strong><br />
<em>/app/views/posts/view.thtml</em></p>
<p><code><br />
&lt;h2&gt;< ?php echo $post['Post']['title']?>&lt;/h2&gt;<br />
&lt;p&gt;&lt;small&gt;Created: < ?php echo $post['Post']['created']?>&lt;/small&gt;&lt;/p&gt;<br />
&lt;p&gt;< ?php echo $post['Post']['body']?>&lt;/p&gt;<br />
</code></p>
<p>Ora se clicco sul titolo del primo post, mi sposto all&#8217;indirizzo:<br />
<em>http://localhost/cake/posts/view/1</em></p>
<p>e vedo la vista view di questo post.</p>
<p><a href='http://blog.ilbonzo.org/wp-content/uploads/2008/02/002_single_post1.png' title='post singolo' rel='lightbox'><img src='http://blog.ilbonzo.org/wp-content/uploads/2008/02/002_single_post1.thumbnail.png' alt='post singolo' /></a></p>
<p>Così ho completato tutte le pagine per visualizzare il blog, la prossima volta passo alle pagine per inserimento, modifica e cancellazione dei post.</p>
<p>Gabba Gabba Hey<br />
Bonzo</p>
]]></content:encoded>
			<wfw:commentRss>http://blog.ilbonzo.org/2008/02/05/cakephp-blog-1/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
	</channel>
</rss>
