Я пытаюсь кодировать функции поиска для сайта и зацикливаться на подобном сравнении в инструкции sql. Почему-то, когда я использую? и pindparam переменная, содержащая строку подобных сравнений, она продолжает возвращаться без каких-либо результатов. Если я удалю? и просто введите сравнение post_title LIKE '%something%'
это работает.
вот мой код:
// Retrieve search results function retrieve_search_posts($searchfield){ //test the connection try{ //connect to the database $dbh = new PDO("mysql:host=localhost;dbname=mjbox","root", "usbw"); //if there is an error catch it here } catch( PDOException $e ) { //display the error echo $e->getMessage(); } $searcharray = array(); $where = ""; $searchfield = preg_split('/[\s]+/',$searchfield); $total_words = count($searchfield); foreach($searchfield AS $key=>$searchword){ $where .= "post_title LIKE '%".$searchword."%'"; if($key != ($total_words - 1)){ $where .= " OR "; echo $searchword . '<br>'; } } echo $where; $stmt = $dbh->prepare("SELECT p.post_id, post_year, post_desc, post_title, post_date, img_file_name, p.cat_id FROM mjbox_posts p JOIN mjbox_images i ON i.post_id = p.post_id AND i.cat_id = p.cat_id AND i.img_is_thumb = 1 AND post_active = 1 WHERE ? ORDER BY post_date DESC LIMIT 9"); $stmt->bindParam(1,$where); $stmt->execute(); while($row = $stmt->fetch(PDO::FETCH_ASSOC)) { $searcharray[] = $row; } return $searcharray; } // Check for errors in search field function search_errors($searchfield){ $searcherrors = array(); if(empty($searchfield)){ $searcherrors[] = '<p>Please enter a search term.</p>'; }else if(strlen($searchfield)<3){ $searcherrors[] = '<p>Your search term must be three characters or more.</p>'; }else if(retrieve_search_posts($searchfield) == false){ $searcherrors[] = '<p>Your search for '.$searchfield.' returned no results.</p>'; } return $searcherrors; }
search.php
// Get the search terms posted $searchfield = trim($_POST['searchfield']); // Check if there are any errors with the search terms $searcherrors = search_errors($searchfield); // If there are errors if(!empty($searcherrors)){ // Display them here foreach($searcherrors AS $value){ echo $value .'<br />'; } } $searcharray = retrieve_search_posts($searchfield); echo '<div id="content-wrap">'; foreach($searcharray AS $value){ $filename = substr($value['img_file_name'],9); $cat_id = $value['cat_id']; echo '<article class="post">'; echo '<div class="post_title">' . $value['post_title'] . '</div>'; echo '<div class="post_info">' . 'Category: ' . $cat_name = get_cat_name($cat_id) .'<br />'. 'Year: ' . $value['post_year'] .'<br />'. $value['post_desc'] .'<br />'. '</div>'; echo '<div class="link-to-post"><a href="#">Click to view</a></div>'; echo '<a name="'.$value['post_id'].'"></a><a href="#'.$value['post_id'].'" class="linktopost"><img class="post-thumb" src="img/thumb_/'.$filename.'" alt="MJbox Michael Jackson memorabilia thumbnail" data-postid="'.$value['post_id'].'"/></a>'; echo '<a name="'.$value['post_id'].'"></a><a href="#'.$value['post_id'].'" class="linktopost"><img class="cover-img" src="img/post-bg-1.png" alt="test" data-postid="'.$value['post_id'].'"/></a>'; echo '</article>'; } echo '</div>';
Определенная запись в базе данных mysql содержит слова (я), которые я помещаю в строку where. Заявление работает как в запросе mysql, так и на моем веб-сайте, когда я просто набираю аналогичное сравнение вместо использования ?
,
Вам нужно связать каждый параметр отдельно, вы можете сделать это со вторым циклом.
function retrieve_search_posts(PDO $pdo, $search_field) { /* * Get the PDO object as an argument, this function shouldn't care * how the PDO object is created, that's the factory's job. */ /* * Use $underscored_names or $camelCase for variable names, easier on the eye */ ## Variable initializations ## $where = array(); ##Function start $words = preg_split("/\s+/", $search_field); for ($i = 0; $i < count($words); $i++) { /* * We don't need to have the word in here, * so we aren't even using the foreach loop, just a normal for */ $where[] .= "`post_title` LIKE ?"; } /* * For cleaner code, use an array and implode the pieces with OR, * this way, you don't get an OR at the beginning, nor the end. */ $where_string = implode(" OR ", $where); $query = <<<MySQL SELECT p.post_id, post_year, post_desc, post_title, post_date, img_file_name, p.cat_id FROM mjbox_posts p JOIN mjbox_images i ON i.post_id = p.post_id AND i.cat_id = p.cat_id AND i.img_is_thumb = 1 AND post_active = 1 WHERE ? ORDER BY post_date DESC LIMIT 9 MySQL; $sth = $pdo->prepare($query); /* * Iterate over the array again, * this time, we're binding the values based on the index */ foreach ($words as $index => $word) { $sth->bindValue($index+1, $word, PDO::PARAM_STR); } $sth->execute(); $result = $sth->fetchAll(PDO::FETCH_ASSOC); //Fetch all the results in associative array form return $result; }
См. Комментарии к коду, чтобы объяснить сделанные изменения.
Вы не можете связывать поля и значения вместе, PDO будет обертывать его в цитату, поскольку она предполагает ?
– значение для запроса:
'post_title LIKE \'%something%\''
Вы можете оставить поле столбца, а затем привязать параметр:
post_title LIKE ?
Затем проверьте, установлено ли поле поиска. Привяжите параметр, используя '%'.$where.'%'
Или если ничего не введено, тогда просто '%'