Передача имени сайта скрипту через cron (crontab)

PHP-скриптВчера на stackoverflow заметил вопрос о том, как передать скрипту через крон адрес сайта, если скрипт может выполняться «под разными сайтами». Это довольно интересный вопрос, и есть много вариантов решения. Сам решал его не так давно, а раз тема интерисует и других, решил об этом написать.

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

Самый простой пример таких сайтов — это локализованные версии одного сайта на разных языках. У меня в практике — это тематические форумы для разных групп.

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

При запуске обработки пользовательского HTTP-запроса скриптам необходимо определить, какому именно домену предназначен запрос, и выбрать соответствующий конфиг. В это довольно просто сделать: заглянуть в переменную $_SERVER[‘SERVER_NAME’]. В других языках программирования под веб, думаю, примерно так же просто.

По имени серевера определяется нужный конфиг и оттуда берутся все необходимые настройки. Все просто.

Но когда дело доходит до вызова скриптов из cron-а (или другого планировщика), то переменная $_SERVER[‘SERVER_NAME’] будет пуста. Оно-то и понятно: никакого сервера нет, скрипт запускается напрямую через CLI. И узнать, для какого сайта вызывается скрипт, без явной передачи домена скрипту невозможно.

Самый простой способ указать домен — это прописать его аргументом командной строки. При вызове из cron-а после имени скрипта просто пишем домен, а в коде получаем его из переменной $argv глобальной области видимости.

Но этот способ не отличается элегантностью, т.к. придется определять, как запускался сайт: через веб или CLI, и в зависимости от этого искать адрес сайта в разных местах.

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

Таким образом ищем более удобный способ передать «указатель» на сайт. И находим: это переменные окружения. Среду окружения интерпретатор PHP получает оттуда, откуда он был запущен. Если скрипт запущен веб-сервером, то переменные будут получены от сервера. Если запускается скрипт через CLI, то среда будет получена от shell-а, в котором производился запуск. Повторю: запуск скриптов из cron-а — это обыкновенный запуск исполнимого файла в режиме CLI.

Теперь к конкретике. Чтобы переменная среды окружения попала из веб-сервера в PHP-скрипт (или скрипт/программу, написанную на других языках), ее надо установить (прописать). Для Апача установить переменную можно в файле .htaccess, либо в конфигах сервера (httpd.conf или конфиги виртуальных хостов). В идеале предпочтительно последнее. Но достаточно и минимального уровня доступа к .htaccess. Добивим в соответствующий конфиг строку:

SetEnv SITE_NAME site1

Чтобы определить переменную среды при запуске в режиме CLI (php /filename), нужно ее объявить и экпортировать:

export SITE_NAME=site1;

При запуске скрипта вручную следующей командой можно запускать сам PHP. Если запуск производится cron-ом, то стоит создать скрипт, на который ссылаться из crontab:

#!/bin/bash
export SITE_NAME=site1;
php /path

Для других сайтов вместо site1 подставляются другие имена.

Остается прочитать переменную в скрипте:

echo getenv('SITE_NAME');

Ну а дальше, в зависимости от значения переменной, подгружать нужный конфиг.

* Стоит отметить, что в случае разных «установок»1 одного и того же сайта (development, testing, production) принято это значение передавать сайту в виде тоже же переменной окружения. Как правило, конфиг в этом случае содержит очень много информации, одинаковой для всех «установок», а отличаться, например, могут только параметры доступа к БД. Тогда имеет смысл все установки считать за один сайт (хоть домены и разные), а отличающиеся параметры вынести в отдельный конфиг, зависимый от «установки».

1 — Я намеряно в последнем абзаце заменил термин «окружение приложения» (application environment: тестовое, рабочее) на «установку», чтобы не было путаницы с тем окружением, где устанавливаюся переменные.

Об авторе Валера Леонтьев

Программист PHP/MySQL.

Запись опубликована в рубрике IT, PC, PHP, Web, Все рубрики с метками , . Добавьте в закладки постоянную ссылку.

2 комментария на «Передача имени сайта скрипту через cron (crontab)»

  1. Bethrezen говорит:

    А почему бы не использовать $argv?

  2. Bethrezen, потому что хотелось унификации. $argv не существует при запуске через веб-сервер. А переменную окружения можно установить практически при любом варианте запуска.

Добавить комментарий