Blogbonzo: Matteo Magni

Consulente Informatico, Web Developer & System Administrator

Drupal Day 2008

leave a comment




DSCF5642

Inserito originariamente da ilbonzo.org

Written by flickr

marzo 5th, 2009 at 4:02 pm

Posted in Senza categoria

Eliminare .svn

leave a comment

Windows:

for /f "tokens=* delims=" %%i in ('dir /s /b /a:d *svn') do (
rd /s /q "%%i"
)

Linux:

find ./ -name .svn -exec rm -rf {} +

Written by Bonzo

febbraio 23rd, 2009 at 5:12 pm

PDO, Abstraction Layer

2 comments

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’:

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 INT(10) NOT NULL AUTO_INCREMENT,
name VARCHAR(255) NOT NULL,
surname VARCHAR(255) NOT NULL,
PRIMARY KEY (id)
) TYPE=innoDB;


INSERT INTO first_table (name,surname) VALUES ('matteo','magni');
INSERT INTO first_table (name,surname) VALUES ('john','starks');
INSERT INTO first_table (name,surname) VALUES ('michael','jordan');
INSERT INTO first_table (name,surname) VALUES ('kobe','bryant');
INSERT INTO first_table (name,surname) VALUES ('earvin','johnson');
INSERT INTO first_table (name,surname) VALUES ('larry','bird');
INSERT INTO first_table (name,surname) VALUES ('patrick','ewing');
INSERT INTO first_table (name,surname) VALUES ('reggie','miller');
INSERT INTO first_table (name,surname) VALUES ('ron','harper');
INSERT INTO first_table (name,surname) VALUES ('anfernee','hardaway');
INSERT INTO first_table (name,surname) VALUES ('tim','hardaway');
INSERT INTO first_table (name,surname) VALUES ('mitch','richmond');
INSERT INTO first_table (name,surname) VALUES ('jason','williams');
INSERT INTO first_table (name,surname) VALUES ('allen','iverson');
INSERT INTO first_table (name,surname) VALUES ('dwayne','wade');

Lo importo così dopo aver creato il DB pdo

mysql -p -D pdo < pdo.sql

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.

Usiamo le eccezioni per connetterci al DB

//USO le eccezioni
$string_dsn = 'mysql:host=localhost;dbname=pdo'; // mysql
$string_username = 'user';
$string_password = 'password';
try {
$mypdo = new PDO($string_dsn, $string_username, $string_password);
}
catch(PDOException $e) {
echo 'Errore di connessione: '.$e->getMessage();
}

Query fatta con errore, mi restituisce il numero dell’errore:

$mypdo->exec('SELECT * FROM SELECT'); // errore generato appositamente
echo 'Errore N: '.$mypdo->errorCode();

Se la uso così è molto utile, mando io il messaggio che voglio:

if($mypdo->errorCode() !== '' || !$mypdo->exec('SELECT * FROM SELECT'))
echo 'errore nella query SELECT * FROM SELECT';

Così mi ritorna un array di tre elementi con le notizie sull’errore:

var_dump($mypdo->errorInfo());
//array di tre elementi
if(count($mypdo->errorInfo()) == 1) // ... tutto ok
if(count($mypdo->errorInfo()) > 1) { // ... ci sono errori
$errorinfo = $mypdo->errorInfo();
echo $errorinfo[2]; // stringa con l' errore
}

QUERY semplice senza preparare niente,
Mi ritorna i dati accessibili sia con il numero della colonna (partendo da 0) che con il nome della colonna
Query senza parametri aggiuntivi per stabilire che Fetch usare:


foreach($mypdo->query('SELECT * FROM first_table') as $row)
{
echo '--------------<br />';
echo '1: '.$row[0].' - 2: '.$row[1].'<br />';
echo 'id: '.$row['id'].' - name: '.$row['name'].'<br />';
}

mi ritorna i dati accessibili sia con il numero della colonna (partendo da 0) che con il nome della colonna.

Esplicito il tipo di Fetch con il parametro PDO_FETCH_*
PDo::FETCH_BOTH #usatelo come mysql fetch_array, risultato duplicato, quello di default

foreach($mypdo->query('SELECT * FROM first_table', PDO::FETCH_BOTH) as $row)
{
echo '--------------<br />';
echo '1: '.$row[0].' - 2: '.$row[1].'<br />';
echo 'id: '.$row['id'].' - name: '.$row['name'].'<br />';
}

