nategood / httpful Goto Github PK
View Code? Open in Web Editor NEWA Chainable, REST Friendly, PHP HTTP Client. A sane alternative to cURL.
License: MIT License
A Chainable, REST Friendly, PHP HTTP Client. A sane alternative to cURL.
License: MIT License
Right now by default the library will take a data structure that is to be used for the payload of a request and do it's best to turn it into a well structured serialized string. (e.g. calling json_encode
on the payload when the Content-Type of the request is application/json
).
A user may want to define their own serialization method in certain use cases (e.g. the user was using XML-RPC and didn't want to have to build long winded associative arrays for every request).
When executing Request::get($url)->send() to a third party API I get the following XML:
<ns1:DbInstanceInfos xmlns:ns1="http://api.xeround.com"><ns1:DbInstanceInfo xmlns:ns1="http://api.xeround.com"><ns1:creationDate>2011-11-27T11:11:54+02:00</ns1:creationDate><ns1:dataCenter>Rackspace-US-ORD1</ns1:dataCenter><ns1:dbInstanceId>2940</ns1:dbInstanceId><ns1:description></ns1:description><ns1:name>AAA</ns1:name><ns1:plan>Free</ns1:plan><ns1:remainingPlanDays>0</ns1:remainingPlanDays><ns1:size>0.244141</ns1:size><ns1:status>DROPPED</ns1:status><ns1:edition>BASIC</ns1:edition></ns1:DbInstanceInfo></ns1:DbInstanceInfos>
The httpful throws 'Unable to parse response as XML'.
The correct way to parse this XML is by providing simplexml_load_string with the namespace:
simplexml_load_string($xmlString, null, null, "http://api.xeround.com")
Please allow passing parameters to the simplexml_load_string method.
Thanks.
If I try to json_encode($e)
, I get json_encode(): type is unsupported, encoded as null
. I dump the exception variable and I see that there is an object there.
Use DIRECTORY_SEPARATOR
constant instead of hard-coded '/' for Bootstrap::DIR_GLUE
. (I would write a Pull Request, but I abandoned my ancient fork.)
If installed extension mbstring and overloaded function strlen then length of content calculates incorrect.
So, solutions is use mb_strlen($payload, '8bit'). Or don't overload 'strlen', but if it already did...
Extend the parseWith
behavior so that I can register a callback. To build off of the (native) CSV example...
Register:
\Httpful\Request::register('csv', function() {
return explode(",", $body);
});
Now that I've registered the csv mime type, I can now use it like I use other mime types directly supported by the library
'expectsCsv' will now use my registered callback
\Httpful\Request::get("http://example.com/report.csv")->expectsCsv()->send();
This may be a nice way to handle the hypermedia stuff mentioned in issue #16.
I'm getting the error
Undefined variable: parse_with in src/Httpful/Request.php on line 763
https://github.com/nategood/httpful/blob/master/src/Httpful/Request.php#L763
Please remove version tag packagist adds it automatically from repository
Hi!
I've noted this bug after commit ef6a59c
If you set 'Content-Length' to 0 some webserver/library won't see the body...
I've reverted to previous commit and everything works fine.
When a document with no content type is parsed Httpful throws an exception:
"Undefined offset: 1" in response.php on line 158
Download link doesn't work.
https://github.com/downloads/nategood/httpful/httpful.phar
any hints how to install and run without phar ?
Timeouts are important they should get an option
Instead of
$r->addOnCurlOption(CURLOPT_TIMEOUT, 10);
Something like
$r->timeoutIn(10);
Alias timeout
Should have a way to configure options that are specific to an individual parser. Expand the MimeHandlerAdapter
to allow for this.
See Case #28.
Add support for uploading files. I imagine adding this as another chainable method upload()
, includeFile()
, or withFile()
.
As part of the Request Template support, it would be nice to also include a URI template seeing as most requests to a URI come from the same base URI.
I've been using and loving httpful. However, I have been having to jump through hoops to get it to work on my hosting accounts that support PHP 5.2 by default.
Is there some way to use the library with PHP versions before 5.3?
Hi,
The phar file is apparently not located at https://github.com/downloads/nategood/httpful/httpful.phar
Could you please provide me the location of the same? Thanks
I'm working with an REST API that responds to a successful DELETE with a 204 and no body (it clearly states this in the response headers with Content-Length: 0)
I found that httpful still tried to parse the response as JSON and falls over in a heap:
Fatal error: Uncaught exception 'Exception' with message 'Unable to parse response as JSON' in phar://C:/Users/colemanb/Documents/Cloud/hpcloud/PHP/lib/httpful.phar/Httpful/Handlers/JsonHandler.php:19 Stack trace: #0 phar://C:/Users/colemanb/Documents/Cloud/hpcloud/PHP/lib/httpful.phar/Httpful/Response.php(92): Httpful\Handlers\JsonHandler->parse('') #1 phar://C:/Users/colemanb/Documents/Cloud/hpcloud/PHP/lib/httpful.phar/Httpful/Response.php(41): Httpful\Response->_parse('') #2 phar://C:/Users/colemanb/Documents/Cloud/hpcloud/PHP/lib/httpful.phar/Httpful/Request.php(174): Httpful\Response->__construct('', 'HTTP/1.1 204 No...', Object(Httpful\Request)) #3 C:\Users\colemanb\Documents\Cloud\hpcloud\PHP\hpcloud-api.php(107): Httpful\Request->send() #4 C:\Users\colemanb\Documents\Cloud\hpcloud\PHP\demo.php(82): api_call_delete('HPAuth_4fb362aa...', 'https://az-2.re...', '41792484084457', 'servers/123657') #5 {main} thrown in phar://C:/Users/colemanb/Documents/Cloud/hpcloud/PHP/lib/httpful.phar/Httpful/Handlers/JsonHandler.php on line 19
I got round this by calling autoParse(false) however should the API call error in some way there might be content in the response body that I want to handle. Shouldn't the Response be checked to ensure it's not zero length before invoking the parser? This would make sense to me!
Seems to be a trend of moving towards vendor specific mime types in the REST world
http://tools.ietf.org/html/rfc4288#section-3.2
http://en.wikipedia.org/wiki/Internet_media_type#Type_vnd
Support these vendor specific mime types by grabbing the +xml
(or similar) from the vnd mime type.
Allow using client side ssl certs for authentication
Demo code:
<?php
include('include/httpful.phar');
function send($uri, $body) {
$response = \Httpful\Request::post($uri)
->sendsXml()
->body($body)
->expectsXml()
->send();
return $response;
}
$uri = "http://spatial.virtualearth.net/REST/v1/Dataflows/Geocode/?input=xml&output=xml&key=";
$key = "Aor625SZAtBjek2AZV08BvD0x-vZ0CgjNYWkbIyE1uGmylsFRNzcPprIkFaFOZJI";
$xmlBody1 = "<GeocodeFeed >
<GeocodeEntity Id='1' xmlns='http://schemas.microsoft.com/search/local/2010/5/geocode'>
<GeocodeRequest Culture='en-us' Query='1501 NE Davis St, Portland, OR'>
</GeocodeRequest>
</GeocodeEntity>
<GeocodeEntity Id='2' xmlns='http://schemas.microsoft.com/search/local/2010/5/geocode'>
<GeocodeRequest Culture='en-us' Query='350 W Burnside St, Portland, OR'>
</GeocodeRequest>
</GeocodeEntity>
<GeocodeEntity Id='3' xmlns='http://schemas.microsoft.com/search/local/2010/5/geocode'>
<GeocodeRequest Culture='en-us' Query='1005 W Burnside St, Portland, OR'>
</GeocodeRequest>
</GeocodeEntity>
<GeocodeEntity Id='4' xmlns='http://schemas.microsoft.com/search/local/2010/5/geocode'>
<GeocodeRequest Culture='en-us' Query='911 NW 14th Ave, Portland, OR'>
</GeocodeRequest>
</GeocodeEntity>
</GeocodeFeed>";
$xmlBody2 = "<GeocodeFeed >
<GeocodeEntity Id='1' xmlns='http://schemas.microsoft.com/search/local/2010/5/geocode'>
<GeocodeRequest Culture='en-us' Query='1501 NE Davis St, Portland, OR'>
</GeocodeRequest>
</GeocodeEntity>
<GeocodeEntity Id='2' xmlns='http://schemas.microsoft.com/search/local/2010/5/geocode'>
<GeocodeRequest Culture='en-us' Query='350 W Burnside St, Portland, OR'>
</GeocodeRequest>
</GeocodeEntity>
<GeocodeEntity Id='3' xmlns='http://schemas.microsoft.com/search/local/2010/5/geocode'>
<GeocodeRequest Culture='en-us' Query='1005 W Burnside St, Portland, OR'>
</GeocodeRequest>
</GeocodeEntity>
<GeocodeEntity Id='4' xmlns='http://schemas.microsoft.com/search/local/2010/5/geocode'>
<GeocodeRequest Culture='en-us' Query='911 NW 14th Ave, Portland, OR'>
</GeocodeRequest>
</GeocodeEntity>
<GeocodeEntity Id='5' xmlns='http://schemas.microsoft.com/search/local/2010/5/geocode'>
<GeocodeRequest Culture='en-us' Query='12000 SW 49th Ave Portland, OR'>
</GeocodeRequest>
</GeocodeEntity>
</GeocodeFeed>";
echo '<h1>Request #1:</h1>';
$r = send($uri . $key, $xmlBody1);
print_r($r);
echo '<h1>Request #2:</h1>';
$r = send($uri . $key, $xmlBody2);
print_r($r);
?>
Demo output:
Request #1:
Httpful\Response Object ( [body] => SimpleXMLElement Object ( [Copyright] => Copyright © 2013 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation. [BrandLogoUri] => http://spatial.virtualearth.net/Branding/logo_powered_by.png [StatusCode] => 201 [StatusDescription] => Created [AuthenticationResultCode] => ValidCredentials [TraceId] => 7b3cbdd74b644ec39a655a28f883c8b3|BAYM001576|02.00.117.2900| [ResourceSets] => SimpleXMLElement Object ( [ResourceSet] => SimpleXMLElement Object ( [EstimatedTotal] => 1 [Resources] => SimpleXMLElement Object ( [DataflowJob] => SimpleXMLElement Object ( [Id] => edf0d066d6604a898ae9e10630eb6fdf [Link] => https://spatial.virtualearth.net/REST/v1/dataflows/Geocode/edf0d066d6604a898ae9e10630eb6fdf [Description] => Geocode [Status] => Pending [CreatedDate] => 2013-05-21T04:10:25.0189272-07:00 [CompletedDate] => SimpleXMLElement Object ( ) [TotalEntityCount] => 4 [ProcessedEntityCount] => 0 [FailedEntityCount] => 0 ) ) ) ) ) [raw_body] => Copyright © 2013 Microsoft and its suppliers. All rights reserved. This API cannot be accessed and the content and any results may not be used, reproduced or transmitted in any manner without express written permission from Microsoft Corporation.http://spatial.virtualearth.net/Branding/logo_powered_by.png201CreatedValidCredentials7b3cbdd74b644ec39a655a28f883c8b3|BAYM001576|02.00.117.2900|1edf0d066d6604a898ae9e10630eb6fdfhttps://spatial.virtualearth.net/REST/v1/dataflows/Geocode/edf0d066d6604a898ae9e10630eb6fdfGeocodePending2013-05-21T04:10:25.0189272-07:00400 [headers] => Httpful\Response\Headers Object ( [headers:Httpful\Response\Headers:private] => Array ( [cache-control] => no-cache [transfer-encoding] => chunked [content-type] => application/xml; charset=utf-8 [location] => https://spatial.virtualearth.net/REST/v1/dataflows/Geocode/edf0d066d6604a898ae9e10630eb6fdf [server] => Microsoft-IIS/8.0 [x-ms-bm-ws-sn] => BAYM001576 [x-ms-bm-ws-info] => 0 [x-sds-elapsed] => 989 [x-aspnet-version] => 4.0.30319 [x-powered-by] => ASP.NET [date] => Tue, 21 May 2013 11:10:24 GMT ) ) [raw_headers] => HTTP/1.1 201 Created Cache-Control: no-cache Transfer-Encoding: chunked Content-Type: application/xml; charset=utf-8 Location: https://spatial.virtualearth.net/REST/v1/dataflows/Geocode/edf0d066d6604a898ae9e10630eb6fdf Server: Microsoft-IIS/8.0 X-MS-BM-WS-SN: BAYM001576 X-MS-BM-WS-INFO: 0 X-SDS-Elapsed: 989 X-AspNet-Version: 4.0.30319 X-Powered-By: ASP.NET Date: Tue, 21 May 2013 11:10:24 GMT [request] => Httpful\Request Object ( [uri] => http://spatial.virtualearth.net/REST/v1/Dataflows/Geocode/?input=xml&output=xml&key=Aor625SZAtBjek2AZV08BvD0x-vZ0CgjNYWkbIyE1uGmylsFRNzcPprIkFaFOZJI [method] => POST [headers] => Array ( ) [raw_headers] => POST /REST/v1/Dataflows/Geocode/?input=xml&output=xml&key=Aor625SZAtBjek2AZV08BvD0x-vZ0CgjNYWkbIyE1uGmylsFRNzcPprIkFaFOZJI HTTP/1.1 Host: spatial.virtualearth.net User-Agent: Httpful/0.1.7 (cURL/7.24.0 PHP/5.4.7 (WINNT) Apache/2.4.3 (Win32) OpenSSL/1.0.1c .4.7 Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.31 (KHTML, like Gecko) Chrome/26.0.1410.64 Safari/537.31) Content-Type: application/xml Accept: /; q=0.5, text/plain; q=0.8, text/html;level=3;q=0.9, application/xml [strict_ssl] => [content_type] => application/xml [expected_type] => application/xml [additional_curl_opts] => Array ( ) [auto_parse] => 1 [serialize_payload_method] => 2 [username] => [password] => [serialized_payload] => [payload] => [parse_callback] => [error_callback] => [follow_redirects] => [max_redirects] => 25 [payload_serializers] => Array ( ) [_ch] => Resource id #23 [_debug] => ) [code] => 201 [content_type] => application/xml [parent_type] => application/xml [charset] => utf-8 [is_mime_vendor_specific] => [is_mime_personal] => [parsers:Httpful\Response:private] => )
Request #2:
Fatal error: Uncaught exception 'Exception' with message 'Unable to parse response code from HTTP response due to malformed response' in phar://C:/xampp/www/geocode-2/include/httpful.phar/Httpful/Response.php:138 Stack trace: #0 phar://C:/xampp/www/geocode-2/include/httpful.phar/Httpful/Response.php(37): Httpful\Response->parseCode('HTTP/1.1 100 Co...') #1 phar://C:/xampp/www/geocode-2/include/httpful.phar/Httpful/Request.php(189): Httpful\Response->_construct('HTTP/1.1 201 Cr...', 'HTTP/1.1 100 Co...', Object(Httpful\Request)) #2 C:\xampp\www\geocode-2\test.php(10): Httpful\Request->send() #3 C:\xampp\www\geocode-2\test.php(50): send('http://spatial....', '?...') #4 {main} thrown in phar://C:/xampp/www/geocode-2/include/httpful.phar/Httpful/Response.php on line 138
The first request goes through fine, but when a little more xml data is added to the POST body, suddenly the response becomes "malformed".
Some servers don't speak HTTP very well. Change the test for errors from inclusive to exclusive; a la "NOT IN [200, 400)".
Include examples that use If-Match
and If-Unmodified-Since
precondition headers.
Hi!
after the last update i've this notice:
Notice: Undefined offset: 10004 in /Users/tondi/Documents/projects/Innobit.PrestaShopPlugIn/trunk/application/wwwRoot/modules/mxSync/vendor/nategood/httpful/src/Httpful/Request.php on line 440
I'm trying to figure out why!
Gabriele
Don't rely on user setting expects
to specify the expected response.
Would be nice to have basic proxy support. Nothing fancy no NTLM or auth needed, just a standard basic proxy
Hi,
I've a situation where is desirable to receive associative arrays rather than plain objects (I'm working with a legacy codebase and I don't want to recheck every variable).
Thanks!
REST is about Hypermedia and self exposing APIs. The library should help pull those things out of responses when they exist.
The download link for the phar file on http://phphttpclient.com/ is broken.
Tis is the particular line
"Httpful provides a PHP Archive file that includes the entire library. Simply download this file and include it in your code."
Seems like the link was updated.
Why do you use in_array
like this (without needle);
public static function isSafeMethod($method)
{
return in_array(self::safeMethods());
}
I think it should be like this;
public static function isSafeMethod($method)
{
return in_array($method, self::safeMethods());
}
Links;
https://github.com/nategood/httpful/blob/master/src/Httpful/Http.php#L31
https://github.com/nategood/httpful/blob/master/src/Httpful/Http.php#L40
Add to Resposne::_parse
method
If no User-Agent header is set it tries to create own using Httpful::VERSION which is just namespace and VERSION constant is not anywhere.
See https://github.com/nategood/httpful/blob/master/src/Httpful/Request.php#L698
Hello
Maybe I'm just new at this but I get this error no matter if I use the .phar or install using Composer (successfully). Monolog works so I don't think it's a problem with Composer. I've tried downgrading but to no avail, still the same error:
Fatal error: Class 'Request' not found in
I've tried both the Twitter and Google samples but it seems to be some kind of include problem?
httpful don't seem to handle "100 continue" reply's
I have added a new header to line 734 in Response.php :
$headers[] = $accept;
+ $headers[] = 'Expect:';
There's a lot of talk about this issue on the net, see eg.
http://www.infernodevelopment.com/expect-100-continue-header-twitter-api-error-using-php-curl
http://www.iandennismiller.com/blog/2009/09/curl-http1-1-100-continue-and-multipartform-data-post/
Hi,
i have worked with httpful for a few weeks - good job. But i think the error handling needs some additions.
Take a closer look on following code lines:
Request::get($this->apiUrl)
->authenticateWith($this->apiUsername, $this->apiPassword)
->withoutStrictSSL()
->expectsJson()
->send();
If you use wrong connection information or the endpoint is still not reachable, httpful will always continue with auto parsing the response because of the following code lines
if ($result === false) {
$this->_error(curl_error($this->_ch));
throw new ConnectionErrorException('Unable to connect.');
}
and setting the curl option CURLOPT_RETURNTRANSFER
. If this option is configured, curl never return false
(look here for further details).
For this reason my application gets only a generic exception Unable to parse response as JSON
You should fix this and return the detailed cURL error information as an exception. You can find the complete cURL error codes here . So other users can catch it and handle their favourite cURL error code.
Greetings,
Patrick
Right now the tests were sort of whipped up in a very basic style, only leveraging PHP's native assert
. Should move this to a more standard testing library.
There is definite appeal for a single file/single line include for a library, however instead of needing to build a concatenated file, might want to move more towards the PHAR route.
This happens when the SimpleXMLElement
returned by simplexml_load_string()
is empty. Somehow adding !
in front of it converts to a boolean false. This can be fixed by checking for $parsed === false
.
Hi all,
I've been having problems to run the phar file in my server.
Locally I tested using xampp with PHP 5.4 and it works like a dream.
The problem is, the online server uses PHP 5.2 and as far as we know it doesn't accept Namespace Backslash.
Is there some alternative for this case? Maybe a .phar's file version written without backslash...
Thanks in advance
Parse HTTP response headers into accessible assoc array.
I am using the latest version(httpful-0.2.0.phar) of HTTPFul phar. On the hosted setup I get following problem:
I have included phar as
include "./httpful.phar";
..........................
PHP Warning: include(): Failed opening 'phar://httpful.phar/Httpful/Bootstrap.php' for inclusion (include_path='.:') in /var/www/tut/soapsync/httpful.phar on line 4
PHP Fatal error: Class 'Httpful\Bootstrap' not found in /var/www/tut/soapsync/httpful.phar on line 5
while on my local(dev) setup it works fine.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.