Rebuilding the script from cURL to multi cURL - php

I'm trying to implement some multi cURL functions instead of simple cURL functions.
I have the following snippet:
$curl = curl_init();
curl_setopt($curl, CURLOPT_ENCODING,'gzip');
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, $url);
$result = curl_exec($curl);
curl_close($curl);
$rv = ($returnArray) ? json_decode($result, true) : json_decode($result);
It gives me results ($result returns success and some data). I want to rewrite it to use curl_multi_init(). I tried this:
$curl = curl_init();
curl_setopt($curl, CURLOPT_ENCODING,'gzip');
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_URL, $url);
$mh = curl_multi_init();
curl_multi_add_handle($mh,$curl);
$running= \null;
do {
curl_multi_exec($mh,$running);
$result = curl_multi_exec($mh,$running);
} while($running > 0);
curl_multi_remove_handle($mh, $curl);
curl_multi_close($mh);
$rv = ($returnArray) ? json_decode($result, true) : json_decode($result);
I get no results ($result is empty). I have no errors whatsoever. What is wrong?

This Works for me :
function get_result( $nodes )
{
$node_count = count($nodes);
$curl_arr = array();
$master = curl_multi_init();
for($i = 0; $i < $node_count; $i++)
{
$url = $nodes[$i];
$curl_arr[$i] = curl_init($url);
curl_setopt($curl_arr[$i], CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl_arr[$i], CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($curl_arr[$i], CURLOPT_TIMEOUT, 10);
curl_setopt($curl_arr[$i], CURLOPT_ENCODING, "gzip");
curl_setopt($curl_arr[$i], CURLOPT_VERBOSE, true);
curl_setopt($curl_arr[$i], CURLOPT_USERAGENT, 'Mozilla/5.0');
curl_setopt($curl_arr[$i], CURLOPT_FOLLOWLOCATION, true);
curl_setopt($curl_arr[$i], CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4);
curl_multi_add_handle($master, $curl_arr[$i]);
}
do {
curl_multi_exec($master,$running);
curl_multi_select($master, 5.0);
} while($running > 0);
$output = "";
for($i = 0; $i < $node_count; $i++)
{
$output .= curl_multi_getcontent( $curl_arr[$i] ) . "<breaktag>";
curl_multi_remove_handle( $master, $curl_arr[$i] );
curl_close( $curl_arr[$i] );
}
curl_multi_close( $master );
return $output;
}
$nodes[] = () // your URLs
$responses = get_result( $nodes );
$responses = explode("<breaktag>", $responses); //now responses is array of result

Related

PHP cURL convert to GuzzleHttp

Please, how to convert the following code to async GuzzleHttp?
In this way, php is waiting for the return of each query.
while ($p = pg_fetch_array($var)) {
$url = "https://url";
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$headers = array("Content-Type: application/json");
curl_setopt($curl, CURLOPT_HTTPHEADER, $headers);
$data = '{"s1":"s1","number":"'.$p['number'].'"}';
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
curl_setopt($curl, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
$resp = curl_exec($curl);
curl_close($curl);
var_dump($resp);
}
Here's a working example using native curl_multi_*() functions. Specifically:
curl_multi_init()
curl_multi_add_handle()
curl_multi_exec()
curl_multi_getcontent()
curl_multi_remove_handle()
curl_multi_close()
<?php
$urls = ['https://example.com/', 'https://google.com'];
$handles = [];
foreach ($urls as $url) {
$handle = curl_init();
curl_setopt($handle, CURLOPT_URL, $url);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
$handles[] = $handle;
}
$multiHandle = curl_multi_init();
foreach ($handles as $handle) {
curl_multi_add_handle($multiHandle, $handle);
}
for(;;){
curl_multi_exec($multiHandle, $stillRunning);
if($stillRunning > 0){
// some handles are still downloading, sleep-wait for data to arrive
curl_multi_select($multiHandle);
}else{
// all downloads completed
break;
}
}
foreach ($handles as $handle) {
$result = curl_multi_getcontent($handle);
var_dump($result);
curl_multi_remove_handle($multiHandle, $handle);
}
curl_multi_close($multiHandle);
Now, how convert the code cUrl to GuzzleHttp?

PHP Curl Multi post json data

I got stuck for 2 hours on this php curl multiple request
i wantta make post json data start from 1111(This is a start point and as a verificationCode) to 1121(end point 1111 + $process_count)
check this out guys :
<?php
$url = "https://api.mywebsite.com/myapp/customer/verification";
$mh = curl_multi_init();
$handles = array();
$process_count = 10;
for($c=1111;$c <= 1121;$c++){
$data_verification = array(
"phone" => "+6285643103039", // +6285643103039 9025
"verificationCode" => $c
);
$str_verification = json_encode($data_verification);
}
while ($process_count--)
{
$ch = curl_init($url);
$headers= array('Accept: application/json','Content-Type: application/json');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_TIMEOUT, 4000);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS,$str_verification);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
ob_start();
curl_multi_add_handle($mh, $ch);
$handles[] = $ch;
}
$running=null;
do
{
curl_multi_exec($mh, $running);
}
while ($running > 0);
for($i = 0; $i < count($handles); $i++)
{
$out = curl_multi_getcontent($handles[$i]);
echo "$i. ";
print $out . "\r\n";
echo "<br>";
curl_multi_remove_handle($mh, $handles[$i]);
}
curl_multi_close($mh);
?>
But
curl_setopt($ch, CURLOPT_POSTFIELDS,$str_verification); always given end point value 1121.
And doesn't looping
from 1111 to 1121.
Anyone can figure it out ? i'll glad for any help
You are doing a mistake in your first loop, you are erasing data every time into only one variable and not array
$str_verification = json_encode($data_verification);
Here is what I suggest you to do :
$str_verification = array();
for($c=1111;$c <= 1121;$c++){
$data_verification = array(
"phone" => "+6285643103039", // +6285643103039 9025
"verificationCode" => $c
);
$str_verification[] = json_encode($data_verification);
}
for ($i = 0; $i != 10; $i++)
{
$ch = curl_init($url);
$headers= array('Accept: application/json','Content-Type: application/json');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_USERAGENT, $_SERVER['HTTP_USER_AGENT']);
curl_setopt($ch, CURLOPT_TIMEOUT, 4000);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_POSTFIELDS,$str_verification[$i]);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
ob_start();
curl_multi_add_handle($mh, $ch);
$handles[] = $ch;
}

