Алгоритмы и структуры данных на PHP: практическое руководство для веб-разработчика

Онлайн-тренажер Python для начинающих

Изучайте Python легко и без перегрузки теорией. Решайте практические задачи с автоматической проверкой, получайте подсказки на русском языке и пишите код прямо в браузере — без необходимости что-либо устанавливать.

Начать курс

Алгоритмы и структуры данных на PHP: от теории к рабочим проектам

Многие PHP-разработчики считают, что алгоритмы и структуры данных — это удел C++ или Java. Однако на практике понимание базовых алгоритмов напрямую влияет на производительность и масштабируемость веб-приложений. В этой статье мы разберём ключевые структуры данных и алгоритмы на PHP с реальными примерами кода, которые можно сразу применить в своих проектах.

Зачем PHP-разработчику знать алгоритмы?

PHP традиционно ассоциируется с быстрой разработкой веб-сайтов, но современные фреймворки (Laravel, Symfony) и высоконагруженные проекты требуют эффективного управления данными. Без понимания алгоритмов вы рискуете:

  • Писать медленные запросы к БД, которые можно заменить кешированием через хеш-таблицы;
  • Создавать неоптимальные циклы с вложенностью O(n³);
  • Терять контроль над памятью при обработке больших массивов.

Базовые структуры данных — это фундамент, на котором строятся все современные системы. Рассмотрим их реализацию на PHP.

Структуры данных на PHP: реализация и примеры

1. Стек (Stack) — принцип LIFO

Стек работает по принципу «последний пришёл — первый ушёл». В PHP его легко реализовать через массив с функциями array_push() и array_pop(). Однако для учебных целей и лучшего понимания создадим класс:

<?php
class Stack {
    private array $items = [];

    public function push($item): void {
        $this->items[] = $item;
    }

    public function pop() {
        if ($this->isEmpty()) {
            return null;
        }
        return array_pop($this->items);
    }

    public function peek() {
        return $this->items[count($this->items) - 1] ?? null;
    }

    public function isEmpty(): bool {
        return empty($this->items);
    }
}

// Пример использования
$stack = new Stack();
$stack->push('Пользователь 1');
$stack->push('Пользователь 2');
echo $stack->pop(); // Пользователь 2
?>

Где применяется: проверка корректности скобок в коде, отмена действий (undo), обход графов в глубину.

2. Очередь (Queue) — принцип FIFO

Очередь работает как живая очередь: первый вошёл — первый вышел. Используем array_shift() и array_push():

<?php
class Queue {
    private array $items = [];

    public function enqueue($item): void {
        $this->items[] = $item;
    }

    public function dequeue() {
        if ($this->isEmpty()) {
            return null;
        }
        return array_shift($this->items);
    }

    public function isEmpty(): bool {
        return empty($this->items);
    }
}

// Пример: обработка задач в фоне
$queue = new Queue();
$queue->enqueue('Отправить email');
$queue->enqueue('Сгенерировать отчёт');
echo $queue->dequeue(); // Отправить email
?>

Где применяется: очереди задач (Job Queue), обработка запросов в порядке поступления, обход графов в ширину (BFS).

3. Хеш-таблица (Hash Table) — быстрый поиск

В PHP ассоциативные массивы — это встроенная хеш-таблица. Но для понимания внутренней механики реализуем простую версию с коллизиями через цепочки:

<?php
class HashTable {
    private array $buckets;
    private int $size;

    public function __construct(int $size = 10) {
        $this->size = $size;
        $this->buckets = array_fill(0, $size, []);
    }

    private function hash(string $key): int {
        return crc32($key) % $this->size;
    }

    public function set(string $key, $value): void {
        $index = $this->hash($key);
        foreach ($this->buckets[$index] as &$item) {
            if ($item[0] === $key) {
                $item[1] = $value;
                return;
            }
        }
        $this->buckets[$index][] = [$key, $value];
    }

    public function get(string $key) {
        $index = $this->hash($key);
        foreach ($this->buckets[$index] as $item) {
            if ($item[0] === $key) {
                return $item[1];
            }
        }
        return null;
    }
}

// Пример: кеширование данных
$cache = new HashTable();
$cache->set('user:123', ['name' => 'Анна', 'role' => 'admin']);
print_r($cache->get('user:123'));
?>

Где применяется: кеширование (Redis, Memcached), хранение сессий, индексация данных.

Алгоритмы на PHP: от простого к сложному

1. Линейный и бинарный поиск

Линейный поиск — самый простой, но медленный (O(n)). Бинарный поиск работает только на отсортированных данных, но даёт O(log n):

<?php
function binarySearch(array $arr, int $target): int {
    $left = 0;
    $right = count($arr) - 1;

    while ($left <= $right) {
        $mid = intdiv($left + $right, 2);
        if ($arr[$mid] === $target) {
            return $mid;
        }
        if ($arr[$mid] < $target) {
            $left = $mid + 1;
        } else {
            $right = $mid - 1;
        }
    }
    return -1;
}

$sorted = [1, 3, 5, 7, 9, 11];
echo binarySearch($sorted, 7); // 3
?>

Совет: Всегда используйте бинарный поиск для поиска в отсортированных массивах — это даёт прирост скорости в десятки раз на больших объёмах данных.

2. Сортировка пузырьком и быстрая сортировка

Пузырьковая сортировка — учебный пример (O(n²)). На практике используйте встроенную sort() или реализуйте быструю сортировку (QuickSort):

<                

Блоги

Рекомендаций по книгам