FAQ Zend Framework
FAQ Zend FrameworkConsultez toutes les FAQ
Nombre d'auteurs : 16, nombre de questions : 39, dernière mise à jour : 15 juin 2021
- Comment construire l'objet $db ?
- Comment travailler avec plusieurs base de données ?
- Zend_Db est-il sensible à la casse ?
- Comment ne plus écrire de requêtes SQL ?
- Faire une requête classique avec Zend_DB ?
- Quels adapteurs sont disponibles ?
- Est-ce que ZF peut s'occuper de la liaison entre les tables ?
- Peut-on faire de l'héritage de tables avec le ZF ?
- Comment récupérer les erreurs retournées par la base de données ?
- 3.1. Zend_Db_Select (5)
Pour construire un objet $db permettant d'utiliser la base de données, une solution est d'utiliser la méthode abstraite Zend_Db::factory().
$params
=
array
(
'
host
'
=>
'
localhost
'
,
'
username
'
=>
'
yogui
'
,
'
password
'
=>
'
1234
'
,
'
dbname
'
=>
'
developpez
'
);
try
{
$db
=
Zend_Db::
factory('
PDO_MYSQL
'
,
$params
);
$db
->
getConnection();
}
catch (Zend_Db_Adapter_Exception $e
)
{
echo $e
->
getMessage();
}
Zend_Db::factory() utilise des adaptateurs (Zend_Db_Adapter_*) pour initialiser la connexion. Cela signifie que vous pouvez utiliser un pilote direct comme MySQLi, DB2 ou Oracle, mais aussi passer par PDO pour avoir plus de flexibilité.
Depuis la version 1.8 et Zend_application, vous pouvez construire un objet $db de la façon suivante:
dans le fichier config.ini
;
connexion à une base de données
resources.
db.
adapter =
"
pdo_mysql
"
resources.
db.
params.
host =
"
localhost
"
resources.
db.
params.
username =
"
mon_user
"
resources.
db.
params.
password =
"
mon_passe
"
resources.
db.
params.
dbname =
"
ma_db
"
resources.
db.
isDefaultTableAdapter =
true
Il est possible de mettre en place un système assez simple pour travailler sur plusieurs base de données, voir même différent SGBDR.
Voici une ébauche de solution.
1) on crée un fichier XML (un tableau est également possible)
<?xml version="1.0" encoding="UTF-8"?>
<config>
<acceptance>
<drivername>
DB2</drivername>
<host>
adresse ip</host>
<port>
50572</port>
<username>
login</username>
<password>
passwor</password>
<dbname>
maDb</dbname>
<database>
MaBase</database>
</acceptance>
<integration
extends
=
"acceptance"
><
<host>
AutreIp</host>
<port>
50571</port>
<username>
autreLogin</username>
<password>
MonPasswd</password>
</integration>
<MySQL>
<drivername>
pdo_mysql</drivername>
<host>
localhost</host>
<port>
3306</port>
<username>
aityahia</username>
<password>
monpasse</password>
<dbname>
zf-project</dbname>
<database>
MaBase</database>
</MySQL>
<MySQL2
extends
=
"MySQL"
>
<!-- It's the name choosen in the application -->
<host>
localhost</host>
<port>
3307</port>
<username>
Gg</username>
<password>
kmljmlhmkl</password>
</MySQL2>
</config>
Ensuite dans la classe model, on crée un objet $db
public function __construct($base
=
'
MySQL
'
) {
$config
=
new Zend_Config_Xml('
vers/fichier/xml
'
,
$base
);
$driverName
=
$config
->
drivername;
$params
=
array
(
'
host
'
=>
$config
->
host,
'
username
'
=>
$config
->
username,
'
password
'
=>
$config
->
password,
'
dbname
'
=>
$config
->
dbname,
'
port
'
=>
$config
->
port,
);
try {
$this
->
_db =
Zend_Db::
factory($driverName
,
$params
);
$this
->
_db->
getConnection();
$this
->
_db->
setFetchMode(Zend_Db::
FETCH_OBJ);
}
catch ( Zend_Db_Adapter_Exception $e
) {
echo $e
->
getMessage ();
}
}
Enfin dans le controller
$db
=
new Model_Db('
DB2
'
);
Lorsque vous utilisez PDO pour les accès à la base de données, l'extension PDO est configurée par ZF avec la constante PDO::CASE_NATURAL par défaut, ainsi les noms des tables et des champs peuvent être précisés indifféremment en majuscules ou minuscules.
Si vous souhaitez modifier ce comportement, utilisez le code suivant :
$db
=
Zend_Db::
factory('
PDO_MYSQL
'
,
$params
);
$db
->
setParams(PDO::
CASE_LOWER);
Zend_Db permet de s'affranchir du code SQL, mais les fonctionnalités de mapping relationnel objet (ORM) sont encore plus utiles. Le Zend Framework propose cette l'ORM grâce à la classe Zend_Db_Table_Abstract.
Exemple :
<?php
class
Membres extends
Zend_Db_Table_Abstract
{
protected
$_name
=
'Membres'
;
protected
$_primary
=
'num'
;
protected
$_dependentTables
=
array
('Emprunts'
);
public
function
findByNom($nom
){
$where
=
$this
->
getAdapter()->
quoteInto('nom = ?'
,(string)
$nom
);
return
$this
->
fetchRow($where
);
}
}
?>
<?php
$tableMembre
=
new
Membres();
$julien
=
$tableMembre
->
findByNom('julien'
);
$julien
->
date_naissance =
'1982-12-08'
;
$julien
->
save();
?>
Lien : EZPDO: Object-Relational Mapping en PHP, par Pierre-Nicolas Mougel
Il est tout à fait possible de faire des requêtes écrites à la main et de récupérer le résultat.
Utilisez toujours la doc en ligne pour obtenir la réponse à ce genre de questions.
- db2
- mysqli
- oracle
- pdo_mssql
- pdo_mysql
- pdo_oci
- pdo_pgsql
- pdo_sqlite
Oui, avec un peu de bonne volonté ;)
Les tuples des tables sont identifiés par un numéro automatique. Zend Framework permet de faire des requêtes en chaîne, de la forme (pour trouver le message #1 d'un forum) :
C'est pratique ; néanmoins, à l'issue de cette requête, j'obtiens l'identifiant de l'auteur $message->id_auteur plutôt que son nom. Je suis donc obligé de faire une seconde requête pour trouver le nom de l'auteur à partir de son identifiant :
$auteur = $auteurs->find($message->id_auteur)->current();
Une solution pour éviter tout ce travail est d'étendre Zend_Db_Table_Abstract et d'utiliser cette nouvelle classe dans nos développements.
Plus de détails dans l'atelier par Julien.
Ce n'est pas prévu par le framework de départ mais c'est possible en utilisant la classe de Réflexion introduite depuis PHP5.
Dans le cas d'une erreur de la base de données lors de la connexion ou d'une requête, une exception Zend_Db_Exception est levée. Ainsi, il vous suffit de capturer cette exception pour récupérer le message d'erreur retourné par la base de données.
try {
// $db est de type Zend_Db_Adapter, $query Zend_Db_Select
$db
->
fetchRow($select
);
}
catch (Zend_Db_Exception $e
) {
die($e
->
getMessage());
}
Si vous utilisez une transaction au moment du déclenchement l'exception, elle est mise en erreur : il vous faut exécuter $db->commit() ou $db->rollback().
$this
->
_db->
beginTransaction();
$row
=
$this
->
createRow();
try {
$row
->
save();
$this
->
_db->
commit
();
// n'est pas exécuté si save() lance une exception
}
catch (Zend_Db_Exception $e
) {
$this
->
_db->
rollback
();
// traiter l'exception
}
Lien : Tutoriel : Les exceptions en PHP 5 par Guillaume Affringue