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

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