Aller au menu - Aller au contenu

Icône Manipulation des données stockées dans la base

Avatar
Mise à jour : 04/09/2010
Difficulté : Intermédiaire Intermédiaire Creative Commons BY-NC-SA
487 visites depuis 7 jours, dont 39 sur ce chapitre classé 233/786
On y arrive enfin !

J'ai pris le temps de bien vous montrer comment fonctionne Doctrine, car cela me paraît important pour la suite. Ce n'est pas primordial pour l'instant, mais comme je l'ai dit, nous explorerons plus en détail le fonctionnement de Doctrine plus loin dans le tuto. Je commence donc à préparer le terrain. ;)

On va maintenant pouvoir créer des objets, les modifier, les sauvegarder... Cool, n'est-ce pas ? ;)
Voyons cela tout de suite.

Ne cherchez pas forcément à tester le code qui suit tout de suite. Le prochain chapitre est consacré à un TP qui vous permettra de mettre tout ça en pratique.
Sommaire du chapitre :
Icône du chapitre
Chapitre précédent Sommaire Chapitre suivant

Utilisation des objets et collections

Vous vous rappelez l'exemple que je vous avais donné au début ?
Et bien, on va utiliser exactement cela.

Utilisation des objets



Créer un objet



Commençons par créer un nouvel objet :

Code : PHP
1
2
<?php
$article = new Article();


Doctrine nous fournit plusieurs manières d'accéder aux propriétés de nos objets :

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<?php
$article->title = 'Mon titre';
$article['title'] = 'Mon titre';
$article->set('title', 'Mon titre');

$article->content = "Contenu de l'article...";
$article['content'] = "Contenu de l'article...";
// etc.

// Et on les récupère de la même manière :
echo $article->title;


Rien que ça !
Personnellement, j'aime bien utiliser la notation $obj->title, mais vous faites bien sûr comme vous voulez. ;)

Si vous utilisez Doctrine par l'intermédiaire de symfony, notez que ce dernier ajoute la possibilité d'utiliser des getters et setters (des méthodes commençant par get ou set permettant de récupérer/modifier les attributs) ; par exemple, <?php $obj->setTitle('mon titre') ou <?php echo $obj->getContent().


Définissons maintenant l'auteur de l'article :

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?php
// Création d'un nouvel utilisateur :
$author = new User();
$author->login = 'Gérard';
$author->password = 'pass';

// Affectation de cet utilisateur à notre article :
$article->user_id = $author->id;
// Ou bien directement :
$article->User = $author;


Comme vous le voyez, on peut directement affecter l'auteur, sans indiquer explicitement son id, même si c'est cette valeur qui est stockée dans la base de données. Doctrine s'occupe de tout cela automatiquement pour nous simplifier la tâche. :)

Pour terminer, on sauvegarde tous les changements effectués sur notre article :

Code : PHP
1
2
<?php
$article->save();


N'oubliez pas de sauvegarder ; sans ça, la base de données ne sera pas modifiée ! ^^

Récupérer un objet



C'est là que les classes représentant les tables vont nous être utiles. Doctrine nous fournit plusieurs « finders magiques » :

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?php
$table = Doctrine_Core::getTable('Article');

// Récupérer un article avec son id, par exemple $id = 1
$article = $table->find($id);

// Récupérer un article avec une autre propriété
$article = $table->findOneByTitle('Mon titre');

// Avec deux propriétés
$article = $table->findOneByTitleAndContent('Mon titre', "Contenu de l'article...");

// Avec une relation
$article = $table->findOneByUser($user);


Comment ça marche ? Je n'ai jamais créé ces méthodes moi ! C'est Doctrine_Table qui les définit ?

Haha, mystère... ^^

Magie, magie...



Pour répondre à la question, et bien... oui et non.

En fait, Doctrine utilise très largement une méthode magique de PHP : __call(). PHP appelle cette méthode lorsque nous en utilisons une qui n'est pas définie. Ensuite, c'est à l'intérieur de cette méthode que tout le travail est fait.

Par exemple, en appelant findOneByTitleAndContent("Mon titre", "Contenu de l'article..."), Doctrine va se dire « Tiens, il veut que je lui donne un article dont le titre est "Mon titre" et le contenu est "Contenu de l'article"... », et exécuter une requête en conséquence. Bon, en réalité, c'est un peu moins magique que ça, et je vous invite à aller voir le détail de cette fonction dans le code de Doctrine (essayez de la retrouver :p ).

