How to use Request::factory()->execute() to call an script from another library in the same host

StackOverflow https://stackoverflow.com/questions/14905188

Question

I'm using Kohana 3.2, and I want to be able to call another script (unrelated to Kohana, outside of its 'jurisdiction') that returns a application/json response. When I tried using:

$response = json_decode(Request::factory('/scripts/index.php?id=json')->execute()->body());

It errors out saying there's no route to scripts/index.php. So I tried using Request_Client_External

Request_Client_External::factory()->execute(Request::factory('/scripts/index.php?page=s'))->body();

Gives me Request_Exception [ 0 ]: Error fetching remote /scripts/index.php?page=s [ status 0 ] Could not resolve host: scripts; Host not found. It appears it need a full flagged URL using http/https, but how to avoid the overhead of it doing a real external request?

Doing a

Request::factory(url::site('/scripts/index.php?page=s', 'http'))->execute()

works but is it considered "external"?

Was it helpful?

Solution

The short answer to your question is that the only way to use Request::factory()->execute() to achieve that is to use pass it the full url (with whatever "overhead" that entails, which shouldn't be too much: your server's probably quite good at talking to itself).

Otherwise, ideally you'd put the functionality of scripts into a library and call that from Kohana. However it sounds like that's not an option for you. If you have to leave /scripts/index.php untouched and insist on an 'internal' request, you could use PHP's output buffering, as illustrated below. But there are a bunch of caveats so I wouldn't recommend it: the best way is passing a full url.

    // Go one level deeper into output buffering
    ob_start();

    // Mimic your query string ?id=json (see first caveat below)
    $_GET = $_REQUEST = array('id' => 'json');
    // Get rid of $_POST and $_FILES
    $_POST = $_FILES = array();

    // Read the file's contents as $json
    include('/scripts/index.php');
    $json = ob_get_clean();

    $response = json_decode($json);

Some caveats.

Firstly, the code changes $_GLOBALS. You probably don't use these in your Kohana code (you use $this->request->get() like a good HMVCer, right?). But in case you do, you should 'remember' and then restore the values, putting $old_globals = $GLOBALS; etc. before the above code, and $GLOBALS = $old_globals; after.

Sessions: if your /scripts/index.php uses `session_start() this will cause a warning if you've already started a session at this point in Kohana.

Note that all variables set in scripts/index.php will remain set in the context you're in. If you want to avoid possible conflicts with that context, you'd start a new context, i.e. wrap the above into its own function.

Finally, you'd also need to make sure that /scripts/index.php doesn't do anything like Kohana::base_url = 'something_else', or touch any other static attributes, or do something catastrophic using this.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top