Я написал небольшой статический метод для моего класса, который возвращает либо $_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?
Это может быть ограничением PHP — при использовании суперглобальных переменных, таких как $ _POST, происходят некоторые «магические» вещи. PHP преобразует имена элементов формы многими способами, например
<input type="text" name="hello[mate]" />
Будет доступен как $ _POST [‘hello’] [‘mate’], потому что имена форм обрабатываются как переменные. Поэтому использование тире, как правило, не очень хорошая идея, поскольку они не допускаются в именах переменных и, вероятно, мешают работе. Я бы советовал использовать только те символы, которые разрешены для переменных в PHP, и заменять черточки подчеркиванием.
Таким образом, проблема заключалась в том, что приведение объекта к массиву добавляет нулевые символы к ключам массива. Это не просто имя класса + имя свойства. Это то, как 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);
}