curl halts script execution - php

my script uses curl to upload images to smugsmug site via smugsmug api.
i loop through a folder and upload every image in there. but after 3-4 uploads, curl_exec would fail, stopped everything and prevent other images from uploading.
$upload_array = array(
"method" => "smugmug.images.upload",
"SessionID" => $session_id,
"AlbumID" => $alb_id,
"FileName" => zerofill($n, 3) . ".jpg",
"Data" => base64_encode($data),
"ByteCount" => strlen($data),
"MD5Sum" => $data_md5);
$ch = curl_init();
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, $upload_array);
curl_setopt(
$ch, CURLOPT_URL,
"https://upload.smugmug.com/services/api/rest/1.2.2/");
$upload_result = curl_exec($ch); //fails here
curl_close($ch);
updated:
so i added logging into my script. when it does fail, the logging stops after fwrite($fh, "begin curl\n");
fwrite($fh, "begin curl\n");
$upload_result = curl_exec($ch);
fwrite($fh, "curl executed\n");
fwrite($fh, "curl info: ".print_r(curl_getinfo($ch,true))."\n");
fwrite($fh, "xml dump: $upload_result \n");
fwrite($fh, "curl error: ".curl_error($ch)."\n");
i also
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 60*60);

Not sure what the issue is... What is in the response when it fails? What do the system and apache logs say?
Now if i were you i wouldnt use curl_init() and curl_close() in the loop. instead i would init before the loop, and close after the loop - then within the loop itsef i would use curl_set_opt to set the url and differing parameters and just call curl_exec(). It may even be its a matter of all these handles exceeding some kind of system limit or something. If you need/want to use multiple connections you could use curl_multi or write some management functions/class to manage multiple handles.

We may need more info before we can help, but it sounds like it could be a timeout issue.
Turn on error reporting or check your error logs to see if anything is being raised.
Try setting a long cURL timeout with CURLOPT_TIMEOUT
Also check that your script timeout is sufficient or increase with set_time_limit()

1- Force Curl to tell you a bit more about what it does
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_HEADER, true);
2- If you are not in safe mode, make sure PHP displays errors by putting this at the beginning of your script:
<?php
ini_set('display_errors', '1');
error_reporting(E_ALL);
3- You can also try to run your script in CLI mode.
4- Finally, still if you are not in safe mode, you can try to directly run the curl binary using exec().
<?php
$curl_str = "curl -k -o /my/path/curl_output.log -d 'var1=".$value1."&var2=".$value2."& etc...' https://upload.smugmug.com/services/api/rest/1.2.2/";
$r = exec($curl_str);

CURL includes the 'multi' (for multiple-resources) options for when one is dealing with multiple high-latency requests (such as uploading images).
See:
http://www.php.net/manual/en/function.curl-multi-exec.php
and the entire library of 'multi' functions described here:
http://php.net/manual/en/book.curl.php
For a complete example of the multiple resource section of the library, see:
http://www.developertutorials.com/blog/php/parallel-web-scraping-in-php-curl-multi-functions-375/

You could try whether outputting curl_error() directly works:
$upload_result = curl_exec($ch); //fails here
$error = curl_error($ch);
if ($error) echo "CURL Error: $error";
curl_close($ch);
If that doesn't help, check your phpinfo(); to see whether error reporting is turned off globally (look for the display_errors setting).

Related

Google finance api is working on local server but not working on live

