Create an array from SimpleXMLElement response in php - php

I am trying to import Google contacts in my code. I've successfully imported the contacts but my problem is that, I have to create an array of imported email addresses and I need to pass it to another page. But when I try to create an array, I get an array containing SimpleXMLElement Object.
Here is my code:
oauth.php:
<?php
$client_id='my-cient-id';
$client_secret='my-client-secret';
$redirect_uri='my-redirect-uri';
$max_results = 100;
$auth_code = $_GET["code"];
function curl_file_get_contents($url)
{
$curl = curl_init();
$userAgent = 'Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1; .NET CLR 1.1.4322)';
curl_setopt($curl,CURLOPT_URL,$url);
curl_setopt($curl,CURLOPT_RETURNTRANSFER,TRUE);
curl_setopt($curl,CURLOPT_CONNECTTIMEOUT,5);
curl_setopt($curl, CURLOPT_USERAGENT, $userAgent);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, TRUE);
curl_setopt($curl, CURLOPT_AUTOREFERER, TRUE);
curl_setopt($curl, CURLOPT_TIMEOUT, 10);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, FALSE);
$contents = curl_exec($curl);
curl_close($curl);
return $contents;
}
$fields=array(
'code'=> urlencode($auth_code),
'client_id'=> urlencode($client_id),
'client_secret'=> urlencode($client_secret),
'redirect_uri'=> urlencode($redirect_uri),
'grant_type'=> urlencode('authorization_code')
);
$post = '';
foreach($fields as $key=>$value) { $post .= $key.'='.$value.'&'; }
$post = rtrim($post,'&');
$curl = curl_init();
curl_setopt($curl,CURLOPT_URL,'https://accounts.google.com/o/oauth2/token');
curl_setopt($curl,CURLOPT_POST,5);
curl_setopt($curl,CURLOPT_POSTFIELDS,$post);
curl_setopt($curl, CURLOPT_RETURNTRANSFER,TRUE);
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER,FALSE);
$result = curl_exec($curl);
curl_close($curl);
$response = json_decode($result);
$accesstoken = $response->access_token;
$url = 'https://www.google.com/m8/feeds/contacts/default/full?max-results='.$max_results.'&oauth_token='.$accesstoken;
$xmlresponse = curl_file_get_contents($url);
if((strlen(stristr($xmlresponse,'Authorization required'))>0) && (strlen(stristr($xmlresponse,'Error '))>0)) //At times you get Authorization error from Google.
{
echo "<h2>OOPS !! Something went wrong. Please try reloading the page.</h2>";
exit();
}
echo "<h3>Email Addresses:</h3>";
$xml = new SimpleXMLElement($xmlresponse);
$xml->registerXPathNamespace('gd', 'http://schemas.google.com/g/2005');
$result = $xml->xpath('//gd:email');
foreach ($result as $title) {
$var=$title->attributes()->address;
echo $var . "<br>"; //here imported contacts is listing properly
$gc[]=array($var); // creates my contacts array
}
print_r($gc); //printing the created array
?>
My result is:
Array ( [0] => Array ( [0] => SimpleXMLElement Object ( [0] => email-address1 ) ) [1] => Array ( [0] => SimpleXMLElement Object ( [0] => email-address2 ) ) )
I need to get like this:
Array ( ([0] => email-address1 ) ( [1] => email-address2 ) )
Can anyone suggest me how to do this. I'm stuck in this for many days. Thanks in advance
Edit
XML Response:
Array ( [0] => SimpleXMLElement Object ( [#attributes] => Array ( [rel] => http://schemas.google.com/g/2005#other [address] => emailaddress1 [primary] => true ) ) [1] => SimpleXMLElement Object ( [#attributes] => Array ( [rel] => http://schemas.google.com/g/2005#other [address] => emailaddress2 [primary] => true ) ) )
I have to separate the emailaddress from the response to a php array.!
Edit 2
here is $xmlresponse:
email-id 2015-01-07T09:03:23.311Z profile-name email-id Contacts 2 1 100 http://www.google.com/m8/feeds/contacts/email-id/base/6cc9fe478fd427bb 2014-12-30T04:54:29.902Z
email-id is the mail id from which contacts are imported.

In the first line of the final foreach loop you could try:
$var=(string)$title->attributes()->address;
or:
$var=(string)$title->attributes()->address[0];
Which is a bit of code from http://php.net/manual/en/simplexml.examples-basic.php#116435
I think that the echo statement that lists the email addresses properly is implicitly calling the SimpleXMLElement::_toString(void) method (http://php.net/manual/en/simplexmlelement.tostring.php). So to get the same result when creating the array you can coerce it to a string by putting (string) in front of the variable name.
EDIT:
You might also try this where you add to the array:
$gc[] = $var;
instead of
$gc[] = array($var);
Since the second way creates a new array object and adds $var to it then the assignment operator adds that entire array to $gc. Which would explain why the SimpleXMLObject was itself in an array. The first way ('$gc[] = $var;') will add a new element to the array $gc. Or you could initialise $gc before the foreach loop with:
$gc = array();
And then inside the foreach loop use:
array_push($gc, $var);
You will need to do both of the suggested changes to get the result you want, so:
foreach ($results as $title) {
$var=(string)$title->attributes()->address;
$gc[] = $var;

Related

cURL to array_map with utf8_encode in PHP

I'm using a cURL request to grab data from a website and adding them to properties within a loop later. However, I'm stuck on making the data adjustable enough where I can add them directly within the objects.
I have a cURL request that I'm calling that grabbing all the content that I need as below:
public function request()
{
$resource = curl_init();
curl_setopt(
$resource,
CURLOPT_URL,
'lorem ipsum'
);
curl_setopt(
$resource,
CURLOPT_HTTPHEADER,
['API Auth']
);
curl_setopt(
$resource,
CURLOPT_REFERER,
'http://' . $_SERVER['SERVER_NAME'] . '/'
);
curl_setopt(
$resource,
CURLOPT_USERAGENT,
'F'
);
curl_setopt(
$resource,
CURLOPT_RETURNTRANSFER,
1
);
$response = json_decode(curl_exec($resource), true);
if (!curl_errno($resource)) {
$info = curl_getinfo($resource);
echo 'Took ', $info['total_time'], ' seconds to send a request to ', $info['url'], "\n";
};
return $response;
}
When I call the following execution $offices_array = $this->request(); print_r2($offices_array);, this is the return that I receive:
Array
(
[paginator] => Array
(
[total] => 131
[per_page] => 500
[current_page] => 1
[last_page] => 1
[prev_page] =>
[next_page] =>
)
[data] => Array
(
[0] => Array
(
[id] => 1
[name] => Atlanta
)
I'm using this function _csv_to_array:
private function _csv_to_array($filepath) {
$data_array = array();
if(is_readable($filepath)) {
$fp = fopen($filepath, 'r');
while(($data_item = fgetcsv($fp, 1000, "\t")) !== false) {
$data_array[] = array_map('utf8_encode', $data_item);
}
fclose($fp);
}
return $data_array;
}
to print out data as this:
Array
(
[0] => Array
(
[0] => ABU DHABI
[1] => FHI
)
How could I do something similar with the cURL request?

Get specific values from CURL JSON response php array

Trying to echo a couple of values from the CURL JSON response so i can put them in to a foreach loop but i can only get single indexed values to work.
$request = curl_init($api); // initiate curl object
curl_setopt($request, CURLOPT_HEADER, 0); // set to 0 to eliminate header info from response
curl_setopt($request, CURLOPT_RETURNTRANSFER, 1); // Returns response data instead of TRUE(1)
//curl_setopt($request, CURLOPT_SSL_VERIFYPEER, FALSE); // uncomment if you get no gateway response and are using HTTPS
curl_setopt($request, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($request, CURLOPT_HTTPHEADER, array(
"Content-Type: application/x-www-form-urlencoded"
));
$response = (string)curl_exec($request); // execute curl fetch and store results in $response
curl_close($request); // close curl object
$result = json_decode($response, true); // true turns it into an array
echo 'First Name: ' . $result['first_name'] . '<br />'; // why doesnt this work
echo 'Last Name: ' . $result[0]['last_name'] . '<br />'; // yet i can return the first value
Example Array output
Array
(
[0] => Array
(
[id] => 34761
[first_name] => A
[last_name] => Bailes
[clinic] =>
[phone] => 7409923279
[fax] => 7409926740
[address1] => 507 Mulberry Heights Rd
[address2] =>
[city] => Pomeroy
[subdivision] => OH
[country_code] =>
[postal_code] => 45769-9573
[timezone] => Array
(
[timezone_type] => 3
[timezone] => America/New_York
)
[state] => OH
)
)
I have json decode set to true for array output
$result = json_decode($response, true); // true turns it into an array
but when i try to echo the 'first_name' values it just returns empty.
echo 'First Name: ' . $result['first_name'] . '<br />'; // why doesnt this work
Yet i can return an indexed value
echo 'First Name: ' . $result[0]['first_name'] . '<br />';
What am i doing wrong here?
Your result array is nested 2 deep. $result is an array of arrays. So:
$result[0]['first_name']
or
foreach ($result as $r) {
echo $r['first_name'];
}
Response depend on server answer your request, the following work perfect to extract access token for example, you can try the following steps to test what you have and extract what you need too
After
$response = curl_exec($ch);
curl_close($ch);
I start to show what I get by
Test:
print_r ($response);
Then go to extract (where server response ) header and body to use what available in each of them
list($header, $body) = explode("\r\n\r\n", $response, 2);
Test:
echo $header;
echo $body;
then I’m extract item in $body to use in my code using stdClass
$bodyObject = json_decode($body);
Test:
print_r($bodyObject);
Test:
echo $bodyObject->access_token;

converting api response to php string

Below is my code, I am trying to get particular api response (msg,amt) in php string.
........................................................................................................................................
$key = "XXXXX";
$mykey = "XXXXX";
$command = "Check";
$value = "5454355435";
$r = array('key' => $key , 'value' => $value, 'command' => $command);
$qs= http_build_query($r);
$wsUrl = "https://info.service-provider.com";
$c = curl_init();
curl_setopt($c, CURLOPT_URL, $wsUrl);
curl_setopt($c, CURLOPT_POST, 1);
curl_setopt($c, CURLOPT_POSTFIELDS, $qs);
curl_setopt($c, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($c, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($c, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($c, CURLOPT_SSL_VERIFYPEER, 0);
$o = curl_exec($c);
if (curl_errno($c)) {
$sad = curl_error($c);
throw new Exception($sad);
}
curl_close($c);
$valueSerialized = #unserialize($o);
if($o === 'b:0;' || $valueSerialized !== false) {
print_r($valueSerialized);
}
print_r($o);
RESPONSE:
{"status":1,"msg":"1 out of 1 Transactions Fetched Successfully","transaction_details":{"2767712494": {"mihpayid":"268999084","request_id":"","ref_num":"020814301298","amt":"1.00","txnid":"5454355435","additional_charges":"0.00","productinfo":"SHIRT"}}}
Your string is in json format. To get value from it, you should convert it into an array like this:
$json = '{"status":1,"msg":"1 out of 1 Transactions Fetched Successfully","transaction_details":{"2767712494": {"mihpayid":"268999084","request_id":"","ref_num":"020814301298","amt":"1.00","txnid":"5454355435","additional_charges":"0.00","productinfo":"SHIRT"}}}';
$array = json_decode($json, true);
echo '<pre>'; print_r($array);
Your array will look like this:
Array
(
[status] => 1
[msg] => 1 out of 1 Transactions Fetched Successfully
[transaction_details] => Array
(
[2767712494] => Array
(
[mihpayid] => 268999084
[request_id] =>
[ref_num] => 020814301298
[amt] => 1.00
[txnid] => 5454355435
[additional_charges] => 0.00
[productinfo] => SHIRT
)
)
)
To get msg you should write like this:
echo $array['msg'];
You can get more information from json_decode
Let me know for more help.
This response looks like JSON format.
Pass this response string to php method json_decode like:
$response = json_decode($yourResponseString,true);
and then you should be able to access it's properties like a regular associative array:
$msg = $response['msg'];

WHMCS getclients searching results

Myself and a few friends are trying to use WHMCS to offer services in a virtual world. Issue is WHMCS does not provide a simple way to search for a specific client record without already having the client id, which wouldn't be stored anywhere besides the WHMCS database. the api function getclients returns results in an XML format, issue is when you search for a client using this method you can only search for firstname, lastname, or email address. Now we have tried passing the variables for firstname and lastname(they have to be passed separately) This unfortunatly returns the client records for all clients that X firstname OR Y Lastname, instead of narrowing down the one client with both X and Y.
What I want to know is how to search PHP array generated from an XML result to try and grab the client records for only the client we are looking for.
The results are posted as such:
Array ( [WHMCSAPI] => Array ( [ACTION] => getclients [RESULT] => success [TOTALRESULTS] => 2 [STARTNUMBER] => 0 [NUMRETURNED] => 2 [CLIENTS] => Array ( [CLIENT] => Array ( [ID] => 9 [FIRSTNAME] => Test1 [LASTNAME] => Test2 [COMPANYNAME] => [EMAIL] => test1#test.com [DATECREATED] => 2013-04-24 [GROUPID] => 1 [STATUS] => Active ) [CLIENT1] => Array ( [ID] => 20 [FIRSTNAME] => Test3 [LASTNAME] => Test2 [COMPANYNAME] => [EMAIL] => test#test.com [DATECREATED] => 2014-01-20 [GROUPID] => 0 [STATUS] => Active ) ) ) )
The code we try using to search is:
$postfields["action"] = "getclients";
$postfields["search"] = $firstname;
$postfields["search"] = $lastname;
$postfields["responsetype"] = "xml";
$query_string = "";
foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
$xml = curl_exec($ch);
if (curl_error($ch) || !$xml) $xml = '<whmcsapi><result>error</result>'.
'<message>Connection Error</message><curlerror>'.
curl_errno($ch).' - '.curl_error($ch).'</curlerror></whmcsapi>';
curl_close($ch);
$arr = whmcsapi_xml_parser($xml); # Parse XML
$client = searchClient($firstname, $lastname, $arr);
print_r($client); # Output XML Response as Array
/*
Debug Output - Uncomment if needed to troubleshoot problems
echo "<textarea rows=50 cols=100>Request: ".print_r($postfields,true);
echo "\nResponse: ".htmlentities($xml)."\n\nArray: ".print_r($arr,true);
echo "</textarea>";
*/
function whmcsapi_xml_parser($rawxml) {
$xml_parser = xml_parser_create();
xml_parse_into_struct($xml_parser, $rawxml, $vals, $index);
xml_parser_free($xml_parser);
$params = array();
$level = array();
$alreadyused = array();
$x=0;
foreach ($vals as $xml_elem) {
if ($xml_elem['type'] == 'open') {
if (in_array($xml_elem['tag'],$alreadyused)) {
$x++;
$xml_elem['tag'] = $xml_elem['tag'].$x;
}
$level[$xml_elem['level']] = $xml_elem['tag'];
$alreadyused[] = $xml_elem['tag'];
}
if ($xml_elem['type'] == 'complete') {
$start_level = 1;
$php_stmt = '$params';
while($start_level < $xml_elem['level']) {
$php_stmt .= '[$level['.$start_level.']]';
$start_level++;
}
$php_stmt .= '[$xml_elem[\'tag\']] = $xml_elem[\'value\'];';
#eval($php_stmt);
}
}
return($params);
}
function searchClient($first, $last, $array)
{
foreach ($array as $key => $val)
{
if($val['FIRSTNAME'] == $first && $val['LASTNAME'] == $last)
{
return $key;
}
}
return null;
}
?>
This returns a blank result. I will admit I am not entirely sure how to do this so any pointers will help.
You are able to "search for a specific client record" via email address utilizing their api and they now support json format for responsetype
"Please note either the clientid or email is required."
http://docs.whmcs.com/API:Get_Clients_Details

Customize array from cURL XML response

I need to output an array with a specif format from a cURL request. I tried many ways to format the XML result as needed without luck.
Here's the PHP code
<?php
$request_url = "http://ws.correios.com.br/calculador/CalcPrecoPrazo.aspx?nCdEmpresa=&sDsSenha=&sCepOrigem=71939360&sCepDestino=72151613&nVlPeso=1&nCdFormato=1&nVlComprimento=16&nVlAltura=5&nVlLargura=15&sCdMaoPropria=s&nVlValorDeclarado=200&sCdAvisoRecebimento=n&nCdServico=41106%2C40045&nVlDiametro=0&StrRetorno=xml 4110616,9034,000,001,50SN04004519,2014,000,002,00SS0";
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $request_url);
curl_setopt($curl, CURLOPT_TIMEOUT, 130);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($curl);
curl_close($curl);
print_r($response);
?>
It prints the following XML
<servicos>
<cservico>
<codigo>41106</codigo>
<valor>16,90</valor>
<prazoentrega>3</prazoentrega>
...
<erro>0</erro>
<msgerro>
</msgerro>
</cservico>
<cservico>
<codigo>40045</codigo>
<valor>19,20</valor>
<prazoentrega>1</prazoentrega>
...
<erro>0</erro>
<msgerro>
</msgerro>
</cservico>
</servicos>
Or the following array if I apply $xml = new SimpleXMLElement($response);
SimpleXMLElement Object
(
[cServico] => Array
(
[0] => SimpleXMLElement Object
(
[Codigo] => 41106
[Valor] => 16,90
[PrazoEntrega] => 3
...
[Erro] => 0
[MsgErro] => SimpleXMLElement Object
(
)
)
[1] => SimpleXMLElement Object
(
[Codigo] => 40045
[Valor] => 19,20
[PrazoEntrega] => 1
...
[Erro] => 0
[MsgErro] => SimpleXMLElement Object
(
)
)
)
)
What I need to return is and Array like this. I tried almost every method found in other questions here but never got a good way to construct this two-dimension array.
array(
'Option Name' => array(
'id'=>'40045',
'quote'=>'20,20',
'days'=>'1',
),
'Option Name' => array(
'id'=>'40215',
'quote'=>'29,27',
'days'=>'3',
)
)
*Option Name will be retrieved afterwards by ID code.
This should work flawlessly!
$xml = simplexml_load_string($response);
$json = json_encode($xml);
$arr = json_decode($json,true);
$temp = array();
foreach($arr as $k=>$v) {
foreach($v as $k1=>$v1) {
$temp[$k][$k1] = $v1;
}
}
echo "<pre>";print_r($temp);echo "</pre>";
http://ka.lpe.sh/2012/07/26/php-convert-xml-to-json-to-array-in-an-easy-way/
Try this function (pass the response to it and it should return you your array) :
function getArrayFromResponse($response) {
$xml = new SimpleXMLElement($response);
$array = array();
foreach($xml->cServico as $node){
$array[] = array(
'id' => $node->Codigo,
'quote' => $node->Valor,
'days' => $node->PrazoEntrega
);
}
return $array;
}
$ch = curl_init();
$sendurl = "http://example.com";
curl_setopt($ch, CURLOPT_URL, $sendurl);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$data = curl_exec($ch);
curl_close($ch);
$response = preg_replace("/(<\/?)(\w+):([^>]*>)/", "$1$2$3", $data);
$xml = new \SimpleXMLElement($response);
$array = json_decode(json_encode((array)$xml), TRUE);
echo "<pre>";
print_r($array);
Working charming for me.
I finally got it. After testing all your suggestions and many others found on google, I came up with this:
<?php
$request_url = "http://ws.correios.com.br/calculador/CalcPrecoPrazo.aspx?nCdEmpresa=&sDsSenha=&sCepOrigem=71939360&sCepDestino=72151613&nVlPeso=1&nCdFormato=1&nVlComprimento=16&nVlAltura=5&nVlLargura=15&sCdMaoPropria=s&nVlValorDeclarado=200&sCdAvisoRecebimento=n&nCdServico=41106%2C40045&nVlDiametro=0&StrRetorno=xml 4110616,9034,000,001,50SN04004519,2014,000,002,00SS0";
//Setup cURL Request
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, $request_url);
curl_setopt($curl, CURLOPT_TIMEOUT, 130);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($curl);
curl_close($curl);
$xml = simplexml_load_string($response);
$services = $xml->cServico;
$result = array();
foreach($services as $service) {
$id = $service->Codigo->__toString();
$quote = $service->Valor->__toString();
$delivery_days = $service->PrazoEntrega->__toString();
//Get simplified service name (option_name)
switch ($id) {
case "40010":
case "40096":
case "40436":
case "40444":
case "40568":
case "40606":
$option_name = 'SEDEX'; break;
case "81019":
case "81868":
case "81833":
case "81850":
$option_name = 'e-SEDEX'; break;
case "41106":
case "41068":
$option_name = 'PAC'; break;
case "40045":
case "40126":
$option_name = 'SEDEX a Cobrar'; break;
case "40215":
$option_name = 'SEDEX 10'; break;
case "40290":
$option_name = 'SEDEX Hoje'; break;
case "81027":
$option_name = 'e-SEDEX Prioritário'; break;
case "81035":
$option_name = 'e-SEDEX Express'; break;
}
$result[$option_name] = array('id' => $id, 'quote' => $quote, 'delivery_days' => $delivery_days);
}
?>
The final secret was to add __toString() to convert values returned as array to a simple string. It prints perfectly. Thank you guys!!
Array
(
[PAC] => Array
(
[id] => 41106
[quote] => 16,90
[delivery_days] => 3
)
[SEDEX a Cobrar] => Array
(
[id] => 40045
[quote] => 19,20
[delivery_days] => 1
)
)

Categories