Realpath cache size: примеры (PHP)

Функция realpath_cache_size: настройка и примеры использования
Раздел: Работа с файловой системой
realpath_cache_size: int

Функция realpath_cache_size

Функция realpath_cache_size() не является функцией в классическом понимании, а представляет собой конфигурационную директиву PHP. Она определяет максимальный размер (в байтах) кеша реальных путей файловой системы.

Назначение и принцип работы

PHP использует кеш реальных путей для ускорения преобразования относительных путей файлов в абсолютные, а также для разрешения символьных ссылок. Когда скрипт обращается к файлу через функции вроде include, require или file_exists, ядро PHP проверяет кеш перед тем, как выполнять относительно дорогой системный вызов для определения реального пути.

Аргументы и настройка

Данная директива не имеет аргументов для вызова в коде. Её значение задается в конфигурационном файле php.ini или изменяется во время выполнения с помощью функции ini_set(). Второй директивой, связанной с этим механизмом, является realpath_cache_ttl, которая определяет время жизни (в секундах) записей в кеше.

  • realpath_cache_size: размер кеша. Значение по умолчанию в PHP 8.0 и выше — 4096 Кбайт (4 Мбайт).
  • realpath_cache_ttl: время жизни записей. Значение по умолчанию — 120 секунд.

Примеры работы с кешем реальных путей

Получение текущих значений

Можно узнать текущий размер и состояние кеша с помощью функции realpath_cache_get().

<?php
// Получение информации о кеше
$cacheInfo = realpath_cache_get();
print_r($cacheInfo);
?>
Array
(
    [/home/user/project/index.php] => Array
        (
            [key] => 1234567890abcdef
            [is_dir] =>
            [realpath] => /home/user/project/index.php
            [expires] => 1645537800
        )
    // ... другие записи
)
Изменение размера кеша во время выполнения
<?php
// Попытка изменить размер кеша
$oldValue = ini_get('realpath_cache_size');
echo "Старый размер: " . $oldValue . "\n";

ini_set('realpath_cache_size', '8192K'); // Пробуем установить 8 Мбайт

$newValue = ini_get('realpath_cache_size');
echo "Новый размер: " . $newValue . "\n";
?>
Старый размер: 4096K
Новый размер: 8192K

Важно отметить, что изменение может быть ограничено настройками окружения или иметь эффект только для текущего скрипта.

Похожие и вспомогательные функции в PHP

Возвращает содержимое кеша реальных путей. Полезна для отладки и мониторинга. Не имеет параметров.

Очищает кеш состояния файлов, который хранит информацию, возвращаемую функциями stat(), file_exists(), filesize() и другими. На кеш реальных путей влияет только при вызове с параметром $clear_realpath_cache = true.

<?php
// Очистка только кеша состояния файлов
clearstatcache();
// Очистка и кеша состояния файлов, и кеша реальных путей
clearstatcache(true);
?>

Возвращает канонизированный абсолютный путь к файлу. Эта функция активно использует и пополняет кеш реальных путей.

Типичные ошибки и недоразумения

Ожидание немедленного эффекта от изменения размера

Кеш имеет время жизни (realpath_cache_ttl). Новый размер не приводит к мгновенной очистке или перераспределению всех данных.

Попытка установить слишком маленькое значение

Установка значения, меньшего чем объем активно используемых путей, приводит к постоянному вытеснению записей и снижению эффективности кеша.

<?php
// Неэффективная настройка для большого проекта
ini_set('realpath_cache_size', '64K');
// Многочисленные операции с файлами будут медленнее.
?>
Заблуждение о работе в CGI/FPM режиме

В режиме CGI кеш создается и уничтожается в рамках одного запроса, поэтому его настройка почти бессмысленна. Эффективность проявляется в постоянных процессах (mod_php, PHP-FPM).

<?php
// В CGI-режиме этот код покажет, что кеш пуст в начале каждого запроса
$cache = realpath_cache_get();
var_dump(empty($cache)); // Вернет true в CGI
?>

История изменений

PHP 8.0.0

Значение по умолчанию для директивы realpath_cache_size изменено с 16K на 4096K (4 Мбайт). Это существенное увеличение, направленное на повышение производительности веб-приложений, работающих с большим количеством файлов.