Find me code below just help me
<?php
$result=file_get_contents('http://finance.google.com/finance/info?client=ig&q=DHAMPURSUG');
$res=json_decode(result);
print_r($res);
?>
Try using basic cURL Post.
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,"http://finance.google.com/finance/info?client=ig&q=DHAMPURSUG");
curl_setopt($ch, CURLOPT_POST, 1);
// receive server response ...
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$server_output = curl_exec ($ch);
curl_close ($ch);
var_dump($server_output);
On your server, allow_url_fopen may be set to false, which would prevent file_get_contents() from fetching a URL (see the manual).
To figure out whether this is the case, run:
var_dump(ini_get('allow_url_fopen'))
If 0 or false is output on your production server, then you've found your problem. 2 possible fixes:
Edit the INI file
One fix is to change your php.ini file to set this setting to 1 or On. To find the ini file that governs your script, execute:
echo php_ini_loaded_file();
Go edit that file, then restart the web server.
Use cURL instead
An alternative is to use cURL to connect to google and fetch the info you need:
$options = [
CURLOPT_URL => 'http://finance.google.com...?client=ig&q=DHAMPURSUG',
CURLOPT_HEADER => 0,
CURLOPT_RETURNTRANSFER => true,
];
$ch = curl_init();
curl_setopt_array($ch,$options);
$result = curl_exec($ch);
curl_close($ch);
if($result===false) die(curl_errno($ch));
$result now holds the response.
Addendum
Another possibility (thanks Hanky Panky) is that the json_decode function is not available on your production server. To test this, run the line below to see whether it prints true
var_dump(function_exists('json_decode'));
You can upload the htaccess file in the root directory.

PHP curl_exec returning partial response

I have set up a php program that calls a RESTful web service using curl and gets back well-formed XML. When I do this on th e command line and I get the correct response but when I do this in PHP using curl_exec() I only get about half of the response. The response is basically cut short.
Does anyone know the cause of this?
Code is as follows:
$url = $this->dspace_url . '/dspace/search.xml?query=' . urlencode($query);
$sac_curl = curl_init();
error_log('query url is'.$url);
curl_setopt($sac_curl, CURLOPT_HTTPGET, true);
curl_setopt($sac_curl, CURLOPT_URL, $url);
curl_setopt($sac_curl, CURLOPT_VERBOSE, true);
curl_setopt($sac_curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($sac_curl, CURLOPT_HEADER, false);
$resp = curl_exec($sac_curl);
error_log('response is '.$resp);
Thanks,
Mark
It looks like you're using the error_log function to save your response to the error log.
There seems to be a limit on this (defaults to 1024 bytes) but you can change it in your php.ini file using the log_errors_max_len attribute. Try setting that to something larger and see if you find any difference.

500 Server error file_get_contents

I have two project on same server. I want some data form on my website so I am using file_get_contents; most of the time I get the 500 internal error
I checked that my url fopen is on using phpinfo().
With default settings, file_get_content() doesn't work behind a proxy or it cannot handle timeouts. It's normally recommended to read local files.
Therefore use cURL instead.
Below function could be used for the job:
function http_request($uri, $time_out = 10, $headers = 0)
{
// Initializing
$ch = curl_init();
// Set URI
curl_setopt($ch, CURLOPT_URL, trim($uri));
curl_setopt($ch, CURLOPT_HEADER, $headers);
// 1 - if output is not needed on the browser
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
// Time-out in seconds
curl_setopt($ch, CURLOPT_TIMEOUT, $time_out);
// Executing
$result = curl_exec($ch);
// Closing the channel
curl_close($ch);
return $result;
}
Let me know whether your're using Linux or Windows to give you cURL installation tips

PHP curl exec fail on php script same domain

I use php curl to get content from a php script in the same domain url. But I get curl_exec error. The curl error code is 28 or operation timed out. After days of debugging, I found that it works on non script page like htm, but not php, it also works if the url is a script on different domain. I have been debugging for days and found no solutions. Helps appreciated.
$url = 'http://...';
$agent = '';
$ch = curl_init();
curl_setopt ($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 8);
curl_setopt($ch, CURLOPT_TIMEOUT, 8);
$result = curl_exec ($ch);
print "<pre>\n";
print_r(curl_getinfo($ch));
// get error info echo "\n\ncURL error number:" .curl_errno($ch);
// print error info echo "\n\ncURL error:" . curl_error($ch);
print "</pre>\n";
curl_close ($ch);
echo $result;
cURL error number:28 cURL error:
Operation timed out after 8000
milliseconds with 0 bytes received
Okay: $url = http://.../page.htm
Fail: $url = http://.../page.php
You're not setting the User Agent. Some servers actually do not even respond to such requests (thus the client doesn't know the connection dropped).
Add the following to your code:
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
Additionally, I use the following in my CURL functionality:
curl_setopt($ch,CURLOPT_FOLLOWLOCATION,true);
curl_setopt($ch,CURLOPT_MAXREDIRS,50);
if(substr($url,0,8)=='https://'){
// The following ensures SSL always works. A little detail:
// SSL does two things at once:
// 1. it encrypts communication
// 2. it ensures the target party is who it claims to be.
// In short, if the following code is allowed, CURL won't check if the
// certificate is known and valid, however, it still encrypts communication.
curl_setopt($ch,CURLOPT_HTTPAUTH,CURLAUTH_ANY);
curl_setopt($ch,CURLOPT_SSL_VERIFYPEER,false);
}
Maybe because of session locks
Try to drop session_start() from page which you try to get using cURL
Also see this session.auto-start
Set into CURL setting
curl_setopt($ch, CURLOPT_TIMEOUT, 300); // 300 seconds
If still have issue so run the script with following location disable.
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, false);