Pendant qu'on y est, parlons des attributs de nos objets (title, content et user_id). En fait, ils ne sont pas définis « en dur » en tant qu'attributs. Pour faire simple, c'est comme s'ils étaient stockés dans un tableau.

Doctrine_Record implémente la méthode magique __set(), qui est appelée automatiquement lorsque l'on essaye d'utiliser un attribut qui n'existe pas. Ensuite, c'est comme pour __call : c'est ici que l'attribut est récupéré.

Et pour ce qui est de $article['title'] = '...', et bien Doctrine_Record implémente l'interface ArrayAccess (dont le nom est assez explicite ;) ).
Je vous encourage par la même occasion à vous documenter au sujet de cette interface. Elle n'est pas extrêmement compliquée à comprendre, et beaucoup de composants de Doctrine l'utilisent.

J'espère que maintenant tout ce fonctionnement « magique » vous paraîtra un peu moins obscur. ;)

Utilisation des collections d'objets



À l'instant, nous avons utilisé des méthodes nommées findOneBy..., qui nous retournent un seul objet. Mais si plusieurs objets peuvent correspondre aux critères, alors il est préférable d'utiliser findBy... qui retourne un objet Doctrine_Collection contenant une liste d'objets. Ces collections peuvent s'utiliser comme des tableaux.

À noter qu'il existe une méthode findAll() qui retourne TOUS les enregistrements de la table. Attention en l'utilisant sur des tables qui contiennent beaucoup d'enregistrements...

Voyons un exemple :

Code : PHP
1
2
3
4
5
6
7
8
<?php
$table = Doctrine_Core::getTable('Article');

$articles = $table->findByTitle('Titre');
foreach($articles as $article)
{
 echo $article->title;
}


Il est bien entendu aussi possible de créer/modifier des collections :

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<?php
$articles = new Doctrine_Collection('Article');
// Ou bien
$articles = $table->findAll();

$articles[0] = new Article();
$articles[1] = new Article();

$articles[0]->title   = "Titre de l'article n°1";
$articles[0]->content = 'Contenu 1';
$articles[1]->title   = "Titre de l'article n°2";
// etc.


Je vous ai dit que beaucoup de composants de Doctrine implémentaient l'interface ArrayAccess. Et bien comme vous le voyez dans le code ci-dessus, c'est le cas de Doctrine_Collection. Notez aussi que pour pouvoir être parcouru avec foreach, il faut aussi implémenter une interface « iterator » (IteratorAggregate en l'occurrence).


Pour sauvegarder tous nos objets, il existe un raccourci : nous ne serons pas obligés de sauvegarder nos objets un par un (ouf ! :p ).
Doctrine_Collection possède tout simplement une méthode save() qui appelle cette même méthode sur tous ses objets.

Code : PHP
1
2
<?php
$articles->save();

Le langage DQL

Nous allons ici explorer un peu plus en profondeur Doctrine et découvrir son langage interne : le DQL.
DQL signifie Doctrine Query Language. L'intérêt est encore une fois de ne pas se soucier du type de base de données utilisé. En effet, même s'ils utilisent le langage SQL, beaucoup de SGBD (tous ? ^^ ) implémentent leurs propres fonctions et spécificités dans le langage. Doctrine se chargera de traduire le DQL dans le langage approprié.

Sélection simple de données



Rassurez-vous, vous n'allez pas devoir apprendre (encore !) un nouveau langage ultra complexe...
Le DQL utilise en fait les mêmes instructions que le SQL.

Pour ce premier chapitre, nous allons donc utiliser le mot clé... SELECT ! ;)

Tout d'abord, petite explication.
Lorsque vous sélectionnez un objet de cette manière :

Code : PHP
1
2
<?php
$article = Doctrine_Core::getTable('Article')->find(1);

Doctrine va générer des instructions en SQL. Mais nous avons la possibilité d'écrire nous-mêmes les requêtes à la main.

Pour cela, nous allons utiliser des objets Doctrine_Query.