Multiple curl json and json print

I want to access multiples urls via curl and print the son output. I've seen this: multiple cURL and output JSON? but I`am not able make it work anyway...
my code:
<?php
$urls = Array(
'URLtoJSON1',
'URLtoJSON1'
);
for($i = 0; $i < 3; $i++) {
$curl[$i] = curl_init($urls);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_USERPWD, "YYY:XXX");
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, $curl_post_data);
$curl_response[$i] = curl_exec($curl);
curl_close($curl);
$data = json_decode($curl_response[$i]);
$name[$i] = $data->fullDisplayName;
$datum[$i] = $data->timestamp;
$result[$i] = $data->result;
}
// here I`d love to be able echo output $name[URLtoJSON], etc...
?>
thank you for any help.
Instead of doing a for loop, you can make a foreach loop that iterates over your $urls array by doing foreach ($urls as $key=>$url). $key will hold the index of the array (starting at 0) and $url will hold the URL.
Here is what the resulting code would look like:
$urls = Array(
'URLtoJSON1',
'URLtoJSON2'
);
foreach ($urls as $key=>$url) {
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($ch, CURLOPT_USERPWD, "YYY:XXX");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $ch_post_data);
$ch_response = curl_exec($ch);
curl_close($ch);
$data = json_decode($ch_response);
$name[$key] = $data->fullDisplayName;
$datum[$key] = $data->timestamp;
$result[$key] = $data->result;
}
Now if you want to access $name of the first URL, you would just do $echo $name[0];
You can also access $datum or $result in a similar way.

Random 500 errors in a multi CURL request

