Skip to content

Instantly share code, notes, and snippets.

@hijarian
Last active December 15, 2015 04:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save hijarian/5202648 to your computer and use it in GitHub Desktop.
Save hijarian/5202648 to your computer and use it in GitHub Desktop.
Решение "маленькой" глупой задачки по PHP, где преподаватель на самом деле не понимает, насколько сложную задачу даёт студентам и сколько различных областей знания в ней используются.
<?php
/**
* Форма поиска по заданной таблице в MySQL базе данных.
* Используйте этот скрипт как веб-страницу.
*
* Ожидается таблица следующего вида:
*
* create table `<TABLENAME>` (
* id int primary key auto_increment,
* name varchar(255), index (name),
* value varchar(255)
* ) DEFAULT CHARSET=utf8 ENGINE=InnoDB;
*
* Пример заполнения таблицы:
*
* INSERT INTO `hash` (`id`, `name`, `value`) VALUES
* (1, 'letters', 'abcdefghi'),
* (2, 'numbers', '123456'),
* (3, 'kanji', '漢字'),
* (4, 'hiragana', 'ひらがな'),
* (5, 'katakana', 'カタカナ'),
* (6, 'devanagari', 'देवनागरी');
*
* Форма поиска ищет записи в таблице,
* имеющие частичные совпадения по полю `name`.
*/
define('MYSQL_HOSTNAME', 'localhost');
define('MYSQL_USERNAME', 'root');
define('MYSQL_PASSWORD', 'mysqlroot');
define('MYSQL_DB', 'my');
define('MYSQL_TABLE', 'hash');
// Старый интерфейс `mysql` использовать больше НЕЛЬЗЯ,
// он устарел и будет удалён из версий PHP > 5.5
// Используем процедурный стиль вызова,
// возможно, мы ещё не умеем работать с объектами.
$connection = mysqli_connect(
MYSQL_HOSTNAME,
MYSQL_USERNAME,
MYSQL_PASSWORD,
MYSQL_DB
);
// ВСЕГДА делайте проверки на успешность выполнения операций I/O.
if (mysqli_connect_errno($connection))
{
die(
sprintf(
'Не могу соединиться! (%s) %s',
mysqli_connect_errno($connection),
mysqli_connect_error()
)
);
}
// Мы в 2013 году, ВСЕГДА ставьте UTF-8 в качестве кодировки соединения.
mysqli_set_charset($connection, 'utf8');
// Начинаем получать данные. Это должно быть выделено в отдельный модуль.
// Общая часть запроса
$query_sql = 'select * from '.MYSQL_TABLE;
// Используем $_REQUEST, потому что он содержит как $_GET, так и $_POST.
if (isset($_REQUEST['search_term']) && $_REQUEST['search_term'])
{
// Если форма передала нам название, то фильтруем.
$filter_value = $_REQUEST['search_term'];
// Обязательная подготовка SQL запроса для того, чтобы предотвратить SQL инъекции.
$query = mysqli_prepare($connection, $query_sql.' where name like concat("%", ?, "%")');
// Для bind_param нужна переменная, а не значение,
// поэтому нельзя просто передать $_REQUEST['search_term']
mysqli_stmt_bind_param($query, 's', $filter_value);
// В тру-продакшен коде здесь должна быть проверка на успех выполнения
mysqli_stmt_execute($query);
// Дебильный интерфейс Mysqli не имеет аналога mysqli_fetch_assoc для подготовленных запросов,
// поэтому приходится делать такое извращение.
mysqli_stmt_bind_result($query, $row_id, $row_name, $row_value);
$result = array();
while (mysqli_stmt_fetch($query))
{
$result[] = array('id' => $row_id, 'name' => $row_name, 'value' => $row_value);
}
mysqli_stmt_close($query);
}
else
{
// Всё равно установим переменную $filter_value,
// чтобы вставить пустое значение в поле ввода на форме.
$filter_value = '';
$raw_result = mysqli_query($connection, $query_sql);
$result = array();
while ($row_data = mysqli_fetch_assoc($raw_result))
{
array_push($result, $row_data);
}
}
mysqli_close($connection);
// Теперь у нас $result это массив массивов вида array('id' => ID, 'name' => NAME, 'value' => VALUE)
// Можно реконструировать таблицу, итерируя по элементам этого массива.
// Метод у формы - GET, потому что так поисковые запросы могут быть сохранены в виде прямого URL.
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>Поиск в базе данных MySQL</title>
</head>
<body>
<form method="get" action="">
<label for="search-term-input">Часть названия элемента:</label>
<input id="search-term-input" name="search_term" type="text" value="<?= $filter_value;?>" />
<input type="submit" value="Найти" />
</form>
<table>
<thead>
<tr>
<th>№</th>
<th>Название</th>
<th>Значение</th>
</tr>
</thead>
<tbody>
<?php foreach($result as $row_data): ?>
<tr>
<td><?= $row_data['id'];?></td>
<td><?= $row_data['name'];?></td>
<td><?= $row_data['value'];?></td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment