PHP: разница между массивами и "дырки" в порядке заполнения id
Представим себе типичную таблицу БД, в которой записи идентифицируются по полю-счётчику id
, автоматически "нумерующему" записи.
Лучший вариант обращения с такими таблицами - вообще ничего не удалять из базы, чтобы id
гарантированно имели значения 1, 2, 3 и т.д. Это позволит, например, без проблем извлекать случайную запись из базы и всегда быть уверенным, что идентификатор последней записи соответствует количеству записей в таблице. Задачи администрирования (удаления) некоторых записей при этом можно решать так, как делается на многих форумах сети - контент заменяется строкой "Эта запись удалена администратором" или чем-то подобным.
К сожалению, в жизни таких идеальных ситуаций практически не бывает и в таблице обязательно оказываются "дырки", то есть, "пропущенные" из-за удалённых записей или по ещё каким-то причинам id
.
Также по разным причинам администратор иногда хочет получить список таких идентификаторов :) Показанный ниже код - пример несложного скрипта PHP, который для этой цели можно выполнить на сервере.
Предполагается, что нужные данные содержатся в поле id
таблицы messages
базы данных test
, конечно, всё это легко поменять в коде.
Для доступа к базе используется современный интерфейс mysqli вместо устаревающего mysql.
Также код иллюстрирует подход к задаче поиска "дырок" в подряд идущих значениях 1,2,3,...,$max
.
Сначала результаты запроса преобразуются в массив $arr1
, состоящий только из упорядоченного по возрастанию списка существующих в таблице id
, затем формируется массив $arr2
, содержащий числа 1,2,3,...,$max
без пропусков, где $max
- максимальный (последний) из полученных id
.
После этого нам остаётся только сравнить массивы стандартной функцией array_diff и вывести информацию об отличиях.
Скрипт проверен на локальном хосте Denwer с PHP 5.5.
<?php error_reporting (E_ALL); $mysqli = new mysqli("localhost", "root", "", "test"); //хост, логин, пароль, база if ($mysqli->connect_errno) { printf("Connect failed: %s\n", $mysqli->connect_error); exit (); } $query = "SELECT id FROM messages ORDER by id asc"; //поле id из таблицы messages $arr1 = array (); if ($result = $mysqli->query($query)) { while ($row = $result->fetch_row()) { $arr1[] = $row[0]; } $result->close(); } else { printf ("Ошибка выполнения запроса: $query, сообщение: %s<br>\n",$mysqli->error); exit (); } $mysqli->close(); $max = $arr1[count($arr1)-1]; $arr2 = array (); for ($i=1; $i<=$max; $i++) $arr2[] = $i; $diff = array_diff ($arr2 , $arr1); echo '<p>Отсутствующие id: '; foreach ($diff as $item) echo $item.' '; echo '</p><p>Всего отсутствует: '.count ($diff).'</p>'; ?>
26.12.2017, 22:06 [2213 просмотров]