views:

228

answers:

3

Can I get a HttpRequest automatically created from the environment? In other words, right now it seems like you have to...

$request = new HttpRequest;
$request->setCookies($_COOKIE);
$request->setHeaders(apache_request_headers());
$request->setPostFields($_POST);
$request->setQueryData($_GET);
$request->setRawPostData(file_get_contents('php://input'));
$request->setUrl($_SERVER['REQUEST_URI'']);

We also need to set the method -- a ridiculous chore, since $_SERVER['REQUEST_METHOD'] is a string and HttpRequest::setMethod takes an int in the HTTP_METH_* series of contants. So you have to set up your own mapping.

I want to like HttpRequest, but it seems cumbersome to use at the moment. I hope I'm missing something.


Edit:

The idea is to make testing cleaner. $_COOKIE and friends are superglobals. How do you test that?

function receiveRequest() {
    $code = 'that touches superglobals like' . $_COOKIE['example'];
    $response = new HttpResponse;
    $response->setStatus(200);
    return $response;
}

function testServer() {
    $oldCookie = $_COOKIE;
    $oldPost = $_POST;
    // etc...
    $_COOKIE = array('example' => 'stuff');
    $_POST = array();
    // etc...
    $response = receiveRequest();
    $_COOKIE = $oldCookie;
    $_POST = $oldPost;
    // etc...
    assert($response->getStatus() === 200);
}

You need to control the state of not just what you use -- $_COOKIE in this example -- but every superglobal. There are about a dozen. It would be a lot cleaner to wrap up all that stuff in HttpRequest.

function receiveRequest(HttpRequest $request) {
    $code = 'is purely a function of arguments like' . $request->getCookie('example');
    $response = new HttpResponse;
    $response->setStatus(200);
    return $response;
}

function testServer() {
    $request = new HttpRequest;
    $request->setCookie('example' => 'stuff');
    $response = receiveRequest($request);
    assert($response->getStatus() === 200);
}

Then my actual server.php would use the hypothetical static method that I'm looking for.

$request = HttpRequest::generateRequestFromEnvironment($_COOKIE, $_POST, ...);
unset($_COOKIE, $_POST, ...);
$response = receiveRequest($request);
$response->send();
A: 

This seems to me like an odd use case - you want to create an HttpRequest to...yourself? Using exactly the parameters you were passed? Why?

The normal case is for requesting another resource, from another host, for which the kind of "automatic setup" you desire is pretty useless. If you really need this situation, it seems trivial to wrap this in a function that's easily reused?

Adam Wright
+1  A: 

From what you've posted, I think you're using HttpRequest as a container for all the information about the request which triggered your script.

This isn't what it is for - it is for making HTTP requests to other services from within your script. For example, you might request data from the Flickr API

Paul Dixon
I want to request data from my own API. And I want to unit test that API. It seems like the whole point of HttpRequest, to abstract incoming and outgoing requests into the same class. After all, they **are** the same thing.
Preston
+1  A: 

I have the same problem. If I could access the current raw HTTP request to my PHP script, I would be happy. I need to do additional handling to the request, but I got delivered those superglobals being variables; not some class I can extend. It's very much not OOP.

I eventually got to the same solution as Preston, I'm rebuilding the original Request as good as I can. To wrap it all up, I extended the HttpRequest/HttpResponse classes. After processing I'll serialize the Object and forward it to the (external) handler (which needs the same environment). Then I deserialize it again and start unwrapping the HttpRequest.

Looks like a lot of work that should been done before calling my initial PHP script, but doesn't seem to be accesable/available from PHP itself.

Any help would be welcome,

Robert de W