Вложенный PHP включает в себя процессор / память? - PullRequest
4 голосов
/ 14 февраля 2012

Я кодирую сайт на PHP и получаю "красивые URL-адреса" (также скрывая мои каталоги), направляя все запросы в один файл index.php (используя .htaccess). Индексный файл затем анализирует URI и включает в себя запрошенные файлы. Эти файлы также содержат более двух включений, и каждый может открыть соединение MySQL. И затем те файлы также включают в себя, которые открывают соединения SQL. Спускается примерно до 3-4 уровней.

Является ли этот процесс интенсивным ЦП и памятью как из PHP-включения, так и открытия (и закрытия) MySQL-соединений в каждом включенном файле?

Кроме того, будут ли красивые URL-адреса, использующие чисто htaccess, использовать меньше ресурсов?

Ответы [ 3 ]

6 голосов
/ 14 февраля 2012

PHP накладные расходы

Ответ - логическая декомпозиция вашего приложения в исходную иерархию зависит от того, как размещается ваше решение.

  • Если вы используете выделенный хост / ВМ, то у вас, вероятно, будет mod_php + Xcache или его эквивалент, и ответ будет: нет, он действительно не попадает во время выполнения, поскольку все кэшируется в памяти на уровне кода операции PHP.
  • Если вы используете службу общего хостинга, то это будет влиять на производительность, поскольку любые PHP-скрипты будут загружаться через PHP-cgi, вероятно, через suPHP, и всю исходную иерархию необходимо будет прочитать и составлено за запрос . Хуже того, в общем решении, если этот запрос является первым, скажем, за 1 минуту, тогда кэш файлов сервера будет очищен, и при сортировке этого источника будет много физического ввода-вывода = время задержки в секундах.

Я управляю несколькими форумами phpBB и обнаружил, что, объединяя общие иерархии включений для реализаций общего хостинга, я могу вдвое сократить время отклика пользователя. Вот некоторые статьи, которые описывают это более подробно ( Терри Эллисон [phpBB] ). И процитировать одну статью:

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

  • 20-40 . Количество файлов, которые вы можете открывать и читать в секунду, если кэш файловой системы не заполнен.
  • 1,500-2,500 . Количество файлов, которые вы можете открывать и читать в секунду, если кэш файловой системы заполнен их содержимым.
  • 300,000-400,000 . Число строк в секунду, которые может скомпилировать интерпретатор PHP.
  • 20.000.000 . Число инструкций PHP в секунду, которые интерпретатор PHP может интерпретировать.
  • 500-1,000 . Число операторов MySQL в секунду, которые может вызвать интерпретатор PHP, если кэш базы данных заполнен содержимым вашей таблицы.

Подробнее см. Подробнее об оптимизации приложений PHP в общей службе Webfusion , где вы можете скопировать тесты для запуска самостоятельно.

MySQL соединение

Самое простое, что можно сделать здесь - это объединить соединение. Я использую свое собственное расширение класса mysqli, которое использует стандартный шаблон «один объект на класс». В моем случае любой модуль может выдать:

$db = AppDB::get();

чтобы вернуть этот объект. Это дешево, поскольку внутренний вызов включает полдюжины опкодов PHP.

Альтернативный, но традиционный метод - использовать глобальный объект для хранения объекта и просто сделать

global $db;

в любой функции, которая должна его использовать.

Сноска для небольших приложений

Вы предложили объединить все включения в один файл включения. Это нормально для стабильного производства, но боль во время тестирования. Могу ли я предложить простой компромисс? Хранит их отдельно для тестирования, но позволяет загружать один композит. Вы делаете это в двух частях (i) Я полагаю, что каждый include определяет функцию или класс, поэтому используйте стандартный шаблон для каждого include, например,

if( !function_exists( 'fred' ) ) {
    require "include/module1.php";
}

Перед любой загрузкой в ​​мастер-скрипт просто сделайте:

@include "include/_all_modules.php";

Таким образом, когда вы тестируете, вы удаляете _all_modules.php, и скрипт возвращается к загрузке отдельных модулей. Когда вы счастливы, вы можете воссоздать _all_modules.php. Вы можете сделать это на стороне сервера простым скриптом "release", который выполняет

system( 'cp include/[a-z]*.php include/_all_modules.php' );

Таким образом, вы получаете лучшее из обоих миров

5 голосов
/ 14 февраля 2012

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

Лично я бы только инициализировал соединение с базой данных на фронт-контроллере (вашindex.php), потому что там все должно пройти.

1 голос
/ 14 февраля 2012

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

http://php.net/manual/en/function.include-once.php

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

...