Более ранние версии

До PHP 5.6.3 значение по умолчанию составляло 16K. В версиях с 5.6.3 по 7.4.x значение по умолчанию оставалось 16K.

Расширенные примеры и сценарии

Мониторинг заполненности кеша
Пример php
<?php
// Получаем данные кеша
$cache = realpath_cache_get();

// Подсчитываем общий размер в байтах
$totalSize = 0;
foreach ($cache as $entry) {
    // Размер записи приблизительный, зависит от реализации PHP
    $totalSize += strlen($entry['key']) + strlen($entry['realpath']) + 32; // + служебные данные
}

$configuredSize = ini_get('realpath_cache_size');
$configuredSizeBytes = intval($configuredSize) * (
    stripos($configuredSize, 'K') ? 1024 : (
    stripos($configuredSize, 'M') ? 1024 * 1024 : 1
    )
);

$usagePercent = ($totalSize / $configuredSizeBytes) * 100;
echo "Использовано кеша: " . round($totalSize/1024, 2) . " Kб из " . $configuredSize . " (" . round($usagePercent, 2) . "%)\n";
?>
Сравнение производительности
Пример php
<?php
// Файл, который будем проверять многократно
$file = __FILE__;

// Выключение кеша (очень маленький размер)
ini_set('realpath_cache_size', '0');
clearstatcache(true);

$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
    file_exists($file);
}
$timeNoCache = microtime(true) - $start;

// Включение кеша
ini_set('realpath_cache_size', '4096K');
clearstatcache(true);

// Первый вызов заполняет кеш
file_exists($file);

$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
    file_exists($file);
}
$timeWithCache = microtime(true) - $start;

echo "Без кеша: " . $timeNoCache . " сек.\n";
echo "С кешем: " . $timeWithCache . " сек.\n";
echo "Ускорение в " . round($timeNoCache / $timeWithCache, 1) . " раз.\n";
?>
Без кеша: 0.0123456 сек.
С кешем: 0.0004567 сек.
Ускорение в 27.0 раз.
Работа с символическими ссылками
Пример php
<?php
// Создадим символическую ссылку для теста
$target = '/tmp/target_file.txt';
$link = '/tmp/my_link.txt';
touch($target);
symlink($target, $link);

// realpath разрешит ссылку и закеширует результат
$realPath = realpath($link);
echo "Реальный путь: " . $realPath . "\n"; // /tmp/target_file.txt

// Посмотрим запись в кеше
$cache = realpath_cache_get();
if (isset($cache[$link])) {
    echo "Запись в кеше для ссылки существует.\n";
    echo "is_dir: " . ($cache[$link]['is_dir'] ? 'true' : 'false') . "\n";
}

// Удаление цели
unlink($target);
clearstatcache(true); // Очищаем кеш

// Теперь realpath вернет false, так как цель исчезла
$newRealPath = realpath($link);
var_dump($newRealPath); // bool(false)
?>

Аналоги в других языках программирования

Realpath cache size в Python

В Python нет встроенного глобального кеша путей, аналогичного PHP. Функция os.path.realpath() выполняет преобразование, но каждый раз обращается к файловой системе.

import os
path = "../myfile.txt"
abs_path = os.path.realpath(path)
print(abs_path) # /home/user/project/myfile.txt
# Кеширование нужно реализовывать самостоятельно, например, через lru_cache.
JavaScript (Node.js)

В Node.js модуль fs.realpath.native или fs.realpathSync.native выполняют системный вызов. Для кеширования используют модуль fs.realpath или fs.realpathSync, которые имеют внутренний кеш.

const fs = require('fs');
// Использует внутренний кеш
fs.realpath('./file.txt', (err, resolvedPath) => {
  console.log(resolvedPath);
});
// Синхронная версия также использует кеш
const path = fs.realpathSync('./file.txt');

Realpath cache size в MySQL

В контексте СУБД аналогия отдалённая. Можно провести параллель с кешем запросов или кешем файлов таблиц. Прямого аналога функции преобразования пути с кешированием нет.

PHP realpath_cache_size function comments

En
Realpath cache size Get realpath cache size