Как организовать поиск последних добавленных элементов в PHP приложении

Раздел: Веб-разработка -> Поисковые функции

Поиск новых записей в PHP: обзор подходов

Задача поиска новых записей возникает при создании ленты новостей, блогов или каталогов, где необходимо показывать пользователям только что добавленные элементы. Рассмотрим несколько вариантов реализации на PHP с использованием различных источников данных.

Основное решение: SQL-запрос с сортировкой по дате и лимитом

Наиболее эффективный способ для реляционных баз данных (MySQL, PostgreSQL) - выполнить запрос, сортирующий записи по убыванию даты создания и ограничивающий количество результатов. Пример для таблицы articles:


$pdo = new PDO('mysql:host=localhost;dbname=test;charset=utf8', 'user', 'pass');
$stmt = $pdo->query('SELECT * FROM articles WHERE active = 1 ORDER BY created_at DESC LIMIT 10');
$newRecords = $stmt->fetchAll(PDO::FETCH_ASSOC);
  

Search php search author (поиск по автору в php)

Запрос возвращает десять последних активных записей. Индекс по полю created_at значительно ускоряет выборку. При необходимости добавить условие поиска по тексту используется WHERE title LIKE ? вместе с сортировкой.

Типичная ошибка: отсутствие индекса

Без индекса ORDER BY created_at DESC вызывает полное сканирование таблицы при большом объёме данных. Решение - создать композитный индекс INDEX(active, created_at).

Вариант 1: Фильтр записей за последние N дней

Как найти записи, добавленные за последние 24 часа?

Если требуется строгий временной интервал, добавляется условие created_at >= NOW() - INTERVAL 1 DAY.


$stmt = $pdo->prepare('SELECT * FROM articles WHERE created_at >= NOW() - INTERVAL :days DAY');
$stmt->execute(['days' => 1]);
$newToday = $stmt->fetchAll();
  

Index php act search ru (поиск с параметром ru в php)

Для недели, месяца меняется значение INTERVAL. Параметризация предотвращает SQL-инъекции.

Проблема: часовые пояса

Функция NOW() использует часовой пояс сервера. Рекомендуется хранить даты в UTC и явно указывать UTC_TIMESTAMP().

Вариант 2: Полнотекстовый поиск с учётом новизны

Как организовать поиск по содержимому и одновременно показывать свежие записи?

Используется MATCH ... AGAINST для текстового поиска и ORDER BY created_at DESC для сортировки.