PDO::FETCH_ASSOC #usatelo come mysql_fetch_assoc

foreach($mypdo->query('SELECT * FROM first_table', PDO::FETCH_ASSOC) as $row)
{
echo '--------------<br />';
echo 'id: '.$row['id'].' - name: '.$row['name'].'<br />';
}

PDO::FETCH_NUM #analogo a mysql_fetch_row

foreach($mypdo->query('SELECT * FROM first_table', PDO::FETCH_NUM) as $row)
{
echo '--------------<br/>';
echo '1: '.$row[0].' - 2: '.$row[1].'<br/>';
}

PDO::FETCH_OBJ #ritorna un oggetto con le proprieta’ che hanno il nome dei campi

foreach($mypdo->query('SELECT * FROM first_table', PDO::FETCH_OBJ) as $row)
{
echo '--------------<br />';
echo 'id->'.$row->id.' - name-> '.$row->name.'<br />';
}

PDO::FETCH_LAZY #combina *_BOTH e *_OBJ

foreach($mypdo->query('SELECT * FROM first_table', PDO::FETCH_LAZY) as $row)
{
echo '--------------<br />';
echo '1: '.$row[0].' - 2: '.$row[1].'<br />';
echo 'id: '.$row['id'].' - name: '.$row['name'].'<br />';
echo 'id->'.$row->id.' - name-> '.$row->name.'<br />';
}

PDO::FETCH_BOUND #Lo vediamo con bindColumn,
restituiti come attributi alle variabili PHP

Per Evitare problemi con DB case sensitive e non case sensitive
Setto che i nomi delle colonne siano restituiti sempre minuscoli

$mypdo->setAttribute(PDO::CASE_LOWER);
/*
* Psso usare anche
* PDO::CASE_UPPER
* PDO::CASE_NATURAL come sono fornite dal driver, metodo di default
*/

oppure si usa sempre FETCH_NUM

Utilizzo delle Transazioni

inizio la transazione

Su Mysql devo usare tabelle InnoDB perchè MyIsam non supportano le transazioni

Però…
The following example begins a transaction and issues two statements that
modify the database before rolling back the changes.
On MySQL, however, the DROP TABLE statement automatically commits the
transaction so that none of the changes in the transaction are rolled back.

Quindi niente drop per una transazione.

$mypdo->beginTransaction();
$mypdo->exec('DROP TABLE first_table');
$mypdo->rollBack(); // la tabella mytable rimarra' invariata :-)

come detto su MySQL la cancella lo stesso.


$mypdo->beginTransaction();
$mypdo->exec("INSERT INTO first_table (name,surname) VALUES ('gianni','morandi')");
$mypdo->rollBack(); // la tabella mytable rimarra' invariata :-)


$mypdo->beginTransaction();
$mypdo->exec("INSERT INTO first_table (name,surname) VALUES ('gianni','morandi')");
$mypdo->commit(); // la tabella mytable rimarra' invariata :-)

mi inserisce il nuovo valore.

Prepared Statement

Metodo Fetch
Metodo implementato nello statement che è in grado di spostare il cursore dei risultati di una query in un ciclo.
Gli posso passare i parametri come a query.
/*
* PDO::FETCH_ASSOC, PDO::FETCH_BOTH, PDO::FETCH_BOUND, PDO::FETCH_LAZY,
* PDO::FETCH_OBJ, PDO::FETCH_NUM
*/

$mypdo->beginTransaction();
// preparo la query
$stpdo = $mypdo->prepare('UPDATE first_table SET name = "pippo" WHERE id = 17');
// eseguo la query
$stpdo->execute();
$mypdo->commit();
echo 'SELECT';
$mypdo->beginTransaction();
// preparo la query
$stpdo = $mypdo->prepare('SELECT * FROM first_table');
// eseguo la query
$stpdo->execute();
//stampo a video il contenuto dell'array che mi crea fetch
while ($row=$stpdo->fetch())
{
echo 'id: '.$row['id'].' - name: '.$row['name'].'<br />';
}
$mypdo->commit();

La potenza prepare e execute
Potenza del metodo prepare

