简体   繁体   中英

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. If I run the scipt in the terminal, the upload process works fine.

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.

My incron file looks like the following:

/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. But for some reasons, the file is not uploaded to the 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';

    $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. 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

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

Option 2) try to chmod to 0777 your scan directory and test again with 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 . I remember once I had to do the similar task that time I have used CURLAUTH_BASIC & it worked. So Please try with it.

Also CURLOPT_USERPWD try including domain in this. 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 :

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

Also by default curl will try to make get request. I feel it should be POST or PUT Request. 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

It describes the second parameter (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. If it is set to SCANDIR_SORT_NONE then the result is unsorted.

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).

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.

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:

/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.

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

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...)

Therefore, setting the proxy and the proxyport directly in my curl command solved the problem for me.

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!

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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