Является ли file_exist () в PHP очень дорогой операцией?

Я добавляю аватары в движок форума, который я разрабатываю, и я обсуждаю, нужно ли сделать что-то простое (изображение форума называется .png) и использовать PHP, чтобы проверить, существует ли файл перед его отображением, или сделать что-то немного сложнее (но не намного) и используйте поле базы данных, чтобы содержать имя изображения, которое нужно показать.

Я бы предпочел лично использовать метод file_exists (), так как это дает мне простой способ вернуться к аватару "по умолчанию", если текущий не существует (пока), и его просто реализовать с помощью кода. Однако меня беспокоит производительность, поскольку это будет запускаться один раз для каждого пользователя, отображаемого для каждой страницы на страницах чтения форума. Итак, я хотел бы знать, вызывает ли функция file_exists () в PHP какое-либо серьезное замедление, которое может привести к значительному снижению производительности в условиях высокого трафика?

Если нет - отлично. Если да, что вы думаете об альтернативах для отслеживания загруженного пользователем изображения? Спасибо!

PS: Различия в коде, которые я вижу, заключаются в том, что версии проверки файлов позволяют файлам говорить, в то время как форма базы данных доверяет точности базы данных и не требует проверки. (это просто URL-адрес, который, конечно же, передается браузеру.)

Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Symfony Station Communiqué - 7 июля 2023 г
Symfony Station Communiqué - 7 июля 2023 г
Это коммюнике первоначально появилось на Symfony Station .
Оживление вашего приложения Laravel: Понимание режима обслуживания
Оживление вашего приложения Laravel: Понимание режима обслуживания
Здравствуйте, разработчики! В сегодняшней статье мы рассмотрим важный аспект управления приложениями, который часто упускается из виду в суете...
Установка и настройка Nginx и PHP на Ubuntu-сервере
Установка и настройка Nginx и PHP на Ubuntu-сервере
В этот раз я сделаю руководство по установке и настройке nginx и php на Ubuntu OS.
Коллекции в Laravel более простым способом
Коллекции в Laravel более простым способом
Привет, читатели, сегодня мы узнаем о коллекциях. В Laravel коллекции - это способ манипулировать массивами и играть с массивами данных. Благодаря...
Как установить PHP на Mac
Как установить PHP на Mac
PHP - это популярный язык программирования, который используется для разработки веб-приложений. Если вы используете Mac и хотите разрабатывать...
17
0
11 748
7
Перейти к ответу Данный вопрос помечен как решенный

Ответы 7

Поскольку ваш веб-сервер уже будет выполнять множество (эквивалентных) операций file_exists () в процессе отображения вашей веб-страницы, повторный запуск вашего сценария, вероятно, не окажет заметного влияния. Веб-сервер, вероятно, сделает как минимум:

  • по одному для каждого подкаталога корневого веб-каталога (для проверки наличия и наличия символических ссылок)
  • один для проверки наличия файла .htaccess для каждого подкаталога корневого веб-каталога
  • один для существования вашего скрипта

Это не означает, что PHP мог бы сделать больше из них.

file_exists () сам по себе не медленный. Настоящая проблема заключается в том, как сконфигурирована ваша система и где есть узкие места в производительности. Помните, что базы данных тоже должны хранить данные на диске, поэтому в любом случае вы можете столкнуться с дисковой активностью. С другой стороны, и базы данных, и файловые системы обычно имеют некоторую форму прозрачного кэширования для оптимизации повторного доступа.

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

Раньше я сохранял метаданные изображения в базе данных (включая его имя), чтобы мы могли генерировать полезную статистику. Что еще более важно, для хранения данных изображения (не самого файла, а только метаданных) используется способствует переменам. Что делать, если в будущем вам нужно «утвердить» изображение, или вы захотите удалить его, не удаляя файл?

В соответствии с аватаром "по умолчанию" ... ну, если запись для этого пользователя не найдена, просто используйте значение по умолчанию.

В любом случае, file_exists () или db, это не должно стать проблемой. Однако одно решение гораздо более расширяемо.

Вы получили отрицательное голосование, и я не уверен, почему, это хороший ответ, и я никогда об этом не думал.

Nicholas Flynt 25.11.2008 11:57

Не могу прокомментировать правильный ответ, но еще один момент - НЕ СОХРАНЯЙТЕ ИЗОБРАЖЕНИЯ КАК БЛОБЫ. Это действительно плохая работа. Поверьте, это до бесконечности обсуждалось в сети.

Kevin Dente 25.11.2008 12:50
Ответ принят как подходящий

Как и то, что говорили другие плакаты, результат file_exists () автоматически кэшируется PHP для повышения производительности.

Однако, если вы уже читаете информацию о пользователе из базы данных, вы можете сохранить ее там. Если пользователю разрешен только один аватар, вы можете просто сохранить один бит в столбце для «имеет аватар» (1/0), а затем иметь имя файла, такое же, как идентификатор пользователя, и использовать что-то вроде SELECT CONCAT(IF(has_avatar, id, 'default'), '.png') AS avatar FROM users

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

Информация кеша очень обнадеживает, я остановился на решении file_exists. Однако идея с большими двоичными объектами выглядит очень интересной, возможно, я попробую ее позже. Спасибо!

Nicholas Flynt 25.11.2008 11:58

но BLOB плохо сказывается на производительности. Вы получаете накладные расходы на запуск PHP, MySQL, и вам придется написать поддержку проверки HTTP-кеша, иначе браузеры будут без нужды повторно загружать аватары.

Kornel 27.11.2008 16:26

Важно отметить, что PHP будет кэшировать только результаты для существующих файлов, он не будет кэшировать результаты для несуществующих файлов. См .: php.net/manual/en/function.clearstatcache.php

Brian 20.02.2013 23:59

Если производительность - ваше единственное соображение, file_exists () будет намного дешевле, чем поиск в базе данных.

В конце концов, это всего лишь поиск в каталоге с помощью системных вызовов. После первого выполнения сценария большая часть соответствующего каталога будет кэширована в хранилище, поэтому фактических операций ввода-вывода будет очень мало, а «file_exists ()» является настолько распространенной операцией, что она и лежащие в ее основе системные вызовы будут сильно загружены. оптимизирован для любой распространенной комбинации php / os.

Как заметил Иоанн II. Если дополнительные функции и функции пользовательского интерфейса являются приоритетом, то база данных будет подходящим вариантом.

В реальном тестировании производительности вы обнаружите, что file_exists работает очень быстро. Как бы то ни было, в php, когда один и тот же URL-адрес дважды указан как "stat", второй вызов просто извлекается из внутреннего кеша статистики php.

И это только в области запуска php. Даже между запусками файловая система / os будет стремиться агрессивно помещать файл в кеш файловой системы, и если файл достаточно мал, не только тест на существование файла выйдет прямо из памяти, но и весь файл тоже.

Вот некоторые реальные данные, подтверждающие мою теорию:

Я просто проводил тесты производительности утилит командной строки linux «find» и «xargs». В процессе я выполнил тест на наличие файла для 13000 файлов, по 100 раз каждый, менее чем за 30 секунд, так что в среднем получается 43000 статистических тестов в секунду, поэтому уверен, что в мелком масштабе это будет медленно, если вы сравните его, чтобы сказать, нужно разделить 9 на 8, но в реальном сценарии вам нужно будет сделать это много раз ужасный, чтобы увидеть заметную проблему с производительностью.

Если у вас есть 43 пользователя тысяча, одновременно обращающихся к вашей странице в течение секунды, я думаю, у вас будут гораздо большие проблемы, чем время, необходимое для копирования статуса существования файла более или менее из память по сценарию среднего случая.

По крайней мере, с PHP4 я обнаружил, что вызов file_exists определенно убивал наше приложение - он многократно делался глубоко в библиотеке, поэтому нам действительно пришлось использовать профилировщик, чтобы найти его. Удаление вызова увеличило вычисление некоторых страниц в десятки раз (вызов выполнялся очень часто).

Возможно, что в PHP5 они кешируют file_exists, но, по крайней мере, с PHP4 это было не так.

Теперь, если вы не в цикле, очевидно, что file_exists не будет иметь большого значения.

Другие вопросы по теме