Code : PHP
1
2
3
4
5
6
7
<?php
$q = Doctrine_Query::create()
  ->from('Article a')
  ->leftJoin('a.User u')
  ->where('a.id = ?', 1);

$article = $q->fetchOne();


Cet exemple produit le même effet que précédemment, le SQL généré étant le même ; mais à la différence près que nous avons construit la requête à la main.
Rassurez-vous, nous allons détailler tout cela juste après. ;)

Euh... C'est quoi l'intérêt de faire ça alors qu'on peut le récupérer en une seule ligne, notre article ?!

Oui, bon, j'avoue, sur cet exemple, l'intérêt n'est pas flagrant. ^^ Mais dès que vous allez vouloir faire des sélections plus complexes qu'avec les finders (souvenez-vous, les méthodes $table->findByXXX()), cela va devenir indispensable.

Imaginons que nos articles possèdent un champ publishable dont le contenu indique si l'article est publiable ou non. Pour récupérer un article, il nous faut alors prendre ceci en compte et filtrer les résultats :

Code : PHP
1
2
3
4
5
6
7
8
<?php
$q = Doctrine_Query::create()
  ->from('Article a')
  ->leftJoin('a.User u')
  ->where('a.id = ?', 1)
  ->andWhere('a.publishable = ?', true);

$article = $q->fetchOne();


SELECT : Doctrine_Query en détails



Passons maintenant en revue les différentes méthodes disponibles pour construire notre Doctrine_Query.

SELECT


Doctrine_Query::select() permet d'indiquer les champs à sélectionner. Notez que pour l'instant, nous récupérons tous nos enregistrements sous forme d'objets ; il est donc inutile de préciser quels champs récupérer, car Doctrine sélectionne automatiquement tous les champs. Nous verrons plus tard comment personnaliser tout ça. ^^

FROM


Doctrine_Query::from() permet d'indiquer la (ou les) table(s) sur lesquelles effectuer la sélection. Pour ajouter d'autres champs à une requête existante, utilisez Doctrine_Query::addFrom().

WHERE


Doctrine_Query::where() permet de filtrer les enregistrements. Utilisez la syntaxe « classique » de la clause WHERE du SQL.
Notez que cette méthode efface toutes les conditions précédemment définies. Pour ajouter une condition à celles existantes, il faut utiliser Doctrine_Query::addWhere() (identique à Doctrine_Query::andWhere()) qui ajoute une condition avec AND, ou Doctrine_Query::orWhere() qui ajoute une condition avec OR.

Cette fonction accepte en deuxième argument la liste des paramètres :
Code : PHP
1
2
3
4
5
6
7
<?php
$q->andWhere('a.id = ? OR a.id = ?', array(1, 2));
$q->orWhere('a.title = ?', array('Mon titre'));
// Ou :
$q->orWhere('a.title = ?', 'Mon titre');
// Ou encore :
$q->orWhere('a.title = :title', array(':title' => 'Mon titre'));


JOIN


Doctrine supporte deux types de jointures :INNER JOIN et LEFT JOIN. RIGHT JOIN n'est pas supporté, mais il suffit de construire ses requêtes autrement pour y pallier. Les méthodes utilisées sont Doctrine_Query::innerJoin() et Doctrine_Query::leftJoin().
Par défaut, Doctrine ajoute automatiquement la condition de jointure (mot-clé ON) en fonction des relations définies entre les tables. Pour utiliser une condition personnalisée, il suffit d'inclure le mot clé ON dans le DQL passé à l'une de ces méthodes :
Code : PHP
1
2
3
4
<?php
$q = Doctrine_Query::create()
  ->from('Article a')
  ->leftJoin('a.User u ON u.id = ?', 3);
  • Le mot-clé WITH (ajout d'une condition sur la jointure) s'utilise de la même manière.
  • Les paramètres sont passés de la même façon que pour le WHERE (voir ci-dessus).


ORDER BY


La clause ORDER BY se définit avec Doctrine_Query::orderBy() (ou Doctrine_Query::addOrderBy()).

LIMIT et OFFSET


Utilisez Doctrine_Query::limit() et Doctrine_Query::offset().

Pour ceux qui formulent leurs limites en faisant LIMIT 14, 50 (avec MySQL par exemple), sachez que cela ne fait pas partie des spécifications officielles de SQL. L'autre formulation possible est LIMIT 50 OFFSET 14. Avec Doctrine, vous devrez donc utiliser la deuxième manière et utiliser limit() et offset().


GROUP BY


Utilisez Doctrine_Query::groupBy() ou Doctrine_Query::addGroupBy().

HAVING


Utilisez Doctrine_Query::having() ou Doctrine_Query::addHaving().

Récupération des résultats


Pour finir, la requête doit être exécutée pour pouvoir récupérer les résultats.
Doctrine possède plusieurs méthodes pour cela :

  • execute() : cette méthode retourne un objet Doctrine_Collection contenant un enregistrement ou plus. Notez que vous pouvez passer en argument un tableau contenant les paramètres n'ayant pas encore été renseignés. On peut également passer en deuxième argument le mode d'hydratation des résultats, mais nous verrons cela plus tard. ;)
  • fetchOne() : cette méthode retourne un objet Doctrine_Record. Cette méthode accepte les mêmes arguments que execute().


