Erreur PHP fetch

a marqué ce sujet comme résolu.
Auteur du sujet

Bonjour,

Après avoir consulté la FAQ du site internet et tenté à maintes reprises de résoudre l’erreur PHP, je n’y parviens pas. J’ai pu lire que l’erreur fetch était souvent du à une mauvaise orthographe des noms des colonnes de la BDD. J’ai vérifié le nom des colonnes de ma base SQL et celles-ci sont bien orthographiées dans mon code.

Pouvez-vous svp m’éclairer à ce sujet ? Mon erreur est la suivante :

Fatal error: Uncaught Error: Call to a member function fetch() on null in /htdocs/sortiesdumetro.fr/search.php:44 Stack trace: #0 {main} thrown in /htdocs/sortiesdumetro.fr/search.php on line 44

Et voici mon code :

<form class="search" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
    <label for="query"></label>
    <input type="text" name="query" placeholder="Rechercher une station..." id="query" />
      <button type="submit"><i class="fa fa-search"></i></button>
</form>
                                            
<?php echo $resultats; ?>
                                        
<?php  

// Traitement de la requête
if(isset($_POST['query']) && !empty($_POST['query'])) {
                                            
$query = iconv("UTF-8", "ASCII//TRANSLIT", $_POST['query']);
$query = str_replace("-", " ", "$query");
$query = str_replace("'", " ", "$query");
$query = trim($query);
                                            
$sql = "SELECT id, page_content, page_title AS title FROM pages WHERE page_title LIKE ? OR page_content LIKE ?";
                                                                                                                                    
// Connexion à la base de données
try {
$db = new PDO('mysql:host=xxx;dbname=xxx', 'xxx', 'xxx');
} 
catch(PDOException $e) {
die('Erreur : '.$e->getMessage()); 
}

$req = $db->prepare($sql);
$req->execute(array('%'.$query.'%', '%'.$query.'%'));

$count = $req->rowCount();
                                            
} 
if($count == "0"){
    echo "Aucun résultat ne correspond à votre recherche pour <b>$query</b><hr/>";
}   
if($count == "1"){
    echo "$count résultat trouvé pour <b>$query</b><hr/>";
}
if($count > "1"){
    echo "$count résultats trouvés pour <b>$query</b><hr/>";
}
    while($data = $req->fetch(PDO::FETCH_OBJ))
    {
    echo '<h3><a href="https://www.sortiesdumetro.fr/'.$data->page_content.'"></li>'.$data->title.'</a></h3><br/>';
                                                    
    }
?>

Merci beaucoup pour le temps que vous passerez à m’aider !

Édité par Billy

+0 -0

Cette réponse a aidé l’auteur du sujet

Salut !

Le souci survient quand $_POST['query'] est vide : $req n’est pas défini (on ne passe pas dans les lignes 12 à 34), seulement tu l’utilises de toute manière à la ligne 44…

Quelques points qui me chagrinent, si tu permets :

  • tu vérifies si $count == "0", pourquoi ne pas mettre directement des entiers plutôt que des chaînes ?
    Note que tu pourrais même mettre des else aux lignes 38 et 41 ;
  • tu testes avec à la fois isset() et !empty(), tu peux ne conserver que le dernier. Ça fait les mêmes vérifications que le premier, et d’autres en plus ;
  • tu "sécurises" le nom de station cherchée avec un naïf str_replace(). Il serait plus sage d’utiliser la méthode PDO::quote, qui est justement prévue pour ton cas, et du coup tu peux te passer de la requête préparée et faire "à l’ancienne". Le cas du LIKE permet de faire ainsi ;
  • tu supprimes les accents pour la recherche. Si les colonnes de ta base de données sont dans des interclassements se terminant par _ci, les diacritiques et la casse ne seront pas pris en compte sans que tu aies à faire la transformation ;
  • je pourrais supposer que tu enlèves les accents parce que "ça ne fonctionne pas", essaie de bien définir le jeu de caractères à la connexion à ta base de données — la FAQ PHP t’en diras plus à ce propos.

P.S. : pour les titres de sujets, préfère mettre une partie de l’erreur quand tu en as une  ;)

Édité par Ymox

Evitez qu’on vous dise de les lire : FAQ PHP et SymfonyTutoriel WAMP • Cliquez 👍 pour dire merci • Marquez vos sujets résolus

+1 -0
Auteur du sujet

Merci d’avoir pris le temps de m’aider :)

Lorsque j’enleve isset() et que je déplace $_POST['query'] de la ligne 12 à 33, le module de recherche m’affiche automatiquement les 340 résultats de la colonne de la BDD… Est-il possible d’éviter cela, et de lancer une requête uniquement lorsque l’internaute clique sur le bouton rechercher (ou appuie sur Entrée) ?

Merci encore !

+0 -0

Salut,

Je ne suis pas vraiment sûr de ce que tu veux mais je suppose que t’utilises un champ de formulaire pour la recherche ?

Après, petite remarque: le triple if à la fin, autant utiliser un switch, cela fera + propre. ;)

+0 -0

Il ne faut pas « déplacer $_POST['query'] de la ligne 12 à 33 » (ce qui ne me semble pas avoir beaucoup d’intérêt), mais plutôt déplacer les lignes 35 et suivantes avant la 34, histoire que tu affiches des résultats seulement si tu en as cherché.
Et si tu souhaites de toute manière afficher quelque chose, il faut dans ce cas imaginer deux requêtes, ou une base qui est de toute manière effectuée et à laquelle tu ajoutes le critère si nécessaire.

