PHP скрипт для загрузки файла работает в терминале, но не как автоматический вызов с incron
У меня есть скрипт PHP, который загружает документ на Sharepoint, используя cURL. Если я запускаю scipt в терминале, процесс загрузки работает нормально.
Поскольку я хотел бы автоматически вызывать скрипт при каждом изменении этого файла, я использую incron, чтобы обнаружить изменение в соответствующей папке и инициировать вызов скрипта PHP.
Мой файл incron выглядит следующим образом:
/var/www/[further path]/temp IN_MODIFY,IN_CREATE /usr/bin/php /var/www/[further path]/uploadToSharepoint.php
Когда я смотрю на системный журнал, я вижу, что вызов скрипта был правильно инициирован incron. Но по некоторым причинам файл не загружен на Sharepoint. Я также пытался создать файл с глобальными правами на запись, но это не решило мою проблему.
-rwxrwxrwx 1 www-data www-data 49058 Mär 3 10:28 [file].xlsx
Вот мой сценарий, который я звоню:
включите "database.php";
$username="[username]";
$password="[password]";
$localFileURL="/var/www/[further path]/temp/";
$files = scandir($localFileURL, 1);
$newest_file = $files[0];
$pathToUpload=getTeamPath($newest_file);
uploadDocument($pathToUpload . '/' . $newest_file, $localFileURL . $newest_file,$username, $password);
function uploadDocument($dest, $localFile,$username, $password){
$fp = fopen($localFile, 'r');
// Connecting to website.
$ch = curl_init();
curl_setopt($ch, CURLOPT_USERPWD, $username . ':' . $password);
curl_setopt($ch, CURLOPT_URL, $dest);
curl_setopt($ch, CURLOPT_UPLOAD, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 86400); // 1 Day Timeout
curl_setopt($ch, CURLOPT_INFILE, $fp);
curl_setopt($ch, CURLOPT_NOPROGRESS, false);
curl_setopt($ch, CURLOPT_BUFFERSIZE, 128);
curl_setopt($ch, CURLOPT_INFILESIZE, filesize($localFile));
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
curl_exec ($ch);
if (curl_errno($ch)) {
$msg = curl_error($ch);
}
else {
$msg = 'File uploaded successfully.';
}
curl_close ($ch);
}
Буду очень признателен за любую помощь!!!
РЕДАКТИРОВАТЬ: У меня также есть тест с нормальным crontab сейчас, и это тоже не работает. Он выполняет сценарий и проходит по нему без вывода сообщения об ошибке, но не загружает файл. Возможно ли, что это имеет отношение к аутентификации?
4 ответа
Наконец выяснилось, что это проблема с настройками прокси.
По какой-либо причине веб-сервер apache, а также incron / cron не распознают переменные среды, установленные на компьютере (http_proxy, https_proxy...)
Поэтому установка прокси и проксипорта непосредственно в моей команде curl решила проблему для меня.
curl_setopt($ch, CURLOPT_PROXY, '[ip.ip.ip...]');
curl_setopt($ch, CURLOPT_PROXYPORT, '[port]');
Более подробную информацию о настройке прокси и проксипорта можно найти в предоставленных ссылках.
Спасибо всем за ваш активный вклад, я рад, что наконец нашел решение для моей проблемы!
Если вы говорите, что все работает, когда вы бежите
> php /var/www/[further path]/uploadToSharepoint.php
вручную из командной строки, а не через incron, тогда, скорее всего, проблема с user
кто запускает команды incrone
Вариант 1) попытаться определить пользователя, который запускает команды incrone, а затем переключиться на этого пользователя и запустить снова php /var/www/[further path]/uploadToSharepoint.php
Вариант 2) попробуйте выполнить команду chmod для 0777 вашего каталога сканирования и повторите тестирование с помощью incron
Что касается ваших вопросов и комментариев, похоже, это не сработает.
Что касается вашего кода, я не очень уверен в функции, которую вы использовали
$pathToUpload=getTeamPath($newest_file);
Надеюсь, это даст вам правильный путь загрузки. Второй Вы используете CURLAUTH_NTLM
, Я помню, как однажды я должен был выполнить аналогичную задачу в тот раз, когда использовал CURLAUTH_BASIC
& это сработало. Поэтому, пожалуйста, попробуйте с этим.
Также CURLOPT_USERPWD
попробуйте включить домен в этом. Как
curl_setopt($ch, CURLOPT_USERPWD, 'domain\\username:password');
Дополнительно вы можете попробовать установить CURLOPT_POSTFIELDS
где данные будут ваши файлы получить пример содержимого:
$data = file_get_contents($file);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
Также по умолчанию curl попытается сделать запрос get. Я чувствую, что это должен быть запрос POST или PUT. Поэтому, пожалуйста, попробуйте указать метод как
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
Я только что прочитал страницу документации по функции scandir: http://php.net/manual/en/function.scandir.php
Он описывает второй параметр (sorting_order):
По умолчанию отсортированный алфавитный порядок в порядке возрастания. Если для необязательного sorting_order задано значение SCANDIR_SORT_DESCENDING, то порядок сортировки в алфавитном порядке в порядке убывания. Если установлено значение SCANDIR_SORT_NONE, то результат не сортируется.
Когда вы указываете 1
как sorting_order, он не сортирует на основе времени создания или изменения файлов в данном каталоге, а устанавливает порядок сортировки по именам файлов (в порядке убывания в алфавитном порядке).
У вас есть две строки в вашем коде:
$files = scandir($localFileURL, 1);
$newest_file = $files[0];
Именование переменной второй строки предлагает $files[0]
должен быть самым новым файлом, но это, вероятно, часто не так.
Это может привести к путанице, когда у вас есть несколько файлов или каталогов внутри вашего временного каталога, и поэтому может объяснить, почему первая попытка работает, а вторая - нет.
Одним из предложений является редактирование вашего incron-файла и использование $@
а также $#
в качестве параметров вашего PHP-скрипта, например:
/var/www/[further path]/temp IN_MODIFY,IN_CREATE /usr/bin/php /var/www/[further path]/uploadToSharepoint.php "$@/$#"
Или, возможно, из-за последствий для безопасности используйте эту форму:
/var/www/[further path]/temp IN_MODIFY,IN_CREATE /usr/bin/php /var/www/[further path]/uploadToSharepoint.php "$#"
При использовании второй формы в качестве параметра для вашего PHP-скрипта указывается только имя файла, которое было только что изменено или только что создано.
Тогда вы можете изменить эту строку:
$newest_file = $files[0];
К этому:
$newest_file = $argv[1];
Обратите внимание, что для $argv
для работы вам нужно включить эту опцию: http://php.net/manual/en/ini.core.php