问题
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