Как вы проверяете, выполняет ли сервер скрипт PHP? - PullRequest
2 голосов
/ 17 февраля 2009

Я запускаю cronjob, который должен записывать данные в кеш. Я хотел поместить этот cronjob в свою личную папку, однако даже после CHMOD, добавив кеш-папку в личную папку, он не получает права на запись. Похоже, это какая-то особенность plesk.

Итак, теперь я поместил cronjob в общую папку. Однако мне нужно убедиться, что только сервер может выполнить скрипт. Как насчет следующего в верхней части cronjob?

if ($_SERVER['SERVER_ADDR'] != $_SERVER['REMOTE_ADDR']) die();

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

Другая проблема, с которой я столкнулся, заключается в том, что приведенный выше код возвращает 2 предупреждения, даже если кажется, что оно работает:

PHP Notice:  Undefined index:  SERVER_ADDR in ... on line 2
PHP Notice:  Undefined index:  REMOTE_ADDR in ... on line 2

Есть идеи, в чем причина этого?

Ответы [ 3 ]

5 голосов
/ 17 февраля 2009

Выполнять скрипт через консоль, а не через веб-сервер.

Cron может выглядеть так:

*/5 * * * * php -f /path/to/cron.php

Тогда файл может сделать это:

cron.php:
<?php

if ( array_key_exists('REMOTE_ADDR', $_SERVER) )
    die("Can only be run from the command line!");

Это гарантирует, что он будет запущен только сервером.

Редактировать в ответ на комментарии

Обычно вы не можете получить доступ к общей папке внутри личной папки, и если вы не можете добавить новые каталоги вне корневого веб-каталога, каталог кэша должен быть защищен другим способом.

Я предполагаю, что все ваши файлы находятся в корне сети, то есть: /home/site/publichtml. Замените его тем, что у вас в каталоге.

Создать новый каталог /home/site/publichtml/.cache. Добавьте в качестве файла .htaccess следующее:

Deny from all

Теперь ваши сценарии должны иметь возможность доступа к папке из файловой системы, но она недоступна через веб-сервер.

Если вы можете настроить задачу cron на сервере (через веб-администратора или другим способом, похоже, что вы можете), сделайте это, как указано выше, то есть: используйте php -f /home/site/publichtml/cron.php в качестве команды и включите проверку для ключ массива.

В качестве альтернативы вы можете проверить так:

if ( !isset($_SERVER['argc']) )
    die("Must be run from the command line!\n");

$_SERVER['argc'] устанавливается только при выполнении сценария из командной строки.

Если вы можете сохранить скрипт cron вне корневого каталога, хорошо. Если нет, то это должно быть безопасно.

Наконец, чтобы избавиться от E_NOTICES, добавьте это в начало cron.php:

error_reporting(E_ALL ^ E_NOTICE); // Turn off notices

или

error_reporting(0); // Hide all error reporting
4 голосов
/ 17 февраля 2009

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

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

Наконец, использование $ _SERVER ['SERVER_ADDR'] и $ _SERVER ['REMOTE_ADDR'], вероятно, не лучший способ проверить, выполняет ли сервер скрипт. Во-первых, я считаю, что $ _SERVER ['REMOTE_ADDR'] не будет установлен при запуске сценария PHP из командной строки. Это взято из заголовков HTTP, и так как их нет, оно будет пустым. На самом деле, именно поэтому вы получаете предупреждения - они не установлены. (редактировать: просматривая документы PHP, вполне вероятно, что переменная 'SERVER_ADDR' не будет установлена ​​для не браузерных скриптов)

1 голос
/ 17 февраля 2009

Я думаю, что ответ скрыт в вашем первом ответе от Джона.

Итак, если вы хотите, чтобы этот скрипт был доступен только через cron, проверьте наличие суперглобальных сессий:

if (is_array($_SESSION)) die();

И, просто потому, что это просто, создайте файл .htaccess и сделайте запрет на все.

Я опечатал $ _SESSION как $ _SERVER, мой плохой. Это работает для ваших нужд.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...