1

Тема: Пошук на PHP+MySQL

Дороблюю сайт.Залишилося пару дрібничок.В тому числі і пошук.

<?php 
include("blocks/bd.php"); /*З'єднання з БД*/
if (isset($_GET['query'])) { $query = $_GET['query']; }

$query = trim($query);
$query = mysql_real_escape_string($query);
$query = htmlspecialchars($query);

if (empty($query)) {
    $result = mysql_query("SELECT id, title FROM articles WHERE title, text, meta_d, meta_k) AGAINST ('$query')", $db) || die(mysql_error());
    $myrow = mysql_fetch_array($result);
    $num = mysql_num_rows($result);
    if ($num > 0) {
        do {
            printf("<p><a href='view_article.php?id=%s'>%s</a></p>", $myrow["id"], $myrow["title"]);
            } while ($myrow = mysql_fetch_array($result));
    } else { echo "<p>За вашим пошуковим запитом нічого не знайдено</p>"; }

} else {
    echo "<p>Заданий порожній пошуковий запит</p>";
}
 ?>

Куча помилок. Поки копіював сюди код ще раз перевірив, вирішив сам розібратись, дещо підправив - так помилок ще більше стало. Підкажіть будь ласка в чому проблема і чи доцільно використовувати такий пошук на простому сайті?

Подякували: 221VOLT1

2 Востаннє редагувалося leofun01 (26.12.2015 18:31:59)

Re: Пошук на PHP+MySQL

misha_bondar_2012 написав:
if (isset($_GET['query'])) { $query = $_GET['query']; }

Може краще почати з

$method = $_SERVER["REQUEST_METHOD"];
$request = $method == "POST" ? $_POST : $_GET;
$query = isset($request) ? $request["query"] : null;

ну і так дальше...
А ще скажіть, що там робить закриваюча дужка у запиті

misha_bondar_2012 написав:
SELECT id, title FROM articles WHERE title, text, meta_d, meta_k) AGAINST ('$query')

?

Подякували: Monolith1

3

Re: Пошук на PHP+MySQL

Таблиця MyISAM?
FULLTEXT index зроблений для поля по якому шукаєте?
Синтаксис має виглядати так:

WHERE MATCH (title, text, meta_d, meta_k) AGAINST ('some words')

Зауважте, що індекс має бути для усіх полів.

Подякували: 221VOLT, Monolith, leofun013

4 Востаннє редагувалося 221VOLT (26.12.2015 22:55:07)

Re: Пошук на PHP+MySQL

Варіанти:

1) причепити гугл-пошук по сайту (гугл користувацький пошук) (або не гугла а іншого пошуковика)
2) зробити пошук з mysql через "LIKE"
3) зробити як ви розпочали - через "AGAINST"
4) http://sphinxsearch.com/ (але це точно не для маленького сайту - буде "з танка по горобцям")
... ще якісь, які зараз на думку не приходять


на мою думку, пошук по невеличкому сайту буде доцільніше зробити через гугл-пошук або з "LIKE"
(стосовно останнього я не зовсім упевнений що при великих об'ємах LIKE краще за AGAINST, можливо скоріше навпаки,, проте для AGAINST потрібні додаткові спеціальні індекси, що збільшує розмір бд,, LIKE виглядає меньш громіздким\більш гнучким )

можу порадити вам почитати документацію (тиць1, тиць2, тиць3, тиць4, тиць5) та статті, подумати над алгоритмами пошуку, попробувати окремі маленькі приклади для початку

окрім того поки ви не впевнені у правильності написаних запитів до mysql - краще їх відразу попробувати у phpmyadmin \ mysql-client -- відразу побачите результат вибірки чи повідомлення про помилку, так буде легше, уже ці помилки будуть окремо від помилок чисто php-коду

(якщо вас цікавлять it-чати хабрахабра у Skype, де також можуть підказати відповіді на різні запитання - дивіться тут)


Sensetivity написав:

Таблиця MyISAM?
FULLTEXT index зроблений для поля по якому шукаєте?
Синтаксис має виглядати так:

WHERE MATCH (title, text, meta_d, meta_k) AGAINST ('some words')

Зауважте, що індекс має бути для усіх полів.

вірно про індекс,
а от MyISAM - якщо не помиляюся - уже певний час (півтора року? два з половиною? більше?) вважається застарілим,
по-замовчуванню mysql використовує InnoDB

Подякували: Monolith, leofun012

5

Re: Пошук на PHP+MySQL

<?php 
include("blocks/bd.php"); /*З'єднання з БД*/
if (isset($_GET['query'])AND($_GET['query']!='')) {
$query = trim($_GET['query']);
$query = mysql_real_escape_string($query);
$query = htmlspecialchars($query);
}

if (!empty($query)) {
    $result = mysql_query("SELECT `id`, `title` FROM `articles` WHERE MATCH (`title`, `text`, `meta_d`, `meta_k`) AGAINST ('".$query."')", $db) OR die(mysql_error());
    
if(mysql_num_rows($result)>0){
while(mysql_fetch_array($result)){
printf("<p><a href='view_article.php?id=%s'>%s</a></p>", $myrow["id"], $myrow["title"]);
}
}else{
echo "<p>За вашим пошуковим запитом нічого не знайдено</p>";
}
} else {
    echo "<p>Заданий порожній пошуковий запит</p>";
}
 ?>

так меньше помилок?
гарантувати їх відсутність не можу - не перевіряв, на супергеніальність також не претендую))

