I am looking for a way to make a post request from a controller to an external url. The data being posted is a php array. The url to recieve is an ecommerce API in an external url. The post has to be done from the controller method. The url should reply with 'success', 'error', 'failure' or 'trylater' string. I have tried the following with no success:
return Redirect::to("https://backoffice.host.iveri.com/Lite/Transactions/New/Authorise.aspx", compact($array));
I have tried curl too:
$url = 'https://backoffice.host.iveri.com/Lite/Transactions/New/Authorise.aspx';
//url-ify the data for the POST
$fields_string ='';
foreach($array as $key=>$value) { $fields_string .= $key.'='.$value.'&'; }
rtrim($fields_string,'& ');
//open connection
$ch = curl_init();
//set the url, number of POST vars, POST data
curl_setopt($ch,CURLOPT_URL, $url);
curl_setopt($ch,CURLOPT_POST, count($array));
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_string);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
//execute post
$result = curl_exec($ch);
//close connection
curl_close($ch);
Part of the array being sent is the callbacks that the API uses to responds:
'Lite_Website_Successful_url' => 'https://mydomain.com/order/'.$order_id,
'Lite_Website_Fail_url' => 'https://mydomain.com/checkout/fail',
'Lite_Website_TryLater_url' => 'https://mydomain.com/checkout/trylater',
'Lite_Website_Error_url' => 'https://mydomain.com/checkout/error'
Please let me know how to do a POST request properly with data carried with it to an external url. An ajax post from the controller too would help but I have tried with no success. But I would prefer a laravel php answer more. Thank you.
We can use package Guzzle in Laravel, it is a PHP HTTP client to send HTTP requests.
You can install Guzzle through composer
composer require guzzlehttp/guzzle:~6.0
Or you can specify Guzzle as a dependency in your project's existing composer.json
{
"require": {
"guzzlehttp/guzzle": "~6.0"
}
}
Example code of POST Request in laravel, using Guzzle is as shown below,
use GuzzleHttp\Client;
class yourController extends Controller {
public function saveApiData()
{
$client = new Client();
$res = $client->request('POST', 'https://url_to_the_api', [
'form_params' => [
'client_id' => 'test_id',
'secret' => 'test_secret',
]
]);
$result= $res->getBody();
dd($result);
}
Let me clarify some stuff and try to point you in the right direction.
First, what you're attempting to do sounds like "making an API request from your web app". The difference in that wording in how I stated it vs yours is that it's more general.
You can make an API request anywhere in your application, not necessarily in your controller (Don't be afraid to make extra classes/models for things like API calls!)
I'm curious about why it "has to be" done in your controller? What's your use case?
AJAX doesn't exist on the server-side (in PHP). That's purely a javascript-specific "technology" that describes javascript making a request to a URL on the client-side.
Lastly, what are you trying to do? Do you need a user to be redirected? Or do you need to make an API call and parse the result within your application?
The cURL request you've attempted should work for making an API request. That's one of the main ways of making an API request within PHP code. It won't, however, allow a user on the front-end to see that request being made and processed. With cURL (and any API request), the processing is all happening behind the scenes in your PHP (which your users can't see).
Either use CURL the way you've been trying, or check this thread for a brief answer on doing it with the Guzzle http client. Guzzle seems to be the preferred client for use with Laravel...
Call external API function from controller, LARAVEL 4
Related
I'm planning to use PHP for a simple requirement. I need to download a XML content from a URL, for which I need to send HTTP GET request to that URL.
How do I do it in PHP?
Unless you need more than just the contents of the file, you could use file_get_contents.
$xml = file_get_contents("http://www.example.com/file.xml");
For anything more complex, I'd use cURL.
For more advanced GET/POST requests, you can install the CURL library (http://us3.php.net/curl):
$ch = curl_init("REMOTE XML FILE URL GOES HERE"); // such as http://example.com/example.xml
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
$data = curl_exec($ch);
curl_close($ch);
http_get should do the trick. The advantages of http_get over file_get_contents include the ability to view HTTP headers, access request details, and control the connection timeout.
$response = http_get("http://www.example.com/file.xml");
Remember that if you are using a proxy you need to do a little trick in your php code:
(PROXY WITHOUT AUTENTICATION EXAMPLE)
<?php
$aContext = array(
'http' => array(
'proxy' => 'proxy:8080',
'request_fulluri' => true,
),
);
$cxContext = stream_context_create($aContext);
$sFile = file_get_contents("http://www.google.com", False, $cxContext);
echo $sFile;
?>
Guzzle is a very well known library which makes it extremely easy to do all sorts of HTTP calls. See https://github.com/guzzle/guzzle. Install with composer require guzzlehttp/guzzle and run composer install. Now code below is enough for a http get call.
$client = new \GuzzleHttp\Client();
$response = $client->get('https://example.com/path/to/resource');
echo $response->getStatusCode();
echo $response->getBody();
Depending on whether your php setup allows fopen on URLs, you could also simply fopen the url with the get arguments in the string (such as http://example.com?variable=value )
Edit: Re-reading the question I'm not certain whether you're looking to pass variables or not - if you're not you can simply send the fopen request containg http://example.com/filename.xml - feel free to ignore the variable=value part
I like using fsockopen open for this.
On the other hand, using the REST API of servers is very popular in PHP. You can suppose all URLs are parts of a REST API and use many well-designed PHP packages.
Actually, REST API is a way to use services from a site.
So, there are many PHP packages developed to simplify REST API call. For example here is a very nice one:
https://github.com/romanpitak/PHP-REST-Client
Using such packages helps you to fetch resources easily.
So, getting the xml file (that you mentioned about) is as easy as:
$client = new Client('http://example.com');
$request = $client->newRequest('/filename.xml');
$response = $request->getResponse();
echo $response->getParsedResponse();
My code makes a curl request to an API that converts image formats e.g. png to jpg.
The API documentation offers a callback from the API which, when the conversion is finished, will send a GET request to a url on my server (hosted, not localhost). I provide this url to the API with the key/value pair:
"callback" => "12coins.net/cc_callback.php"
Unfortunately the API never calls back. Are my curl_setopt parameters wrong or what could be the problem?
$ch_start_process = curl_init();
$start_process_data = array(
"callback" => "https://12coins.com/cc_callback.php",
"input" => "download",
"file" => "https://12coins.com/photo_file.png",//the image I want converted
"tag" => "tag - unused for now",
"outputformat" => "jpg");
$process_url = "https:".$url_from_create;//prepend https to construct a valid endpoint.
//$url_from_create is a url returned by the API to a request immediately prior to this one
curl_setopt($ch_start_process, CURLOPT_URL, $process_url);
curl_setopt($ch_start_process, CURLOPT_POSTFIELDS, http_build_query ($start_process_data));
curl_setopt($ch_start_process, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch_start_process, CURLOPT_IPRESOLVE, CURL_IPRESOLVE_V4 );
$start_response=curl_exec($ch_start_process);//assign return value of curl_exec()
This is the script on my (remote) server 12coins.net/cc_callback.php to which the API should call back but doesn't:
<?php
header('Access-Control-Allow-Origin: *');
echo 'cc_callback has been called';
echo 'The GET request from CloudConvert is: '. $_GET;
?>
The API does in fact make a call back. It was just that with the code as shown in cc_callback.php there was no way for me to detect the callback. I had assumed that the echo statements would allow me to see the API's response in the (Chrome) network tab of my brower's dev tools. But of course the echo statements echo to the client that 'called' it with a GET request. In this case, that client is the API and not my browser/html page.
Realising this, I was then easily able to check that it had worked all along by adding
mail(myemailaddress#gmail.com, 'This is the url returned to the callback',$GET[url]); to my php script (shown in the question). This sent me an email when I sent an image to the API for processing and thus confirmed that the API was making the call back..
The curl code in the question is good. It makes a successful request to the API.
Lastly, the curl code is for a request to the CloudConvert API, version 1. There is a version 2 but the code above is not good for that. Also, there's an earlier curl request which must be used in conjunction with the one above which I'll post later for the sake of completeness.
I'm wondering, is there an easy way to perform a REST API GET call? I've been reading about cURL, but is that a good way to do it?
I also came across php://input but I have no idea how to use it. Does anyone have an example for me?
I don't need advanced API client stuff, I just need to perform a GET call to a certain URL to get some JSON data that will be parsed by the client.
Thanks!
There are multiple ways to make REST client API call:
Use CURL
CURL is the simplest and good way to go. Here is a simple call
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, POST DATA);
$result = curl_exec($ch);
print_r($result);
curl_close($ch);
Use Guzzle
It's a "PHP HTTP client that makes it easy to work with HTTP/1.1 and takes the pain out of consuming web services". Working with Guzzle is much easier than working with cURL.
Here's an example from the Web site:
$client = new GuzzleHttp\Client();
$res = $client->get('https://api.github.com/user', [
'auth' => ['user', 'pass']
]);
echo $res->getStatusCode(); // 200
echo $res->getHeader('content-type'); // 'application/json; charset=utf8'
echo $res->getBody(); // {"type":"User"...'
var_export($res->json()); // Outputs the JSON decoded data
Use file_get_contents
If you have a url and your php supports it, you could just call file_get_contents:
$response = file_get_contents('http://example.com/path/to/api/call?param1=5');
if $response is JSON, use json_decode to turn it into php array:
$response = json_decode($response);
Use Symfony's RestClient
If you are using Symfony there's a great rest client bundle that even includes all of the ~100 exceptions and throws them instead of returning some meaningless error code + message.
try {
$restClient = new RestClient();
$response = $restClient->get('http://www.someUrl.com');
$statusCode = $response->getStatusCode();
$content = $response->getContent();
} catch(OperationTimedOutException $e) {
// do something
}
Use HTTPFUL
Httpful is a simple, chainable, readable PHP library intended to make speaking HTTP sane. It lets the developer focus on interacting with APIs instead of sifting through curl set_opt pages and is an ideal PHP REST client.
Httpful includes...
Readable HTTP Method Support (GET, PUT, POST, DELETE, HEAD, and OPTIONS)
Custom Headers
Automatic "Smart" Parsing
Automatic Payload Serialization
Basic Auth
Client Side Certificate Auth
Request "Templates"
Ex.
Send off a GET request. Get automatically parsed JSON response.
The library notices the JSON Content-Type in the response and automatically parses the response into a native PHP object.
$uri = "https://www.googleapis.com/freebase/v1/mqlread?query=%7B%22type%22:%22/music/artist%22%2C%22name%22:%22The%20Dead%20Weather%22%2C%22album%22:%5B%5D%7D";
$response = \Httpful\Request::get($uri)->send();
echo 'The Dead Weather has ' . count($response->body->result->album) . " albums.\n";
You can use file_get_contents if the fopen wrappers are enabled. See: http://php.net/manual/en/function.file-get-contents.php
If they are not, and you cannot fix that because your host doesn't allow it, cURL is a good method to use.
You can use:
$result = file_get_contents( $url );
http://php.net/manual/en/function.file-get-contents.php
I have a PHP script that syncs data with a third party service, and I would like to, if possible, replace nuSOAP with cURL as I have heard cURL is faster. The web service I am calling just takes simple HTTP post and returns it, so the cURL parameters shouldn't be too involved.
I need to pass 4 things, a user id, password, organization id, and the name of the web service to receive data from.
Which part of the cURL options do I pass them? I was trying to pass them in the header, but I am not sure if that is correct. I kept receiving 'Bad Request (Invalid Number)' error.
Edit: I am setting the HTTPHEADER but it looks like its still setting it to text/html.
Since, i have a thought that you have some basic understanding of cURL. I am giving you some shallow information.
If you are just posting some information to a page make use of
curl_setopt($agent, CURLOPT_POST, true);
curl_setopt($agent, CURLOPT_POSTFIELDS, $post_data);
where $post_data will be the information you post to the page , something like
$post_data="name=stanley&feedback=good";
Or
If you are trying to make an authentication to a page, Just use
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt(CURLOPT_USERPWD, '[username]:[password]');
If you say 'The web service I am calling just takes simple HTTP post', assuming it doesn't use SOAP, you would do it by:
curl_setopt($handle,CURLOPT_POST,true);
curl_setopt($handle,CURLOPT_POSTFIELDS,array(
'user_id' => 'user',
'password' => 'pass' //etc, all the key/value pairs you need.
));
However, if it is a SOAP service, you would have to make a SOAP request, and which for it would take we cannot tell you without a WSDL. Any of the PHP XML packages would do to create it, possibly for simple things even normal string manipulation.
A help in the built-in soapclient (not nusoap) would be to do a request with SOAPClient and just examine the output of __getLastRequest().
I'm planning to use PHP for a simple requirement. I need to download a XML content from a URL, for which I need to send HTTP GET request to that URL.
How do I do it in PHP?
Unless you need more than just the contents of the file, you could use file_get_contents.
$xml = file_get_contents("http://www.example.com/file.xml");
For anything more complex, I'd use cURL.
For more advanced GET/POST requests, you can install the CURL library (http://us3.php.net/curl):
$ch = curl_init("REMOTE XML FILE URL GOES HERE"); // such as http://example.com/example.xml
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, 0);
$data = curl_exec($ch);
curl_close($ch);
http_get should do the trick. The advantages of http_get over file_get_contents include the ability to view HTTP headers, access request details, and control the connection timeout.
$response = http_get("http://www.example.com/file.xml");
Remember that if you are using a proxy you need to do a little trick in your php code:
(PROXY WITHOUT AUTENTICATION EXAMPLE)
<?php
$aContext = array(
'http' => array(
'proxy' => 'proxy:8080',
'request_fulluri' => true,
),
);
$cxContext = stream_context_create($aContext);
$sFile = file_get_contents("http://www.google.com", False, $cxContext);
echo $sFile;
?>
Guzzle is a very well known library which makes it extremely easy to do all sorts of HTTP calls. See https://github.com/guzzle/guzzle. Install with composer require guzzlehttp/guzzle and run composer install. Now code below is enough for a http get call.
$client = new \GuzzleHttp\Client();
$response = $client->get('https://example.com/path/to/resource');
echo $response->getStatusCode();
echo $response->getBody();
Depending on whether your php setup allows fopen on URLs, you could also simply fopen the url with the get arguments in the string (such as http://example.com?variable=value )
Edit: Re-reading the question I'm not certain whether you're looking to pass variables or not - if you're not you can simply send the fopen request containg http://example.com/filename.xml - feel free to ignore the variable=value part
I like using fsockopen open for this.
On the other hand, using the REST API of servers is very popular in PHP. You can suppose all URLs are parts of a REST API and use many well-designed PHP packages.
Actually, REST API is a way to use services from a site.
So, there are many PHP packages developed to simplify REST API call. For example here is a very nice one:
https://github.com/romanpitak/PHP-REST-Client
Using such packages helps you to fetch resources easily.
So, getting the xml file (that you mentioned about) is as easy as:
$client = new Client('http://example.com');
$request = $client->newRequest('/filename.xml');
$response = $request->getResponse();
echo $response->getParsedResponse();