Intereting Posts
Извлечение содержимого html-страницы в php Вставка базы данных mysql меняет все ID на 4294967295 PHP Получить возвращаемое значение из конструктора php / mysql – подготовленная в PDO вставка, не работает, и никаких сообщений об ошибках CodeIgniter – Загрузка изображения через форму, сохранение местоположения изображения в базе данных Триггер не работает – измените таблицу, чтобы добавить новый столбец, прежде чем вставлять в нее PHP Array – удаление пустых значений Заголовок NGINX «Access-Control-Allow-Origin» содержит несколько значений Поиск свободных блоков времени в mysql и php? Как рассчитать интервал между 2 временными метками unix в php БЕЗ деления на 86400 (60 * 60 * 24) Мне нужно знать, что предопределенная точка находится в море или на земле Code Igniter – использование моего собственного API и авторизации Переход на новую версию PHP Как получить имя текущего шаблона в функции TWIG Laravel Передача данных из одного вида в другой вид

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

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

Поэтому я думаю, что я мог бы получить к ним доступ, как этот $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 = ... 

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

EDIT 2 – Протестировано на phptester.net версии 5.2, 5.3, 5.4, 5.5 php. Получение такой же ошибки.

EDIT 3 – Протестировано по следующему сценарию. Если передать строку в качестве ключа, я получаю элемент в супер-глобальном массиве $ _POST /. Но если передать переменную, которая указывает на строку, элемент не может быть доступен

 <?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 , null-byte-injection-php

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