Evitez qu’on vous dise de les lire : FAQ PHP et SymfonyTutoriel WAMP • Cliquez 👍 pour dire merci • Marquez vos sujets résolus

+0 -0
Auteur du sujet

Bonjour et merci pour tous vos retours.

J’ai tenté de modifier les chaines par les entiers et j’ai la requête qui s’exécute automatiquement en affichant "Aucun résultat ne correspond à votre recherche pour …", tandis qu’avec la chaine il n’y a rien d’affiché tant que la recherche n’est pas lancée. Cela se rapproche davantage de ce que je souhaite.

Lorsque je retire isset() pour ne conserver que !empty(), je n’ai plus aucun résultat trouvé :(

Idem en déplaçant les lignes 34 à 48 à la ligne 20, les résultats ne s’affichent plus :(

Si cela peut vous aider à comprendre mon souci, la page où se trouve le formulaire de recherche est ici

Édité par Billy

+0 -0

Remontre-nous ton code actuel complet, s’il te plaît. Tu dois avoir un peu mélangé les choses : supprimer le test isset() et ne garder que !empty() tout comme avoir des entiers au lieu de chaînes ne doit rien changer au niveau du comportement. Sauf si tu as fait d’autres modifications — comme déplacer des lignes autres que 35 et suivantes ailleurs qu’avant la 34, tu parles des 34 à 48 avant la 20 — ou que par chance avant ces modifications ça fonctionnait comme tu le souhaitais à cause de cas particuliers.

Édité par Ymox

Evitez qu’on vous dise de les lire : FAQ PHP et SymfonyTutoriel WAMP • Cliquez 👍 pour dire merci • Marquez vos sujets résolus

+0 -0
Auteur du sujet

Bonjour,

Merci pour ton retour Ymox. Voici mon code actuel :

                                            
<form class="search" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
<label for="query"></label>
<input type="text" name="query" placeholder="Rechercher une station..." id="query" />
<button type="submit"><i class="fa fa-search"></i></button>
</form>
                                            
<?php echo $resultats; ?>
                                        
<?php  
// Traitement de la requête
if(!empty($_POST['query'])) {


$req = $db->prepare($sql);
$req->execute(array('%'.$query.'%', '%'.$query.'%'));

$count = $req->rowCount();

} 
    if($count == 0){
    echo "Aucun résultat ne correspond à votre recherche pour <b>$query</b><hr/>";
}   
    if($count == 1){
    echo "$count résultat trouvé pour <b>$query</b><hr/>";
}
    if($count > 1){ 
    echo "$count résultats trouvés pour <b>$query</b><hr/>";
}
        while($data = $req->fetch(PDO::FETCH_OBJ))
        {
        echo '<h3><a href="https://www.sortiesdumetro.fr/'.$data->page_content.'"></li>'.$data->title.'</a></h3><br/>';                         
        }

                                            
    $query = iconv("UTF-8", "ASCII//TRANSLIT", $_POST['query']);
    $query = str_replace("-", " ", "$query");
    $query = str_replace("'", " ", "$query");
    $query = trim($query);
                                            
    $sql = "SELECT id, page_content, page_title AS title FROM pages WHERE page_title LIKE ? OR page_content LIKE ?";
                                                                                                                                    
    // Connexion à la base de données
    try {
    $db = new PDO('mysql:host=xxx;dbname=xxx', 'xxx', 'xxx');
    } 
        catch(PDOException $e) {
        die('Erreur : '.$e->getMessage()); 
        }
?>

Avec ce code, la fonction de recherche ne fonctionne plus. De plus, la requête est lancée automatiquement car sous la barre de recherche s’affiche

Aucun résultat ne correspond à votre recherche pour xxx

Et j’ai hélas, toujours l’erreur fetch() :(

Fatal error: Uncaught Error: Call to a member function prepare() on null in /htdocs/sortiesdumetro.fr/search.php:30 Stack trace: #0 {main} thrown in /htdocs/sortiesdumetro.fr/search.php on line 30

+0 -0

$db, $query et $sql (lignes 15 et 16) n’existent pas.

Tu dois reprendre ton code, tu cherches à utiliser des variables que tu ne crées que plus tard. Ca devrait être l’inverse …

Édité par vibrice

+1 -0

Non, la requête n’est pas lancée automatiquement, vu que $db n’existe pas au moment ou tu l’utilises, donc impossible de préparer la requête. C’est d’ailleurs l’erreur que tu mentionnes — qui n’est en l’occurrence plus une erreur de fetch(), si tu regardes bien.

Je ne peux pour le coup que répéter ce qui t’a été dit dans le message précédent : reprend ton code, quitte à reprendre celui avec lequel tu as ouvert le sujet, et reprend les messages. Je t’ai dit exactement quelles lignes il fallait mettre avant quelle autre dans ma seconde réponse, adapte déjà ça pour que ça fonctionne comme tu l’attends, et à ce moment-là tu pourras réfléchir aux cinq points que j’ai listés.
Aucun ne doit changer le comportement de ton programme. Les deux premiers sont des questions de lisibilité et de logique d’écriture du code, le troisième est une question de sécurité, et les deux derniers sont eux pour éviter un traitement inutile, donc gagner en performances.

Evitez qu’on vous dise de les lire : FAQ PHP et SymfonyTutoriel WAMP • Cliquez 👍 pour dire merci • Marquez vos sujets résolus

+0 -0
Vous devez être connecté pour pouvoir poster un message.
Connexion

Pas encore inscrit ?

Créez un compte en une minute pour profiter pleinement de toutes les fonctionnalités de Zeste de Savoir. Ici, tout est gratuit et sans publicité.
Créer un compte