Newsgroup: it.comp.www.php
Titolo: Mi dareste una mano ad iniziare con Zend

Ok, ho deciso che Zend sara' il mio framework e mi appresto ad
iniziare questa nuova avventura....
Tanto per iniziare volevo fare quanto segue:
Ho una tabella mysql che ha dei campi chiave e dun campo bolob dove
dentro c'e' un pdf.
Tempo fa ho scritto una paginetta php che mi presenta un form per la
ricerca dove metto le mie selezioni, parte la query, e si pare una
paginetta con con tutti i record trovati, con una iconcina nell'ultima
colonna che e' un link che mi apre il pdf contenuto nel campo blob di
quel record. La paginetta dei risultati ha le righe che si alternano
di colore per una lettura facile, e ha anche i tastini per andare
avanti e in dietro, dato che ogni pagina mostra un tot di record.
Il tutto col mio php maccheronico funziona egregiamente ma ci ho messo
qualche ora di lavoro per farla.
Con un framework, per fare una cosa cosi' banale credo ci si mettano
pochi minuti vero?
Qualche esempio in merito o qualche consiglio su come iniziare?

 Ok, ho deciso che Zend sara' il mio framework
Scrivero' su questo 3d tutti i passaggi che mi appresto ad eseguire,
cosi' chi ne sa di piu' mi puo' correggere, e chi inizia ora come me
puo' trarre qualche profitto da questo piccolo diario.
Sto studiando da un po' la filosofia dei framework. Si basano sul
concetto Model View Controller, e zend non fa eccezione giusto?
Quindi
Model:
Quindi tornando al mio esempio, per me' il model e' un insieme di
classi che forniscono i metodi per gestire il mio DB Mysql, che in
questo caso e' molto semplice dato che il progetto deve solo
permettermi di fare una query di interrogazione. Giusto?
View:
Il view e' un insieme di classi che si dovrebbero occupare di
disegnare la famosa griglia con i risultati della query, magari con le
righe di colore alternato e la suddivisione dei risultati in pagine
etc... Giusto?
Il controller infine dovrebbe contenere le funzioni che rispondono
alla pressione del tasto cerca facendo scatenare la query, al click
sull'iconcina che apre il pdf desiderato.
Quindi nella mia macchina di prova, un pc con centos 4.4 con
php-5.1.6-3 e Apache/2.0.52:
1) Sotto /var/www/html ho creato una nuova dir che ho chiamato
ProvaZend
2) Dentro ProvaZend ho messo la dir library che altro non e' che tutto
il framework zend 1.5.2
3) Dentro ProvaZend ho creato quindi la struttura del mio progetto, ho
creato la dir application e qui dentro ho creato le dir models, views
e controllers in linea con quanto detto prima sull' mvc. Inoltre ho
creato la directory public, che e' quella che conterra' le pagine che
effettivamente verranno visualizzate dal browser
4) Nella directory public, ho creato un file .htaccess conenente le
seguenti righe:
RewriteEngine on
RewriteRule !\.(js|ico|gif|jpg|png|css)$ index.php
Questo fa si che quando il browser punta su http://<ip_server>/public
ongni richiesta venga forwardata su index.php, ad eccezione degli url
con estensioni js,ico,gif,jpg,png e css
Poi ho creato index.php sempre dentro public... e per il momento mi
sono fermato.
Non ho ben capito come scrivere il codice nelle directory models,
views e controllers ne come questi possano dialogare magicamnete tra
di loro.

 sono fermato.