Call to new HttpRequest fails

I am trying to get a PHP script working. The purpose of the script is to call out to a web service. I've reduced the script down to it's simpliest components and it is still failing. Here it is:
<?php
print "Hello";
$request = new HttpRequest('http://www.pivotaltracker.com/services/v3/source_commits', HttpRequest::METH_POST);
print "Done";
?>
The output is:
D:\svn\svndb\hooks>"c:\Program Files\PHP\php.exe" -f test.php
Hello
D:\svn\svndb\hooks>
As you can see, the script fails when trying to instantiate an instance of HttpRequest. However, no exception is thrown.
I am not a PHP program... I'm just trying to get this feature working. I suspect I have no loaded an extension library that I need... but I can't figure out which one that would be, if indeed that is the problem.
I am running on Windows 2003. I am running PHP 5.3.3.
I did run phpinfo() but am hesitant to post the results here since it is so large. Is there a section of the phpinfo() output that would be helpful to provide?
Put a error_reporting(E_ALL); in front and see what happens.
My bet is that the HTTPRequest class doesn't exist. The HTTP extension is a PECL package that needs to be installed separately.
Thank you everyone for your answers. They were all spot on. I thought I'd summnarize what I did in the end in case it helps someone else.
The problem was indeed that I had not installed the http PECL extension. Unfortunately, I am on windows and there was no distriubtion of this extension and I didn't want to install the microsoft tools on this box to be able to compile the source. So, I went with the suggestion listed above and implemented it using curl.
The script I was working on was to integration svn to http://www.pivotaltracker.com using the excellent php script found at http://phpjack.com/content/pivotal-tracker-and-subversion. I modified that script as follows (in case someone else is in a similar spot):
$request = new HttpRequest('http://www.pivotaltracker.com/services/v3/source_commits', HttpRequest::METH_POST);
$headers = array(
'X-TrackerToken' => $token,
'Content-type' => 'application/xml'
);
$request->setHeaders($headers);
$request->setBody("<source_commit><message>$message</message><author>$author</author><commit_id>$rev</commit_id></source_commit>");
$request->send();
became
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, array("Content-Type: application/xml","X-TrackerToken: $token"));
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_setopt($ch, CURLOPT_POST, 1);
$result = curl_exec ($ch);
curl_close ($ch);
print $result;
Thanks again for all the excellent and timely advise.
Error reporting by error_reporting( E_ALL );
Enable display errors ini_set('display_errors', 1);
Better to change these settings from php.ini.
If it's not working look at apache logs (error.log)
You could use cURL for that simple purpose:
<?php
$url = "http://www.pivotaltracker.com/services/v3/source_commits";
$ch = curl_init();
// set the target url
curl_setopt($ch, CURLOPT_URL, $url);
// howmany parameter to post
curl_setopt($ch, CURLOPT_POST, 1);
// parameters
curl_setopt($ch, CURLOPT_POSTFIELDS, "someParameter=someValue");
$result = curl_exec ($ch);
curl_close ($ch);
print $result;
?>
Or use fsockopen() to connect to a server and fwrite to send a raw http post request.

Categories