How to add a parameter to the request header sent by a PHP script? - php

I'm trying to use a web service REST API for which I need to add a parameter for authorization (with the appropriate key, of course) to get a XML result. I'm developing in PHP. How can I add a parameter to the request header in such a situation?
Edit: The way I'm doing the request right now is $xml = simplexml_load_file($query_string);

Are you using curl? (recommended)
I assume that you are using curl to do these requests towards the REST API, if you aren't; use it.
When using curl you can add a custom header by calling curl_setopt with the appropriate parameters, such as in below.
curl_setopt (
$curl_handle, CURLOPT_HTTPHEADER,
array ('Authentication-Key: foobar')
); // make curl send a HTTP header named 'Authentication-key'
// with the value 'foobar'
Documentation:
PHP: cURL - Manual
PHP: curl_setopt - Manual
Are you using file_get_contents or similar?
This method is not recommended, though it is functional.
Note: allow_url_fopen needs to be enabled for file_get_contents to be able to access resources over HTTP.
If you'd like to add a custom header to such request you'll need to create yourself a valid stream context, as in the below snippet:
$context_options = array(
'http' =>array (
'method' => 'GET',
'header' => 'Authentication-Key'
)
);
$context = stream_context_create ($context_options);
$response = file_get_contents (
'http://www.stackoverflow.com', false, $context_options
);
Documentation:
PHP: file_get_contents - Manual
PHP: stream_context_create - Manual
PHP: Runtime Configuration, allow_url_fopen
I'm using neither of the above solutions, what should I do?
[Post OP EDIT]
My recommendation is to fetch the data using curl and then pass it off to the parser in question when all the data is received. Separate data fetching from the processing of the returned data.
[/Post OP EDIT]

When you use $xml = simplexml_load_file($query_string);, the PHP interpreter invokes it's wrapper over fopen to open the contents of a file located at $query_string. If $query_string is a remote file, the PHP interpreter opens a stream to that remote URL and retrieves the contents of the file there (if the HTTP response code 200 OK). It uses the default stream context to do that.
There is a way to alter the headers sent by altering that stream context, however, in most cases, this is a bad idea. You're relying on PHP to always open all files, local or remote, using a function that was meant to take a local file name only. Not only is it a security problem but it also could be the source of a bug that is very hard to track down.
Instead, consider splitting the loading of the remote content using cURL (checking the returned HTTP status code and other sanity checks) and then parsing that content into a SimpleXMLElement object to use. When you use cURL, you can set any headers you want to send with the request by invoking something similar to curl_setopt($ch, CURLOPT_HTTPHEADER, array('HeaderName' => 'value');
Hope this helps.

Related

HOW TO USE API's in PHP LARAVEL [duplicate]

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();

Stream context in PHP - what is it?

I have searched for hours and I cannot figure out what a 'stream context' in PHP is. I'm trying to use an API and it involves using this 'stream context'.
The documentation says:
A context is a set of parameters and wrapper specific options which modify or enhance the behavior of a stream.
A parameter of what?
What is meant by an option being 'specific to a wrapper'?
What stream?
Here is the code I'm talking about:
// Encode the credentials and create the stream context.
$auth = base64_encode("$acctKey:$acctKey");
$data = array(
'http' => array(
'request_fulluri' => true,
// ignore_errors can help debug – remove for production. This option added in PHP 5.2.10
'ignore_errors' => true,
'header' => "Authorization: Basic $auth")
);
$context = stream_context_create($data);
// Get the response from Bing.
$response = file_get_contents($requestUri, 0, $context);
It took me a while to understand the stream contexts options and wrappers of PHP. I wrote an article about what helped me finally wrap my brain around how to understand PHP stream contexts options and wrappers. I hope it helps.
To properly handle whatever is coming down the line (streamed data), you will need the appropriate code to handle the different kinds of items being passed (data types). The tools for handling each different kind of data type are the “parameters”.
The “context” is determined by what is being pass along (streamed). So for different “contexts” (kinds of items) being “streamed” (passed along) the “parameters” (required tools for handling) the “data type” (kind of item) will change.
The term context simply makes reference to the fact that for different data types the situation is unique with its own required parameters.
The PHP stream wrapper would require a context in order to know which parameters are needed to handle the data type.
A parameter of the context that modifies the properties of the stream.
The options are specific to whatever wrapper the stream is using. Examples of these include files, all the different php:// URIs, the HTTP wrapper (like when you do file_get_contents('http://example.com') — it’s not the same thing as file_get_contents('some-file.txt'))
Any stream!
In this case, the stream context is passed to file_get_contents to tell it to send that authorization header and those options to the wrapper that allows file_get_contents to get contents from HTTP URLs.
You can find a list of the HTTP context options on the PHP website.
http, request_fulluri, ignore_errors, header are all parameters.
They change the way the function (file_get_contents in this case) works.
An option that is specific to a wrapper is something like 'http' --
you wouldn't use that on a filesystem file stream since it's not applicable.
The stream is the transfer of data itself which occurs when file_get_contents opens the connection, transfers everything, etc...

Replace nuSOAP with cURL

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().

How to send a PUT request with a file and an array of data with PHP

I've set up a REST service and client in PHP and I'm having a bit of trouble with PUT.
Here's my situation:
I'm coding a REST resource that should accept an array of data and an image. The REST resource should update an existing record, so I'm using PUT. I'm sending the data with a PHP curl client I wrote. So - pretty much the same situation as if you were sending a HTML multipart form to a PHP script that does a file upload and accepts some additional POST fields - except with PUT and PHP curl..
Up 'till now I've been sending the PUT request something like this (pseudo code):
$a_some_data = array('name' => 'test', 'user_id' => 4);
$body = http_build_query($a_data);
$fh = fopen('php://memory', 'rw');
fwrite($body);
rewind($fh);
$ch = curl_init();
curl_setopt_array($ch, array(
CURLOPT_URL => 'http://myapi/resource/someid',
CURLOPT_PUT => TRUE,
CURLOPT_INFILE => $fh,
CURLOPT_INFILESIZE => strlen($body)
));
curl_exec($ch);
and reading the data on the server like so:
parse_str(file_get_contents('php://input'), $put_data);
..which works just fine.
So now I would like to add a (binary) file into the mix.
- How would I implement this on the client side?
- How would I deal with the file on the server?
For a test I set up a HTML form with a file input, copied the raw multipart/form-data request it sends, and tried sending that data as a file with curl in a PUT request. That kind of works, but I would have to parse the raw data on the server manually, which I'm not sure is the best idea. Alternatively, I guess I could send the file as the body of the PUT request, and add the other parameters in the URL as a query string - but I guess that kind of defies the point of a PUT REST resource..
Please share your thoughts on this.
Thanks!
There are at least two other ways unless your original version isn't enough (since libcurl should deal just fine with binary files too with that script). Note that how you decide receive the PUT in the receiving end is not a curl issue so I'll leave it out of this response.
1 - Like you started out, but provide a CURLOPT_READFUNCTION with which you feed the data to libcurl that it will send.
2 - Use CURLOPT_POSTFIELDS (with a string) and make it look like a POST, and then you change the HTTP method with CURLOPT_CUSTOMREQUEST to "PUT"

How to send a GET request from PHP?

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();

Categories