Почему я не могу получить доступ к переменной $ _POST с дефисом / тире в ключе, если передаю ключ как переменную?

Я написал небольшой статический метод для моего класса, который возвращает либо $_POST переменная, если она установлена ​​или NULL иначе. Элементы ввода в форме HTML имеют имена с дефисами, например, «customer-name».

Так что я думаю, что мог бы получить к ним доступ, как это $var = $_POST['customer-name'], Но с моим методом:

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

Я не могу. И я замечаю какое-то странное поведение при добавлении некоторых echo заявления к моему методу. После дефиса все обрезается, поэтому я получил ошибку:

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

Вот как я это проверяю:

$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);
}

И это результат моего теста:

...
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 =
...

РЕДАКТИРОВАТЬ 1 — меня попросили HTML-форму:

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

РЕДАКТИРОВАТЬ 2 — Проверено на phptester.net на версиях 5.2, 5.3, 5.4, 5.5 php. Получаю ту же ошибку.

РЕДАКТИРОВАТЬ 3 — Проверено следующий скрипт. Если передать строку в качестве ключа, я получу элемент в суперглобальном массиве $ _POST / a. Но если передать переменную, которая указывает на строку, элемент не может быть доступен

<?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);
}

Может ли это быть ошибка PHP?

1

Решение

Это может быть ограничением PHP — при использовании суперглобальных переменных, таких как $ _POST, происходят некоторые «магические» вещи. PHP преобразует имена элементов формы многими способами, например

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

Будет доступен как $ _POST [‘hello’] [‘mate’], потому что имена форм обрабатываются как переменные. Поэтому использование тире, как правило, не очень хорошая идея, поскольку они не допускаются в именах переменных и, вероятно, мешают работе. Я бы советовал использовать только те символы, которые разрешены для переменных в PHP, и заменять черточки подчеркиванием.

1

Другие решения

Таким образом, проблема заключалась в том, что приведение объекта к массиву добавляет нулевые символы к ключам массива. Это не просто имя класса + имя свойства. Это то, как PHP управляет свойствами частного класса при приведении.

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

Выходы:

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

Я не уверен почему var_dump() не показывает эти нулевые байты. Наверное, мой следующий вопрос. Так что эти нули все еще были в моем аргументе статического метода. Но почему PHP останавливается сразу после тире / дефиса?

В PHP мы можем просто написать:

$Tmp= 'hehe';

Но для того же в C, мы будем использовать следующий код:

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

C обрабатывает строки как символьный массив, ему нужен способ определить
последний символ строки. Это делается с помощью нулевого байта. Ноль
байт передается на \ 0 в C. Таким образом, когда программа запускается, она запускается
чтение строки от первого символа до нулевого байта
достиг. Это создает проблему. Как известно, PHP также реализован
в C. Это может стать проблемой, потому что некоторые функции в PHP могут
обрабатывать входную строку, так как они обрабатываются C.

Источники: # 71673, нуль-байт-инъекции PHP

РЕДАКТИРОВАТЬ 1: Решение добавлено

Решение состоит в том, чтобы заменить символы \ 0 и имя класса на "" в моем цикле foreach:

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