1

我为我的类编写了一个小的静态方法,$_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 =
...

编辑 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/an 数组中获得元素。但是如果传递指向字符串的变量,则无法访问元素

<?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 错误吗?

4

2 回答 2

1

这可能是 PHP 的一个限制——当使用诸如 $_POST 之类的超全局变量时,会发生一些“神奇”的事情。PHP 以多种方式转换表单元素的名称,例如

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

将作为 $_POST['hello']['mate'] 访问,因为表单名称被作为变量处理。因此,使用破折号通常不是一个好主意,因为它们不允许在变量名中使用,并且可能会干扰这里。我建议只使用 PHP 中允许用于变量的字符,并用下划线替换破折号。

于 2016-02-26T19:45:23.710 回答
0

所以问题是,将对象转换为数组会将空字符添加到数组键中。它们不仅仅是类名+属性名。这是 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 将字符串作为字符数组处理,它需要一种方法来定义字符串的最后一个字符。这是使用空字节完成的。空字节由 C 中的 \0 提供。因此,当程序运行时,它会从第一个字符开始读取字符串,直到到达空字节。这就产生了一个问题。众所周知,PHP 也是用 C 实现的。这可能会成为一个问题,因为 PHP 中的某些函数可能会处理输入字符串,因为它们是由 C 处理的。

来源:#71673空字节注入-php

编辑 1:添加了解决方案

""解决方案是在我的 foreach 循环中替换 '\0' 字符以及类名:

foreach($arr as $key => $val) {
    $newKey = str_replace(array(get_class($object), "\0"), "", $key);
    $newArr[$newKey] = getPost(strtolower(get_class($object))."-".$newKey);
}
于 2016-02-27T09:42:27.480 回答