Bonjour,
J'ai installé un petit moteur de recherche interne sur mon site, il marche bien, mais le problème c'est que si l'on rentre deux mots dans la recherche, alors les résultats qui s'affiche doivent contenir ces deux mots qui se suivent exactement.. Je suis en PHP 5.4
Voilà un exemple de ce que je voudrais :
Recherche = Sac dos
Résultat = sac a dos
En gros je voudrais que la recherche de deux mots soit divisé en deux, pour rechercher à la fois les "sac" et les "dos" et afficher les nom de résultats qui contiennent les deux..
Voilà mon code actuel :
mysql_connect("XXXXXXXXXXXXX.mysql.db", "XXXXXXXXX", "XXXXXXX") or die (mysql_error ());
// Select database
mysql_select_db("XXXXXXXXXX") or die(mysql_error());
// SQL query
$recherche = isset($_POST['recherche']) ? $_POST['recherche'] : '';
$strSQL = "SELECT * FROM XXXXXXXXX WHERE nom LIKE '%$recherche%' OR description LIKE '%$recherche%' ORDER BY nom limit 100";
// Execute the query (the recordset $rs contains the result)
$rs = mysql_query($strSQL);
// Loop the recordset $rs
while($row = mysql_fetch_array($rs)) {
// Name of the person
$strName1 = $row['nom'];
$strName2 = $row['prix'];
$strImg = $row['img'];
// Create a link to person.php with the id-value in the URL
$strLink = " $strLink2 = " $strLink3 = " // List link
echo "
" . $strLink . " | " . $strLink2 . " | " . $strLink3 . " |
}
// Close the database connection
mysql_close();
?>
à mon avis tu devrais te documenter sur "sql injection"
Bonjour
Techniquement, vous avec 2 solutions qui me viennent à l'esprit
- simplement scinder les mots de recherches (genre un explode sur espace, +, tiret, virgule... enfin tout ce que peut entrer un visiteur...) et construire votre requête, avec un Like sur chaque mot.
(une petite boucle sur votre tableau obtenu via explode)
- un peu moins simple de prime abord, mais bien plus simple à gérer. Ue recherche avec une requête à base de MATCH .... AGAINST, qui va vous sortir les résultats en fonction de la pertinence (plus il y a de mots, plus le résultat sera en haut de liste). Il faut que les champs recherchés soit en Full Index dans la table.
Je pense que la solution 2 est de loin la plus pertinente.
Et comme mis par Fritz2cat, attention là, votre base de données est à la merci de tous les pirates amateurs. Vous devez impérativement traiter et contrôler ce que le client peut entrer.
accessoirement, passer en php7.4, 7.3 sur Ovh
Merci Kyodev, je sais que ça serait bien, mais ça à l'air de demander beaucoup de travail. J'ai lu ce que tu m'as écris sur l'autre post.
En full index dans la table ? Que voulez vous dire ?
En augmentant la version de php ou en changeant ce morceau de code ?
Contrôler les données utilisateurs :
- quelle que soit la version PHP utilisée, vous devez contrôler ce que l'utilisateur peut entrer.
Car n'importe quel pirate amateur ou robot va tester et envoyer du texte, qui lui permettra d'accéder à votre base de données, si vous ne faites rien.
Full Index : c'est une option à mettre sur les champs de votre table, où seront faites les recherches.
C'est un index plus poussé qu'un simple index.
Mais ça n'est pas supporté par tous les types de champs.
Si on n'utilise pas de moteur de recherche ou de bouton formulaire, c'est plus sécurisé ?
Comment contrôler les données utilisateurs ?
Je voudrais faire une recherche a base de MATCH j'avais essayé mais cela n'avait pas donné de résultat, je vais retenter.
Je ne trouve pas comment activer le Full index, c'est l'option ADD INDEX ?
Pourriez vous me donner le code qui va scinder $recherche en $recherche1 et $recherche2 en pas d'espace? Si possible le placer dans mon code. Merci d'avance, car j'ai cherché mais je ne trouve pas.
Non, c'est l'option Full Index, qui se trouve probablement au même endroit, mais n'ayant pas de base mutualisée ovh, je ne sais pas.
Vous avez actuellement ça :
$recherche = isset($_POST['recherche']) ? $_POST['recherche'] : '';
$strSQL = "SELECT * FROM XXXXXXXXX WHERE nom LIKE '%$recherche%' OR description LIKE '%$recherche%' ORDER BY nom limit 100";
Je reprends ça :
` $recherche = isset($_POST['recherche']) ? $_POST['recherche'] : '';`
Maintenant, je vais faire un explode sur les espace
` $rrr = explode(' ', $recherche);`
Ensuite, je construis la requête :
$where1 = '';
$where2 = '';
foreach ($rrr as $r) {
$where1 .= ($where1 == '' ? '' : ' OR ').' nom LIKE "%$r%";
$where2 .= ($where2 == '' ? '' : ' OR ').' description LIKE "%$r%";
}
Et la requête qui devient :
`$strSQL = "SELECT * FROM XXXXXXXXX WHERE $where1 OR $where2 ORDER BY nom limit 100";`
A vérifier, car il faudrait au moins :
- vérifier que $r n'est pas vide
- vérifier que $r n'est pas une injection de code
- supprimer les caractères bizarre qui n'ont rien à faire là...
Mais c'est l'idée générale
Avec match against, ça donnerait un truc de ce genre :
SELECT nom, prix, img,
MATCH(nom,description) AGAINST (:lesmots IN BOOLEAN MODE) as Relevance
FROM `votretable`
WHERE MATCH(nom,description) AGAINST(:lesmots IN BOOLEAN MODE)
HAVING Relevance > 0.2
ORDER BY Relevance DESC
Merci beaucoup pour votre aide Pppplus, je suis en train d'essayer tout ca.
La solution avec Match et Against est elle plus sécure que Like ? Ou il va falloir également contrôler les données utilisateurs ?
Est ce que quelqu'un sait comment activer l'option Full Index chez ovh ? J'ai trouvé Fulltext, je ne sais pas si c'est la même chose et de toute façon j'ai un message d'erreur.. Peut-être que chez OVH cela ne s'appelle pas Full Index, car j'ai bien regardé
```text J'essaye votre code avec explode, mais il doit avoir une erreur quelque part, car la page refuse de s'ouvrir ( ou alors ce n'est pas compatible php 5.6 )
Voilà mon code qui ne s'ouvre pas :
$recherche = isset($_POST['recherche']) ? $_POST['recherche'] : '';
$rrr = explode(' ', $recherche);
$where1 = '';
$where2 = '';
foreach ($rrr as $r) {
$where1 .= ($where1 == '' ? '' : ' OR ').' nom LIKE "%$r%";
$where2 .= ($where2 == '' ? '' : ' OR ').' description LIKE "%$r%";
}
$strSQL = "SELECT * FROM XXXXXXXX WHERE $where1 OR $where2 ORDER BY nom limit 100";
// Execute the query (the recordset $rs contains the result)
$rs = mysql_query($strSQL);
// Loop the recordset $rs
while($row = mysql_fetch_array($rs)) {
// Name of the person
$strName1 = $row['nom'];
$strName2 = $row['prix'];
$strImg = $row['img'];
// Create a link to person.php with the id-value in the URL
$strLink = "produit_recyclage.php?id=" . $row[produit_recyclage.php?id=" . $row[produit_recyclage.php?id=" . $row[
}
// Close the database connection
mysql_close();
?> ```
Activez les erreurs pour voir quelles lignes déconnent.
J'ai oublié de fermer le texte :
$where1 .= ($where1 == '' ? '' : ' OR ').' nom LIKE "%$r%"';
$where2 .= ($where2 == '' ? '' : ' OR ').' description LIKE "%$r%"';
Si vous activez les erreurs PHP, vous pourrez voir à quelle ligne ça bloque.
Il y a peut-être d'autres erreurs, je n'ai pas testé.
Et j'ai écrit directement dans la fenêtre du forum, ce qui n'est pas optimum du tout.
```text Les 2 méthodes ne sont pas plus sécurisées l'une que l'autre.
il faut regarder du côté de : mysql_real_escape_string et/ou filter_var
si vous passez sur mysqli (obligatoire à partir de php 7), ce sera mysqli_real_escape_string
Et sinon full text est bien ce qu'il faut prendre pour les requêtes match against
Et un petit tuto assez sympa là dessus : https://blog.axe-net.fr/recherche-pertinence-mysql-fulltext/
Je n'ai pas tout lu, mais ça a l'air plutôt clair.
Et même le suivant est encore mieux : https://blog.axe-net.fr/tuto-mysql-fulltext-in-boolean-mode/
(boolean, c'est ce que j'utilise dans mon exemple plus haut et qui marche très bien) ```
à tout hasard :
SELECT * FROM TABLE_X WHERE COLONNE_X LIKE '%Val_1%' AND COLONNE_X LIKE '%Val_2%' ORDER BY xxx asc LIMIT 0, 10
Merci à Pppplus et Gaston_Phone pour votre aide,
Malheureusement, cela ne marche toujours pas, les deux solutions. Avec Val de Gaston ou Where de Pppplus. Par contre grâce aux erreurs j'en sais un peu plus :
"Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead"
Donc si je comprend bien, les lignes de code que vous m'avez donné en plus, ne sont pas compatible Php 5.6.
La seule solution serait de passer au PHP 7 ? De toute façon tôt au tard je m'y serais attelé.
> les lignes de code que vous m'avez donné en plus, ne sont pas compatible Php 5.6.
pas vraiment, ton code est **_déjà déprécié_** en 5.6 (lui-même périmé depuis longtemps)
tu es donc averti que ça ne passera plus à l'avenir, notamment avec 7.x oui
php stable: 7.4
Effectivement tu as raison une fois de plus Kyodev, sur ma page avec mon moteur de recherche qui ne marche bien qu'avec un mot, j'ai aussi ce message d'erreur alors que le moteur marche.
Le problème vient donc surtout de mon code pour ce nouveau moteur deux mots qui n'est pas bon...
Je pense que je vais passer au PHP 7 dans la journée, enfin essayer, mais j'aurais bien voulu avoir un bon moteur avant, dommage !
le moteur "tourne" en php7, je te laisse conclure ;)
et vise haut si possible, chez Ovh, c'est php7.3 maxi, ça évitera d'y revenir à court terme
tout ce que j'ai indiqué marche en PHP 5.6.
Le deprecated ne veut pas dire que ça ne marche pas. Ca veut juste dire qu'il faut se mettre à jour.
Lorsque vous testez une requête mysql, faite un echo dessus. Parfois, on s'aperçoit qu'on a mal écrit qq chose (d'ailleurs peut-être mon script est-il inexact.
Exemple, au lieu de : $rs = mysql_query($strSQL);
Faites : echo $strSQL;
Déjà vous détecterez peut-être une incohérence.
Ensuite collez la requête dans phpmyadmin pour tester les résultats.
Le SELECT que je t'ai donné est extrait d'un script fonctionnant en PDO.
Cerise sur le gâteau, tu peux mettre plusieurs **AND COLONNE_X LIKE '%Val_x%'** dans le même SELECT et dans _n'importe quel ordre._
😊
EDIT : Testé sous " MySQL 5.1.46 " et " PHP 5.3.2 "
```text Merci encore pour votre aide, alors pour la solution de Gaston, j'ai essayé le PDO, j'ai réussi à me connecter, mais je crois que j'ai encore pas mal de changement à faire dans mon code, voilà mon code actuel :
error_reporting(E_ALL);
ini_set("display_errors", 1);
$servername = "xxxxxxxxxx.mysql.db";
$username = "xxxxxxxxx";
$password = "xxxxxxxxxxx";
try {
$conn = new PDO("mysql:host=$servername;dbname=xxxxxxxxxx", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
} catch(PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
mysql_select_db("xxxxxxxxxxx") or die(mysql_error());
// SQL query
$recherche = isset($_POST['recherche']) ? $_POST['recherche'] : '';
$strSQL = "SELECT * FROM xxxxxxxxxx WHERE nom LIKE '%Val_1%' AND description LIKE '%Val_2%' ORDER BY nom ASC LIMIT 0,100";
// Execute the query (the recordset $rs contains the result)
$rs = mysql_query($strSQL);
// Loop the recordset $rs
while($row = mysql_fetch_array($rs)) {
// Name of the person
$strName1 = $row['nom'];
$strName2 = $row['prix'];
$strImg = $row['img'];
// Create a link to person.php with the id-value in the URL
$strLink = "produit_recyclage.php?id=" . $row[produit_recyclage.php?id=" . $row[produit_recyclage.php?id=" . $row[
}
// Close the database connection
mysql_close();
?>
et les erreurs sont les suivantes :
Connected successfully
Deprecated: mysql_select_db(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in /xxxxxx.php on line 44
Warning: mysql_select_db(): Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2) in /xxxxxxxx.php on line 44
Warning: mysql_select_db(): A link to the server could not be established in /xxxxxxxx.php on line 44
Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2) ```
```text Et pour ne pas faire de jaloux ;-) j'ai aussi testé la solution de Pppplus "echo" pour identifier le problème.
Deprecated: mysql_connect(): The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead in /xxxxxxxxxxx.php on line 48
SELECT * FROM xxxxxxxxxx WHERE nom LIKE "%$r%" OR description LIKE "%$r%" ORDER BY nom limit 100
Notice: Undefined variable: rs in /xxxxxxxxxxx.php on line 64
Warning: mysql_fetch_array() expects parameter 1 to be resource, null given in /xxxxxxxxxxx.php on line 64
Je remet le code qui donne cette erreur :
error_reporting(E_ALL);
ini_set("display_errors", 1);
mysql_connect("xxxxxxx.db", "xxxxxxx", "xxxxxxxxxxx") or die (mysql_error ());
mysql_set_charset('utf8');
mysql_select_db("xxxxxxxxxx") or die(mysql_error());
// SQL query
$recherche = isset($_POST['recherche']) ? $_POST['recherche'] : '';
$rrr = explode(' ', $recherche);
$where1 = '';
$where2 = '';
foreach ($rrr as $r) {
$where1 .= ($where1 == '' ? '' : ' OR ').' nom LIKE "%$r%"';
$where2 .= ($where2 == '' ? '' : ' OR ').' description LIKE "%$r%"';
}
$strSQL = "SELECT * FROM xxxxxxxxxxx WHERE $where1 OR $where2 ORDER BY nom limit 100";
// Execute the query (the recordset $rs contains the result)
echo $strSQL;
// Loop the recordset $rs
while($row = mysql_fetch_array($rs)) {
// Name of the person
$strName1 = $row['nom'];
$strName2 = $row['prix'];
$strImg = $row['img'];
// Create a link to person.php with the id-value in the URL
$strLink = "produit_recyclage.php?id=" . $row[produit_recyclage.php?id=" . $row[produit_recyclage.php?id=" . $row[
}
// Close the database connection
mysql_close();
?> ```
Bonjour @OLIVIERM79
Je n'utilise pas " mysql_select_db(): ".
Après le **new PDO ...** je fais :
**$Query = "SELECT * FROM TABLE_X WHERE COLONNE_X LIKE '%Val_1%' AND COLONNE_X LIKE '%Val_2%' ORDER BY xxx asc LIMIT 0, 10";**
** $result_Query = $pdo->query($Query);**
je ne comprends pas bien pourquoi persister avec mysql, déprécié même en 5.6
utilise mysqli, en php5 (mais faut évoluer) ou 7.3, plus simple à migrer: https://www.php.net/manual/fr/function.mysqli-connect.php
Bonjour @OLIVIERM79
Pour t'aider à utiliser le mode PDO, je t'invite à regarder ma page de TEST de mode PDO :
**https://wordetweb.com/word-et-web/OVH-Tester-une-base-de-donnees-via-un-script-PDO-FR.htm OVH - Test de Base de Données via un script en langage PDO**
😁
encore du spam... le souci n'est pas sur la connexion
inutile d'aller voir un site à pub en word, pour migrer en mysqli...
on parle de web là ;)
```text Je sens que je me rapproche du but, mais j'ai toujours un message d'erreur :
error_reporting(E_ALL);
ini_set("display_errors", 1);
$servername = "xxxxxxxxxdb";
$username = "xxxxxxxxxxx";
$password = "xxxxxxxxxxxx";
try {
$conn = new PDO("mysql:host=$servername;dbname=xxxxxxxxxxxxx", $username, $password);
// set the PDO error mode to exception
$conn->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
echo "Connected successfully";
} catch(PDOException $e) {
echo "Connection failed: " . $e->getMessage();
}
$Query = "SELECT * FROMxxxxxxxxxxx WHERE nom LIKE '%Val_1%' AND description LIKE '%Val_2%' ORDER BY nom ASC LIMIT 0,100";
$result_Query = $pdo->query($Query);
while($row = mysql_fetch_array($result_Query)) {
// Name of the person
$strName1 = $row['nom'];
$strName2 = $row['prix'];
$strImg = $row['img'];
// Create a link to person.php with the id-value in the URL
$strLink = "produit_recyclage.php?id=" . $row[produit_recyclage.php?id=" . $row[produit_recyclage.php?id=" . $row[
}
// Close the database connection
mysql_close();
?>
et les messages sont :
Connected successfully
Notice: Undefined variable: pdo in /xxxxxxxxx.php on line 46
Fatal error: Call to a member function query() on null in /xxxxxxxxxxxx.php on line 46 ```
je pense que le problème est là
Effectivement, $pdo n'est pas initialisée.
Au début tu utilises $conn, puis ensuite $pdo.
Cela vient de là.
Sûrement des mélanges de recopie de code.
Et je pense, par anticipation, que la ligne "mysql_close();" indiquera un message d'erreur car l'ouverture de connexion est réalisée en PDO et la fermeture avec "mysql_close".
Peux tu me donner le code en entier s'il te plait ?
Ou le votre car j'ai une page qui s'affiche maintenant sans erreur, mais sans résultat..
Suite à des réponses désagréables, je ne continuerai plus que par MP
bonne initiative, les liens sans rapport piqueront moins les yeux, quant à PDO...
```text Merci à tous pour votre aide, je viens enfin de faire fonctionner un moteur de recherche qui fonctionne pas trop mal sur deux mots.
J'ai encore un ou deux petits détails à régler, par exemple est ce que quelqu'un sait comment faire pour que les requêtes avec un apostrophe marchent aussi, par exemple "d'eau" pour l'instant, il ne trouve pas de résultat. Aussi, je suppose que mon moteur n'est pas très sécurisé contre les attaques malveillantes, quelqu'un aurait quelques lignes de code qui sécurisent un peu ? Par exemple interdire certains caractères ? Je n'y connais vraiment rien en hacking...
Je partage avec vous le code pour ceux que ça intéressent :
$button = $_GET ['submit'];
$search = $_GET ['search'];
if(!$button)
echo "Entrez votre recherche.";
else
{
if(strlen($search)<=1)
echo "trop court";
else{
echo "Votre recherche $search
";
mysql_connect("xxxxxxxxxxxxxxxxxxxxxxx");
mysql_select_db("xxxxxxxxxxxxxx");
mysql_set_charset('utf8');
$search_exploded = explode (" ", $search);
foreach($search_exploded as $search_each)
{
$x++;
if($x==1)
$construct .="nom LIKE '%$search_each%'";
else
$construct .="AND nom LIKE '%$search_each%' AND description LIKE '%$search_each%' OR nom LIKE '%$search_each%' AND cat LIKE '%$search%'";
}
$construct ="SELECT * FROM xxxxxxxxxx WHERE $construct limit 150";
$run = mysql_query($construct);
$foundnum = mysql_num_rows($run);
if ($foundnum==0)
echo "Désolé, aucun résultat pour $search.";
else
{
echo "$foundnum résultats trouvés
";
while($runrows = mysql_fetch_assoc($run))
{
$title = $runrows ['nom'];
$prix = $runrows ['prix'];
$img = $runrows ['img'];
$strLink = "produit_recyclage.php?id=" . $runrows[produit_recyclage.php?id=" . $runrows[produit_recyclage.php?id=" . $runrows[
}
}
}
}
?> ```