Table of content
Table of Contents | ||
---|---|---|
|
DB class best practices
Most of the time, creating a module or overriding PrestaShop means using or inserting data in the database. Knowing how to properly use the DB core class is therefore mandatory for developers. Besides providing you with an abstraction for other potential database system, the DB class offers several tools to make your life easier.
...
- The
Db
class, which can found in the/classes/db/Db.php
, and is abstracted. - A subclass which extends the
Db
class. Currently, three class abstractions are supported as subclasses: MySQL, MySQLi and PDO.
PDF PDO is used by default; however, if the PDF PDO extension is not installed on the server, the MySQLi extension is used instead. And if MySQLi is not installed either, then MySQL is used.
DB is a pseudo-singleton, as it can still be manually instantiated, because its constructor is public. However, within PrestaShop, it is recommended to instantiate it this way:
Code Block |
---|
$db = Db::getInstance();
|
In some cases, you might encounter this alternative:
Code Block |
---|
$db = Db::getInstance(_PS_USE_SQL_SLAVE_);
|
If PrestaShop's database user allows the use of MySQL slave servers in its architecture, then this last instance's connection can be done on the slave servers.
You should only use the PS_USE_SQL_SLAVE
argument when making read-only queries (SELECT
, SHOW
, etc.), and only if these do not need a result to be immediately updated with a result. If you make a query on a table right after inserting data in that same table, you should make that query on the master server.
Les différentes méthodes
...
The available methods
insert()
Method signature: insert($table, $data, $null_values = false, $use_cache = true, $type = Db::INSERT, $add_prefix = true)
...
Cette méthode permet de générer automatiquement l’insertion de données dans la base à partir d’un tableau de données. Il faut utiliser cette méthode à la place de faire des requêtes INSERT, sauf si ces requêtes sont un peu complexes (utilisation de fonctions SQL, requêtes imbriquées, etc.). L’avantage de tout faire via une seule méthode est de centraliser les appels. Le jour où il y a un traitement en particulier à faire sur certaines tables lors de l’insertion il est ainsi possible de le faire en surchargeant cette méthode via le système d’override de PrestaShop.
Exemple fictif :
$target = .
This method was created to automatically generate data insertion in the database, from a data table. It should be used instead of doing INSERT
queries, unless these queries are rather complex (use of SQL functions, nested queries, etc.).
Building every query using one method allows you to centralize your calls. If one day you need to perform a specific processing on some tables during data insertion, you can do so by overloading this method using PrestaShop's overriding system.
Fictitious example:
Code Block |
---|
$target = Tools::getValue('id'); |
...
$name = Tools::getValue('name'); |
...
Db::getInstance()->insert('target_table', array( |
...
'id_target' => (int)$target, |
...
'name' => pSQL($name), |
...
)); |
...
|
Triggering this code generates the following SQL query:
Code Block |
---|
INSERT INTO `prefix_target_table` (`id_target`, `name`) VALUES (10, 'myName') |
...
|
Info |
---|
Make sure that your data is always checked and protected when doing an insertion. In our example, we want to make sure that we do have an integer with an explicit |
Method parameters
Parameter | Description |
---|---|
$table | Table's name. The PrestaShop prefix is automatically inserted, you do not have to put it in. |
$data | The data array, containing the data to be inserted, with name as keys and data as values. |
$null_values | If |
$use_cache | If |
$type | If you wish to change the insertion, this parameter can take the following constants: |
...
or |
...
. |
$add_prefix |
...
Important :
Veillez à toujours protéger vos données avant de les passer à insert(). Dans l’exemple, on s’assure que id_target soit un entier et que name soit protégé contre les injections SQL avec pSQL()
...
If |
update()
Method signature: update($table, $data, $where = '', $limit = 0, $null_values = false, $use_cache = true, $add_prefix = true)
Cette méthode s’utilise de la même façon que la méthode
This method works as the insert()
, mais pour les mises à jour de données (requêtes UPDATE). Les arguments étant principalement les même, voici juste une description des deux qui diffèrent :
• $where : prend la clause WHERE pour la mise à jour
• $limit : vous pouvez limiter le nombre de résultats que vous mettrez à jour3. La méthode delete( method does, but for data update (UPDATE
queries). Both have roughly the same parameters, with type
gone and these two additions:
Parameter | Description |
---|---|
$where | Takes the update's |
$limit | You can limit the number of records that you will update. |
delete()
Method signature: delete($table, $where = '', $limit = 0, $use_cache = true, $add_prefix = true)
Cette méthode est l’équivalent de .
This method is an equivalent to insert()
et and update()
en version , only for DELETE
. Elle est à utiliser pour les mêmes raisons. L’argument $limit permet de limiter le nombre d’enregistrements que l’on souhaite supprimer. L’autre avantage d’utiliser cette méthode est qu’elle sera utilisée par le système de cache des requêtes SQL de PrestaShop et effacera donc les requêtes concernées en cache sauf si l’argument $use_cache vaut false.
Exemple :
queries. You should use it for the same reasons.
The $limit
parameter enables you to limit the number of records to that you wish to delete. The other advantage of this method is that it will be used by PrestaShop's SQL queries cache system, and will therefore delete the affected queries in cache, unles the $use_cache
is false
.
Example:
Code Block |
---|
Db::getInstance()->delete( |
...
'target_ |
...
table', 'myField < 15', 3); |
...
|
...will generate the following query:
Code Block |
---|
DELETE FROM `prefix_target_table` WHERE myField < 15 LIMIT 3 |
...
execute()
Method signature: execute($sql, $use_cache = 1)
Cette méthode exécute la requête SQL donnée. Elle n’est à utiliser que pour les requêtes en écriture .
This method executes the given SQL query. It should only be used for 'write' queries (INSERT
, UPDATE
, DELETE
, TRUNCATE…) car elle supprime de plus le cache de requêtes (sauf si l’argument $use_cache vaut TRUNCATE
, etc.), because it also deletes the query cache (unles $use_cache
is set to false
). Exemple
Example:
Code Block |
---|
$sql = |
...
'DELETE FROM '._DB_PREFIX_. |
...
'product WHERE active = |
...
0'; |
...
if (!Db::getInstance()->execute($sql)) |
...
die( |
...
'Erreur etc.) |
...
'; |
...
Tip |
---|
You should use |
...
and |
...
as much as possible, |
...
and only use |
...
5. La méthode query($sql,)
Toutes les méthodes de la classe exécutant des requêtes SQL utilisent cette méthode de plus bas niveau. Elle fait la même chose que la méthode execute() à deux exceptions prêt :
1. Aucune gestion du cache dans cette méthode
2. Elle ne retournera non pas un boolean mais une ressource que vous pourrez exploiter avec d’autres méthodes comme nextRow()
...
if the query gets too complex. |
query()
Method signature: query($sql)
.
All the method of the DB classes that make SQL query use the query()
as the common, low-level method. It does the same as the execute()
method, with two exceptions:
- No cache control management.
- Will not return a boolean; instead returns a database resource that you can use with other DB class methods, such as
nextRow()
.
executeS()
Method signature: executeS($sql, $array = true, $use_cache = 1)
Cette méthode exécute la requête SQL donnée et charge l’ensemble des résultats qu’elle retourne dans un tableau multidimensionnel. Elle n’est à utiliser que pour les requêtes en lecture .
This method executes a given SQL query, and makes that whole resulting data available through a multidimensional array. It should only be used for 'read' queries (SELECT
, SHOW
, etc.). Les résultats de cette requête seront mis en cache, sauf si l’argument The query's results are cached, unless the $use_cache
vaut parameter is set to false
. Le The second argument $array est déprécié et ne doit plus être utilisé, laissez-le à parameter, $array()
, is deprecated and should not be used, leave it as true
.
Exemple Example:
Code Block |
---|
$sql = |
...
'SELECT * FROM |
...
'._DB_PREFIX_. |
...
'shop'; |
...
if ($results = Db::getInstance()->ExecuteS($sql)) |
...
foreach ($results as $row) |
...
echo $row |
...
['id_shop'].' :: '.$row['name'].'<br />';
|
getRow()
Method signature: getRow($sql, $use_cache = 1)
Cette méthode exécute la requête SQL donnée et récupère la première ligne de résultats. Elle n’est à utiliser que pour les requêtes en lecture .
This method executes a given SQL query and retrieves the first row of results. It should only be used with 'read' queries (SELECT
, SHOW
, etc.). Les résultats de cette requête seront mis en cache, sauf si l’argument The query's results are cached, unless the $use_cache
vaut parameter is set to false
.
Attention : cette méthode ajoute automatiquement une clause LIMIT à la requête. Veillez à ne pas en ajouter une vous-même manuellement.
...
Warning |
---|
This method automatically adds a LIMIT clause to the query. Be careful not to add one manually. |
Example:
Code Block |
---|
$sql = 'SELECT * FROM '._DB_PREFIX_.'shop WHERE id_shop = 42’; if ($row = Db::getInstance()->getRow($sql)) |
...
echo $row |
...
['id_shop'].' :: '.$row['name'];
|
getValue()
Method signature: getValue($sql, $use_cache = 1)
Cette méthode exécute la requête SQL donnée et récupère uniquement le premier résultat de la première ligne. Elle n’est à utiliser que pour les requêtes en lecture .
This method executes a given SQL query and retrieves the first value of the first row of results. It should only be used with 'read' queries (SELECT
, SHOW
, etc.). Les résultats de cette requête seront mis en cache, sauf si l’argument The query's results are cached, unless the $use_cache
vaut parameter is set to false
. Attention : cette méthode ajoute automatiquement une clause LIMIT à la requête. Veillez à ne pas en ajouter une vous-même manuellement.Exemple :
$sql = ‘SELECT COUNT FROM ‘.DB_PREFIX.’shop’;
$totalShop =
Warning |
---|
This method automatically adds a LIMIT clause to the query. Be careful not to add one manually. |
Example:
Code Block |
---|
$sql = 'SELECT COUNT(*) FROM '._DB_PREFIX_.'shop'; $totalShop = Db::getInstance()->getValue($sql); |
...
9. La méthode NumRows()
Cette méthode met en cache et retourne le nombre de résultats de la dernière requête SQL.
Attention : cette méthode n’est pas dépréciée mais il est fortement déconseillé de l’utiliser pour des raisons de bonnes pratiques. En effet, il vaut mieux récupérer le nombre de résultats via une requête de type SELECT COUNT au préalable.
10. Quelques méthodes annexes
• Insert_ID() : retourne l’identifiant créé de la dernière requête INSERT exécutée
• Affected_Rows() : retourne le nombre de lignes concernées par la dernière requête UPDATE ou DELETE exécutée
• getMsgError() : retourne le dernier message d’erreur si une requête a échoué
• getNumberError() : retourne le dernier numéro d’erreur si une requête a échoué
...
|
Note |
---|
|
NumRows()
This method caches and returns the number of results from the most recent SQL query;
Warning |
---|
This method has not yet been deprecated, but it is still not recommended to use for best-practices reasons. Indeed, it is better to retrieve the number of results using a |
A few other methods
Insert_ID()
: returns the ID created during the latestINSERT
query.Affected_Rows()
: returns the number of lines impacted by the latestUPDATE
orDELETE
query.getMsgError()
: returns the latest error message, if the query has failed.getNumberError()
: returns the latest error number, if the query has failed.
Changes between PrestaShop 1.4 and 1.5
- The
autoExecute()
andautoExecuteWithNullValues()
are deprecated. You should replace them withinsert()
andupdate()
, respectively. - The table prefix is no longer mandatory for the
delete()
method. - The
execute()
method does not return a SQL resource but a boolean value. Usequery()
to get a resource. - PDO and MySQLi support.