$mypdo->beginTransaction();
$stpdo = $mypdo->prepare('UPDATE first_table SET name = ? WHERE id = ?');
//i punti interrogativi saranno sostituiti da execute
$stpdo->execute(array('gianni', 17));
$mypdo->commit();
echo 'SELECT';
$mypdo->beginTransaction();
// preparo la query
$stpdo = $mypdo->prepare('SELECT * FROM first_table');
// eseguo la query
$stpdo->execute();
//stampo a video il contenuto dell'array che mi crea fetch
while ($row=$stpdo->fetch())
{
echo 'id: '.$row['id'].' - name: '.$row['name'].'<br />';
}
$mypdo->commit();

Posso preparare la query una volta e fare poi i vari inserimenti.
potenza prepare e execute ancora

$mypdo->beginTransaction();
$stpdo = $mypdo->prepare('UPDATE first_table SET name = :name WHERE id = :id');
//i punti interrogativi non sempre sono chiari, così lo è di più
$stpdo->execute(array(':name'=>'marcello',':id'=>17));
$mypdo->commit();
echo 'SELECT';
$mypdo->beginTransaction();
// preparo la query
$stpdo = $mypdo->prepare('SELECT * FROM first_table');
// eseguo la query
$stpdo->execute();
//stampo a video il contenuto dell'array che mi crea fetch
while ($row=$stpdo->fetch())
{
echo 'id: '.$row['id'].' - name: '.$row['name'].'<br />';
}
$mypdo->commit();

Metodo fetchAll
ritorna un array le righe del resultset

$mypdo->beginTransaction();
// preparo la query
$stpdo = $mypdo->prepare('SELECT * FROM first_table');
// eseguo la query
$stpdo->execute();
$row=$stpdo->fetchAll();
//stampo a video il contenuto dell'array che mi crea fetch
var_dump($row);
$mypdo->commit();

Metodo fetchAll

$mypdo->beginTransaction();
// preparo la query
$stpdo = $mypdo->prepare('SELECT * FROM first_table');
// eseguo la query
$stpdo->execute();
$row=$stpdo->fetchAll(PDO::FETCH_OBJ);
//così ho un array di oggetti
//stampo a video il contenuto dell'array che mi crea fetch
var_dump($row);
$mypdo->commit();

Metodi bind

bindParam

$id=10;
$mypdo->beginTransaction();
// preparo la query
$stpdo = $mypdo->prepare("SELECT * FROM first_table WHERE id = ? ");
$stpdo->bindParam(1,$id, PDO::PARAM_INT);
$stpdo->execute();
while ($row=$stpdo->fetch())
{
echo 'id: '.$row['id'].' - name: '.$row['name'].'<br />';
}
$mypdo->commit();

Oppure:

$id=10;
$mypdo->beginTransaction();
// preparo la query
$stpdo = $mypdo->prepare("SELECT * FROM first_table WHERE id = :id ");
$stpdo->bindParam(':id',$id, PDO::PARAM_INT);
$stpdo->execute();
while ($row=$stpdo->fetch())
{
echo 'id: '.$row['id'].' - name: '.$row['name'].'<br />';
}
$id=13;
$stpdo->bindParam(':id',$id, PDO::PARAM_INT);
$stpdo->execute();
while ($row=$stpdo->fetch())
{
echo 'id: '.$row['id'].' - name: '.$row['name'].'<br />';
}
$mypdo->commit();

Così ho preparato la query una volta sola, ed ho legato :id al valore della variabile $id.

bindValue

$id=10;
$mypdo->beginTransaction();
$stpdo = $mypdo->prepare('SELECT * FROM first_table WHERE id < ? ');
$stpdo->bindValue(1, $id, PDO::PARAM_INT);
$stpdo->execute();
while ($row=$stpdo->fetch())
{
echo 'id: '.$row['id'].' - name: '.$row['name'].'<br />';
}
$mypdo->commit();

bindColumn

$mypdo->beginTransaction();
// preparo la query
$stpdo = $mypdo->prepare("SELECT * FROM first_table ");
$stpdo->bindColumn(1,$id);
$stpdo->bindColumn(2,$name);
$stpdo->bindColumn(3,$surname);
$stpdo->execute();
while($row = $stpdo->fetch(PDO::FETCH_BOUND))
echo $id.' '.$name.' '.$surname.'<br />'; // stampo i nomi
$mypdo->commit();

