简体   繁体   English

用于上传文件的PHP脚本在终端中工作,但不能与incron一起自动调用

[英]PHP script to upload file works in terminal, but not as automatical call with incron

I have a PHP script that uploads a document on a Sharepoint using cURL. 我有一个PHP脚本,使用cURL在Sharepoint上上传文档。 If I run the scipt in the terminal, the upload process works fine. 如果我在终端中运行scipt,则上传过程正常。

As I would like to automatically call the script whenever this file is changed, I use incron to detect a change in the respective folder and trigger the call of the PHP script. 因为我想在更改此文件时自动调用脚本,我使用incron来检测相应文件夹中的更改并触发PHP脚本的调用。

My incron file looks like the following: 我的incron文件如下所示:

/var/www/[further path]/temp IN_MODIFY,IN_CREATE /usr/bin/php /var/www/[further path]/uploadToSharepoint.php

When I have a look at the syslog, I can see that the script call has been triggered correctly by incron. 当我查看syslog时,我可以看到incron正确触发了脚本调用。 But for some reasons, the file is not uploaded to the Sharepoint. 但由于某些原因,该文件未上载到Sharepoint。 I also tried to create the file with global write permissions, but this didn't solve my problem. 我还尝试使用全局写权限创建文件,但这并没有解决我的问题。

-rwxrwxrwx 1 www-data www-data 49058 Mär  3 10:28 [file].xlsx

Here is my script I'm calling: 这是我正在调用的脚本:

include 'database.php'; 包括'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);
  }

I would really appreciate any help!!! 我真的很感激任何帮助!

EDIT: I have also teste it with a normal crontab now and this doesn't work either. 编辑:我现在也用普通的crontab测试它,这也不起作用。 It does execute the script and loops through it without printing an error, but doesn't upload the file. 它执行脚本并循环遍历它而不打印错误,但不上传文件。 Is it possible that is has somethin to do with the authentication? 是否有可能与身份验证有关?

If you says that all works when you run 如果你说跑步时一切正常

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

manually from command line but not through incron then most probably problem is with user who runs incrone commands 从命令行手动但不通过incron然后很可能问题是运行incrone命令的user

Option 1) try to identify user who runs incrone commands and then switch to that user and run again same php /var/www/[further path]/uploadToSharepoint.php 选项1)尝试识别运行incrone命令的用户,然后切换到该用户并再次运行相同的php /var/www/[further path]/uploadToSharepoint.php

Option 2) try to chmod to 0777 your scan directory and test again with incron 选项2)尝试chmod到0777扫描目录并再次使用incron进行测试

As per your questions and comments, it doesn't seems to work either way. 根据您的问题和评论,它似乎无论如何都不起作用。

As per your code, I am not very sure about the function you have used 根据您的代码,我不太确定您使用的功能

$pathToUpload=getTeamPath($newest_file);

Hope it gives you correct upload path. 希望它能为您提供正确的上传路径。 Second You are using CURLAUTH_NTLM . 第二,您正在使用CURLAUTH_NTLM I remember once I had to do the similar task that time I have used CURLAUTH_BASIC & it worked. 我记得有一次,当我使用CURLAUTH_BASIC时,我必须完成类似的任务。 So Please try with it. 所以请试试吧。

Also CURLOPT_USERPWD try including domain in this. 此外, CURLOPT_USERPWD尝试包含域名。 As

curl_setopt($ch, CURLOPT_USERPWD, 'domain\\username:password');

Additionally you can try setting CURLOPT_POSTFIELDS where data will be your file get content example : 此外,您可以尝试设置CURLOPT_POSTFIELDS ,其中数据将是您的文件获取内容示例:

$data = file_get_contents($file); 
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

Also by default curl will try to make get request. 此外,默认情况下curl将尝试生成get请求。 I feel it should be POST or PUT Request. 我觉得应该是POST或PUT请求。 SO please try with specifying method as 所以请尝试指定方法为

curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");

I just read the documentation page of the scandir-function: http://php.net/manual/en/function.scandir.php 我刚刚阅读了scandir-function的文档页面: http//php.net/manual/en/function.scandir.php

It describes the second parameter (sorting_order): 它描述了第二个参数(sorting_order):

By default, the sorted order is alphabetical in ascending order. 默认情况下,排序顺序按字母顺序升序排列。 If the optional sorting_order is set to SCANDIR_SORT_DESCENDING, then the sort order is alphabetical in descending order. 如果可选的sorting_order设置为SCANDIR_SORT_DESCENDING,则排序顺序按字母顺序降序排列。 If it is set to SCANDIR_SORT_NONE then the result is unsorted. 如果设置为SCANDIR_SORT_NONE,则结果未排序。

When you specify 1 as sorting_order it does not sort based on creation or modification time of the files in given directory but bases the sort order on the names of the files (descending alphabetical order). 当您指定1作为sorting_order时,它不会根据给定目录中文件的创建或修改时间进行排序,而是基于文件名称的排序顺序(按字母顺序降序)。

You have these two lines in your code: 你的代码中有这两行:

$files = scandir($localFileURL, 1);
$newest_file = $files[0];

The variable naming of the second line suggests $files[0] should be the newest file but this is probably often not the case. 第二行的变量命名表明$files[0]应该是最新的文件,但通常情况并非如此。

This would get confusing when you have multiple files or directories inside your temporary directory and as such could explain why the first try works and a second try does not. 当您在临时目录中有多个文件或目录时,这会让人感到困惑,因此可以解释为什么第一次尝试有效,第二次尝试没有。

One suggestion is to edit your incron-file and use $@ and $# as parameters to your PHP-script, like: 一个建议是编辑你的incron文件并使用$@$#作为PHP脚本的参数,例如:

/var/www/[further path]/temp IN_MODIFY,IN_CREATE /usr/bin/php /var/www/[further path]/uploadToSharepoint.php "$@/$#"

Or maybe because of security implications use this form: 或者可能因安全问题使用此表单:

/var/www/[further path]/temp IN_MODIFY,IN_CREATE /usr/bin/php /var/www/[further path]/uploadToSharepoint.php "$#"

Using the second form only the filename which has just been modified or just been created is given as a parameter to your PHP-script. 使用第二种形式,只有刚修改或刚刚创建的文件名作为PHP脚本的参数给出。

Then you can change this line: 然后你可以改变这一行:

$newest_file = $files[0];

To this: 对此:

$newest_file = $argv[1];

Note though that for $argv to work you need to have this option enabled: http://php.net/manual/en/ini.core.php#ini.register-argc-argv 请注意,要使$argv正常工作,您需要启用此选项: http//php.net/manual/en/ini.core.php#ini.register-argc-argv

Finally it turned out, that it has been an issue with the proxy settings . 最后结果是,它一直是代理设置问题

For whatever reason the apache webserver as well as the incron/cron don't recognize the environment variables that have been set in the machine (http_proxy, https_proxy...) 无论出于何种原因,apache webserver以及incron / cron都无法识别机器中设置的环境变量(http_proxy,https_proxy ......)

Therefore, setting the proxy and the proxyport directly in my curl command solved the problem for me. 因此, 直接在我的curl命令中设置代理和代理端口为我解决了问题。

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

More information about setting proxy and proxyport can be found in the provided links. 有关设置代理代理 端口的更多信息,请参阅提供的链接。

Thank you all for your active contributon, I'm glad that i finally found a solution for my problem! 谢谢大家的积极贡献,我很高兴我终于找到了解决问题的方法!

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM