Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does PHP cURL drop numeric keys?

Tags:

php

curl

I'm trying to use cURL to POST an array containing numeric indices, but curl_setopt is dropping the numeric indices. I'm using PHP Version 5.3.29.

Here's a simple script I setup to illustrate what is happening:

<?php

$is_curled = isset($_GET['curl']) ? !!$_GET['curl'] : false;

if (!$is_curled) {
    $url = $_SERVER['SCRIPT_URI'] . '?curl=1';

    $_POST['1'] = 'test1234';               // dropped because numeric
    $_POST[234] = 'test3211';               // dropped because numeric
    $_POST['t3'] = 'test1325';              // NOT dropped
    $_POST['4t'] = 'test6347';              // NOT dropped
    $_POST['_5'] = 'test3235';              // NOT dropped
    $_POST['*4'] = 'test7432';              // NOT dropped BUT gets the NEXT POST value
    $_POST["3"] = 'test8521';               // dropped because numeric
    $_POST['"2"'] = 'test9472';             // NOT dropped because the string "2"
    $_POST["'1'"] = 'test2741';             // NOT dropped because the string '1' BUT gets the NEXT POST value
    $_POST["10"] = 'test1738';              // dropped because numeric
    $_POST['test_field'] = 'test6123';      // NOT dropped

    $ch = curl_init();

    curl_setopt($ch, CURLOPT_URL, $url);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $_POST);       // this drops numeric keys

    echo '<pre>' . print_r($_POST, 1) . '</pre>';

    curl_exec($ch);

    curl_close($ch);

} else {
    echo '<pre>' . print_r($_POST, 1) . '</pre>';

}

?>

Here is the output:

Array
(
    [1] => test1234
    [234] => test3211
    [t3] => test1325
    [4t] => test6347
    [_5] => test3235
    [*4] => test7432
    [3] => test8521
    ["2"] => test9472
    ['1'] => test2741
    [10] => test1738
    [test_field] => test6123
)
Array
(
    [t3] => test1325
    [4t] => test6347
    [_5] => test3235
    [*4] => test8521
    ["2"] => test9472
    ['1'] => test1738
    [test_field] => test6123
)

What's even weirder, is not only are some indices dropped, but the values appear to be shifted in the ones next to the ones that are dropped.

like image 941
pfela Avatar asked Dec 04 '25 15:12

pfela


1 Answers

Assuming your sending content type application/x-www-form-urlencoded means you're sending HTML Form data. (PHP curl defaults to this content type as it is the w3c recommended default https://www.w3.org/TR/html401/interact/forms.html#h-17.13.4).

According to the spec, NAME tokens (a.k.a. the post and get parameter names )have to start with an letter: https://www.w3.org/TR/html4/types.html#h-6.2

ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").

This is probably why it's not being handled as you expect, because starting a param in the POST body with a number for the indicated content type is unsupported.

like image 171
Ray Avatar answered Dec 06 '25 03:12

Ray