Stockage Persistant Interface avec bases de données SQL

Stockage persistant

Toute application web nécessite de stocker des données de façon permanente sur le server.

  • Système de fichiers : SQLite, …
  • BDs SQL : MySQL, PostgreSQL, …
  • BDs NoSQL : MongoDB, Couchbase, CouchDB, …

Abstractions

Tous les frameworks offrent des modules pour faciliter l’interaction avec les bases de données :

  • DBAL (Database Abstraction Layer) : accès à plusieurs systèmes de BD (par ex., MySQL, SQLite, …) avec une API unique.
  • ORM (Object Relational Mapping) : traduction entre objets dans le langage du framework, et entités de la BD.

PHP, Silex et MySQL

PHP fournit deux modules pour l’accès aux bases MySQL :

  • mysqli (spécifique pour MySQL),
  • PDO (DBAL générique).

Silex ajoute son propre DBAL par dessus PDO : Doctrine.

Fonctionnalités

  • Connexion à une base de donnée (distante),
  • Interrogations SQL, parcours des résultats,
  • Requêtes préparées,
  • Query builder,
  • Transactions,

Doctrine

Activer Doctrine et se connecter à la base

use Silex\Provider\DoctrineServiceProvider;

$app->register(new DoctrineServiceProvider(),
  array('db.options' => array(
            'driver'   => 'pdo_mysql',
            'host'     => 'localhost',
			'user'     => 'toto',
			'password' => '12345'
    ),
));

Plus sur la configuration:

Faire une requête

$q = $app['db']->executeQuery('SELECT * FROM users');

Parcourir le résultat (en le copiant dans un tableau PHP)

$results = $q->fetchAll();
foreach ($results as $row) {
  $row['name'];
}

ou (ligne par ligne)

while ($row = $q->fetch()) {
  $row['name'];
}

Tout en un

$app['db']->fetchAll('SELECT * FROM users');

Plus de fonctions dans le manuel.

MySQL pour Node.js

Installer le module mysql

npm install mysql

Configurer

var mysql = require('mysql');
var db    = mysql.createConnection({
  host     : 'localhost',
  user     : 'toto',
  password : '12345',
  database : 'ma_base'
});

Plus d’options : https://www.npmjs.com/package/mysql

Faire une requête

db.query('SELECT * FROM users',
  // callback
  function(err, rows) {
    if (!err) {
      for (var i = 0 ; i < rows.length ; i++) {
        console.log(rows[i]);
      }
	}
  });

Attention : Node.js a un modèle d’exécution asyncrhone. Le résultat de la requête est passé à une callback.

Autres interfaces de BD pour Node.js

Échappement

Échappement SQL

On a avec SQL le même problème que dans la génération de HTML

function (Application $app, Request $req) {
 $app['db']->query(
  'SELECT * FROM users WHERE id = \'' . $req->query->get('nom') . '\';' );
}

Les caractères spéciaux SQL `, ', ", ; doivent être échappés.

La syntaxe de l’échappement dépend de la base de données (MySQL, PostgreSQL, …)

Fonctions d’échappement:

  • PHP : mysqli::real_escape_string,
  • PDO/Doctrine : PDO::quote, Doctrine::quote,
  • Échappement automatique : requêtes préparées.

Requêtes préparées

En Silex

$app['db']->fetchAssoc("SELECT * FROM users WHERE id = ?",
                       array($req->query->get("nom")));
$app['db']->fetchAssoc("SELECT * FROM users WHERE id = :name",
                       array(':name' => $req->query->get("nom")));

En Node.js avec mysql

db.query('SELECT * FROM users WHERE id = ?', [ req.query.nom ],
		 function() { ... });
db.query('SELECT * FROM users WHERE ?', { id: req.query.nom },
		 function() { ... });

Tous donnent

SELECT * FROM users WHERE id='toto'

Lectures

DBAL pour PHP

MySQL pour Node.js

Fork me on GitHub