Il existe d'autres méthodes qui retournent des résultats, telle que fetchArray(). Mais nous verrons cela plus tard (oui, encore ^^ ).

Note sur le passage des paramètres


Vous avez vu que les méthodes acceptant des variables peuvent recevoir en paramètre ces valeurs à remplir. Lorsque vous utilisez des valeurs dynamiques comme cela, vous devez toujours les passer en paramètre. De cette manière, les caractères dangereux seront échappés automatiquement, évitant des injections SQL.
Ces paramètres s'utilisent de la même manière qu'avec PDO. Deux choix s'offrent à vous pour indiquer leur emplacement :
  • Utiliser des ?.
    Dans ce cas, les paramètres doivent être passés dans le même ordre que les ?.
    Par exemple : <?php $q->where('a.title = ?', $title).
  • Utiliser des paramètres nommés, comme :name.
    Dans ce cas, l'argument supplémentaire doit être un tableau associatif de paires nom => valeur.
    Par exemple : <?php $q->where('a.title = :title', array(':title' => $title)).


Pour finir, comme je vous l'ai dit, les méthodes qui exécutent la requête (telles que execute() et fetchOne()) acceptent elles aussi comme premier argument un tableau de paramètres à passer.
Pourquoi ? Et bien, il se peut qu'au moment de construire votre requête, vous ne connaissiez pas encore la valeur des variables que vous utiliserez à l'intérieur. Vous avez donc la possibilité de les passer tout à la fin, juste au moment de l'exécution.

Par exemple, les deux codes ci-dessous sont identiques :

Code : PHP - Passage des paramètres lors de la construction
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
<?php
$q = Doctrine_Query::create()
  ->from('Article a')
  ->where('a.title = :title AND a.publishable = :publishable', array(
      ':title'       => $title, 
      ':publishable' => $publishable
    ))
  ->andWhere('a.content LIKE :keyword', '%'.$keyword.'%');

$resultats = $q->execute();

Code : PHP - Passage des paramètres lors de l'exécution
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
<?php
$q = Doctrine_Query::create()
  ->from('Article a')
  ->where('a.title = :title OR a.publishable = :publishable')
  ->andWhere('a.content LIKE :keyword');

$resultats = $q->execute(array(
  ':title'       => $title,
  ':publishable' => $publishable,
  ':keyword'     => '%'.$keyword.'%',
));


Ceci peut vous être utile lorsque vous utilisez des requêtes comme modèles. Notez que dans ce cas, il est conseillé d'utiliser les paramètres nommés (tels que :title), à moins que vous ne connaissiez par coeur l'ordre dans lequel vous devez passer les paramètres. ^^

UPDATE et DELETE


Les mises à jour et suppressions de données se font tout aussi simplement avec un objet Doctrine_Query.

DELETE


Ici, au lieu d'utiliser Doctrine_Query::select(), nous allons utiliser... Doctrine_Query::delete() ! Surprenant, hein ? ;)
Nous pouvons appliquer les mêmes filtres que pour un SELECT ; voici un exemple :
Code : PHP
1
2
3
4
5
6
7
<?php
$q = Doctrine_Query::create()
  ->delete('Article a')
  ->where('a.title LIKE ?', 'Mauvais titre')
  ->orWhere('a.published = ?', false)
  ->limit(20);
