pfela February 2016

Why does PHP cURL drop numeric keys?

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'] => tes        

Answers


Ray February 2016

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.

Post Status

Asked in February 2016
Viewed 1,959 times
Voted 8
Answered 1 times

Search




Leave an answer