6

我有一个 PHP 脚本,它使用 cURL 在 Sharepoint 上上传文档。如果我在终端中运行 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

4 回答 4

0

如果你说跑步时一切正常

> php /var/www/[further path]/uploadToSharepoint.php 

从命令行手动但不是通过 incron 然后最有可能的问题是user谁运行 incrone 命令

选项 1)尝试识别运行 incrone 命令的用户,然后切换到该用户并再次运行相同php /var/www/[further path]/uploadToSharepoint.php

选项 2)尝试 chmod 到 0777 您的扫描目录并使用 incron 再次测试

于 2017-03-07T14:24:06.283 回答
0

根据您的问题和评论,这两种方法似乎都不起作用。

根据您的代码,我不太确定您使用的功能

$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");
于 2017-03-09T05:04:29.620 回答
0

我刚刚阅读了 scandir-function 的文档页面:http: //php.net/manual/en/function.scandir.php

它描述了第二个参数(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#ini.register-argc-argv

于 2017-03-09T07:56:09.153 回答
0

最后发现,代理设置有问题

无论出于何种原因,apache 网络服务器以及 incron/cron 都无法识别机器中设置的环境变量(http_proxy、https_proxy ...)

因此,直接在我的 curl 命令中设置代理和代理端口为我解决了这个问题。

curl_setopt($ch, CURLOPT_PROXY, '[ip.ip.ip...]'); 
curl_setopt($ch, CURLOPT_PROXYPORT, '[port]'); 

可以在提供的链接中找到有关设置代理和代理端口的更多信息。

感谢大家的积极贡献,我很高兴我终于找到了解决我问题的方法!

于 2017-03-11T19:23:23.560 回答