Comment faire recherche fulltext [PHP]

Répondre


Cette question est un moyen d’empêcher des soumissions automatisées de formulaires par des robots.
Smileys
:D :) :( :o :shock: :? 8-) :lol: :x :P :oops: :cry: :evil: :twisted: :roll: :wink: :!: :?: :idea: :arrow: :| :mrgreen: =D> #-o =P~ :^o :non: :priere: 8-|
Voir plus de smileys
  Revue du sujet
 

  Étendre la vue Revue du sujet : Comment faire recherche fulltext [PHP]

par Invité » 29 févr. 2008, 19:24

Salut,

Ben voila j'ai change la base de donnée, je ne suis plus en SQlite mais bien en MySQL maintenant !

qui peu m'aider ?? Merci .....

par Invité » 24 févr. 2008, 17:55

Autre idée qui me vient en tête.

Plutôt que de faire la recherche full text sur SQLite une fois la base créer,
Ne peu t on pas réaliser le tri avant la création de la base, donc lors de la sélection des différents rss XML qui doivent être intégré a cette base de donnée (via PHP ou simpleXML).

Merci de m'aider dans cette tourmante, la solution ne semble pas facile ...

par Invité » 24 févr. 2008, 12:44

Merci pour ta reponse, je vais essayer ca mais ca me pose probleme car chez OVH je ne crois pas que SQlite soit installer en dehos de la 2.0 qui est avec php5 !

Y as t-il un moyen que je l'install ?

d'autre part il me semble que tout le script devrait etre reecrit par rapport a fts ? non ?

Y aurai pas une autre solution plus facile ?

parce que je debute et ca va un peu vite pour moi !

Merci

par Berzemus » 22 févr. 2008, 19:22

a noter que, avec une simple clause "like", ce n'est pas du fulltext que tu fais, mais une simple "comparaison". C'est lent et loin, très loin d'être optimal (surtout s'ily a un bon bout de texte derrière).