$number = $q->execute();


UPDATE


De la même manière, nous pouvons mettre à jour des champs. Il faut en revanche spécifier en plus les champs à mettre à jour avec Doctrine_Query::set() :
Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
<?php
$q = Doctrine_Query::create()
  ->update('Article a')
  ->where('a.title = ?', 'mon titre')
  ->orWhere('a.id = ?', 1)

  // Soit :
  ->set('content', 'un super texte');
  // ou soit :
  ->set('content', '?', $content);
  // ou encore 
  ->set(array('content' => $content))

$number = $q->execute();


Le nombre de lignes affectées (mises à jour ou supprimées) est retourné par la méthode execute() dans le cas d'un update d'un delete.

Utilité des classes de tables

Au chapitre précédent, je vous avais dit de créer, en plus des classes classiques de modèles, des classes de tables (par exemple ArticleTable.class.php). Mais peut-être n'en voyez-vous pas l'utilité.

En fait, nous allons nous en servir pour effectuer des traitements lorsqu'il y en aura besoin. Tout le code (ou du moins le plus possible ^^ ) concernant des actions sur la table et ses données devra être placé dans cette classe.

Prenons un exemple. Imaginons que nos articles contiennent un champ is_publishable qui indique si l'article est publiable ou non. Par défaut, la méthode find() cherche un article avec son id. Mais nous voulons en plus une « sécurité », c'est-à-dire ne pas pouvoir récupérer les articles non publiables, par exemple.

Pour cela, nous allons redéfinir cette méthode :

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
<?php
class ArticleTable extends Doctrine_Table
{
 public function find($id)
 {
  $q = $this->createQuery('a')
    ->where('a.id = ?', $id)
    ->andWhere('a.is_publishable = ?', true);
  
  return $q->fetchOne();
 }
}

