У меня есть устаревший сценарий PHP, который создает список ресурсов из информации, хранящейся в базе данных MySQL. Пользователи могут выполнять поиск в списке или фильтровать по первой букве в заголовке (это сохраняется как столбец в базе данных). Вы можете увидеть это в действии здесь: http://lib.skidmore.edu/library/index.php/researchdatabases). Скрипт работает нормально, за исключением одного ресурса FT.com, который некорректно отображается при фильтрации пользователей по буквам. Независимо от того, какая буква выбрана, ее ввод будет либо вверху, либо внизу. Обратите внимание, что в режиме просмотра без фильтров FT.com находится в правильном алфавитном порядке. Моей первой мыслью было посмотреть на запись в базе данных, но все выглядит нормально.
Моя гипотеза заключается в том, что переменная устанавливается неправильно. Скрипт работает так, что его верхняя половина содержит веб-форму. Приведенный ниже PHP затем принимает ввод и присваивает его переменной $searchletter.
Затем комбинация циклов while и запросов mysqli извлекает и отображает результаты. Интересно, что когда строка $searchletter = !empty закомментирована, весь список исчезает для нефильтрованного представления Кроме для записи FT.com (см. Этот тестовый сценарий для примера: http://lib.skidmore.edu/library/search_dbs2.php). В противном случае я не вижу ничего ни в сценарии, ни в базе данных, что могло бы вызвать наблюдаемое поведение. Верно ли мое подозрение?
Вот код. Я включил все, кроме информации о подключении, чтобы вы могли увидеть, как все это работает.
$search=(isset($_GET['search']) ? $_GET['search'] : null);
$search = !empty($_GET['search']) ? $_GET['search'] : 'default';
$search= addslashes($search);
$searchletter=(isset($_GET['searchletter']) ? $_GET['searchletter'] : null);
$searchletter = !empty($_GET['searchletter']) ? $_GET['searchletter'] : 'default';
var_dump ($_GET['searchletter']);
$con=mysqli_connect(DB_HOST,WEBMISC_USER,WEBMISC_PASS,DB_NAME);
if (mysqli_connect_errno())
{
echo "Failed to connect to MySQL: " . mysqli_connect_error();
}
if ($search == "default" && $searchletter == "default"){
$result = mysqli_query($con,"SELECT title,summary,url,coverage,format FROM dbs");
//This while loop creates the inital A to Z list.
while($row = mysqli_fetch_array($result))
{
$url=$row['url'];
$title=$row['title'];
$summary=$row['summary'];
$coverage=$row['coverage'];
$format=$row['format'];
echo <<<HTML
<p><h6><a href = "$url">$title</a></h6>
<br />$summary</p>
HTML;
}
}
else {
$result = mysqli_query($con,"SELECT title,summary,url,coverage,format,fletter FROM dbs where title like '%$search%' or summary like '%$search%' or fletter = TRIM('$searchletter')");
//This block creates the filtered and searched version of the list.
while($row = mysqli_fetch_array($result))
{
$url=$row['url'];
$title=$row['title'];
$summary=$row['summary'];
$coverage=$row['coverage'];
$format=$row['format'];
echo <<<HTML
<p><h6><a href = "$url">$title</a></h6>
<br />$summary</p>
HTML;
}
mysqli_close($con);
Я пробовал использовать TRIM (fletter) в операторе SELECT и fletter = TRIM ('$ searchletter'), но это не помогло. fletter - это столбец базы данных, в котором хранится первая буква заголовка.






Первая серьезная проблема с этим сценарием заключается в том, что он, по-видимому, подвержен MySQL Injection, самой серьезной проблеме из всех. (но я могу ошибаться). Пожалуйста, подумайте о переключении этого кода на PDO и его подготовленные операторы и метод bindParam.
во-вторых, в ФОРМЕ вы либо поддерживаете поиск, либо букву (но не оба сразу) НО вы используете оба в запросе mysql. вы должны разделить результат, полученный из
$result = mysqli_query($con,"SELECT
title,summary,url,coverage,format,fletter
FROM dbs
where title like
'%$search%' or summary like '%$search%' or fletter = '$searchletter'");
в оператор if / else:
if (!empty($search)){
$result = mysqli_query($con,"SELECT
title,summary,url,coverage,format,fletter
FROM dbs
where title like
'%$search%' or summary like '%$search%'");
} elseif (!empty($searchletter)){
$result = mysqli_query($con,"SELECT
title,summary,url,coverage,format,fletter
FROM dbs
where fletter = '$searchletter'");
}
это не приведет к срабатыванию ОБОИХ случаев при поиске и даст более надежный результат на основе вашего выбора.
Обновлено: после того, как вы добавили больше кода, ясно, что каждое поле «не установлено пользователем» имеет значение «по умолчанию». что значит: какую бы букву вы ни выбрали, для «seachphrase» будет установлено значение «default», а «default» будет частью поля сводки FT.com (вы можете увидеть это слово в результатах поиска). Опять же: разделение запроса на два случая решит эту проблему, поэтому слово «по умолчанию» никогда не используется в поисковом запросе.
В сценарии есть нечто большее, чем то, что я опубликовал. Поиск обрабатывается другой переменной, запросом SQL и циклом while. Существует также отдельная форма для поиска, которая находится над раскрывающимся меню с буквой поиска. Поскольку этот бит работает нормально, я не публиковал его, так как он не имел отношения к вопросу. Этот сценарий является частью устаревшей системы, от которой мы со временем избавимся.
Тем не менее, пожалуйста, разделите поисковую рассылку и поисковый запрос mysql, и если это не поможет, опубликуйте, как вы определяете значение переменной $ search, чтобы мы могли получить лучшую картину.
и я прошу выполнить поиск, потому что, если поиск определяется так же, как поисковый бюллетень, он всегда будет получать значение «по умолчанию», которое существует в «резюме» статьи FT.com;)
Я включил все, кроме информации о подключении, в свой исходный пост.
Спасибо за вашу помощь. Это сработало. Я также добавил третий блок else для отображения исходного, нефильтрованного представления.
«штраф» может сбивать с толку. Посмотрите, сможете ли вы запустить функцию
trimдля результата перед его сортировкой. он удалит пробелы из имени. У меня слишком много раз, когда клиент копировал что-то из файла excel;) Кроме того, это можно очистить в mysql с помощью TRIM, см .: stackoverflow.com/questions/1504962/… для примера