Sous sqlite (selon la version d'sqlite que tu utilises), il vaut mieux utiliser le module fts (pour full-text-search).

Alors tu pourras utiliser des requêtes du type:

Code : Tout sélectionner

select * from table where description match 'voiture OR camion'


Voici toujours une description de son utilisation. (j'ai jamais trouvé de truc plus clair..)

(a ce que je me souviens, le simple sqlite 2.X inclus dans php5 ne le permets pas. La version 3.3.x de pdo_sqlite devrait l'inclure, mais tu peux aussi utiliser une plus récente version de sqlite, la 3.5.x)

par Invité » 22 févr. 2008, 17:20

Oups,
Comme ici j'ai bien utiliser la balise CODE, je suppose qu'en faite j'aurai plutôt du utiliser la balise PHP ?

par mere-teresa » 22 févr. 2008, 17:16

Modération :
glou, afin d'améliorer la lisibilité de ton message,
pense à utiliser les balises [code] ou [php] (selon le langage utilisé).

Elles sont disponibles au-dessus de la zone de saisie de ton message
lorsque tu postes un nouveau message.

Des indications sont disponibles sur la manière de mettre en forme vos messages dans la FAQ

par Invité » 22 févr. 2008, 17:00

Bonjour,

Et merci pour votre réponse.

En faite je n'avais pas mis tout le code histoire de ne pas être trop lourd.

Je vais le mettre ci dessous afin que vous puissiez avoir une vision global.

Merci d'avoir déplacer ce sujet plus a sa place, c'est pas tjs facile de définir si c'est plus SQL ou php.

Ou mettirez vous votre proposition de WHERE ?
<?
// PARAMETRES
$db_path = "rss.db";
$rub_path = "rubriques.xml";
$password = "xxxxxxx";
$maxperpage = 100;
$refresh = 1; // minutes
$an = "2007";

// Identification sommaire :)
if(@$_POST["mdp"]==$password) {
   setcookie("log","ok");
   Header("Location: ".$_SERVER["PHP_SELF"]);
} elseif(@$_GET["log"]) {
   setcookie("log");
   Header("Location: ".$_SERVER["PHP_SELF"]);
}

$isAdmin = (@$_COOKIE["log"]!="");

// Connexion/création de la base
$db = @sqlite_open($db_path) or die("Impossible de créer la base !");

// Génération des tables
@sqlite_query($db,"CREATE TABLE flux(
   ID INTEGER PRIMARY KEY,
   titre varchar(50),
   url varchar(255),
   rubrique varchar(20),
   maj INTEGER
)");
@sqlite_query($db,"CREATE TABLE item(
   ID INTEGER PRIMARY KEY,
   IDflux INTEGER,
   titre varchar(50),
   lien varchar(255),
   pubdate INTEGER,
   description TEXT
)");

// SQLite n'aime pas les ' :s
function sql($txt) { return str_replace("'","’",$txt); }

// Extrait le nom du site de l'url
function site($url) {
   $site = parse_url($url);
   return str_replace("www.","",$site["host"]);
}

// Date française (Merci Fabrice :)
function datefr($time) {
   setlocale(LC_TIME, "fr");
   return ucfirst(strftime("%A %d %B %Y",$time));
}

// Mise à jour de la base
function lit_rss($url) {
   global $db;
   // Récupération de l'ID du flux
   $result = sqlite_query($db,"SELECT ID FROM flux WHERE url='".$url."'");
   $id = sqlite_fetch_single($result);
   // Lecture du flux
   if($flux=simplexml_load_file($url)) {
      $flux = $flux->channel;
      $titre = $flux->title;
	  $desc = $flux->descritpion;
      // Mise à jour du flux
      sqlite_query($db,"UPDATE flux SET titre='".sql($titre)."',maj=".time()." WHERE ID=".$id);
	
      // Pour chaque <item>
      foreach($flux->item as $item) {
         // On récupère les champs
         $date = strtotime($item->pubDate); if(!$date) $date=time();
         $titre = $item->title;
         $lien = $item->link;
         $desc = $item->description;
		//sqlite_query($db,"DELETE item WHERE description LIKE '%".$an."%'");
         // Anti-doublon sur URL
         $result = sqlite_query($db,"SELECT ID FROM item WHERE lien='".$lien."' AND IDflux=".$id);
         // Mise à jour
         if(sqlite_num_rows($result)>0) {
            sqlite_query($db,"UPDATE item SET titre='".sql($titre)."',description='".sql($desc)
               ."' WHERE ID=".sqlite_fetch_single($result));
         // ou ajout à la BD
         } else {
            sqlite_query($db,"INSERT INTO item(IDflux,titre,lien,pubdate,description) 
               VALUES(".$id.",'".sql($titre)."','".$lien."',".$date.",'".sql($desc)."')");
         }
      }
   }
}

if($isAdmin) {
   
   // Ajout d'un flux
   if(@$_POST["flux"]) {
      // Test validité de l'url
      if(!$flux=simplexml_load_file($_POST["flux"]))
         $error = "[".$_POST["flux"]."] n'est pas un flux RSS !";
      else {
         // Test anti-doublon
         $result = sqlite_query($db,"SELECT * FROM flux WHERE url='".$_POST["flux"]."'");
         if(sqlite_num_rows($result)<1) {
            // Ajout à la table flux
            $SQL = "INSERT INTO flux(url,rubrique) VALUES('".$_POST["flux"]."','";
            // rubrique saisie ou choisie dans la liste ?
            if(@$_POST["rubrique"]) $SQL.=sql($_POST["rubrique"]);
            elseif(@$_POST["listrub"]) $SQL.=sql($_POST["listrub"]);
            $SQL.="')";
            sqlite_query($db,$SQL);
            // et va lire le flux
            lit_rss($_POST["flux"]);
         }
      }
   }

   // Destruction d'un flux
   if(@$_GET["delflux"]) {
      sqlite_query($db,"DELETE FROM flux WHERE ID=".$_GET["delflux"]);
      sqlite_query($db,"DELETE FROM item WHERE IDflux=".$_GET["delflux"]);
      sqlite_query($db,"VACUUM"); // compresse la bd
      sqlite_close($db);
      Header("Location: ".$_SERVER["PHP_SELF"]);
   }

   // Génération du fichier xml contenant la liste des channels
   if(@$_GET["action"]=="generexml") {
      $xml = "<"."?xml version='1.0' encoding='ISO-8859-1'?".">\n<liste>\n";
      $result = sqlite_query($db,"SELECT * FROM flux ORDER BY lower(rubrique),lower(titre)");
      $tmp = "";
      // pour chaque flux
      while($val=sqlite_fetch_array($result)) {
         // si la rubrique a changé -> nouveau <channel>
         if($tmp!=$val["rubrique"]) {
            if($tmp) $xml.="</channel>\n";
            $xml.="<channel>\n<title>".$val["rubrique"]."</title>\n";
            $tmp = $val["rubrique"];
         }
         // Ajoute le flux en <item>
         $xml.="<item>\n<title>".$val["titre"]."</title>\n<link>".$val["url"]."</link>\n</item>\n";
      }
      if($tmp) $xml.="</channel>\n";
      $xml.="</liste>";
      // et enregistre le tout
      @file_put_contents($rub_path,utf8_decode($xml)); // Tiens c'est nouveau ça aussi en PHP5 :)
   }

}

// Mise à jour de la base (lecture de tous les flux non encore à jour - cf $refresh)
function update() {
   global $db,$refresh;
   set_time_limit(300); // parfois c'est un peu long :)
   $result = sqlite_query($db,"SELECT url FROM flux WHERE maj<".(time()-$refresh*60));
   while($val=sqlite_fetch_array($result))
      lit_rss($val["url"]);
}
update();

// Affichage
?><HTML><HEAD>
   <TITLE>Agrégateur RSS v1.0</TITLE>
   <STYLE>
      body { background:#FFFFFF }
      td,input,select { font:normal 8pt Verdana }
      i { font: normal 7pt Arial; color:gray }
      A { text-decoration:none }
      A:hover { text-decoration:underline }
      .a { font:bold 8pt Verdana }
      .stabilo { background:yellow }
   </STYLE>
</HEAD><BODY>

<table width=100% cellpadding=5 style="border:solid 1pt black"><tr>
   <td valign=top style="border-right:dashed 1pt gray" nowrap>

      <center>
     
         <table><tr><form method="post">
            <td><input name="mdp" size=7 value="Password" onclick="this.value=''"></td>
            <td><input type="submit" value="OK"></td>
         </form></tr></table>
   
      
      </center><hr size=1>
      
      <? // Liste des flux
         $result = sqlite_query($db,"SELECT * FROM flux ORDER BY lower(rubrique),lower(titre)");
         echo "<center><strong>".sqlite_num_rows($result)." flux RSS</strong></center>\n";
         $temp="";
         echo "<br><A class=a href='rss.php5''>Toutes rubriques</A><br>\n";
         // pour chaque flux
         while($val=sqlite_fetch_array($result)) {
            // si la rubrique a changé, affiche la nouvelle + lien
            if($temp!=$val["rubrique"]) {
               echo "<br><A class=a href='?rubrique=".urlencode($val["rubrique"])."'>"
                  .$val["rubrique"]."</A><br>\n";
               $temp = $val["rubrique"];
            }
            // Affiche le lien interne vers le flux
            echo "<A href='?delflux=".$val["ID"]."'>
               <img src='img/minipoub.gif' width=14 height=15 border=0 align=absmiddle></A> ";
            echo "<A href='?flux=".$val["ID"]."'>".substr($val["titre"],0,20)."</A><br>\n";
         }
      
       { ?>
         <hr size=1><center><b>Admin</b><br><br>
            <A href="?action=generexml">Générer la liste XML</A><br>
         </center>
      <? } ?>

   </td><td valign=top>

      <? // Ajout de flux si identifié
       { ?>
         <table><form method="post" name="addflux"><tr>
            <td>Flux RSS</td>
            <td><input name="flux"></td>
            <td><select name="liste" onchange="addflux.flux.value=this.options[this.selectedIndex].value">
               <option>=== Liste de flux RSS ===</option>
               <? // Génération d'après rubriques.xml
               if($xml=simplexml_load_file($rub_path)) {
                  foreach($xml->channel as $channel) {
                     // pour chaque <channel> fais un <optgroup>
                     echo '<optgroup label="'.$channel->title.'">';
                     // et une ligne par <item>
                     foreach($channel->item as $item) {
                        echo '<option value="'.$item->link.'">'.substr(utf8_decode($item->title),0,20).'</option>';
                     }
                     echo '</optgroup>';
                  }
               } ?>
             </select></td>
            <td rowspan=2>&nbsp;&nbsp;</td>
            <td rowspan=2><input type="submit" value="Ajouter le flux"></td>
         </tr><tr>
            <td align=right>Rubrique</td>
            <td colspan=2><table border=0 cellspacing=0 cellpadding=0><tr>
               <td><select name="listrub">
                  <option></option>
                  <? // Liste des rubriques
                  $result = sqlite_query($db,"SELECT DISTINCT rubrique FROM flux ORDER BY rubrique");
                  while($val=sqlite_fetch_array($result)) {
                     echo "<option>".$val["rubrique"]."</option>\n";
                  }
                  ?>
               </select></td>
               <td>&nbsp;ou&nbsp;</td>
               <td><input name="rubrique" size=20 maxlength=20></td>
            </tr></table></td>
         </tr></form></table>
         <hr size=1>
      <? }

      // AFFICHAGE DES NEWS
      $deb = @$_GET["deb"]; if(!$deb) $deb=0;
      $SQL = " FROM item INNER JOIN flux ON item.IDflux=flux.ID";
      $lien = "";

      // sélection de news
      if(@$_GET["rubrique"]) {
         $SQL .= " AND flux.rubrique='".$_GET["rubrique"]."'";
         $lien .= "&rubrique=".urlencode($_GET["rubrique"]);
      }
      if(@$_GET["flux"]) {
         $SQL .= " AND flux.ID=".$_GET["flux"];
         $lien .= "&flux=".urlencode($_GET["flux"]);
      }

      // Pagination
      $result = sqlite_query($db,"SELECT count(*)".$SQL);
      $pagine = ""; $j=0;
      if($deb)
         $pagine.="<A class=a href='?deb=".max(0,$deb-$maxperpage).$lien."'><< RETOUR</A>&nbsp;";
      $pagine .= "&nbsp;Page";
      $max = sqlite_fetch_single($result);
      for($i=0;$i<$max;$i+=$maxperpage) { $j++;
         if($deb==$i) $pagine .= "<b><font color=red> ".$j." </font></b>";
         else $pagine .= "<A class=a href='?deb=".$i.$lien."'> ".$j." </A>";
      }
      if($deb<$max-$maxperpage)
         $pagine.="&nbsp;<A class=a href='?deb=".($deb+$maxperpage).$lien."'>SUITE >></A>";
      $pagine = "<div align=right>".$pagine."</div>";
      echo $pagine;

      $lien .= "&deb=".$deb;

      // Sélection des news
      $SQL = "SELECT flux.url as url,item.titre as titre,item.pubdate as pubdate,item.lien as lien,
         item.ID as ID,item.description as description"
         .$SQL." ORDER BY pubdate DESC LIMIT ".$deb.",".$maxperpage;

      // et zou... lecture
      $result = sqlite_query($db,$SQL);
      echo "<dl>"; $temp="";

      // Pour chaque news
      while($val=sqlite_fetch_array($result)) {
         // si la date a changé, affiche-la
         if(date("d/m/Y",$val["pubdate"])!=$temp) {
            if($temp) echo "<br>";
            echo "<dt>".datefr($val["pubdate"])."</dt>";
            $temp = date("d/m/Y",$val["pubdate"]);
         }
         // affiche la news
         echo "<dd>
            <i>".date("H:i",$val["pubdate"])."</i> 
            <A ";
         // si c'est une news avec description non sélectionnée -> lien interne
         if($val["description"]&&(@$_GET["news"]!=$val["ID"])) {
            echo "class=a href='?news=".$val["ID"].$lien;
         } else {
            // si c'est un news à description sélectionnée, stabilote
            if(@$_GET["news"]==$val["ID"]) echo "class=stabilo ";
            // lien vers le site
            echo "target='_blank' href='".$val["lien"];
         }
         echo "'>".utf8_decode($val["titre"])."</A>
            <i></i>
            <br>
         </dd>";
      }
      echo "</dl>";
      echo $pagine;
      ?>

   </td><td valign=top style="border-left:dashed 1pt gray" width=20%>

      </td>
</tr></table>

<? // Affichage des erreurs
if(@$error) { ?><script>alert("<?echo $error?>")</script><? } ?>

</BODY></HTML><?

// Déconnexion
sqlite_close($db);

?>
edit mere T. : j'ai mis les balises PHP pour toi :)

par Ryle » 22 févr. 2008, 16:12

Je dois passer à côté de quelque chose parce que je ne vois absolument pas où tu utilise ta variable $an... et je ne comprends pas bien non plus pourquoi un WHERE description='2007' ou WHERE description LIKE '%2007%' ne satisferait pas à ton problème (c'est quoi d'ailleurs cette histoire de DELETE ?)

Seul problème que je vois, c'est que si $_GET["rubrique"] ou $_GET["flux"] sont renseignés, tu vas ajouter des AND dans ta requête alors que celle-ci ne comporte pas le moindre WHERE....


Bon et pis tant que j'y suis, et vu qu'il semble s'agir d'avantage d'un problème SQL que PHP je déménage dans le forum idoine :)

Comment faire recherche fulltext [PHP]

par glou » 22 févr. 2008, 15:53

Bonjour,

Je m'explique, j'ai une base donnée SQLite qui comprend un champs "description" dans laquelle je souhaite faire une recherche fulltext afin de ne ressortir que les ID ou le ce champs "description contient une année précise (2007).

J'ai essayer pas mal de chose, mais je ne vois plus ou essayer et surtout si mon ecriture etait bonne.

- J'ai essayer la technique du WHERE LIKE sur le champs.
- j'ai essayer lors de la création de la base de ne pas enregistrer les ID dont la description ne contenait pas 2007
- j'ai essayer aussi le DELETE WHERE LIKE juste apres la creation.

Rien ne marchais mais comme je l'ai dit il y de grande chance pour que mon ecriture ne soit pas correcte.
Le champs dans lequelle se trouve l'année est "description" variable $desc et l'année qu'il me faut est 2007 que j'ai mis en variable $an.

Voici la creation de la base

Code : Tout sélectionner

/ Mise à jour de la base function lit_rss($url) { global $db; // Récupération de l'ID du flux $result = sqlite_query($db,"SELECT ID FROM flux WHERE url='".$url."'"); $id = sqlite_fetch_single($result); // Lecture du flux if($flux=simplexml_load_file($url)) { $flux = $flux->channel; $titre = $flux->title; // Mise à jour du flux sqlite_query($db,"UPDATE flux SET titre='".sql($titre)."',maj=".time()." WHERE ID=".$id); // Pour chaque <item> foreach($flux->item as $item) { // On récupère les champs $date = strtotime($item->pubDate); if(!$date) $date=time(); $titre = $item->title; $lien = $item->link; $desc = $item->description; // Anti-doublon sur URL $result = sqlite_query($db,"SELECT ID FROM item WHERE lien='".$lien."' AND IDflux=".$id); // Mise à jour if(sqlite_num_rows($result)>0) { sqlite_query($db,"UPDATE item SET titre='".sql($titre)."',description='".sql($desc) ."' WHERE ID=".sqlite_fetch_single($result)); // ou ajout à la BD } else { sqlite_query($db,"INSERT INTO item(IDflux,titre,lien,pubdate,description) VALUES(".$id.",'".sql($titre)."','".$lien."',".$date.",'".sql($desc)."')"); } } } }
Voici l'affichage de la base

Code : Tout sélectionner

<? // AFFICHAGE DES NEWS $deb = @$_GET["deb"]; if(!$deb) $deb=0; $SQL = " FROM item INNER JOIN flux ON item.IDflux=flux.ID"; $lien = ""; // sélection de news if(@$_GET["rubrique"]) { $SQL .= " AND flux.rubrique='".$_GET["rubrique"]."'"; $lien .= "&rubrique=".urlencode($_GET["rubrique"]); } if(@$_GET["flux"]) { $SQL .= " AND flux.ID=".$_GET["flux"]; $lien .= "&flux=".urlencode($_GET["flux"]); } // Sélection des news $SQL = "SELECT flux.url as url,item.titre as titre,item.pubdate as pubdate,item.lien as lien, item.ID as ID,item.description as description" .$SQL." ORDER BY pubdate DESC LIMIT ".$deb.",".$maxperpage; // et zou... lecture $result = sqlite_query($db,$SQL); echo "<dl>"; $temp=""; // Pour chaque news while($val=sqlite_fetch_array($result)) { // affiche la news echo "<dd> <i>".date("d/m/Y",$val["pubdate"])."</i> <A "; // lien vers le site echo "target='_blank' href='".$val["lien"]; echo "'>".utf8_decode($val["titre"])."</A>"; echo "<br> <i>".utf8_decode($val["description"])."</i></dd>"; } echo "</dl>"; echo $pagine; ?>
Un tout grand merci d'avance à celui qui m'aidera a écrire la ligne adéquate et à me dire ou je doit la mettre.