I often think the most overlooked and underrated part of PHP are streams. First added in PHP 4.3 by Wez, streams enable the magic that lets you call file_get_contents() (and friends) on more than just local files, but also remote files using ftp, http, https, etc.
In PHP 5, you can do lots of really cool things with streams, including filtering them using a concept similar to Unix pipes. You can also define your own stream wrappers in PHP, so you can “speak” LDAP or to shared memory using fopen() and other file system commands.
This totally rocks. You should really check it out.
At first, I thought nobody used streams because it wasn’t documented. Lots of PHP books have been queued up waiting for the release of PHP 5, so a PHP 4.3 feature didn’t have the chance to make it into print. However, the streams documentation on PHP.net is actually quite comprehensive.
When I wrote the “Streams, Wrappers, and Filters” chapter in “Upgrading to PHP 5,” I was able to find quite a bit of information in the manual if I was willing to look around long enough. Normally, I needed to do quite a bit of wrangling about amid the mailing lists, CVS commit logs, test cases, and the source code itself. (Or, if all else failed, I broke down and e-mailed the author directly.)
However, the more I play with streams — or to be more specific the HTTP wrapper — the more I run into trouble. Everything works fine for plain-vanilla requests, but when I try to do a more complex HTTPS POST request, then I run into mysterious issues and frustrating limitations.
For instance, you can only make HTTP 1.0 requests. You can’t use HTTP 1.1. And I’m running into this weird problem that seems to occur because PHP sends the request in chunks, and one of those divides is between the opening line and the Host HTTP header. (Even worse, since it’s an HTTPS request, I can’t easily monitor the wire.)
I don’t know whether it’s a “bug” in PHP, the web server, or a vagueness in the HTTP specification, but, honestly, I don’t really care. I just want it to work. Not surprisingly, implementing a protocol is somewhat subtle and tricky, and maybe it doesn’t make sense to embed your own handwritten HTTP and FTP client libraries inside of a language. Maybe it’s better to save the headache and just use cURL. (And, indeed, the request does work great when I do.)
This attitude has led to a clear tension over the future direction of streams. There was a bit of a fuss on php-internals a few months back, last time someone contributed a major patch to the HTTP wrapper. The prevailing sentiment was exactly what I just described: don’t continue to reimplement cURL inside of PHP, but figure out how to better embed cURL as stream wrappers.
Sadly, this hasn’t happened. Instead, there’s been no progress in either direction.
So now I’m stuck. I’d like to remove cURL entirely from the equation, if for no other reason than to remove a dependency on yet-another extension. Yet, cURL seems to be the way to go for anything serious — if for no other reason than it works and the HTTP wrapper doesn’t.
But if cURL is good, why are we bothering with streams and wrappers in the first place? Am I crazy for not wanting to use both cURL and streams? What’s a good PHP 5 programmer to do?
Popularity: 7% [?]