mvdn
mvdn

Reputation: 23

Can't access $_SERVER['QUERY_STRING'] when using curl

I'm calling a php script as follows:

$data="param1=P1";
$data.= "param2=P2&"; 
$data.= "param3=P3";  

$ch = curl_init();

curl_setopt($ch, CURLOPT_URL," http://www.example.com/readcurl.php");
curl_setopt($ch, CURLOPT_POST, count($data));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$data);

curl_exec ($ch);
curl_close ($ch); 

Now in the receiving script (readcurl.php) I can read the params through:

$par1= $_REQUEST['param1'];
$par2= $_REQUEST['param2'];
$par3= $_REQUEST['param3'];

I want to check if all the parameter have been supplied. But when I do

count(explode('&', $_SERVER['QUERY_STRING']))

this gives "1" as the count. When supplying the parameters from within a browser:

http://www.example.com/readcurl?param1=P1&param2=P2&param3=P3

count(explode('&', $_SERVER['QUERY_STRING'])) 

gives '3'

What do I do wrong here?

Upvotes: 0

Views: 373

Answers (2)

Daniel W.
Daniel W.

Reputation: 32280

Very long answer above/below.

Here is the TL;DR and best practice way which urlencodes the data properly:

$dataArray = array(
    'param1' => 'data1',
    'param2' => 'data2',
);

$postData = http_build_query($dataArray, '', '&');

curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);

http://us.php.net/manual/en/function.http-build-query.php

In the receiving script, you check

$_POST['param1']

because POST data does not get appended to the QUERY_STRING

Upvotes: 0

Mikk3lRo
Mikk3lRo

Reputation: 3496

You are setting POST parameters:

curl_setopt($ch, CURLOPT_URL," http://www.example.com/readcurl.php");
//This line is not needed, and in fact it should produce a warning
//curl_setopt($ch, CURLOPT_POST, count($data));
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS,$data);

...but are attempting to read GET parameters (which would be in the URL, ie. the QUERY_STRING):

count(explode('&', $_SERVER['QUERY_STRING']))

You could simply count the $_REQUEST array instead:

count($_REQUEST);

...but since this can very easily break I would recommend strongly against it unless you have absolute control of the entire application, don't expect any users other than yourself, and never expect to add another parameter.

I would recommend explicitly checking each parameter instead:

if (isset($_REQUEST['param1']) && isset($_REQUEST['param2']) && isset($_REQUEST['param3'])) {
    //All parameters are here, get them
    $param1 = $_REQUEST['param1'];
    $param2 = $_REQUEST['param2'];
    $param3 = $_REQUEST['param3'];
}

Further I would recommend against using the $_REQUEST superglobal in general - it contains all POST parameters, all GET parameters and all COOKIE parameters. This means that you are giving up some amount of control, and thereby (in the worst case) opening up you application to unnecessary security vulnerabilities - or in the best case increasing the complexity of future debugging.

Instead you should access the $_GET, $_POST and $_COOKIE superglobals directly - I would recommend going with $_POST whenever you can:

if (isset($_POST['param1']) && isset($_POST['param2']) && isset($_POST['param3'])) {
    //All parameters are here
    $param1 = $_POST['param1'];
    $param2 = $_POST['param2'];
    $param3 = $_POST['param3'];
}

...oh - and you have a typo here:

$data="param1=P1";
$data.= "param2=P2&"; 
$data.= "param3=P3";

(ampersand missing between param1 and param2)

To avoid having to manually construct a valid querystring you should be able to simply pass an array to curl like this:

$data = array(
    'param1' => 'P1',
    'param2' => 'P2',
    'param3' => 'P3'
);
curl_setopt($ch, CURLOPT_URL," http://www.example.com/readcurl.php");
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);

All of the curl options are quite well-documented here

Upvotes: 3

Related Questions