$stmt = $pdo->prepare('
    SELECT *, MATCH(title, body) AGAINST(:query) AS relevance
    FROM articles
    WHERE MATCH(title, body) AGAINST(:query)
    ORDER BY created_at DESC, relevance DESC
    LIMIT 20
');
$stmt->execute(['query' => $searchTerm]);
  

Advance search php (расширенный поиск в php)

Сначала записи сортируются по новизне, затем по релевантности. Если нужно приоритетнее показывать свежие - меняется порядок.

Типичная ошибка: не создан полнотекстовый индекс

Без индекса FULLTEXT(title, body) запрос выдаст ошибку. Для больших таблиц требуется настройка стоп-слов и минимальной длины слова.

Вариант 3: Поиск новых записей в массиве данных (без БД)

Как выбрать новые элементы из JSON-файла или кэша?

Если данные хранятся в виде массива PHP, используется array_filter и сортировка.


$records = json_decode(file_get_contents('data.json'), true);
$newThreshold = strtotime('-1 day');
$newRecords = array_filter($records, function($item) use ($newThreshold) {
    return strtotime($item['created_at']) >= $newThreshold;
});
usort($newRecords, function($a, $b) {
    return strtotime($b['created_at']) - strtotime($a['created_at']);
});
  

Search php vars (переменные поиска в php)

Такой подход подходит для небольших объёмов данных (до нескольких тысяч записей). При больших массивах лучше использовать коллекции или базу данных.

Проблема: производительность при частой загрузке файла

Каждый запрос загружает весь файл в память. Решение - кэшировать декодированный массив в apcu или использовать SQLite.

Вариант 4: Поиск через внешнее API (например, Elasticsearch)

Как искать новые записи в поисковом движке?

Если используется Elasticsearch, запрос может выглядеть так:


$client = ClientBuilder::create()->build();
$params = [
    'index' => 'articles',
    'body'  => [
        'sort' => [
            'created_at' => ['order' => 'desc']
        ],
        'query' => [
            'bool' => [
                'filter' => [
                    'range' => ['created_at' => ['gte' => 'now-1d/d']]
                ]
            ]
        ],
        'size' => 10
    ]
];
$response = $client->search($params);
  

Результат уже отсортирован по дате и ограничен. Такой подход эффективен при миллионах записей.

Типичная ошибка: путаница в формате даты

Elasticsearch ожидает дату в формате ISO 8601. Необходимо привести данные к единому формату при индексации.

Выбор метода зависит от объёма данных, частоты обновлений и требуемой функциональности. Для простых сайтов достаточно SQL с индексом, для высоконагруженных проектов - полнотекстовый движок или Elasticsearch.

- Search php p 1 (поиск по странице 1 в php)
- Search php new (поиск новых записей в php)
- Search php search id 0 (поиск по id 0 в php)

Расширенные примеры кода с пояснениями

Пример 1: Поиск новых записей с пагинацией и превью

Задача: вывести 5 последних статей, каждая с кратким описанием, и добавить ссылку «Показать ещё».

Пример

$page = $_GET['page'] ?? 1;
$perPage = 5;
$offset = ($page - 1) * $perPage;

$stmt = $pdo->prepare('
    SELECT id, title, SUBSTRING(body, 1, 200) AS preview, created_at
    FROM articles
    WHERE active = 1
    ORDER BY created_at DESC
    LIMIT :limit OFFSET :offset
');
$stmt->bindValue(':limit', $perPage, PDO::PARAM_INT);
$stmt->bindValue(':offset', $offset, PDO::PARAM_INT);
$stmt->execute();
$articles = $stmt->fetchAll();

// Вывод (HTML опущен)
foreach ($articles as $article) {
    echo '
'; echo '

' . htmlspecialchars($article['title']) . '

'; echo '

' . htmlspecialchars($article['preview']) . '...

'; echo '' . $article['created_at'] . ''; echo '
'; }
Результат: список из 5 статей с датами, отсортированными от самой новой к старой.

Пример 2: Комбинированный поиск по тексту и дате с взвешенной сортировкой

Пользователь вводит слово «PHP», и система показывает сначала статьи за последнюю неделю, затем остальные.

Пример

$search = 'PHP';
$stmt = $pdo->prepare('
    SELECT *,
           CASE WHEN created_at >= NOW() - INTERVAL 7 DAY THEN 1 ELSE 0 END AS is_recent,
           MATCH(title, body) AGAINST(:q) AS relevance
    FROM articles
    WHERE MATCH(title, body) AGAINST(:q)
    ORDER BY is_recent DESC, relevance DESC
    LIMIT 15
');
$stmt->execute(['q' => $search]);
$results = $stmt->fetchAll();
Результат: сначала записи за последние 7 дней (по убыванию релевантности), затем более старые (тоже по релевантности).

Пример 3: Поиск новых записей с использованием Redis как кэша

Если записи добавляются редко, можно кэшировать список последних ID в Redis и затем получать полные данные из БД.

Пример

$redis = new Redis();
$redis->connect('127.0.0.1', 6379);

// При добавлении записи сохраняем её ID в сортированном множестве с весом = timestamp
// $redis->zAdd('new_articles', time(), $articleId);

// Получаем последние 10 ID
$lastIds = $redis->zRevRange('new_articles', 0, 9);
if (!empty($lastIds)) {
    $placeholders = implode(',', array_fill(0, count($lastIds), '?'));
    $stmt = $pdo->prepare("SELECT * FROM articles WHERE id IN ($placeholders) ORDER BY FIELD(id, " . implode(',', $lastIds) . ")");
    $stmt->execute($lastIds);
    $articles = $stmt->fetchAll();
}
Результат: быстрый доступ к последним записям без сортировки всей таблицы.

Пример 4: Использование генератора для потоковой обработки больших наборов новых записей

При экспорте или фоновой обработке всех новых записей за день.

Пример

function getNewRecordsGenerator(PDO $pdo, int $days = 1): Generator {
    $stmt = $pdo->prepare('
        SELECT * FROM articles
        WHERE created_at >= NOW() - INTERVAL :days DAY
        ORDER BY created_at ASC
    ');
    $stmt->execute(['days' => $days]);
    while ($row = $stmt->fetch(PDO::FETCH_ASSOC)) {
        yield $row;
    }
}

$generator = getNewRecordsGenerator($pdo, 7);
foreach ($generator as $record) {
    // Обработка каждой записи без загрузки всего результата в память
    echo $record['title'] . "\n";
}
Результат: построчный вывод заголовков всех статей за неделю, экономя память.

Пример 5: Поиск новых записей через REST API (например, WordPress)

Если данные доступны через JSON REST, можно получить последние записи одним запросом.

Пример

$url = 'https://example.com/wp-json/wp/v2/posts?per_page=5&orderby=date&order=desc';
$response = file_get_contents($url);
$posts = json_decode($response, true);
foreach ($posts as $post) {
    echo $post['title']['rendered'] . ' - ' . $post['date'] . "\n";
}
Результат: заголовки и даты последних 5 постов с блога.

Поиск новых записей в PHP - comments

En
Search php new (php)