curl_exec($handle) returns nothing - php

I'm building a simple CRUD API in PHP and Curl and I have an HTML form that sends ID, FName, LName.
The form is posted to create.php and then calls ApiHandler.php that set up the Curl request, then send it to read-api.php.
The json file is updated with the new user and returns the json file content as a string but $response is an empty string and doesn't contain the json content
$response = curl_exec($handle); // $response = ""
ApiHandler.php
<?php
function callAPI($method, $url, $request){
$handle = curl_init();
switch ($method){
case "GET":
curl_setopt($handle, CURLOPT_CUSTOMREQUEST, 'GET');
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
break;
case "PUT":
curl_setopt($handle, CURLOPT_CUSTOMREQUEST, "PUT");
if ($request)
curl_setopt($handle, CURLOPT_POSTFIELDS, $request);
break;
case "POST":
curl_setopt($handle, CURLOPT_POST, 1);
if ($request)
curl_setopt($handle, CURLOPT_POSTFIELDS, $request);
break;
case "DELETE":
curl_setopt($handle, CURLOPT_CUSTOMREQUEST, "DELETE");
default:
if ($request)
$handle = sprintf("%s?%s", $url, http_build_query($request));
}
curl_setopt($handle, CURLOPT_HTTPHEADER, [
"Content-Type: application/json; charset=UTF-8",
"Access-Control-Allow-Origin: *"
]);
curl_setopt($handle, CURLOPT_URL, $url);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($handle); // $response = ""??
$errno = curl_errno($handle);
$err = curl_error($handle);
curl_close($handle);
if ($errno) {
return "cURL Error #:" . $err;}
else {
return $response;
}
}
function getBaseUrl()
{
return "http://localhost/api/";
}
?>
This is the api that take the request and supposed to save it to a file and return the json string.
create-api.php
<?php
include('ApiHandler.php');
header("Access-Control-Allow-Origin: *");
header("Content-Type: application/json; charset=UTF-8");
$postData = file_get_contents('php://input');
$data = array();
parse_str($postData, $data);
$json = file_get_contents('employees.json');
$obj = json_decode($postData,true);
$jsonarray = json_decode($json,true);
array_push($jsonarray,$obj);
$result = json_encode($jsonarray);
$file = fopen('employees.json','w');
fwrite($file,$result);
fclose($file);
return $result;
?>
create.php
<?php
include('ApiHandler.php');
$url = getBaseUrl()."create-api.php";
$postdata = file_get_contents("php://input");
$id = $_REQUEST["id"];
$firstname = $_REQUEST["firstname"];
$lastname = $_REQUEST["lastname"];
$arrayRequest = array("id"=>$id,"firstname"=>$firstname,"lastname"=>$lastname);
$json = json_encode($arrayRequest,true);
$output = callAPI("POST", $url, $json);
var_dump($output);
echo ("<p>$output</p>");
?>
Does anyone have any idea why the response is empty?

Your create-api.php script needs to output something to be caught by curl_exec()
So you need to replace your return $result; (which makes no sense in this context as you are not in a function) by echo $result;

Try to change this line in your code from:
curl_setopt($handle, CURLOPT_RETURNTRANSFER, 1);
to this:
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true)

Related

Show error if data is not posted to an external URL or external URL's server is down

I used the method POST to post data to www.stackoverflow.com in the case when data is not sent or the www.stackoverflow.com server is down I want to redirect to 404.php I have tried the following code.
$sub_req_url = "www.stackoverflow.com";
if (!extension_loaded('curl')) {
header('HTTP/1.1 404 Not Found');
include '404.php';
echo "error";
exit;
} else {
$ch = curl_init($sub_req_url);
$encoded = '';
foreach($sendArr as $name => $value) {
$encoded .= urlencode($name).'='.urlencode($value).'&';
}
$encoded = substr($encoded, 0, strlen($encoded)-1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
curl_exec($ch);
curl_close($ch);
echo json_encode($oderid);
}
Check the return value of curl_exec(). It will be false if there was an error.
$ch = curl_init($sub_req_url);
$encoded = http_build_query($sendArr); // use this instead of your loop
curl_setopt($ch, CURLOPT_POSTFIELDS, $encoded);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_POST, 1);
if (curl_exec($ch) === false) {
header('HTTP/1.1 404 Not Found');
include '404.php';
echo "error";
exit;
}
curl_close($ch);
echo json_encode($oderid);

