In PHP, what are the biggest considerations when choosing between using http_get("https://...") and a sockets loop with fsockopen("ssl://..."), fputs() and fread()?
I’ve seen a couple of implementations lately that use the latter. Is that just old legacy code or is there some good reason for it?
Thanks.
http_get requires a PECL extension, which is not bundled with PHP.
fsockopen is more complicated to use (requires looping, sending the headers manually, reading the headers manually, and, in general, more code), but is part of the PHP (it's always present).
In my opinion, the best fail-safe option is to use the http wrapper, as in:
file_get_contents('https://...')
The http wrapper, however, has its own set of limitations – no digest authentication, no automatic handling of encoded content, etc. So if either the PECL http extension or the curl extension are available, those would probably be a better option.
Related
I have a websocket server, implemented using PHP's socket library, and all works well... provided you are using the ws:// protocol.
However, we now need to upgrade the library to work over SSL, i.e. to support the wss:// protocol.
Is it possible to implement wss:// (or more generally, I suppose, SSL connections) using the PHP socket functions, or will we need to rewrite the code to use the stream_socket functions?
(Note that there may be other good reasons to switch to stream_socket, so regardless of the answer we may consider doing that anyway. However, before I spend time evaluating the two options, I want to confirm that sticking with socket is even an option for us.)
I'm submitting an answer on behalf of #BA_Webimax who posted what is probably the correct answer in a comment, but hasn't returned to make that into an answer that I can accept.
So as a direct answer to the question "Is it possible?":
It is possible to do but requires you to implement a lot of things that are already done for you when using stream_socket functions.
-- #BA_Webimax
To flesh that out a bit further, it would mean handling all of the SSL negotiation and encryption manually. This would be a fair amount of work, require a lot of testing and runs the risk of introducing security holes if not implemented exactly right.
Rewriting the code to use the stream_socket functions is likely to be quicker, safer and more robust.
So, whilst the technical answer is yes, it is possible, the pragmatic answer is probably no, it is not.
There are actually two sub questions:
what's the difference between PHP curl library and libcurl? is the PHP curl library just a bridge to connect and use the libcurl or it is libcurl re-written in PHP language?
Why curl is much faster than the file_get_contents function in PHP?
the difference between PHP curl library and libcurl
PHP/CURL is a "binding" for the underlying libcurl library. It means that there's a bunch of glue code in the PHP curl extension that ultimately calls libcurl to actually perform the transfer operations.
The PHP code doesn't do very much more than converting from PHP conventions to libcurl conventions (and back again). It allows PHP users to take advantage of libcurl's raw native speed and latest developments without anyone having to change anything.
Why is curl faster than file_get_contents function in PHP?
Both are implemented in C and offer file transfer capabilities for PHP programs. The explanation is probably because of their respective software architectures and particular feature sets that makes one faster than the other for certain use cases.
There have possibly also been more work and efforts spent on optimizing transfer performance in libcurl.
As in most cases, it might be worth benchmarking exactly your case so that you know that you're not relying on speed tests done for cases that have other characteristics than yours.
It's evident that the cURL functions are very widely used. But why is that? Is it really only because the extension is mostly enabled per default?
While I can certainly relate to not introducing 3rd party libraries over builtins (DOMDocument vs phpQuery), using curl appears somewhat odd to me. There are heaps of HTTP libraries like Zend_Http or PEAR Http_Request. And despite my disdain for needless object-oriented interfaces, the pull-parameter-procedural API of curl strikes me as less legible in comparison.
There is of course a reason for that. But I'm wondering if most PHP developers realize what else libcurl can actually be used for, and that it's not just a HTTP library?
Do you have examples or actual code which utilizes cURL for <any other things> it was made for?
Or if you just use it for HTTP, what are the reasons. Why are real PHP HTTP libraries seemingly avoided nowadays?
I think this would be related to why do people use the mysql functions instead of mysqli (more object oriented interface) or take a step further and use a data abstraction layer or PDOs.
HTTP_Request2 says that there is a cURL adapter available to wrap around PHP's cURL functions.
Personally a lot of the PEAR extensions I have tried out, I haven't been that impressed with (and I feel less confident with PEAR libraries that are sitting in alpha that haven't been updated in a long time). Whereas the HTTP_Request2 Library does look quite nice
I for one would have used cURL without thinking of looking at a possible PEAR library to use. So thanks for raising my awareness.
The libraries you mentioned aren't default, and from my experience in PHP, I prefer to use less of such libraries; they enable a broader attack surface, decrease reliability, open to future modification/deprecation more than PHP itself.
Then, there's the sockets functionality which, although I've used some times, I prefer to rely on a higher level approach whenever possible.
What have I used CURL for?
As some may know, I'm currently working on a PHP framework. The communication core extension (appropriately called "connect") makes use of CURL as it's base.
I've used it widely, from extracting favicons form websites (together with parser utilities and stuff) to standard API calls over HTTP as well as the FTP layer when PHP's FTP is disabled (through stream wrappers) - and we all know native PHP FTP ain't that reliable.
Functional reasons as mentioned in the comments:
It's very old, [widely used and] well tested code, works reliably
is usually enabled by default
allows very fine grained control over the details of the request.
This might need expanding. By nature of the common-denominator protocol API cURL might provide features that plain HTTP libraries in PHP can't...
Historic reasons:
curl used to be the only thing that could handle cookies, POST, file uploads...
A lot of curl use probably comes from tutorials that pre-date PHP 5.
I've looked online for ways to do this, and I've found two PHP methods for accesing WebDAV:
http://freshmeat.net/projects/class_webdav_client/
This is less than ideal, because it doesn't support WebDAV at a sub-path of the server; it cannot access, say, http://my-dav-server/configuration, only http://my-dav-server
http://php-webdav.pureftpd.org/project/php-webdav
This requires me to compile a new PHP module, which might be necessary, but is a bit of a pain. Plus, it's not clear from the docs how to do simple things like report errors or which versions of PHP it supports.
Basically, I want a WebDAV API - doesn't matter how complex, really - that can get/put files with HTTP BASIC authentication. I don't need anything more complex than that. I'm backing this with a subversion autoversioning DAV server, but I can foresee using it in other ways, too, so I don't want to lock myself in to subversion by using an SVN-specific API.
If you are just looking for GET and PUT, just use Curl! That, or any other decent HTTP library.
It's actually quite simple that way.
I have a need to do RAW POST (PUT a $var) requests to a server, and accept the results from that page as a string. Also need to add custom HTTP header information (like x-example-info: 2342342)
I have two ways of doing it
Curl (http://us.php.net/manual/en/book.curl.php)
PHP HTTP using the HTTPRequest (http://us.php.net/manual/en/book.http.php)
What are the differences between the two? what's more lean? faster? Both seem pretty much the same to me...
Curl is bundled with PHP, HTTPRequest is a separate PECL extension.
As such, it's much more likely that CURL will be installed on your target platform, which is pretty much the deciding factor for most projects. I'd only consider using HTTPRequest if you plan to only ever install your software on servers you personally have the ability to install PECL extensions on; if your clients will be doing their own installations, installing PECL extensions is usually out of the question.
This page seems to suggest that HTTPRequest uses CURL under the hood anyway. Sounds like it might offer a slightly more elegant interface to curl_multi_*(), though.
HTTPRequest (and the PECL extension) is built on libcurl.
http://us.php.net/manual/en/http.requirements.php
The HTTPRequest is really just an easier/more syntactically friendly way to perform the same task.
As Frank Farmer mentioned, you're more likely to have a target platform with curl already installed and could have difficulty getting the PECL library installed by the hosting provider.
The HTTPRequest is "kind of" a wrapper for curl. This two quotes from the manual should give you a clue:
It provides powerful request functionality, if built with CURL support. Parallel requests are available for PHP 5 and greater.
The extension must be built with » libcurl support to enable request functionality (--with-http-curl-requests). A library version equal or greater to v7.12.3 is required.
Said that (and said that I've never used this extension myself), looks like if you want your code to look more object oriented, you can go for this one, but it might be a bit slower, though nothing compared with the external call that you are going to make, so I won't consider performance to make my choice. I would give preference to the fact that curl is built in and this other you have to add it yourself, which is unconvenient and reduces portability in case you want to host your app in a shared environment that you don't control.
For the needs that you explained in your question, I would definitely go for curl.