Why cant I access $_POST variable with a hyphen/dash in its key if passing key as variable?

萝らか妹 提交于 2019-12-20 04:56:26

问题


I've written a small static method for my class which returns either $_POST variable if it is set or NULL otherwise. Input elements in HTML form have names with hyphens for example 'customer-name'.

So I think I could access them like this $var = $_POST['customer-name']. But with my method:

public static function getPost($param) {
    echo $param." = ".$_POST[$param]."<br/>";
    return isset($_POST[$param]) ? $_POST[$param] : NULL;
}

I can not. And I notice some strange behavior when added some echo statements to my method. It cuts off everything after a hyphen, so I got error:

Notice: Undefined index: customer- in .. on line ..

This is how I test it:

$arr = (array)$object;
$newArr = array();
foreach($arr as $key => $val) {
    $newKey = str_replace(get_class($object), "", $key);
    $newArr[$newKey] = MyObject::getPost(strtolower(get_class($object))."-".$newKey);
}

And this is the output from my test:

...
Notice: Undefined index: customer- in .. on line 116
customer-id =

Notice: Undefined index: customer- in .. on line 116
customer-name =

Notice: Undefined index: customer- in .. on line 116
customer-phonecode =
...

EDIT 1 - I was asked for HTML form:

<form action="" method="post" class="form-horizontal" role="form">
   <input type="text" name="customer-name" id="customer-name" class="form-control" placeholder="Name" required="required" autocomplete="off" />
   <select id="customer-phonecode" name="customer-phonecode" class="form-control">
      <option value="+123"></option>
   </select>
</form>

EDIT 2 - Tested on phptester.net on 5.2, 5.3, 5.4, 5.5 php versions. Getting same error.

EDIT 3 - Tested following script. If passing string as key I get element in super global $_POST/an array. But if passing a variable which points to a string, an element cannot be accessed

<?php
$test = array('customer-test1' => 1, 'customer-test2' => 2);
function getPost($param) {
    global $test;
    $newParam = (string)$param;
    echo $param." = ".$test[$newParam]."<br/>";
    return isset($test[$newParam]) ? $test[$newParam] : NULL;
}
class Customer {
    private $test1;
    private $test2;     
    function __construct() { }
}
$object = new Customer();
$arr = (array)$object;
$newArr = array();
foreach($arr as $key => $val) {
    $newKey = str_replace(get_class($object), "", $key);
    $newArr[$newKey] = getPost(strtolower(get_class($object))."-".$newKey);
}

Might this be a PHP bug?


回答1:


This may be a limitation of PHP - when using superglobals such as $_POST, there are some "magical" things going on. PHP converts the names of form elements in many ways, for example

<input type="text" name="hello[mate]" />

Will be accessible as $_POST['hello']['mate'], because the form names are processed as variables. Using dashes is therefore generally not a good idea, because they are not allowed in variable names and probably interfere here. I would advise to only use characters which are allowed for variables in PHP, and replace dashes with underscores.




回答2:


So the problem was, that casting object to an array adds null characters to array keys. They are not just class name+property name. It's how PHP manages private class properties when casting.

$object = new Customer();
$arr = (array)$object;
print_r(array_map("addslashes", array_keys($arr)));

Outputs:

Array ( 
        [0] => \0Customer\0test1 
        [1] => \0Customer\0test2
      )

Im not sure why var_dump() doesnt show those null bytes. Might be my next question I guess. So those nulls were still there in my static method argument. But why PHP stops right after dash/hyphen?

In PHP we can simply write:

$Tmp= 'hehe';

But for the same in C, we would use the following code:

Char Tmp [4];
Tmp [0] = 'h';
Tmp [1] = 'e';
Tmp [2] = 'h';
Tmp [3] = 'e';
Tmp [4] = '\0';

C handles strings as a character array, it needs a way to define the last character of the string. This is done using a null byte. A null byte is donated by \0 in C. So when the program runs, it starts reading the string from the first character until the null byte is reached. This creates a problem. As we know, PHP is also implemented in C. This can become an issue, because some functions in PHP might handle an input string as they are handled by C.

Sources: #71673, null-byte-injection-php

EDIT 1: Solution added

Solution is to replace '\0' characters as well as class name with "" in my foreach loop:

foreach($arr as $key => $val) {
    $newKey = str_replace(array(get_class($object), "\0"), "", $key);
    $newArr[$newKey] = getPost(strtolower(get_class($object))."-".$newKey);
}


来源:https://stackoverflow.com/questions/35655093/why-cant-i-access-post-variable-with-a-hyphen-dash-in-its-key-if-passing-key-a

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!