Ok, ho capito qualcos'altro.... corregetemi se sbaglio come al solito.
E' pratica comune mettere in index.php una include... pardon...
require che punti ad un file comunemente chiamato di "bootstrap" che
si occupa di "preparare" l'ambiente, o environment che dir si voglia.
Quindi il mio index.php ora e' cosi':
<?php
require '../application/bootstrap.php';
Dentro bootstrap.php metto cose del tipo set_include_path('../
library' . PATH_SEPARATOR . get_include_path()); che aggiunge la mia
directory library (il framework di zend) all'include path. Da notare
che il server e' mio quindi avrei potuto configurare tale diretiva in
php.ini, ma mi piace pensare che il mio server sia un hosting di Aruba
per esempio, li non potrei mettere le mani su php.ini, allora
tantovale che ragiono fin da subito in questo modo. Stesso discorso
per il .htaccess con il RewriteEngine, avrei potuto metterlo in
httpd.conf.
Proseguiamo....
quindi il mio file bootstrap.php ora e' cosi':
<?php
/* Imposto il TimeZone */
date_default_timezone_set('Europe/Rome');
/* Mando gli errori a video, comodo per il debugging */
error_reporting(E_ALL | E_STRICT);
ini_set('display_startup_errors', 1);
ini_set('display_errors', 1);
/* Informo l'interprete php su dove prendere le librerye di Zend */
set_include_path('../library' . PATH_SEPARATOR . get_include_path());
/* Utilizzo il metodo registerAutoload() */
/* Questa funzione e' comododissima, fa le include delle classi
istanziate */
/* In maniera del tutto automatica */
require_once "Zend/Loader.php";
Zend_Loader::registerAutoload();
/* Finalmente ora pensiamo al mio DB */
/* Usufruisco delal classe Db di Zend * /
Zend_Loader::loadClass('Zend_Db');
/* Istanzio l'oggetto db passandogli i parametri necessari */
$db = Zend_Db::factory
(
    mysqli,
    array
    (
        'host'        => 192.168.0.1,
        'username'    => davide,
        'password'    => xxxxxxxx,
        'dbname'    => db_prova
    )
);
/*Tento la connessione*/
try
{
    $db->getConnection();
}
/*se ritorna degli errori, intercetto e stampo a video*/
catch (Zend_Db_Adapter_Mysqli_Exception $errore)
{
    echo "Errori nella connessione MySQL";
    print ": " . $error;
    exit();
}
catch (Zend_Db_Exception $errore)
{
    echo "Errori nella connessione MySQL";
    print ": " . $errore;
    exit();
}
/* La struttura MVC funziona cosi' */
$frontController = Zend_Controller_Front::getInstance();
$frontController->throwExceptions(true);
$frontController->setControllerDirectory('../application/
controllers');
/* Avvia l'applicazione */
$frontController->dispatch();
A me sembrava che funzionasse cosi' la cosa..... ma se apro il browser
su 
http://ip_server/public
 ottengo una pagina bianca e nulla di
piu'!!!

 piu'!!!
Scusate.... il problema e' che nell'array dei parametri per la
connessione mysql non mettevo i campi racchiusi tra apici. Ora
funziona.
Ora devo capire conme si scrive il codice per i controllers, e come
usare i template per i viewers... I am very confused!

 usare i template per i viewers... I am very confused!
http://blog.astrumfutura.com/archives/351-An-Example-Zend-Framework-Blog-
Application-Part-1-Introductory-Planning.html
Comincia da qui e prosegui per tutte e 10 le puntate, piu` i due addendum. 
E` scritto molto bene e parte da prima delle basi per arrivare a 
un'applicazione completa.
OK, a te non serve un blog, ma ti servira` sicuramente gestire il layout, 
gli utenti, l'accesso al DB, ed anche la generazione di PDF, e li` spiega 
tutto.
Io ho fatto qualche modifica al suo codice, e non uso Zend_Form (non mi 
piace), ma almeno avrai delle buone basi.
Bye.

 usare i template per i viewers...
Ok, andiamo avanti.
Qui, ho capito, e' tutto una questione di nomenclatura!
La dir controllers, dentro application, deve contenere tanti files
quanti sono i controllers che ci servono, e si devono chiamare cosi':
<Nome>Controller.php, dove Nome e' il nome del controller con la prima
lettera maiuscola, e' la classe Zend_Controller_Front che abbiamo
istanziato nel bootstrap che si occupa di cercare i files in questo
modo.
Se si esegue in un browser il codice che ho postato fino ad ora si
ottiene un erreore generato dal throwExceptions(true) che e' sempre in
bootstrap.php. Si lamenta dicendo che non trova alcun controller al
momento del dispatch().
Ora non ho ancora le idee chiare su come scrivere il mio (o i miei
controllers), ma ce ne e' uno di default che e' Index, quindi creo
IndexController.php dentro la dir controllers.
E dentro cosa ci va? Ci vanno tutti i metodi che il controller deve
fornire. Non ho le idee chiare nemmeno sui metodi che usero' per il
momento, ma anche qui, come per i controllers c'e' un metodo di
default, e come si chiama? Ovvio si chiama index! La nomnclatura e'
importante anche qui ed e' <nome>Action
Quindi l'azione di default la cro cosi':
dentro IndexController.php metto:
<?php
class IndexController extends Zend_Controller_Action
{
        function indexAction()
        {
                echo "<p>Sto usando il metodo di default nella classe
di default</p>";
        }
}
Quindi aprendo l'applicazione nel browser otterrei a video la scritta
"Sto usando il metodo di default nella classe di default"

 "Sto usando il metodo di default nella classe di default"
Mai, mai, mai mettere HTML dentro i controller.
L'HTML va SOLO nelle view.
L'accesso al DB e ai file va SOLO nei model.
La gestione dei parametri passati in GET o POST va SOLO nel controller.
Bye.

 "Sto usando il metodo di default nella classe di default"
Ho detto otterrei non a caso. Infatti cosi' come stanno le cose
otteniamo silo un errore, dato che non abbiamo creato ancora un
viewer, cioe' un layout con il quale le informazioni che ci ritorna il
controller vengano impaginate.
Zend usa anche per i layout una nomenclatura particolare.
dentro la dir application/views dovremo creare una dir chiamata
scripts, e qui dentro una directory con il nome del controller che
chiama il layaut che andremo a creare.
Nel nostro caso index.
Quindi avremo ./application/views/scripts/index
Qui dentro metteremo un file che si chiama index.phtml (attenzione
all'estensione e' .phtml)
Il mio file per il momento e' cosi':
<html>
<head>
<title>
<?php
echo "Titolo - Prova1";
?>
</title>
</head>
<body>
<h1>
<?php echo "Prova1";
?>
</h1>
</body>
</html>
Quindi il risultato e' che quando apro 
http://ip_server/ProvaZend/public
ottengo nle browser la scritta Prova1 con formato h1 (quindi grassetto
e grande) e una scritta sotto "Sto usando il metodo di default nella
classe di default", in piu' il titolo della finestra del browser
diventa "Titolo - Prova1"
Quindi una prima bozza di applicazione scritta con zend l'ho
raggiunta.
Ora pero 'devo capire come arrivare a concludere il mio progettino.
Un ultimo appunto.
Zend si basa moltissimo sulla riscrittura dell'url, facendo passare
tutte le richieste per il bootstrap, che fa in un certo senso da hub,
in modo che vengano invocati i giusti metodi.
Praticamnete tutto cio' che sull'url viene dopo il nome
dell'aplicazione (
http://server/ProvaZend
 in questo caso) rappresenta
il controller e poi il metodo
quindi 
http://server/ProvaZend/pippo/pluto
 va ad eseguire il metodo
plutoAction() del controller PippoController.php
Per fare cio' c'e' bisogno il sistema di riscrittura  RewriteEngine
funzioni, e quindi apache deve permetterne l'utilizzo. In httpd.conf
ci deve essere:
AllowOverride All
ed anche:
LoadModule rewrite_module modules/mod_rewrite.so
Se il webserver non permette niente paura, zend offre la classe
Zend_Controller_Router_Rewrite che serve proprio allo scopo (gli
esperti mi correggano se sbaglio)
Per oggi e' tutto.
Alla prossima, e spero che qualcuno intervenga nel correggermi e darmi
qualche consiglio per portare a termine il mio propedeutico
progettino.
Ciao.

 La gestione dei parametri passati in GET o POST va SOLO nel controller.
Un milione di grazie!!!!
Sper odi ricevere tanti commenti proprio come questo. A proposito, con
zend, come si gestiscono i parametri passati, e soprattutto come
scelgo la possibilita' di usare post o get? Inoltre, quale delle due
tecniche e' piu' congeniale in un ottica mvc?
Ciao e grazie ancora.

 e' piu' congeniale in un ottica mvc? Ciao e grazie ancora.
GET o POST lo usi in base a quello che ti serve. Per gran parte del tempo 
userai GET, esattamente come in qualsiasi sito.
POST lo usi solo con i form.
Per prendere i parametri, io nelle action uso qualcosa del genere:
public function procesasformAction()
{
 $req = $this->getRequest();
 if ( ! $req->isPost() ) {
  $this->redirect("index", "form"); // questa funzione l'ho aggiunta io
 }
 $username = $req->getPost("username");
 $password = $req->getPost("password");
 ...
}
redirect() e` un metodo che ho scritto io, ereditando un mio 
Controller_Action, e sfruttando il plugin Redirector. Semplificando al 
massimo, una cosa cosi` (scusa il wrapping, ma non ci sta...):
public function redirect($controller="index", $action="index", $param=array
(), $module="")
{
 
 $redirector = Zend_Controller_Action_HelperBroker::getStaticHelper
("redirector");
 
 $redirector->goto($action, $controller, $module, $param);
}
Comunque ti invito a leggere bene il manuale ufficiale e il sito che ti ho 
linkato, perche` stai andando troppo a naso.
Bye.

 Comunque ti invito a leggere bene il manuale ufficiale
Ok, prima di proseguire seguo il tuo consiglio, mi sto leggendo il
manuale, che tra l'altro trovo fatto incredibilmente bene!!!
Ho visto una cosa interessante... Zend_Service_Yahoo
Da quello che ho capito e' una classe che mi permette di integrare i
Web Services di Yahoo all'interno del mio progetto vero? Molto bello,
ma mi chideveo... per i widgets di Google non c'e' nulla che finzioni
allo stesso modo?

 allo stesso modo?
Mi rispondo da solo.... Zend_Gdata

 progettino.
Te ne do' io uno: l'entusiasmo è una gran cosa, ma tu moderalo, e
prima di passare alla sperimentazione passa un po' più tempo allo
studio della teoria. Altrimenti finisce che sviluppi i progetti
"intorno" al paradigma MVC piuttosto che sfruttando lo stesso. In
bocca al lupo e buon lavoro ;^)
bye!

 studio della teoria.
Quanto hai ragione.... questa e' una mia tara che mi accompagna da
tutta la vita!
Grazie ;-)