Child pages
  • DB class best practices
Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 4 Next »

Table of content

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.

This page explains the various methods, the contexts in which they should be used, and the development best practices.

At the bottom of the page are the main differences in the DB class between version 1.4 and 1.5 of PrestaShop.

Fundamentals

The DB class is really made of two classes:

  • 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 is used by default; however, if the PDF 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:

$db = Db::getInstance();

In some cases, you might encounter this alternative:

$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.

The available methods

insert()

Method signature: insert($table, $data, $null_values = false, $use_cache = true, $type = Db::INSERT, $add_prefix = true).

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:

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

INSERT INTO `prefix_target_table` (`id_target`, `name`) VALUES (10, 'myName')

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()

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 true, then values that are passed as NULL will be inserted as such in the database.

$use_cache

If false, PrestaShop's cache management is disabled during this query. Do not change this parameter unless you knew exactly what you are doing.

$type

If you wish to change the insertion, this parameter can take the following constants: Db::INSERT, Db::INSERT_IGNORE or Db::REPLACE.

$add_prefix

If flase, table prefix will not be automatically added to the table name.

update()

Methode signature: update($table, $data, $where = '', $limit = 0, $null_values = false, $use_cache = true, $add_prefix = true)
($table, $data, $null_values = false, $use_cache = true, $type = Db::INSERT, $add_prefix = true)

This method works as the insert() 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 WHERE clause.

$limit

You can limit the number of results that you will update.

La méthode delete($table, $where = '', $limit = 0, $use_cache = true, $add_prefix = true)

Cette méthode est l’équivalent de insert() et update() en version 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 :

Db::getInstance()->delete(‘target_table’, ‘myField < 15’, 3);

va générer la requête

DELETE FROM `prefix_target_table` WHERE myField < 15 LIMIT 3

La méthode 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 (INSERT, UPDATE, DELETE, TRUNCATE…) car elle supprime de plus le cache de requêtes (sauf si l’argument $use_cache vaut false).

Exemple :

$sql = ‘DELETE FROM ‘._DB_PREFIX_.’product WHERE active = 0’;
if (!Db::getInstance()->execute($sql))
die(‘Erreur etc.)’;

Il est recommandé d’utiliser les méthodes insert(), update() et delete() autant que possible, n’utilisez execute() que si les requêtes sont trop complexes.
Veuillez noter aussi que cette méthode retourne un boolean (true ou false), et non pas une ressource de base de donnée à utiliser.

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()

La méthode 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 (SELECT, SHOW, etc.). Les résultats de cette requête seront mis en cache, sauf si l’argument $use_cache vaut false. Le second argument $array est déprécié et ne doit plus être utilisé, laissez-le à true.

Exemple :

$sql = ‘SELECT * FROM ‘._DB_PREFIX_.’shop’;
if ($results = Db::getInstance()->ExecuteS($sql))
    foreach ($results as $row)
        echo $row[‘id_shop’].’ :: ‘.$row[‘name’].’<br />’;

La méthode 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 (SELECT, SHOW, etc.). Les résultats de cette requête seront mis en cache, sauf si l’argument $use_cache vaut 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 * FROM ‘._DB_PREFIX_.’shop
    WHERE id_shop = 42’;
if ($row = Db::getInstance()->getRow($sql))
    echo $row[‘id_shop’].’ :: ‘.$row[‘name’];

La méthode 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 (SELECT, SHOW, etc.). Les résultats de cette requête seront mis en cache, sauf si l’argument $use_cache vaut false.

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 = Db::getInstance()->getValue($sql);

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(star) au préalable.

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é

Les changements entre la 1.4 et la 1.5

  • Les méthodes autoExecute() et autoExecuteWithNullValues() sont dépréciées au profit de insert() et update()
  • Le préfixe des tables n’est plus obligatoire pour la méthode delete()
  • La méthode execute() ne retourne plus une ressource mais un boolean, utilisez query() pour obtenir une ressource
  • Support de PDO et MySQLi
  • No labels