I am posting data(including a media file (.wav)) from my app to an API with curl. When submitting my data, i check for the data including the mediafile submitted in my API. From the response i get from my API, see below
Response
{"status":"success","media":false,"data":{"message":"Media Campaign","recipient":["34505140704"],
"file":{"name":"\/Users\/path\/to\/folder\/public\/Voice\/aaaah.wav","mime":null,"postname":null}}}true
In the response, the file is being retrieved as well but when i check for the file using $request->hasFile('file') or $request->file('file'), I get false and null respectively.
Can someone let me know why this is happening in my code please ?
Controller
public function test()
{
$file_name_with_full_path = '/Users/path/to/folder/public/Voice/aaaah.wav';
if(function_exists('curl_file_create'))
{
$cFile = curl_file_create($file_name_with_full_path);
}
else
{
$cFile = '#' . realpath($file_name_with_full_path);
}
$post = array('message' => 'Media Campaign', 'recipient' => ['34505140704'],'file' => $cFile);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL,$url);
curl_setopt($ch, CURLOPT_POST,1);
curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query($post));
$result=curl_exec ($ch);
curl_close ($ch);
}
APIController
public function campaign(Request $request)
{
if (($request->get('message')) {
return response()->json([
'status' => 'success',
'data' => $request->all()
]);
}
}
To be honest, I'd use Guzzle to hide the details of cURL requests in PHP. The way PHP's cURL extension handles file transfers changed a couple of years ago, which broke a lot of legacy code at the company I was working for. By using a third-party wrapper like Guzzle, you can let the Guzzle developers worry about changes in the underlying extension - all you need to do is keep your Guzzle package up to date.
PHP - Why Use Guzzle Instead of cURL?
Related
I want to fetch data from Third_party API called BirdEye. I was using Core PHP Inbuilt Functions of CURL to fetch data, it was working fine, Now When I switched to Library I am bit confused because it doesn't gives me any response in return.
I have Downloaded Curl Libray from Here : Curl Library Download and Example
I tried to create a demo just to check my Library is working fine or not, it worked. Now If I fetch data from Bird-Eye Api I don't know It gives me nothing in response.
My Code is here:
<?php
defined('BASEPATH') OR exit('No direct script access allowed');
class Welcome extends CI_Controller {
public function index()
{
$this->load->library('curl');
$get_url = "https://api.birdeye.com/resources/v1/business/147802929307762?api_key=ApiKeyGoesHere";
echo $this->curl->simple_get($get_url, false, array(CURLOPT_USERAGENT => true));
echo $this->curl->error_code;
$this->load->view('welcome_message');
}
}
I don't know where I am going wrong I am passing all the required parameters to the Api and when I try to echo error code it gives me 22. I even searched on birdeye documentation but nothing found.
Link to Api Documentation is : Link to BirdEye Api Documentation
So according to the BirdEye API your cURL script should be like the following:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "https://api.birdeye.com/resources/v1/business/businessId ");
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_HEADER, FALSE);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
"Content-Type: application/json",
"Accept: application/json"
));
$response = curl_exec($ch);
curl_close($ch);
Now, when I'm comparing your library usage code to the example above, I see you're missing the definitions of several options.
Before adding those options to your code, try to follow this part:
In the example they're not using the APIKEY, but when you do use it, you might need to pass it as a parameter and not in the get_url variable.
Which means:
$get_url = "https://api.birdeye.com/resources/v1/business/147802929307762";
echo $this->curl->simple_get($get_url, array('api_key' => 'YourApiKeyGoesHere'), array(..));
If it still doesn't work, try to add the options to your code:
$this->load->library('curl');
$get_url = "https://api.birdeye.com/resources/v1/business/147802929307762?api_key=ApiKeyGoesHere";
echo $this->curl->simple_get($get_url, false, array(CURLOPT_USERAGENT => true, CURLOPT_RETURNTRANSFER => TRUE, CURLOPT_HEADER => FALSE, CURLOPT_HTTPHEADER => array("Content-Type: application/json", "Accept: application/json")));
echo $this->curl->error_code;
$this->load->view('welcome_message');
I have a service, that needs to authenticate via another service.
For this I setup a Middleware that extracts the Authorization header out of my initial request, and then creates a curl request to the Auth Service with the header set.
public function handle($request, Closure $next) {
$authHeader = $request->header('Authorization');
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, "http://api.user.eventmanager.app/getAccess");
curl_setopt($ch,CURLOPT_HTTPHEADER,array(
'Authorization: ' . $authHeader,
'Origin: http://api.asdf.rerere.app'
));
$result = curl_exec($ch);
if($result) {
curl_close($ch);
return $next($request);
} else {
curl_close($ch);
return response("Invalid Token or expired Token", 401);
}
}
The request returns the requested ressource as expected, but also adds in the User object in the response (the one I get via the curl request, I want to do further checking with the user object in the middleware, but I dont want it returned to the inital request).
Here is what my controller for the response I want looks like:
public function show($id)
{
$event = Event::with('timeTableEntries', 'venue', 'bands')->find($id);
if(!$event) {
return $this->respondNotFound('Event does not exist!');
}
return $this->respond([
'data' => $this->eventTransformer->transform($event)
]);
}
Somehow the User Object from the curl ends up in my respons.
Any idea why this happens?
You're not returning transfer on your curl options, which stops the response from outputting and returns the string instead.
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
as per http://php.net/manual/en/function.curl-setopt.php
Using elasticsearch-php on Laravel 5 through Shift31/laravel-elasticsearch (provides facade for elasticsearch-php). Hosting an ES instance on Facetflow.
config/elasticsearch.php:
return array(
'hosts' => array(
'https://accessUsername#ilovelasagna.east-us.azr.facetflow.io:443'
)
);
WelcomeController.php:
public function elasticsearch()
{
$searchParams['index'] = 'your_index';
$searchParams['size'] = 50;
$searchParams['body']['query']['query_string']['query'] = 'foofield:barstring';
return Es::search($searchParams);
// throws Authentication401Exception exception
}
This returns Authentication401Exception. My guess is the username is not passed to the Facetflow server, but I have not found a way to check if this is true.
The problem does not seem to be in the server's settings, because when I use plain curl, I get a 200 response:
public function justCurl()
{
$ch = curl_init();
// Now set some options (most are optional)
// Set URL to download
curl_setopt($ch, CURLOPT_URL, "https://accessUsername#ilovelasagna.east-us.azr.facetflow.io:443");
// Download the given URL, and return output
$output = curl_exec($ch);
// Close the cURL resource, and free system resources
curl_close($ch);
return $output;
// returns 200 response
}
How do I fix this issue?
Facetflow's blazing-fast customer support pointed out the issue here.
Host was supposed to be marked as
'https://accessUsername:#ilovelasagna.east-us.azr.facetflow.io:443'
Note the colon after accessUsername.
How to make http request to another server through Laravel?
I'll be pleased to provide whatever information you need
any help is much appreciated
Depends how complex the request needs to be. You can use curl or even, file_get_contents for simple get requests, or install a package like Guzzle for more complex things.
https://github.com/guzzle/guzzle
With 'normal' PHP, you can use Curl to work with the http protocol (POST/GET). If you are using Laravel, you can either build your own curl methods or you can use a 3rd party curl library compatible with composer/Laravel:
https://packagist.org/packages/unikent/curl
You can use Guzzle
add the dependency package in the composer.json file
{
"require": {
"guzzlehttp/guzzle": "~4.0" //you can change the version
}
}
make composer install or update
To create your very first request with guzzle, a code snippet as simple as below will work:
use GuzzleHttp\Client;
use GuzzleHttp\Message\Request;
use GuzzleHttp\Message\Response;
$client = new Client();
$response = $client->get("https://api.github.com/");
retrun $response;
If for some reason you are running an old Laravel version or don't want to bother with guzzle, you can always use php-curl:
sudo apt-get install php-curl
Then create a function for your needs eg POST:
function httpPost($url, $data){
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_POSTFIELDS, http_build_query($data));
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
or GET
public function httpGet($url){
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
$response = curl_exec($curl);
curl_close($curl);
return $response;
}
Simply call your function in controller:
$response = $this->httpPost($url, $data);
$response = $this->httpget($url);
Where $url is your endpoint where you need to send request and $data - parameters required.
First of all run this command
composer require guzzlehttp/guzzle
use GuzzleHttp\Client;
$client = new Client();
$response = $client->get("http://www.somewebsite.com/getSmth");
$response = (string) $response->getBody();
return $response;
getBody() function will return object.
You can use via converting to string and after that if you want you can change it to integer also
$response = (int) (string) $response->getBody();
Using Symfony2, I need to access an external API based on HTTPS.
How can I call an external URI and manage the response to "play" with it. For example, to render a success or a failure message?
I am thinking in something like (note that performRequest is a completely invented method):
$response = $this -> performRequest("www.someapi.com?param1=A¶m2=B");
if ($response -> getError() == 0){
// Do something good
}else{
// Do something too bad
}
I have been reading about Buzz and other clients. But I guess that Symfony2 should be able to do it by its own.
I'd suggest using CURL:
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, 'www.someapi.com?param1=A¶m2=B');
curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-type: application/json')); // Assuming you're requesting JSON
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
$response = curl_exec($ch);
// If using JSON...
$data = json_decode($response);
Note: The php on your web server must have the php5-curl library installed.
Assuming the API request is returning JSON data, this page may be useful.
This doesn't use any code that is specific to Symfony2. There may well be a bundle that can simplify this process for you, but if there is I don't know about it.
Symfony doesn't have a built-in service for this, but this is a perfect opportunity to create your own, using the dependency injection framework. What you can do here is write a service to manage the external call. Let's call the service "http".
First, write a class with a performRequest() method:
namespace MyBundle\Service;
class Http
{
public function performRequest($siteUrl)
{
// Code to make the external request goes here
// ...probably using cUrl
}
}
Register it as a service in app/config/config.yml:
services:
http:
class: MyBundle\Service\Http
Now your controller has access to a service called "http". Symfony manages a single instance of this class in the "container", and you can access it via $this->get("http"):
class MyController
{
$response = $this->get("http")->performRequest("www.something.com");
...
}
Best client that I know is: http://docs.guzzlephp.org/en/latest/
There is already bundle that integrates it into Symfony2 project:
https://github.com/8p/GuzzleBundle
$client = $this->get('guzzle.client');
// send an asynchronous request.
$request = $client->createRequest('GET', 'http://httpbin.org', ['future' => true]);
// callback
$client->send($request)->then(function ($response) {
echo 'I completed! ' . $response;
});
// optional parameters
$response = $client->get('http://httpbin.org/get', [
'headers' => ['X-Foo-Header' => 'value'],
'query' => ['foo' => 'bar']
]);
$code = $response->getStatusCode();
$body = $response->getBody();
// json response
$response = $client->get('http://httpbin.org/get');
$json = $response->json();
// extra methods
$response = $client->delete('http://httpbin.org/delete');
$response = $client->head('http://httpbin.org/get');
$response = $client->options('http://httpbin.org/get');
$response = $client->patch('http://httpbin.org/patch');
$response = $client->post('http://httpbin.org/post');
$response = $client->put('http://httpbin.org/put');
More info can be found on: http://docs.guzzlephp.org/en/latest/index.html
https://github.com/sensio/SensioBuzzBundle seems to be what you are looking for.
It implements the Kris Wallsmith buzz library to perform HTTP requests.
I'll let you read the doc on the github page, usage is pretty basic:
$buzz = $this->container->get('buzz');
$response = $buzz->get('http://google.com');
echo $response->getContent();
Symfony does not have its own rest client, but as you already mentioned there are a couple of bundles. This one is my prefered one:
https://github.com/CircleOfNice/CiRestClientBundle
$restClient = $this->container->get('ci.restclient');
$restClient->get('http://www.someUrl.com');
$restClient->post('http://www.someUrl.com', 'somePayload');
$restClient->put('http://www.someUrl.com', 'somePayload');
$restClient->delete('http://www.someUrl.com');
$restClient->patch('http://www.someUrl.com', 'somePayload');
$restClient->head('http://www.someUrl.com');
$restClient->options('http://www.someUrl.com', 'somePayload');
$restClient->trace('http://www.someUrl.com');
$restClient->connect('http://www.someUrl.com');
You send the request via
$response = $restclient->get($url);
and get a Symfony response object.
Then you can get the status code via
$httpCode = $response-> getStatusCode();
Your code would look like:
$restClient = $this->container->get('ci.restclient');
if ($restClient->get('http://www.yourUrl.com')->getStatusCode !== 200) {
// no error
} else {
// error
}
Use the HttpClient class to create the low-level HTTP client that makes requests, like the following GET request:
use Symfony\Component\HttpClient\HttpClient;
$client = HttpClient::create();
$response = $client->request('GET', 'https://api.github.com/repos/symfony/symfony-docs');
$statusCode = $response->getStatusCode();
// $statusCode = 200
$contentType = $response->getHeaders()['content-type'][0];
// $contentType = 'application/json'
$content = $response->getContent();
// $content = '{"id":521583, "name":"symfony-docs", ...}'
$content = $response->toArray();
// $content = ['id' => 521583, 'name' => 'symfony-docs', ...]
This is compatible with Symfony 5. Symfony Manual on this topic: The HttpClient Component