з огляду на те, що mysql у php - "deprecated" - пропоную вам розглянути та "взяти на озброєння" mysqli (приклади, з яких я розпочав своє знайомство з mysqli)
ще можу вам запропонувати спрощення коду -- ви можете винести всі функції для роботи з бд у окремий файл, і його інклудити де потрібно після файлу підключення до бд

для прикладу щось таке -

function dbgetOne($sql){
    global $db;
    $out=Array();
    $res = mysqli_query($db, $sql);
    dberr($res);
    $out = mysqli_fetch_assoc($res);
    return $out;
}
function dbgetAll($sql){
    global $db;
    $out=Array();
    $res = mysqli_query($db, $sql);
    dberr($res);
    while($row = mysqli_fetch_assoc($res)){
        $out[]=$row;
    }
    return $out;
}
/*......*/
function getAllSort($sort, $up, $count){
    global $dbOptions;
    if (!checkSortUp($sort, $up)) return getAllData($count);
    $l = getL($count, 0);
    $desc = "";
    if (!$up){$desc = "DESC";}else{$desc="ASC";}
    $rez = dbgetAll("SELECT * FROM `".$dbOptions['db_prefix'].$dbOptions['db_t3']."` ORDER BY `".$sort."` ".$desc." ,`date` DESC ".$l);
    $rez = transform($rez);
    return $rez;
}
Подякували: Monolith1

6

Re: Пошук на PHP+MySQL

221VOLT написав:
<?php 
include("blocks/bd.php"); /*З'єднання з БД*/
if (isset($_GET['query'])AND($_GET['query']!='')) {
$query = trim($_GET['query']);
$query = mysql_real_escape_string($query);
$query = htmlspecialchars($query);
}

if (!empty($query)) {
    $result = mysql_query("SELECT `id`, `title` FROM `articles` WHERE MATCH (`title`, `text`, `meta_d`, `meta_k`) AGAINST ('".$query."')", $db) OR die(mysql_error());
    
if(mysql_num_rows($result)>0){
while(mysql_fetch_array($result)){
printf("<p><a href='view_article.php?id=%s'>%s</a></p>", $myrow["id"], $myrow["title"]);
}
}else{
echo "<p>За вашим пошуковим запитом нічого не знайдено</p>";
}
} else {
    echo "<p>Заданий порожній пошуковий запит</p>";
}
 ?>

так меньше помилок?
гарантувати їх відсутність не можу - не перевіряв, на супергеніальність також не претендую))

з огляду на те, що mysql у php - "deprecated" - пропоную вам розглянути та "взяти на озброєння" mysqli (приклади, з яких я розпочав своє знайомство з mysqli)
ще можу вам запропонувати спрощення коду -- ви можете винести всі функції для роботи з бд у окремий файл, і його інклудити де потрібно після файлу підключення до бд

для прикладу щось таке -

function dbgetOne($sql){
    global $db;
    $out=Array();
    $res = mysqli_query($db, $sql);
    dberr($res);
    $out = mysqli_fetch_assoc($res);
    return $out;
}
function dbgetAll($sql){
    global $db;
    $out=Array();
    $res = mysqli_query($db, $sql);
    dberr($res);
    while($row = mysqli_fetch_assoc($res)){
        $out[]=$row;
    }
    return $out;
}
/*......*/
function getAllSort($sort, $up, $count){
    global $dbOptions;
    if (!checkSortUp($sort, $up)) return getAllData($count);
    $l = getL($count, 0);
    $desc = "";
    if (!$up){$desc = "DESC";}else{$desc="ASC";}
    $rez = dbgetAll("SELECT * FROM `".$dbOptions['db_prefix'].$dbOptions['db_t3']."` ORDER BY `".$sort."` ".$desc." ,`date` DESC ".$l);
    $rez = transform($rez);
    return $rez;
}

Не використовуйте глобальні змінні global, передавайте об'єкт з'єднання з бд в аргумент функції.

Подякували: Monolith, 221VOLT, leofun013

7

Re: Пошук на PHP+MySQL

У вас маса помилок і застарілий код..
Наведу вам приклад простого пошуку на об'єктно орієнотованому mysql(i) з використанням підготовчих виразів та іменованих параметрів для уникнення SQL ін'єкцій і filter_var для уникнення XSS.

