Related
I'm trying to make a site for my battlefield 1 clan, on one of the pages i'd like to display our team and some of their stats.
This API allows me to request just what I need, I decide to use php curl requests to get this data on my site. It all works perfectly fine, but it is super slow, sometimes it even reaches the 30s max of php.
Here is my code
<?php
$data = $connection->query("SELECT * FROM bfplayers");
while($row = mysqli_fetch_assoc($data)){
$psnid = $row['psnid'];
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://battlefieldtracker.com/bf1/api/Stats/BasicStats?platform=2&displayName=".$psnid);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
$headers = [
'TRN-Api-Key: MYKEY',
];
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
curl_close($ch);
$result = json_decode($response, true);
print($result['profile']['displayName']);
}
?>
I have no idea why it's going this slow, is it because I am using xamp on localhost or because the requests are going through a loop?
Thanks in advance
your loop is not optimized in the slightest, i believe if you optimized your loop code, your code could run A LOT faster. you create and delete the curl handle on each iteration, when you could just keep re-using the same curl handle on each player (this would use less cpu and be faster), you don't use compressed transfer (enabling compression would probably make the transfer faster), and most importantly, you run the api calls sequentially, i believe if you did the api requests in parallel, it would load much faster. also, you don't urlencode psnid, that's probably a bug. try this
<?php
$cmh = curl_multi_init ();
$curls = array ();
$data = $connection->query ( "SELECT * FROM bfplayers" );
while ( ($row = mysqli_fetch_assoc ( $data )) ) {
$psnid = $row ['psnid'];
$tmp = array ();
$tmp [0] = ($ch = curl_init ());
$tmp [1] = tmpfile ();
$curls [] = $tmp;
curl_setopt_array ( $ch, array (
CURLOPT_URL => "https://battlefieldtracker.com/bf1/api/Stats/BasicStats?platform=2&displayName=" . urlencode ( $psnid ),
CURLOPT_ENCODING => '',
CURLOPT_SSL_VERIFYPEER => false,
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_HTTPHEADER => array (
'TRN-Api-Key: MYKEY'
),
CURLOPT_FILE => $tmp [1]
) );
curl_multi_add_handle ( $cmh, $ch );
curl_multi_exec ( $cmh, $active );
}
do {
do {
$ret = curl_multi_exec ( $cmh, $active );
} while ( $ret == CURLM_CALL_MULTI_PERFORM );
curl_multi_select ( $cmh, 1 );
} while ( $active );
foreach ( $curls as $curr ) {
fseek ( $curr [1], 0, SEEK_SET ); // https://bugs.php.net/bug.php?id=76268
$response = stream_get_contents ( $curr [1] );
$result = json_decode ( $response,true );
print ($result ['profile'] ['displayName']) ;
}
// the rest is just cleanup, the client shouldn't have to wait for this
// OPTIMIZEME: apache version of fastcgi_finish_request() ?
if (is_callable ( 'fastcgi_finish_request' )) {
fastcgi_finish_request ();
}
foreach ( $curls as $curr ) {
curl_multi_remove_handle ( $cmh, $curr [0] );
curl_close ( $curr [0] );
fclose ( $curr [1] );
}
curl_multi_close ( $cmh );
it runs all api calls in parallel, and use transfer compression (CURLOPT_ENCODING), and runs api requests in parallel with downloading results from the db, and it tries to disconnect the client before running cleanup routines, it will probably run much faster.
also, if mysqli_fetch_assoc() are causing slow roundtrips to your db, it would probably be even faster to replace it with mysqli_fetch_all()
also, something that would probably be much faster than this, would be to have a cronjob run every minute (or every 10 seconds?) that caches the results, and show a cached result to the client. (even if the api calls lags, the client pageload wouldn't be affected at all.)
I am building a function to download images from an external source, and then write the id of each product has been downloaded along with the path to json file,
The download loop is working correctly but when am trying to save the product id & image path to a text file only the first record is saved.
i tried to print the output before using the file_put_contents function and it turns out am getting the correct result. I am wondering why only the first result is saved not all of them ?
I spent almost all day tryinf to figure it out but no luck. any help will be appreciated.
here is my code:
$url = 'product-test2.json'; // path to JSON file
$data = file_get_contents($url);
$characters = json_decode($data, true);
$i = array_column ($characters , 'Id');
foreach ( $i as $value => $productid){
include 'login.php';
$url = "http://xxxx.com/api/products/image/";
$url .= implode($matches [0]); // get the token form login.php
$url .= '/' . $productid ; //product id
// echo $url . '<br>';
$opts = array ('http' => array (
'methos' => 'GET',
'header' => 'Content-typpe: application/json',
)
);
$context = stream_context_create ($opts);
$urlImage = file_get_contents ($url , false , $context);
$urlImage = substr_replace ($urlImage , "",-1);
$urlImage = substr ($urlImage , 1);
$fopenpath = 'C:\\xampp\htdocs\\test\\api\\images\\' ;
$fopenpath .= $productid . '.jpg';
$fp = fopen ( $fopenpath, 'w');
$c = curl_init ($urlImage);
curl_setopt ($c , CURLOPT_FILE , $fp);
curl_setopt ($c , CURLOPT_HEADER, 0);
curl_setopt ($c , CURLOPT_POST, false);
curl_setopt ($c , CURLOPT_SSL_VERIFYPEER, false);
$rawdata = curl_exec ($c);
fwrite ($fp, $rawdata);
fclose ($fp);
//
$result3= ["id" => $productid ,"image_path" => $fopenpath] ;
$image_file = "images.json";
$output = json_encode ($result3);
print_r ($output);
file_put_contents ($image_file , $output );
};
and here is the result from print_r ($result3);
{"id":2977,"image_path":"C:\\xampp\\htdocs\\test\\api\\images\\2977.jpg"} {"id":2981,"image_path":"C:\\xampp\\htdocs\\test\\api\\images\\2981.jpg"} {"id":3009,"image_path":"C:\\xampp\\htdocs\\test\\api\\images\\3009.jpg"} {"id":3018,"image_path":"C:\\xampp\\htdocs\\test\\api\\images\\3018.jpg"} {"id":11531,"image_path":"C:\\xampp\\htdocs\\test\\api\\images\\11531.jpg"}
as you can see the Print_r is correct all what i want to do is to save the output into file and currently here is the result from file_put_contents only one array :
{"id":11531,"image_path":"C:\\xampp\\htdocs\\test\\api\\images\\11531.jpg"}
can you please help and tell me what am doing wrong i already spend a lot of time on this :)
file_put_contents is the same as opening, writing, and closing the file, which doesn't really make sense to do in a foreach loop. If you really want to use it, I think you could add the FILE_APPEND flag, which will stop it from overwriting itself over and over and over.
An alternative would be to fopen before the foreach loop with the 'a' flag, which will create the file then keep appending lines instead of wiping out the file contents every loop. (And fclose after the foreach.)
here i am trying to fetch all issues from Redmine by using curl php below is the code which i used.
my CURL.php:
flie class file in redmine/redmine_curl.php
<?php # Redmine Api
class class_redmine{
function get_upload_token($filecontent){
global $redmine_url , $redmine_key;
$upload_url = $redmine_url.'uploads.json?key='.$redmine_key;
$request['type'] = 'post';
$request['content_type'] = 'application/octet-stream';
//$filecontent = file_get_contents('test.php');
return $token = $this->curl_redmine($upload_url,$request,$filecontent);
//$token->upload->token;
}
#Issue
function create_issue($post_data){
global $redmine_url , $redmine_key;
$issue_url = $redmine_url.'issues.json?key='.$redmine_key;
$request['type'] = 'post';
$request['content_type'] = 'application/json';
return $this->curl_redmine($issue_url,$request,$post_data);
}
function get_issue($issue_id='',$project_id=''){
global $redmine_url , $redmine_key;
if($project_id!=''){
$issue_url = $redmine_url.'issues.json?key='.$redmine_key.'&project_id='.$project_id;
}else{ $issue_url = ($issue_id=='')?$redmine_url.'issues.json?key='.$redmine_key : $redmine_url.'issues/'.$issue_id.'.json?key='.$redmine_key;
}
return $this->curl_redmine($issue_url,'','');
}
#Projects
function get_projects($project_id=''){
global $redmine_url , $redmine_key;
$proj_url = ($project_id=='')?$redmine_url.'projects.json?key='.$redmine_key : $redmine_url.'projects/'.$project_id.'.json?key='.$redmine_key;
return $this->curl_redmine($proj_url,'','');
}
#Curl
function curl_redmine($redmine_url,$request='',$post_data=''){
if(!isset($request['type'])){ $request['type']=null; }
if(!isset($request['content_type'])){ $request['content_type']=null; }
//Create a curl object
$ch = curl_init();
//Set the useragent
$agent = $_SERVER["HTTP_USER_AGENT"];
curl_setopt($ch, CURLOPT_USERAGENT, $agent);
//Set the URL
curl_setopt($ch, CURLOPT_URL, $redmine_url );
if($request['type'] == 'post'){
//This is a POST query
curl_setopt($ch, CURLOPT_POST,1);
// curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
//Set the post data
curl_setopt($ch, CURLOPT_POSTFIELDS,$post_data);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: '.$request['content_type'],
'Content-Length: ' . strlen($post_data))
);
}
//We want the content after the query
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
//Follow Location redirects
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
/*
Set the cookie storing files
Cookie files are necessary since we are logging and session data needs to be saved
*/
//curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
//curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
//Execute the action to login
$postResult = curl_exec($ch);
//if($postResult == false){ return $info = curl_getinfo($ch);}
$response = json_decode($postResult);
//echo '<pre>'; print_r($response); echo '</pre>';
return $response;
}
}//class_redmine
?>
here is my example.php
<?php
function get_redmine($methodName='',$data=''){
global $redmine_url , $redmine_key;
$redmine_url = 'http://192.168.12.231:80/';
$redmine_key = 'API KEY';
include_once('curlcall.php');
$obj_redmine = new class_redmine();
#check Auth
$res = $obj_redmine->get_projects();
if(!isset($res->projects) || (isset($res->total_count) && ($res->total_count)==0)){ return -1; }
switch($methodName){
case 'check_status' : return $login_integrate;
##check redmine integration in vision break;
##Project
case 'projectAll' : return $obj_redmine->get_projects(); #used
break;
case 'projectById' : return $obj_redmine->get_projects($data['project_id']);
break;
##Issues
case 'issueAll' : return $obj_redmine->get_issue();
break;
case 'issueByProjectId' : return $obj_redmine->get_issue('',$data['project_id']);
break;
case 'uploadFileToIssue' : return $obj_redmine->get_upload_token($data);
break;
default: return 0;
}
}
#get all issue
$res = get_redmine('issueAll');
echo '<pre>';print_r($res);
?>
This code is giving only 25 records.at the end of my output it is saying like
total:201
offset:0
limit:25
I can't understand how to get all issues please help anybody, i am new for php.
the answer is all in the API docs, if you'd just bother to read it. use the limit parameter to get more results, and the offset parameter to load more
/issues.json?offset=0&limit=100 would fetch the first 100 issues
/issues.json?offset=100&limit=100 would fetch the next 100 issues, and so on.
... but the first thing you should do is get your code formatted, because that unformatted thing is very annoying to read. then get rid of this line 'Content-Length: ' . strlen ( $post_data ) because curl will add that header automatically if you don't, and curl won't make any typos, nor will it calculate the length incorrectly, unlike us the progammers (curl has automated tests ran on every commit to make sure content-length is correct, i bet that's not part of your test suite), then get rid of this
if (! isset ( $request ['content_type'] )) {
$request ['content_type'] = null;
}
because it should never be null. for future reference, if you literally have no idea what it's supposed to be, set it to application/octet-stream, but even that is wrong in this case, because the API docs says the only supported POST encodings are application/json and application/xml, so the correct thing to do here would be:
if (isset ( $request ['content_type'] ) && $request ['content_type'] !== 'application/json' && $request ['content_type'] !== 'application/xml') {
throw new \InvalidArgumentException ( 'invalid content-type specified. supported types are "application/json" and "application/xml"' );
}
if($request ['type'] === 'post' && !isset($request ['content_type'])){
throw new \LogicException('no content-type was specified for this POST request, which is required. supported types are "application/json" and "application/xml"');
}
as for fetching all the issues, make a request first to see how many issues there are, then make a second request with limit=number_of_issues, like this
if (! $issue_id) {
// first we check how many issues there are (OPTIMIZEME: there is probably a more efficient way to do this, for example limit=0 ?)
$issues_url .= '&limit=1';
$number_of_issues = $this->curl_redmine ( $issue_url, '', '' ) ['total_count'];
$issue_url = substr ( $issues_url, 0, - 1 ) . $number_of_issues;
}
putting it all together, and you get this
<?php
// Redmine Api
class class_redmine {
function get_upload_token($filecontent) {
global $redmine_url, $redmine_key;
$upload_url = $redmine_url . 'uploads.json?key=' . $redmine_key;
$request ['type'] = 'post';
$request ['content_type'] = 'application/octet-stream';
// $filecontent = file_get_contents('test.php');
return $token = $this->curl_redmine ( $upload_url, $request, $filecontent );
// $token->upload->token;
}
// Issue
function create_issue($post_data) {
global $redmine_url, $redmine_key;
$issue_url = $redmine_url . 'issues.json?key=' . $redmine_key;
$request ['type'] = 'post';
$request ['content_type'] = 'application/json';
return $this->curl_redmine ( $issue_url, $request, $post_data );
}
function get_issue($issue_id = '', $project_id = '') {
global $redmine_url, $redmine_key;
if ($project_id != '') {
$issue_url = $redmine_url . 'issues.json?key=' . $redmine_key . '&project_id=' . $project_id;
} else {
$issue_url = ($issue_id == '') ? $redmine_url . 'issues.json?key=' . $redmine_key : $redmine_url . 'issues/' . $issue_id . '.json?key=' . $redmine_key;
}
if (! $issue_id) {
// first we check how many issues there are (OPTIMIZEME: there is probably a more efficient way to do this, for example limit=0 ?)
$issues_url .= '&limit=1';
$number_of_issues = $this->curl_redmine ( $issue_url, '', '' ) ['total_count'];
$issue_url = substr ( $issues_url, 0, - 1 ) . $number_of_issues;
}
return $this->curl_redmine ( $issue_url, '', '' );
}
// Projects
function get_projects($project_id = '') {
global $redmine_url, $redmine_key;
$proj_url = ($project_id == '') ? $redmine_url . 'projects.json?key=' . $redmine_key : $redmine_url . 'projects/' . $project_id . '.json?key=' . $redmine_key;
return $this->curl_redmine ( $proj_url, '', '' );
}
// Curl
function curl_redmine($redmine_url, $request = '', $post_data = '') {
if (! isset ( $request ['type'] )) {
$request ['type'] = null;
}
if (isset ( $request ['content_type'] ) && $request ['content_type'] !== 'application/json' && $request ['content_type'] !== 'application/xml') {
throw new \InvalidArgumentException ( 'invalid content-type specified. supported types are "application/json" and "application/xml"' );
}
if ($request ['type'] === 'post' && ! isset ( $request ['content_type'] )) {
throw new \LogicException ( 'no content-type was specified for this POST request, which is required. supported types are "application/json" and "application/xml"' );
}
// Create a curl object
$ch = curl_init ();
// Set the useragent
$agent = $_SERVER ["HTTP_USER_AGENT"];
curl_setopt ( $ch, CURLOPT_USERAGENT, $agent );
// Set the URL
curl_setopt ( $ch, CURLOPT_URL, $redmine_url );
if ($request ['type'] == 'post') {
// This is a POST query
curl_setopt ( $ch, CURLOPT_POST, 1 );
// curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
// Set the post data
curl_setopt ( $ch, CURLOPT_POSTFIELDS, $post_data );
curl_setopt ( $ch, CURLOPT_HTTPHEADER, array (
'Content-Type: ' . $request ['content_type']
) );
}
// We want the content after the query
curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
curl_setopt ( $ch, CURLOPT_SSL_VERIFYPEER, false );
// Follow Location redirects
curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION, 1 );
/*
* Set the cookie storing files
* Cookie files are necessary since we are logging and session data needs to be saved
*/
// curl_setopt($ch, CURLOPT_COOKIEJAR, 'cookie.txt');
// curl_setopt($ch, CURLOPT_COOKIEFILE, 'cookie.txt');
// Execute the action to login
$postResult = curl_exec ( $ch );
// if($postResult == false){ return $info = curl_getinfo($ch);}
$response = json_decode ( $postResult );
// echo '<pre>'; print_r($response); echo '</pre>';
return $response;
}
}//class_redmine
(which is completely untested on my part, by the way.)
another issue you should fix is that your curl code is executed completely without error detection. for example, curl_setopt returns bool(false) if there was a problem setting your option, and curl_exec() returns bool(false) if there was a problem with during the transfer, add error detection for that. these functions should make that rather easy:
function ecurl_setopt ( /*resource*/$ch , int $option , /*mixed*/ $value ):bool{
$ret=curl_setopt($ch,$option,$value);
if($ret!==true){
//option should be obvious by stack trace
throw new RuntimeException ( 'curl_setopt() failed. curl_errno: ' . return_var_dump ( curl_errno ($ch) ).'. curl_error: '.curl_error($ch) );
}
return true;
}
function ecurl_exec ( /*resource*/$ch):bool{
$ret=curl_exec($ch);
if($ret===false){
throw new RuntimeException ( 'curl_exec() failed. curl_errno: ' . return_var_dump ( curl_errno ($ch) ).'. curl_error: '.curl_error($ch) );
}
return $ret;
}
function return_var_dump(/*...*/){
$args = func_get_args ();
ob_start ();
call_user_func_array ( 'var_dump', $args );
return ob_get_clean ();
}
and to be sure you're not leaking any memory, you can wrap it all around a try{...curl...}finally{curl_close($ch);}, making sure curl_close would always be called, regardless of which curl function throws an exception. (this prevents memory leaks)
I have a function to create cache data xml file on my server.
I've used file_get_contents and file_put_contents, but now my hosting provider is restricting usage of them. The single way to use same function is to convert it to CURL. Can anyone give some ideas?
function checkXmlCache($xmlQuery) {
$fibulabasexml="http://any url that give xml data/"; $cachedir="/tmp/"; $ageInSeconds = 36000;
$xmlQuery=str_replace(array("'",'"'),"",$xmlQuery);
$xmlQuery2=$xmlQuery;
$long=array("stars=","TURKEY","bestprice=","country=", "location=","hotelcode=","prices=yes","tara=","simple=yes","rand()","sort=","limit=","price ","hotelname"," desc","desc");
$short=array("ST-","TR","B-","C-", "L-", "H-", "PY-", "T-", "-S-", "-R-", "S-", "LT-", "PP-","HN","-D","-D");
$xmlQuery2=str_replace($long,$short,$xmlQuery2);
$xmlQuery2=str_replace(array("xmlhotels.php","xmllocations.php"),array("XH-","XL-"),$xmlQuery2);
$xmlQuery2=str_replace(array("&","?"),array(""),$xmlQuery2);
$xmlQuery2.="_.XML";
$xmlQuery2=strip_tags($xmlQuery2);
if(!file_exists($cachedir.$xmlQuery2) || (filemtime($cachedir.$xmlQuery2) + $ageInSeconds < (time() )) ) {
$contents = file_get_contents($fibulabasexml.str_replace(" ","%20",$xmlQuery));
if(strlen($contents)>200 ) { file_put_contents($cachedir.$xmlQuery2, $contents); }
}
return($cachedir.$xmlQuery2);
Thanks for helping!
Create a simple curl function that will return the response from the request and use it in place of file_get_contents. This is not tested but it should give you the general idea perhaps.
function checkXmlCache( $xml ) {
$url="http://any url that give xml data/";
$dir="/tmp/";
$age = 36000;
$xml=str_replace( array("'",'"'), "", $xml );
$query=$xml;
$long=array("stars=","TURKEY","bestprice=","country=", "location=","hotelcode=","prices=yes","tara=","simple=yes","rand()","sort=","limit=","price ","hotelname"," desc","desc");
$short=array("ST-","TR","B-","C-","L-","H-","PY-","T-","-S-","-R-","S-","LT-","PP-","HN","-D","-D");
$query=str_replace($long,$short,$query);
$query=str_replace(array("xmlhotels.php","xmllocations.php"),array("XH-","XL-"),$query);
$query=str_replace(array("&","?"),array(""),$query);
$query.="_.XML";
$query=strip_tags( $query );
if( !file_exists( $dir.$query ) || ( filemtime( $dir.$query ) + $age < ( time() ) ) ) {
$targeturl=$url . str_replace( " ", "%20", $xml );
/* call curl function rather than file_get_contents */
$contents = curl( $targeturl );
if( strlen( $contents ) > 200 ) { file_put_contents( $dir . $query, $contents ); }
}
return( $dir.$query );
}
function curl( $url ){
$ch=curl_init( $url );
curl_setopt( $ch, CURLOPT_RETURNTRANSFER,true );
curl_setopt( $ch, CURLOPT_USERAGENT,$_SERVER['HTTP_USER_AGENT'] );
curl_setopt( $ch, CURLOPT_FOLLOWLOCATION, true );
curl_setopt( $ch, CURLOPT_AUTOREFERER, true );
$res=curl_exec( $ch );
curl_close( $ch );
return $res;
}
We have written code in cakephp to enter contacts in Google contacts through api,
Contacts have added in Google through Google xml request , but how can we get total number
of contacts added or updated in Google contacts after code successfully executed
here is code:
public function addContact($token=null,$atContacts=null){
foreach ( $atContacts as $contact ) {
$xml = <<<'EOF'
<atom:entry xmlns:atom='http://www.w3.org/2005/Atom'
xmlns:gd='http://schemas.google.com/g/2005'>
<atom:category scheme='http://schemas.google.com/g/2005#kind'
term='http://schemas.google.com/contact/2008#contact'/>
<title type="text">TITLE</title>
<gd:name>
<gd:givenName>First</gd:givenName>
<gd:additionalName>ADDITIONALNAME</gd:additionalName>
<gd:familyName>Last</gd:familyName>
<gd:namePrefix>NAMEPREFIX</gd:namePrefix>
<gd:nameSuffix>NAMESUFFIX</gd:nameSuffix>
</gd:name>
<gd:structuredPostalAddress rel='http://schemas.google.com/g/2005#work' primary='true'>
<gd:city>CITY</gd:city>
<gd:street>STREET</gd:street>
<gd:region>REGION</gd:region>
<gd:postcode>POSTCODE</gd:postcode>
<gd:country>COUNTRY</gd:country>
</gd:structuredPostalAddress>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#home' primary='true'>
HOMEPHONENUMBER
</gd:phoneNumber>\
<gd:phoneNumber rel='http://schemas.google.com/g/2005#mobile'>MOBILENO</gd:phoneNumber>
<gd:phoneNumber rel='http://schemas.google.com/g/2005#work'>WORKPHONENO</gd:phoneNumber>
<gd:email label="home" address="EMAILADDRESS" displayName="DISPLAYNAME" />
</atom:entry>
EOF;
$xml = str_replace ( "TITLE", $contact->Title, $xml );
$xml = str_replace ( "EMAILADDRESS", $contact->EMailAddress, $xml );
$xml = str_replace ( "DISPLAYNAME", $contact->FirstName, $xml );
$xml = str_replace ( "HOMEPHONENUMBER", $contact->AlternatePhone,
$xml );
$xml = str_replace ( "MOBILENO", $contact->MobilePhone, $xml );
$xml = str_replace ( "WORKPHONENO", $contact->Phone, $xml );
$xml = str_replace ( "CITY", $contact->City, $xml );
$xml = str_replace ( "STREET", $contact->AddressLine, $xml );
$xml = str_replace ( "POSTCODE", $contact->ZipCode, $xml );
$xml = str_replace ( "REGION", $contact->State, $xml );
$xml = str_replace ( "COUNTRY", $contact->Country, $xml );
$auth_header = array ('Content-Type: application/atom+xml; charset=utf-8;',
'Authorization: GoogleLogin auth=' . trim ( $token ),
'Content-length:' . strlen ( $xml ) );
$url = 'https://www.google.com/m8/feeds/contacts/default/full';
$curl = curl_init ();
curl_setopt ( $curl, CURLOPT_URL, $url );
curl_setopt ( $curl, CURLOPT_POST, 5 );
curl_setopt ( $curl, CURLOPT_POSTFIELDS, $xml );
curl_setopt ( $curl, CURLOPT_RETURNTRANSFER, TRUE );
curl_setopt ( $curl, CURLOPT_SSL_VERIFYPEER, FALSE );
curl_setopt ( $curl, CURLOPT_HTTPHEADER, $auth_header );
$xmlresponse = curl_exec ( $curl );
}
return $xmlresponse;
}
In your code it does not appear that you do any validation to check that the contact was added successfully and you don't catch any cURL errors either, so with your code as it currently stands just do ..
$number_of_contacts = count($atContact);
If taken a guess to the structure of your $atContact array.
That will give you number of contacts you are trying to add to Google. If you add some validation at some point and want to make that more accurate, then create a new variable...
public function addContact($token=null,$atContacts=null){
$number_of_contacts = 0;
foreach ( $atContacts as $contact ) {
$xml = <<<'EOF'
...
if(no_errors){
$number_of_contacts++;
}