Passing parameters from external PHP service to CakePHP controller actions

1.3k Views Asked by At

Asking this question here because in CakePHP google group got no answer.I have the following pipeline: There is a CakePHP based application.It has a controller with an action called save_results. The action is a method accepting 3 arguments.So it looks like this:

function save_results($data,$rawdataset,$status){

 ///stub///
   return "all the data received";
}

Besides CakePHP app I have a WebOrb(PHP) which I use to communicate with Flash application using AMF format.The flash application sends data to WebOrb service which then sends it to the action I described above in Cake.So I receive from the Flash app 3 objects to match the params I pass into the cake method (save_results) : data -of type array of objects. rawdataset-of type string containing xml object. status-unsigned integer 0 or 1. In the WebOrb service the data received from the Flash is ok.But when I try to send it further into CakePHP it doesn't pass through. I do it this way (In The WebOrb class):

public function sendToCake($data,$rawdataset,$status){


    $encodedData=urlencode($data);
    $encodedRawData=urlencode($rawdataset);

    $destinationURL="http://localhost/mycakeapp/resultscontroller/save_results  /".$encodedData."/". $encodedRawData."/".$status;

   return file_get_contents( $destinationURL);

}

I found that a parameter passed into url for cake can not have spaces between characters.SO I use urlencode().It works for simple strings like "Hello world".But once I pass more complex strings like xml strings ($rawdataset object) the cake doesn't receive such a call.I tried also rawurlencode() and still no results.Is it possible that cake doesn't know how to treat xml structured strings when passed via http call? Any help or advice on this issue will be highly appreciated.

2

There are 2 best solutions below

2
Shaz MJ On BEST ANSWER

For your WebOrb class, change it so it uses HttpRequest instead:

public function sendToCake($data,$rawdataset,$status){
    $url = 'http://localhost/mycakeapp/resultscontroller/save_results';
    $r = new HttpRequest($url, HttpRequest::METH_GET);
    $r->addQueryData(array('data' => $data, 'rawdata' => $rawdata, 'status' => $status));

    try {
        $r->send();
        return $r->getResponseData();
    } catch (HttpException $ex) {
        return $ex;
    }    
}

^^ You may have to tweak it around a bit to return exactly what you want. For your CakePHP Controller / Action, inside it you can access the get request via the Parameters Attribute.

function save_results(){
    $data = $this->params[];
    //do stuff to my data;
    return $data;
}

Hope that helps!

1
Danny Lieberman On

The question is not specifically related to CakePHP and WebORb but it is a general question on how to perform an HTTP GET to a url with a query string that has special characters. The Server return code of 500 is an indication that the MVC framework is returning a server error, which indicates that the request was not well-formed. In the future - fwiw - it's good to have a snapshop of the Apache error log in order to see what kind of error was thrown behind the code 500.

Here is what should be happening:

A program wants to perform an HTTP GET to url/controller/action/query_string

query_string should be url_encoded but in addition, since query string may contain quotes and ampersands that break the string, it should also be processed with htmlentities

In Michael's case he has 3 parameters - $data, $rawdataset, $status that make up a query string like this: service/controller/action/data/rawdataset/status

Here is a PHP code snippet that should work:

$query_string = urlencode($data) . '/' . urlencode($rawdataset).'/'.urlencode($status);

then perform an http_get( 'service/' . htmlentities($query_string) ) the http_get will return the HTTP response.

A similar strategy can be employed for HTTP POST

In general, unless the query string is an integer, this is what needs to be done.

Inside the CakePHP Controller action that actually processes that query-string, one can statically call the Sanitize class like this:

App::import('Sanitize');

class Service extends AppController { ... ... }

AFAIK - if you use CakePHP's ORM methods (such as find() and save()) and proper array notation (ie. array('field' => $value)) instead of raw SQL the controller action is already protected from SQL injection vulnerabilities. There should be no need to perform hand-crafted SQL once the data parameters hit the controller action.

This is best practice in any MVC framework like CakePHP, RoR or Django anyhow.

Let me know how it works Danny