Maintenant, lorsque nous utiliserons <?php Doctrine_Core::getTable('Article')->find(3), ce sera cette méthode qui sera appelée (merci l'héritage :p ).

Remarquez que nous avons utilisé <?php $this->createQuery('a'). Ceci est en fait un raccourci pour :
Code : PHP
1
2
3
<?php
Doctrine_Query::create()
    ->from('Article a')


Mais nous avons encore un problème : si on utilise une autre méthode que find() pour récupérer un article, le filtrage ne sera pas effectué.
Afin de simplifier l'ajout de cette condition à toutes nos requêtes, nous allons créer une méthode getPublishableArticleQuery() :

Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
<?php
class ArticleTable extends Doctrine_Table
{
 public function getPublishableArticleQuery(Doctrine_Query $q = null)
 {
  if(null === $q)
  {
   $q = $this->createQuery();
  }

  // getRootAlias() renvoie l'alias principal de la requête 
  // (jusqu'à maintenant j'ai utilisé 'a' pour cette table,
  // mais j'aurais pu utiliser n'importe quoi).
  $q->andWhere($q->getRootAlias().'.is_publishable = ?', true);
  
  return $q;
 }

 public function find($id)
 {
  $q = $this->createQuery('a')
    ->where('a.id = ?', $id);

  return $this
    ->getPublishableArticleQuery($q)
    ->fetchOne();
 }
}


Explications :
La méthode ArticleTable::getPublishableArticleQuery() accepte en argument un objet Doctrine_Query, et lui ajoute une condition WHERE, puis la retourne.

Nous voyons ici toute la puissance de Doctrine_Query : il est possible de modifier la requête à plusieurs endroits dans notre programme, de lui ajouter des conditions, etc. sans se soucier de ce qu'elle fait. Notre méthode getPublishableArticleQuery ajoute la condition, sans savoir comment la requête est construite ni les éléments qu'elle sélectionne déjà.


Il reste un petit inconvénient : dans toutes les requêtes de sélection telles que find(), nous devrons penser à bien passer par cette méthode afin d'ajouter le filtre.
Nous verrons plus tard une méthode beaucoup plus propre et pratique pour pallier cela, afin que ce soit fait automatiquement (oui oui, Doctrine réserve encore beaucoup de surprises... :D ). Je vous ai expliqué cela ici pour vous montrer la force de l'héritage : nous pouvons redéfinir tous les comportements que nous voulons (tout en restant raisonnable, et en ne « détruisant » pas tout... ^^ ).
Pour conclure cette partie, notez que l'objet Doctrine_Connection (à ne pas confondre avec Doctrine_Collection :) ) possède une méthode flush(), qui permet de sauvegarder tout ce qui a été modifié avec la connexion courante. C'est utile lorsque vous modifiez un grand nombre d'objets et collections différents : cela vous évite de sauvegarder les objets/collections un par un.
Chapitre précédent Sommaire Chapitre suivant

Partager

15 commentaires pour "Manipulation des données stockées dans la base"
Note moyenne : 3.54 / 4 (35 votes)
Pseudo Commentaire
Hors ligne Nami Doc # Posté le 26/08/2010 à 12:32:45
Lamaer taler dansk

Avis : Très bon

avec <? Doctrine_Expression( 'GeomFromText( .. )' ); ça ne marche pas ?

La flemme conquerra le monde !
Secret (cliquez pour afficher)
Image utilisateur
 
Hors ligne Cybermanu # Posté le 26/08/2010 à 12:39:10
Avatar

Avis : Très bon

Ville : Hostun
Pays : France métropolitaine

Si, c'est bon on avait réglé le problème par MP.
En fait, ça venait du fait que le formulaire par défaut généré par l'admin générator de symfony ne le prennait pas correctement en compte.

Mais finalement il a arrangé ça avec un listener qui "transforme" le champ en Doctrine_Expression manuellement.

Programmeur : c'est celui qui résout pour toi, de façon incompréhensible, un problème que tu ne savais pas que tu avait... :p
Image utilisateur

Apprenez à utiliser un ORM pour PHP : Doctrine !
 
Hors ligne Kail-Ra # Posté le 27/07/2011 à 15:04:58

Salut Cybermanu
Dans l'arborescence du projet que tu décris ici ou se place le code de ce chapitre?
A priori je suis tenté de le caser dans ~/web/index.php qui semble faire office de 'controleur frontal' mais dans le doute je préfère demander.
Merci d'avance
Hors ligne Cybermanu # Posté le 27/07/2011 à 15:25:33
Avatar

Avis : Très bon

Ville : Hostun
Pays : France métropolitaine

Tu le place ou tu veux !

Si tu utilise un modèle MVC, il vaut mieux se limiter à des instructions "simples" dans le controleur.
Par exemple :
Code : PHP
1
2
3
<?php
$article = Doctrine_Core::getTable('Article')->findOneByMachin($truc);
// ...


Pour des requêtes plus complexes, il vaut mieux alors déplacer leur constructions dans le modèle :
Code : PHP
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
<?php
// Dans le modèle (ArticleTable par exemple) :
public function maRequete()
{
    $q = $this->createQuery();

    $q->orderBy('truc')
      ->where('machin');
      // etc...

    return $q->exexute();
}

// Dans le controleur :
$articles = Doctrine_Core::getTable('Article')->maRequete();


Note que mon index.php n'est pas vraiment un vrai controleur frontal, j'ai simplement fait comme ça pour l'exemple, afin que ça soit accessible à plus de monde.

Programmeur : c'est celui qui résout pour toi, de façon incompréhensible, un problème que tu ne savais pas que tu avait... :p
Image utilisateur

Apprenez à utiliser un ORM pour PHP : Doctrine !
 
Hors ligne seanelp # Posté le 13/12/2011 à 13:22:14
Avatar

Salut!
je suis débutant et je travaille sur un site internet actuellement,je l'ai tout d'abord codé à l'ancienne (POO) et je souhaite le faire passer en MVC.
pour être bref ce site est un moteur de recherche dans une base de données;mon problème c'est la
routine de base,une requête sql : "SELECT * FROM 'matable' WHERE 'matable.nom' REGEXP '$var'"

$var = données sous forme d'expression régulière simple ex: toto|paris|heure
elle permet d'avoir tout les lignes dont le champ 'nom' contient au moins un de ces mots..

j'ai lu et relu la doc de Doctrine je ne trouve pas comment utiliser le mot REGEXP dans le langage propre à Doctrine
Merci d'avance, bien à vous..

Voir tous les commentaires
Ce tutoriel a été corrigé par les zCorrecteurs.