Fonctions de manipulation SQL

Dans le but de manipuler plus facilement les requêtes SQL avant leur exécution, je me suis créé trois fonctions simples d'emploi (enfin deux fonctions puisque la troisième est plutôt une fonction privée) :

  • sql2array : extrait les differentes clauses d'une requête SQL et les retourne dans un tableau associatif
  • sql2string : transforme une requête stockée sous la forme d'un tableau en chaîne de caractères
  • sqlksort : ordonne les clés d'un tableau suivant l'ordre natural des clauses SQL

L'idée est de traiter les requêtes sous la forme d'un tableau associatif plutôt que sous la forme d'une chaîne de caratères. Il est ainsi plus facile d'ajouter/modifier/supprimer des clauses dans le code.

Avertissement : ces fonctions ont été développées pour une utilisation avec MySQL, certaines clauses disponibles dans d'autres systèmes de base de données ne sont donc pas présentes ; libre � vous d'adapter le code de ces fonctions selon vos besoins. N'hésitez pas à me faire part de vos modifications et/ou améliorations afin que je les intègre ici.

sql2array

Cette fonction transforme une requête depuis une chaîne de caractères vers un tableau associatif, chaque clause étant une clé de ce tableau. Elle retourne FALSE si une erreur survient (en gros, si la requête ne correspond pas au "pattern" de recherche).

/**
 * Extrait les differentes clauses d'une requete SQL et 
 * les retourne dans un tableau associatif
 *
 * @access    private
 * @param     string $sql		requête SQL à traiter
 * @return    array
 */
function sql2array( $sql ) {

    if ( is_array($sql) ) return $sql;

    $pattern = '/^'.
               'select(.*?)'.
               'from(.*?)'.
               '(?:where(.*?))?'.
               '(?:group by(.*?))?'.
               '(?:having(.*?))?'.
               '(?:order by(.*?))?'.
               '(?:limit(.*?))?'.
               '$/is';

    if ( !preg_match($pattern, $sql, $match) ) return FALSE;

    $result             = array();
    $result['select']   = trim($match[1]);
    $result['from']     = trim($match[2]);
    $result['where']    = ( isset($match[3]) ) ? trim($match[3]) : '';
    $result['group by'] = ( isset($match[4]) ) ? trim($match[4]) : '';
    $result['having']   = ( isset($match[5]) ) ? trim($match[5]) : '';
    $result['order by'] = ( isset($match[6]) ) ? trim($match[6]) : '';
    $result['limit']    = ( isset($match[7]) ) ? trim($match[7]) : '';

    return $result;

} // end of 'sql2array()'

sql2string

Cette fonction permet de faire l'opération inverse de sql2array, c'est � dire qu'elle transforme une requête d'un tableau vers une chaîne de caractères. C'est cette chaîne finale qui pourra être utilisée pour exécuter la requête.

/**
 * Transforme une requete sous forme d'array en string
 *
 * @access    private
 * @param     string $sql		requête SQL à traiter
 * @return    array
 */
function sql2string( $sql ) {

    if ( is_string($sql) ) return $sql;
    
    sqlksort($sql);

    $built = '';
    foreach ( $sql as $statement => $value ) {
        if ( !empty($value) ) $built .= $statement.' '.$value.' ';
    }

    return trim($built);

} // end of 'sql2string()'

On utilise au sein de cette fonction la fonction sqlksort suivante pour ordonner ses clés dans l'ordre naturel des clauses d'un requête si besoin est.

sqlksort

Comme dit juste au-dessus, cette fonction ordonne les clés du tableau passé à sql2string dans l'ordre naturel des clauses d'une requête SQL ; cela nous permet de spécifier ces clauses dans n'importe quel ordre à la création du tableau et en sortie d'avoir une requête "propre".

/**
 * Ordonne les valeurs d'une requête SQL stockée dans un tableau 
 * suivant l'ordre de ses clauses
 *
 * @access    private
 * @param     string    $sql		requête SQL sous la forme d'un tableau
 * @return	  array
 */
function sqlksort( &$sql ) {

    function _sqlksort( $a, $b ) {

        // Liste des clauses possibles pour une requête SQL
        $statements = array(
            'select'    => 0, 
            'from'      => 1, 
            'where'     => 2, 
            'group by'  => 3, 
            'having'    => 4, 
            'order by'  => 5, 
            'limit'     => 6
        );
		
        if ( $statements[$a] == $statements[$b] ) return 0;
        return ( $statements[$a] < $statements[$b] ) ? -1 : 1;

    } // end of '_sqlksort()'
	
    uksort($sql, '_sqlksort');

} // end of 'sqlksort()'

Exemple d'utilisation

Cet exemple illustre une manière de contruire un moteur de recherche simpliste ; il s'agit ici d'ajouter une clause where dans le cas où une recherche aurait été effectuée et le mot-clé passé dans l'URL.

$sql = 'select nom, email from contacts order by nom asc';
$sql = sql2array($sql);
// un print_r($sql) nous donne :
// Array(
// 	[select]    => nom, email
// 	[from]      => contacts
// 	[order by]  => nom asc
// )

if ( isset($_GET['search') && !empty($_GET['search']) ) {
	$sql['where'] = 'nom LIKE \'%'.$_GET['search'].'%\'';
}
// en supposant que la recherche porte sur "dupont",
// un print_r($sql) nous donne maintenant :
// Array(
// 	[select]    => nom, email
// 	[from]      => contacts
// 	[order by]  => nom asc
// 	[where]     => nom LIKE '%dupont%'
// )

$sql = sql2string($sql);
// un print_r($sql) nous donne pour finir :
// select nom, email from contacts where nom LIKE '%dupont%' order by nom asc

Et voilà, il n'y a plus qu'a exécuter cette requête résultante :)

Posté le mercredi 03 novembre 2004 dans , .

Commentaires

Il n'y a aucun commentaire ; soyez le premier à déposer le vôtre.

Ajouter un commentaire

Il n'est plus possible de réagir à cette entrée directement mais si vous pensez que votre intervention peut être intéressante, envoyez-moi votre commentaire, je l'ajouterai ici en votre nom.