$db = new mysqli('localhost', 'login', 'password', 'database');
if($db->connect_errno) exit('Помилка підключення: '.$db->connect_error);

if(isset($_GET['search']) && !empty($_GET['search'])) {

$searchText = '%'.$_GET['search'].'%';

$search = $db->prepare("SELECT * FROM users WHERE name LIKE ? OR last_name LIKE ?");
$search->bind_param('ss', $searchText, $searchText);  
$search->execute(); 
$result = $search->get_result();
if($result->num_rows > 0) {
echo 'Результати пошуку: <br/>';
while($out = $result->fetch_object()) {
$login = filter_var($out->login, FILTER_SANITIZE_FULL_SPECIAL_CHARS);
echo $login.'<br/>';
}
}
else {
  echo 'Нічого не знайдено.';
}

}
else {
echo '<form method="GET">
      <input type="text" name="search">
      <input type="submit" value="Пошук">
      </form>';
}
Подякували: Monolith, 221VOLT, leofun013

8 Востаннє редагувалося Monolith (27.12.2015 12:37:10)

Re: Пошук на PHP+MySQL

Величезне спасибі за допомогу. Так як це мій перший сайт і хочеться якомога скоріше доробити його, то вирішив зробити простий пошук с оператором LIKE. Бо відчуваю якщо почну розбиратися детальніше сайт - ніколи не закінчу. :) Краще викладу сайт і буду "допилювати"...

Подякували: 221VOLT1

9

Re: Пошук на PHP+MySQL

Є такий запит:

SELECT id, title FROM articles WHERE title LIKE '%" . $query . "%' OR meta_d LIKE '%" . $query . "%' ORDER BY id DESC

Помилок ніби немає.Все працює, але у результаті виводяться всі записи з БД.

10 Востаннє редагувалося VTrim (27.12.2015 12:57:13)

Re: Пошук на PHP+MySQL

перед самим запитом зробіть

var_dump($query);

І подивіться чи не пуста змінна.
Ну і скажіть,що ви вводите,можливо букву 'а',яка є у всіх рядках (або щось типу того) :), тим більше,що використовується OR і пошук по декількох полях.

Подякували: Monolith, 221VOLT, leofun013

11

Re: Пошук на PHP+MySQL

VTrim написав:

перед самим запитом зробіть

var_dump($query);

І подивіться чи не пуста змінна.
Ну і скажіть,що ви вводите,можливо букву 'а',яка є у всіх рядках (або щось типу того) :), тим більше,що використовується OR і пошук по декількох полях.

Результат:

Прихований текст

string(0) ""

Наскільки я зрозумів змінна пуста.

12

Re: Пошук на PHP+MySQL

misha_bondar_2012 написав:
VTrim написав:

перед самим запитом зробіть

var_dump($query);

І подивіться чи не пуста змінна.
Ну і скажіть,що ви вводите,можливо букву 'а',яка є у всіх рядках (або щось типу того) :), тим більше,що використовується OR і пошук по декількох полях.

Результат:

Прихований текст

string(0) ""

Наскільки я зрозумів змінна пуста.

Так,тому і виводить всі.

Подякували: Monolith1

13

Re: Пошук на PHP+MySQL

Буду розбиратися чого пуста тоді...Дякую.

14 Востаннє редагувалося Monolith (27.12.2015 14:52:25)

Re: Пошук на PHP+MySQL

Наскільки зрозумів вся проблема тут:

$query = trim($query);
$query = mysql_real_escape_string($query);
$query = htmlspecialchars($query);

Але, в чому саме?
Хочу якщо ці рядки прибрати значення змінної стає NULL.

15

Re: Пошук на PHP+MySQL

Знайшов помилку: неправильно написав змінну(аж смішно).Все-рівно є помилки, але вже легше.

16

Re: Пошук на PHP+MySQL

По коду з першого вашого поста.
if (empty($query)) {
//ваш код і запит
}

Тобто виконуєте запит при умові,що $query пуста :)

Подякували: Monolith, 221VOLT2

17

Re: Пошук на PHP+MySQL

VTrim написав:

По коду з першого вашого поста.
if (empty($query)) {
//ваш код і запит
}

Тобто виконуєте запит при умові,що $query пуста :)

Оце так вчитися по відео на ю тубі...
Дякую. :)

Подякували: 221VOLT1

18

Re: Пошук на PHP+MySQL

Фууууух. Працює! :D

19

Re: Пошук на PHP+MySQL

Не дивіться, питайте тут)

Подякували: Monolith, 221VOLT2

20

Re: Пошук на PHP+MySQL

VTrim написав:

Не використовуйте глобальні змінні global, передавайте об'єкт з'єднання з бд в аргумент функції.

можете написати коротеньке пояснення - чому? якщо можете - з невеличким прикладом)

тому що працює повільніше?
тому що є можливість підставили ліві дані?