In pratica specifico prima come devono chiamarsi i dati letti da una query e di che tipo devono essere.
a variabile $id non l’avevo mai creata, nonostante ciò non ho avuto nessun notice o warning perche’ questa viene popolata e inizializzata ( se inesistente ) automaticamente all’ interno della chiamata a bindColumn.
Poi la variabile viene automaticamente riassegnata ad ogni ciclo del while ,
permettendoci di evitare i soliti $row[N] per il fetch_row o $row['key'] per il fetch_assoc.

bindColumn

$mypdo->beginTransaction();
// preparo la query
$stpdo = $mypdo->prepare("SELECT * FROM first_table ");
$stpdo->bindColumn(1,$id, PDO::PARAM_INT);
$stpdo->bindColumn(2,$name, PDO::PARAM_STR);
$stpdo->bindColumn(3,$surname, PDO::PARAM_STR);
$stpdo->execute();
while($row = $stpdo->fetch(PDO::FETCH_BOUND))
echo $id.' '.$name.' '.$surname.'<br />'; // stampo i nomi
$mypdo->commit();

i parametri non modificano il risultato, ma “forse” ottimizzano le query

così abbiamo visto anche come funizona PDO::FETCH_BOUND

E se volessi usare Postgres invece di Mysql?
Semplice creo il DB pgsql come quello mysql e basta che cambi queste rige con i diversi parametri di connessione:

$string_dsn = 'pgsql:host=localhost;dbname=pdo'; // pgsql
$string_username = 'user';
$string_password = 'password';

ed il gioco è fatto, bello no?!

Lo studio l’ho fatto partendo da questi link:

http://it2.php.net/pdo
Pillola PDO

Gabba Gabba Hey
Bonzo

Written by Bonzo

giugno 16th, 2008 at 3:19 pm

PHP day 2008

leave a comment

Venerdì scorso ho partecipato al primo giorno del PHP day 2008.
Rispetto allo scorso anno l’evento è risultato molto più interessante, forse anche per una mia maggior predisposizione allo scambio di opinioni e battute con i partecipanti. Purtroppo non ho potuto partecipare ai workshop del sabato, speriamo nel prossimo anno.

Ecco il talk che ho apprezzato di più:
Nel canale Enterprise si è assistito a un piccolo confronto tra tre CMS tra i più diffusi.

Avendoli utilizzati tutti e tre, ho apprezzato e seguito con interesse il confronto e la mia piccola conclusione è che Drupal è il miglior compromesso tra potenza e semplicità (ovviamente grazie a views e cck), eZpublish è potentissimo ma adatto a grosse realtà (con le sue 102 tabelle e tutto il resto è forse troppo esoso di risorse per un semplice blog), mentre Joomla rimane un po’ staccato avendo una flessibilità minore rispetto agli altri due, nonostante ciò è quello con un community maggiore, quindi è sempre da tenere d’occhio.

I pochi rimasti per i talk finali del venerdì

Oltre a questo ho fatto in tempo a sentire il talk di Daniele Teti sui Design patterns e quello di Simone Carletti sullo zend framework ed i web services. Quest’ultimo è stato ricco di esempi e molto interessante, non a caso ho scaricato lo Zend il giorno dopo e penso che, almeno come libreria comicerò ad usarlo. Uno dei suoi vantaggi è proprio il fatto di poter essere usato a pezzi, non costringendo il programmatore a sapere tutto sul framework.

Dal Blog di Fullo un po’ di Link su foto, video e altro dell’evento.
Fullo Blog

Ci si vede nel 2009

Gabba Gabba Hey
Bonzo

Written by Bonzo

maggio 31st, 2008 at 6:44 am

Plugin Shadowbox per Wordpress versione 0.2

leave a comment

Ecco “finalmente” la versione 0.2 del mio plugin Shadowbox per wordpress.

Novità:
Ora è possibile utilizzare il plugin sia con Yahoo! User Interface Library che con Prototype + Scriptaculous oltre ovviamente a MooTools.

Di default è attivato quest’ultimo, ma per chi volesse modificando il file shadowbox.php e commentando la porzione mootools e decommentando quella del framework interessato si può usare il plugin nel modo che si preferisce.

Versioni:

Ecco il repository SVN per chi volesse collaborare:
http://svn.wp-plugins.org/shadowbox/

Gabba Gabba Hey
Bonzo

Written by Bonzo

maggio 2nd, 2008 at 11:59 am

Posted in wordpress