PHP Curl get data

I'm created a simple PHP curl client that call a external webservice. This webservice return the XML.
<?php
// Method: POST, PUT, GET etc
// Data: array("param" => "value") ==> index.php?param=value
function CallAPI($method, $url, $data = false)
{
$curl = curl_init();
switch ($method)
{
case "POST":
curl_setopt($curl, CURLOPT_POST, 1);
if ($data)
curl_setopt($curl, CURLOPT_POSTFIELDS, $data);
break;
case "PUT":
curl_setopt($curl, CURLOPT_PUT, 1);
break;
default:
if ($data)
$url = sprintf("%s?%s", $url, http_build_query($data));
}
// Optional Authentication:
curl_setopt($curl, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curl, CURLOPT_URL, $url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
$result = curl_exec($curl);
curl_close($curl);
return $result;
}
$response = CallAPI('GET','https://s1-en.ogame.gameforge.com/api/universes.xml');
var_dump($response);
//print string(1121) " "
?>
But it always gives me back the wrong value. I print string(1121) " ".
How can I get the call data? (line 41 in the test.php).
This is because you are viewing the result in browser and the browser parses the xml as valid html tag. So you get empty result.
Its not your code issue. you can press ctrl + u (view source) in browser to see the actual result.
Or you can edit your var_dump to echo htmlentities($response); on line 41.

Basic Authorization PHP with Server related

I have some problem that related to HTTP_HEADERS in curl php in opencart. The code below is caller.
$ch = curl_init();
$url = 'http://aaa.com/index.php?route=common/home/getTotalCustomer';
$url2 = 'http://bbb.com/index.php?route=common/home/getTotalCustomer';
$url3 = 'http://ccc.com/index.php?route=common/home/getTotalCustomer';
$header = array('Authorization:Basic ' . base64_encode('user:password'));
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_HEADER, false);
$results = curl_exec($ch);
echo '<pre>';
print_r(json_decode($results, true));
echo '</pre>';
The receiver code like below:
public function getTotalCustomer(){
$json = array();
$this->load->model('account/customer');
if(isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])){
if(($_SERVER['PHP_AUTH_PW'] == 'password') && ($_SERVER['PHP_AUTH_USER'] == 'user')){
$json['total_customer'] = $this->model_account_customer->getTotalCustomer();
}
} else{
$json['message'] = 'failed';
}
$this->response->addHeader('Content-Type: application/json');
$this->response->setOutput(json_encode($json));
}
I had tried in multiple domain with different servers. Some server can return the data but some server cannot return the data. Why?
Your header that you're sending is incorrect.
You're passing
Authorization:Basic <username:password>
it should be
Authorization: Basic <username:password>
note the space.

PHP CURL DELETE request

