368 Chapitre 9. Introduction au Zend Framework ∗ Quelques informations sur la configuration ∗ / function configAction() { $this−>view−>titre_page = "Contenu du fichier de configuration"; // On prend la configuration dans le registre , on la met dans // la vue $registry = Zend_Registry :: getInstance() ; $this−>view−>config = $registry−>get( ’config ’) ;; } } On remarque d’abord que tout contrôleur est une sous-classe de Zend_Controller_Action. Un contrôleur hérite donc des propriétés de cette super-classe, notamment de $this->view qui est le composant Vue avec lequel nous pouvons produire le document résultat. On peut placer des informations dans la vue avec une affectation $this->view->nom = valeur. On peut se demander d’où vient le fragment HTML qui constitue la page d’ac- cueil du site ZS COPE, produite par cette action. Dans le Zend Framework, beaucoup de décisions s’appuient sur des conventions de nommage et d’emplacement, ce qui évite de se répéter. La convention pour les vues est la suivante : Le fragment (ou script) associé à une action nommée act du contrôleur ctrl se trouve dans le répertoire views/scripts/ctrl, et se nomme act.phtml. Ici, l’action index se conclut donc automatiquement par l’exécution du script views/scripts/index/index.phtml. Vous pouvez consulter ce fichier. Il contient le code HTML qui s’affiche dans la zone principale de la page d’accueil de ZS COPE. Tout le reste de la page, incluant le logo, le menu, les différents tableaux imbriqués spécifiant le positionnement des différentes parties et notamment de la zone principale d’affichage, relève du layout. La gestion de ce dernier sera présentée page 376. Prenons un autre exemple avec l’action configAction() du contrôleur Index (voir ci-dessus). Le code est très simple : on récupère dans le registre l’objet de configuration et on l’affecte à la vue. La vue, un script PHP un peu spécial, est alors exécutée. Au sein de ce script on dispose de l’objet $config que l’on vient d’affecter, ainsi que de la chaîne de caractères titre_page. Exemple 9.4 zscope/application/views/scripts/index/config.phtml : Le script Vue de l’action config du contrôleur Index Voici quelques informations extraites du fichier de configuration <h4>Informations générales sur l ’application </h4> 9.2 Accès à la base de données 369 <ol> <li>Nom de l ’application : <?php echo $this−>config−>app−>name ; ?></li > <li >Affichage des erreurs : <?php echo $this−>config−>app−> display_errors ; ?></li> <li>Administrateur : <?php echo $this−>config−>app−>admin_mail ; ?></li > </ol> <h4>Connexion à la base de données </h4> <ol> <li >Pilote PDO: <?php echo $this−>config−>db−>adapter ; ?></li > <li >Serveur: <?php echo $this−>config−>db−>params−>host ; ?></li > <li >Base: <?php echo $this−>config−>db−>params−>dbname ; ?></ li > <li >Login: <?php echo $this−>config−>db−>params−>username ; ?></li > </ol> On programme dans la vue comme dans n’importe quel script PHP, avec la particularité que les données « dynamiques » sont disponibles dans l’objet $this parce qu’elles ont été placées là par l’action associée à la vue. Le script-vue ne sert qu’à mettre en forme ces données, pas à les créer ou les modifier. Nous reviendrons sur la gestion de la vue dans le Zend Framework page 376. Le moment est probablement venu pour vous de faire une pause. Parcourez l’arborescence des fichiers, et modifiez ceux qui interviennent dans l’exécution de l’action index du contrôleur Index. Il s’agit de controllers/IndexControlller.php et views/s- cript/index/index.phtml . Clarifiez les interactions entre ces compoants (contrôleur, action et vue : nous n’avons pas encore vu le modèle). La suite revient plus longuement sur les composants Zend relatifs au MVC et aux bases de données. 9.2 ACCÈS À LA BASE DE DONNÉES Le contrôleur bd de l’application ZSCOPE montre comment utiliser la connexion à la base, instance de Zend_Db_Adapter, pour accéder classiquement à une base de données par des requêtes SQL. Sur ce point, le ZF s’appuie très largement sur PDO (voir page 238) qui propose déjà tout ce qui est nécessaire à un accès normalisé aux bases relationnelles. Ce qui suit n’est donc qu’une introduction assez rapide, que vous pouvez compléter avec la documentation PDO en ligne. 370 Chapitre 9. Introduction au Zend Framework 9.2.1 Interrogation La méthode query() prend une requête et retourne une instance de Zend_Db_Statement qui permet de parcourir le résultat. Le mécanisme est totalement standard et conforme à ce que nous utilisons depuis le début du livre. Voici l’action queryfetch() qui interroge la table Film. function queryfetchAction () { // On récupère la connexion dans le registre $bd = Zend_Registry :: getInstance ()−>get( ’db ’); // Exécution de la requête $result = $bd−>q uery ( "SELECT id , t i t r e , annee FROM Film WHERE annee > 1980" ) ; // Itération sur les films $this−>view−>films = array() ; while ($film = $result−>fetch (Zend_Db::FETCH_OBJ)) { $this−>view−>films [] = $film ; } } Essentiellement, on interroge la base, puis on itère sur le résultat en plaçant chaque objet dans un tableau de $this->view. Le paramètre de la méthode fetch() indique le format dans lequel on souhaite récupérer chaque ligne. Comme d’habitude, au lieu d’OBJ, on peut utiliser ASSOC pour des tableaux associatifs, NUM pour des tableaux indicés, et quelques autres options moins utiles. Le script de vue parcourt ce tableau et crée le document HTML de présentation. Notez la méthode escape() de la vue qui s’assure que les caractères perturbant le document HTML sont neutralisés. Exemple 9.5 zscope/application/views/scripts/bd/queryfetch.phtml : La vue affichant la liste des films Voici la liste des films trouvés dans la base. <ol> <?php foreach ($this−>films as $film) { ?> <li ><?php echo $this−>escape($film−>titre) ; ?></li> <?php } ?> </ol> En général, on utilise des requêtes contenant des paramètres venant de formu- laires ou autres, qu’il faut prendre garde d’échapper pour éviter les caractères posant problème. Les méthodes quoteInto() et quote() effectuent cet échappement en tenant compte des règles propres au serveur auquel on est connecté. Ces régles 9.2 Accès à la base de données 371 varient d’un SGBD à un autre. Pour MySQL, nous savons qu’il faut placer une barre oblique inversée devant les « ’ », pour ORACLE il faut les doubler, etc. Voici un exemple avec quoteInto(). function quoteAction () { // On récupère la connexion dans le registre $bd = Zend_Registry :: getInstance()−>get( ’db ’) ; // Le titre du film cherché $titre = "Jeanne d’Arc"; $this−>view−>titre = $titre; // Préparation de la requête $requete = $bd−>quoteInto("SELECT ∗ FROM Film WHERE titre =?" , $titre); $result = $bd−>query($requete); // Itération sur les films $this−>view−>films = array () ; while ($film = $result−>fetch (Zend_Db::FETCH_OBJ)) { $this−>view−>films [] = $film ; } } Il existe tout un catalogue de méthodes fetch pour récupérer, au choix, toutes les lignes d’un résultat, ou bien sa première ligne, ou bien la première colonne de sa première ligne, etc. Voici l’action fetch qui vous donnera une idée de l’utilisation de ces méthodes. La documentation de Zend sur le composant Zend_Db détaille la liste de toutes les possibilités. /∗∗ ∗ Quelques méthodes fetch∗∗∗ def Zmax_Db_Adapter ∗ / function fetchAction () { // On récupère la connexion dans le registre $bd = Zend_Registry :: getInstance()−>get( ’db ’) ; // Tous les films contenant un ’v’, $ r e quete = "SELECT t i t r e , annee , g enre FROM Film WHERE t i t r e LIKE ’%v%’" ; $this−>view−>requete = $requete ; // Attention , on veut toujours récupérer des objets $bd−>setFetchMode(Zend_Db ::FETCH_OBJ) ; / / Fetch : comme un tablea u d ’ ob j ets $this−>view−>films = $bd−>fetchAll($requete); // On prend une seule ligne , la première du résultat $this−>view−>film = $bd−>fetchRow($requete); 372 Chapitre 9. Introduction au Zend Framework // On prend une valeur dans une ligne $this−>view−>t itr e = $bd−>fetchOne($requete); } Avec ces méthodes fetch, l’exécution de la requête et la récupération du résultat s’effectuent en un seul appel. Il est souvent pratique de pouvoir récupérer facilement une ligne ou une valeur spécifique dans la base de données. 9.2.2 Insertion et mise à jour Les modifications de la base, que ce soit insertion ou mises à jour, bénéficient également de méthodes génériques. Ces méthodes effectuent automatiquement les échappements nécessaires pour s’assurer que les modifications s’exécutent sans pro- blème. Voici l’action insert illustrant une insertion. /∗∗ ∗ Comment i ns é r er dans une t a ble ∗ / function insertAction() { // On récupère la connexion dans le registre $bd = Zend_Registry :: getInstance ()−>get( ’db ’); // On veut insérer l ’Espagne. On commence par supprimer // si elle existe déjà. $bd−>q uery ( "DELETE FROM P ays WHERE code = ’ ES ’ " ) ; // Maintenant on définit le tableau des données à insérer $espagne = array ("code"=>"ES","nom"=>"Espagne","langue " => "Espagnol") ; // On insère et on récupère le nombre de lignes insérées $this−>view−>nb_lignes = $bd−>insert ("Pays" , $espagne); } Pour être complet, voici le code d’une mise à jour. function updateAction() { // On récupère la connexion dans le registre $bd = Zend_Registry :: getInstance ()−>get( ’db ’); // Tableau des colonnes à modifier $update_val = array ("langue" => "Anglais US") ; // Clause where pour la modification $where [] = "code=’US’" ; $nb_rows = $bd−>update("Pays" , $update_val , $where); } . ; $this−>view−>requete = $requete ; // Attention , on veut toujours récupérer des objets $bd−>setFetchMode(Zend_Db ::FETCH_OBJ) ; / / Fetch : comme un tablea u d ’ ob j ets $this−>view−>films. l’exécution de l’action index du contrôleur Index. Il s’agit de controllers/IndexControlller.php et views/s- cript/index/index.phtml . Clarifiez les interactions entre ces compoants (contrôleur, action et. donnera une idée de l’utilisation de ces méthodes. La documentation de Zend sur le composant Zend_Db détaille la liste de toutes les possibilités. /∗∗ ∗ Quelques méthodes fetch∗∗∗ def Zmax_Db_Adapter ∗