I am trying to get some hal+json data from a web service through a curl_multi to fill in a Bootstrap Typeahead. Every time I run this code, some of my requests in the curl_multi will be 500, and some will return the data I need. The ones that are 500 are completely random; the next time I load the page different queries will be 500 instead (And I get no errors). Why does that keep happening?
<?php
$curlurl = 'https://service.domain.com/'.$_POST['customer-name'].'/contact?callback=?';
$cuurl = singleRequest($curlurl);
global $contacts_typeahead_data;
$contacts_typeahead_data = array();
$clinks = $cuurl['_links']['https://service.domain.com/rel/contacts'];
for ($i=0; $i < count($clinks); $i++) {
$data[] = 'https://service.domain.com'.$clinks[$i]['href'].'?callback=?';
};
print_r($data);
$datar = multiRequest($data);
print_r($datar);
foreach($datar as $c){
$cs = json_decode($c, true);?>
<option value="<?php echo $cs['id']; ?>"><?php echo $cs['id'].' ('.$cs['info'][0]['name'].')'; ?></option>
<?php $contacts_typeahead_data[] = $cs['id'].' ('.$cs['info'][0]['name'].')';
}?>
And here is the code to the singleRequest and multiRequest, which is based on http://www.phpied.com/simultaneuos-http-requests-in-php-with-curl/:
function multiRequest($data, $options = array()) {
// array of curl handles
$curly = array();
// data to be returned
$result = array();
// multi handle
$mh = curl_multi_init();
// loop through $data and create curl handles
// then add them to the multi-handle
foreach ($data as $id => $d) {
$curly[$id] = curl_init();
$url = (is_array($d) && !empty($d['url'])) ? $d['url'] : $d;
$username = base64_encode('username');
$password2 = 'password';
$auth_token = $username . $password2 . 'QQ==';
curl_setopt($curly[$id], CURLOPT_URL, $url);
curl_setopt($curly[$id], CURLOPT_HEADER, 0);
curl_setopt($curly[$id], CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curly[$id], CURLOPT_USERPWD, "$username:$password2");
curl_setopt($curly[$id], CURLOPT_SSLVERSION,3);
curl_setopt($curly[$id], CURLOPT_HTTPHEADER, array(
'Accept: application/hal+json',
'Access-Control-Allow-Origin: *',
'Content-Type: application/hal+json',
'Authorization: Basic ' . $auth_token
));
curl_setopt($curly[$id], CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($curly[$id], CURLOPT_CONNECTTIMEOUT, 0);
curl_setopt($curly[$id], CURLOPT_TIMEOUT, 30);
curl_setopt($curly[$id], CURLOPT_PORT, 443);
curl_setopt($curly[$id], CURLOPT_REFERER, $_SERVER['HTTP_REFERER']);
curl_setopt($curly[$id], CURLOPT_USERAGENT, 'Mozilla/4.0 (compatible; MSIE 5.01; Windows NT 5.0)');
curl_setopt($curly[$id], CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($curly[$id], CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($curly[$id], CURLOPT_COOKIE, 'cert_url=https://service.domain.com/cert/yagowyefayygwflagliwygelifyaigwepifgpai');
// post?
if (is_array($d)) {
if (!empty($d['post'])) {
curl_setopt($curly[$id], CURLOPT_POST, 1);
curl_setopt($curly[$id], CURLOPT_POSTFIELDS, $d['post']);
}
}
// extra options?
if (!empty($options)) {
curl_setopt_array($curly[$id], $options);
}
curl_multi_add_handle($mh, $curly[$id]);
}
// execute the handles
$running = null;
do {
curl_multi_exec($mh, $running);
} while($running > 0);
// get content and remove handles
foreach($curly as $id => $c) {
// cURL error number
$curl_errno = curl_errno($c);
// cURL error message
$curl_error = curl_error($c);
// output if there was an error
if ($curl_error) {
echo " *** cURL error: (".$curl_errno.") ".$curl_error;
} else {
$result[$id] = curl_multi_getcontent($c);
}
curl_multi_remove_handle($mh, $c);
}
// all done
curl_multi_close($mh);
return $result;
}
function singleRequest($curlurl){
$username = base64_encode('username');
$password2 = 'password';
$auth_token = $username . $password2 . 'QQ==';
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_USERPWD, "$username:$password2");
curl_setopt($ch, CURLOPT_SSLVERSION,3);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Accept: application/hal+json',
'Access-Control-Allow-Origin: *',
'Content-Type: application/hal+json',
'Authorization: Basic ' . $auth_token
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_COOKIE, 'cert_url=https://service.domain.com/cert/yagowyefayygwflagliwygelifyaigwepifgpai');
$result = curl_exec($ch);
if($result === false){
echo 'Curl error: ' . curl_error($ch). '<br><br>';
print_r(error_get_last());
}
$response = json_decode($result, true);
curl_close($ch);
return $response;
}
Edit Added error check
Why does that keep happening?
The server you send the request to makes this happen. It is just that requests can fail.
Deal with it and design for failure.

Accessing Google Bookmarks server side with PHP

I used to access my Google Bookmarks, server side with this PHP code:
$curlObj = curl_init();
curl_setopt($curlObj, CURLOPT_URL, "https://www.google.com/bookmarks/?output=rss");
curl_setopt($curlObj, CURLOPT_USERPWD, "whatever#googlemail.com:mypassword");
curl_setopt ($curlObj, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($curlObj);
echo $response;
curl_close($curlObj);
Formerly, with the code above, I would have seen an XML feed.
Now it shows "302 Your document has moved. Click Here".
The link takes me to a login page.
Any ideas?
Thanks.
such authorization is no longer working. you need auth via https://accounts.google.com/ServiceLogin and after get https://www.google.com/bookmarks/?output=rss
example:
<?
$USERNAME = 'aaa';
$PASSWORD = 'bbb';
$ch = curl_init();
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_USERAGENT, "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_COOKIEJAR, "cookie.txt");
curl_setopt($ch, CURLOPT_COOKIEFILE, "cookie.txt");
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER,1);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 120);
curl_setopt($ch, CURLOPT_TIMEOUT, 120);
curl_setopt($ch, CURLOPT_URL,
'https://accounts.google.com/ServiceLogin?hl=en&service=bookmarks&continue=http://www.google.com/bookmarks');
$data = curl_exec($ch);
$formFields = getFormFields($data); // my code to get form fields, ask if you want it
$formFields['Email'] = $USERNAME;
$formFields['Passwd'] = $PASSWORD;
unset($formFields['PersistentCookie']);
$post_string = '';
foreach($formFields as $key => $value) {
$post_string .= $key . '=' . urlencode($value) . '&';
}
$post_string = substr($post_string, 0, -1);
curl_setopt($ch, CURLOPT_URL, 'https://accounts.google.com/ServiceLoginAuth');
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $post_string);
$result = curl_exec($ch);
$info = curl_getinfo($ch);
// echo var_dump($info);
if ($info['url']=="https://accounts.google.com/ServiceLoginAuth")
{
die("Login failed");
var_dump($result);
} else {
curl_setopt($ch, CURLOPT_URL, 'http://www.google.com/bookmarks/?output=rss');
curl_setopt($ch, CURLOPT_POST, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, null);
$result = curl_exec($ch);
var_dump($result);
}
function getFormFields($data)
{
if (preg_match('/(<form id=.?gaia_loginform.*?<\/form>)/is', $data, $matches)) {
$inputs = getInputs($matches[1]);
return $inputs;
} else {
die('didnt find login form');
}
}
function getInputs($form)
{
$inputs = array();
$elements = preg_match_all('/(<input[^>]+>)/is', $form, $matches);
if ($elements > 0) {
for($i = 0; $i < $elements; $i++) {
$el = preg_replace('/\s{2,}/', ' ', $matches[1][$i]);
if (preg_match('/name=(?:["\'])?([^"\'\s]*)/i', $el, $name)) {
$name = $name[1];
$value = '';
if (preg_match('/value=(?:["\'])?([^"\'\s]*)/i', $el, $value)) {
$value = $value[1];
}
$inputs[$name] = $value;
}
}
}
return $inputs;
}

Categories