I'm trying to do a DELETE http request using PHP and cURL.
I have read how to do it many places, but nothing seems to work for me.
This is how I do it:
public function curl_req($path,$json,$req)
{
$ch = curl_init($this->__url.$path);
$data = json_encode($json);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, $req);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json','Content-Length: ' . strlen($data)));
$result = curl_exec($ch);
$result = json_decode($result);
return $result;
}
I then go ahead and use my function:
public function deleteUser($extid)
{
$path = "/rest/user/".$extid."/;token=".$this->__token;
$result = $this->curl_req($path,"","DELETE");
return $result;
}
This gives me HTTP internal server ERROR.
In my other functions using the same curl_req method with GET and POST, everything goes well.
So what am I doing wrong?
I finally solved this myself. If anyone else is having this problem, here is my solution:
I created a new method:
public function curl_del($path)
{
$url = $this->__url.$path;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
$result = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
return $result;
}
Update 2
Since this seems to help some people, here is my final curl DELETE method, which returns the HTTP response in JSON decoded object:
/**
* #desc Do a DELETE request with cURL
*
* #param string $path path that goes after the URL fx. "/user/login"
* #param array $json If you need to send some json with your request.
* For me delete requests are always blank
* #return Obj $result HTTP response from REST interface in JSON decoded.
*/
public function curl_del($path, $json = '')
{
$url = $this->__url.$path;
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($ch, CURLOPT_POSTFIELDS, $json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$result = curl_exec($ch);
$result = json_decode($result);
curl_close($ch);
return $result;
}
To call GET,POST,DELETE,PUT All kind of request, i have created one common function
function CallAPI($method, $api, $data) {
$url = "http://localhost:82/slimdemo/RESTAPI/" . $api;
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
switch ($method) {
case "GET":
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "GET");
break;
case "POST":
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "POST");
break;
case "PUT":
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "PUT");
break;
case "DELETE":
curl_setopt($curl, CURLOPT_CUSTOMREQUEST, "DELETE");
curl_setopt($curl, CURLOPT_POSTFIELDS, json_encode($data));
break;
}
$response = curl_exec($curl);
$data = json_decode($response);
/* Check for 404 (file not found). */
$httpCode = curl_getinfo($curl, CURLINFO_HTTP_CODE);
// Check the HTTP Status code
switch ($httpCode) {
case 200:
$error_status = "200: Success";
return ($data);
break;
case 404:
$error_status = "404: API Not found";
break;
case 500:
$error_status = "500: servers replied with an error.";
break;
case 502:
$error_status = "502: servers may be down or being upgraded. Hopefully they'll be OK soon!";
break;
case 503:
$error_status = "503: service unavailable. Hopefully they'll be OK soon!";
break;
default:
$error_status = "Undocumented error: " . $httpCode . " : " . curl_error($curl);
break;
}
curl_close($curl);
echo $error_status;
die;
}
CALL Delete Method
$data = array('id'=>$_GET['did']);
$result = CallAPI('DELETE', "DeleteCategory", $data);
CALL Post Method
$data = array('title'=>$_POST['txtcategory'],'description'=>$_POST['txtdesc']);
$result = CallAPI('POST', "InsertCategory", $data);
CALL Get Method
$data = array('id'=>$_GET['eid']);
$result = CallAPI('GET', "GetCategoryById", $data);
CALL Put Method
$data = array('id'=>$_REQUEST['eid'],'title'=>$_REQUEST['txtcategory'],'description'=>$_REQUEST['txtdesc']);
$result = CallAPI('POST', "UpdateCategory", $data);

Need to Implement Zend_Rest_Client for the following curl method

I usually use curl to call rest api's like this
$user_data = array("userName" => "myuser#mydomain.com" ,"password" => "mydomain123" );
$data = json_encode($user_data);
$headers = array('Accept: application/json', 'Content-Type: application/json',);
$handle = curl_init();
curl_setopt($handle, CURLOPT_URL, 'http://myursl.com/myapi/v1/Api.svc/something/someother');
curl_setopt($handle, CURLOPT_HTTPHEADER, $headers);
curl_setopt($handle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($handle, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($handle, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($handle, CURLOPT_POST, true);
curl_setopt($handle, CURLOPT_POSTFIELDS, $data);
$response = curl_exec($handle);
$code = curl_getinfo($handle, CURLINFO_HTTP_CODE);
curl_close($handle);
print_r($response);
The above code is working fine with API and printing the expected response , When I do the same thing using Zend_Rest_client of Zend Framework
like this
$base_url = 'http://myursl.com/myapi/v1_0/Api.svc';
$endpoint = '/something/someother';
$user_data = array("userName" => "myuser#mydomain.com" ,"password" => "mydomain123" );
$client = new Zend_Rest_Client($base_url);
$response = $client->restPost($endpoint, $user_data);
I am getting 404 error like this
(Zend_Http_Response)#62 (5) { ["version":protected]=> string(3) "1.1" ["code":protected]=> int(404) ["message":protected]=> string(9) "Not Found"] }
Where actually I am wrong in implementing Zend Rest Client
Thanks in advance for responding to this post
Although it might not be the finest solution I finally ended up inheriting Zend_Rest_Client and overriding _performPost() like this:
class My_Rest_Client extends Zend_Rest_Client {
protected function _performPost($method, $data = null)
{
$client = self::getHttpClient();
if (is_string($data)) {
$client->setRawData($data, 'application/json');
} elseif (is_array($data) || is_object($data)) {
$client->setParameterPost((array) $data);
}
return $client->request($method);
}
}
And then:
$rest = new My_Rest_Client('http://my.rest.url');
$rest->restPost('post-path', $data);

Categories