我的开源项目工作正常,直到我在休息6个月后开始工作.更新到最新的XAMPP,并开始收到大量奇怪的错误,其中一个是:
我有Input类,调用方法如下:
<?php
class Input
{
public function __call ( $name , $arguments )
{
if ( !in_array( $name, array( "post", "get", "cookie", "request", "server", "env" ) ) )
{
throw new Exception( "Input::" . $name . "() not declared!" );
}
$_name_of_superglobal = "_" . strtoupper( $name );
$_max_iteration_level_for_cleanup = in_array( $name, array( "server", "env" ) ) ? 1 : 10;
# $arguments[0] is the index of the value, to be fetched from within the array.
if ( !empty( $arguments[0] ) and array_key_exists( $arguments[0], $this->$name ) )
{
return $this->$name[ $arguments[0] ];
}
elseif ( !empty( $arguments[0] ) and array_key_exists( $arguments[0], $GLOBALS[ $_name_of_superglobal ] ) )
{
return $this->$name[ $this->clean__makesafe_key( $arguments[0] ) ] = $this->clean__makesafe_value( $GLOBALS[ $_name_of_superglobal ][ $arguments[0] ], array(), true );
}
elseif ( !empty( $arguments[0] ) and !array_key_exists( $arguments[0], $GLOBALS[ $_name_of_superglobal ] ) )
{
return null;
}
else
{
if ( $this->_is_cleanup_done_for[ $name ] === true )
{
return $this->$name;
}
$this->_is_cleanup_done_for[ $name ] = true;
return $this->$name = $this->clean__makesafe_recursively( $GLOBALS[ $_name_of_superglobal ], $_max_iteration_level_for_cleanup );
}
}
?>
Run Code Online (Sandbox Code Playgroud)
这段代码的工作原理如下:你从它那里询问某些超全局值,然后按需返回它的干净版本:
<?php
$input = new Input();
$server_name = $input->server("SERVER_NAME");
?>
Run Code Online (Sandbox Code Playgroud)
容易吗?好吧,在我用XAMPP更新PHP后,它只是不起作用[编辑:它的工作原理,带有警告信息] - 错误是:
PHP Warning: Illegal string offset 'SERVER_NAME' in S:\...\kernel\input.php on line 159
Run Code Online (Sandbox Code Playgroud)
line,对应代码行:
return $this->$name[ $this->clean__makesafe_key( $arguments[0] ) ] = $this->clean__makesafe_value( $GLOBALS[ $_name_of_superglobal ][ $arguments[0] ], array(), true );
Run Code Online (Sandbox Code Playgroud)
这是愚蠢的:$_name_of_superglobal="_ SERVER",$arguments[0]="SERVER_NAME",整体分配是被清理的字符串.
可能有什么问题?我完全迷失在这里!
Bab*_*aba 26
介绍
我知道这已经得到了解答,但这Illegal string offset ERROR不是我在这里看到的唯一问题.我相信他们是更好的方式来引入你想要的灵活性,并且仍然使元素保存没有所有这些complexity和使用$GLOBALS.
你可以先看看:
快速复审
$input = new Input(); <-- You add to initiate a class
$server_name = $input->server("SERVER_NAME");
^ ^ ^
| | |
variable | |
Variable |
Variable
Run Code Online (Sandbox Code Playgroud)
我不确定是什么阻止你使用
$_SERVER['SERVER_NAME'] = makeSave($_SERVER['SERVER_NAME']);
^
|- I guess this is what you want to introduce
Run Code Online (Sandbox Code Playgroud)
假设 - 你想要灵活性
为了避免您需要灵活性和递归,那么您的类调用可以像以下一样灵活:
print_r($input->SERVER_NAME); |
print_r($input['SERVER_NAME']); |----- Would Produce same result
print_r($input->SERVER_NAME()); |
Run Code Online (Sandbox Code Playgroud)
如果这是你想要的那种灵活性,我会考虑你合并__get,__call并且ArrayAccess完全......
让我们想象一下
$var = array();
$var["name"] = "<b>" . $_SERVER['SERVER_NAME'] . "</b>";
$var["example"]['xss'] = '<IMG SRC=javascript:alert("XSS")>';
$var["example"]['sql'] = "x' AND email IS NULL; --";
$var["example"]['filter'] = "Let's meet 4:30am Ât the \tcafé\n";
$_SERVER['SERVER_NAME'] = $var ; // Just for example
Run Code Online (Sandbox Code Playgroud)
现在回到你的格式
$makeSave = new MakeSafe(MakeSafe::SAVE_XSS | MakeSafe::SAVE_FILTER);
$input = new Input($_SERVER, $makeSafe);
//You can
print_r($input->SERVER_NAME);
//Or
print_r($input['SERVER_NAME']);
//Or
print_r($input->SERVER_NAME());
Run Code Online (Sandbox Code Playgroud)
Array
(
[0] => <b>localhost</b>
[1] => Array
(
[0] => <IMG SRC=javascript:alert("XSS")>
[1] => x' AND email IS NULL; --
[2] => Let's meet 4:30am Ât the 	café
)
)
Run Code Online (Sandbox Code Playgroud)
您的INPUT类已修改
class INPUT implements \ArrayAccess {
private $request = array();
private $makeSafe;
public function __construct(array $array, MakeSafe $makeSafe) {
$this->request = $array;
$this->makeSave = $makeSafe;
}
function __get($offset) {
return $this->offsetGet($offset);
}
function __call($offset, $value) {
return $this->offsetGet($offset);
}
public function setRequest(array $array) {
$this->request = $array;
}
public function offsetSet($offset, $value) {
trigger_error("Error: SUPER GLOBAL data cannot be modified");
}
public function offsetExists($offset) {
return isset($this->request[$offset]);
}
public function offsetUnset($offset) {
unset($this->request[$offset]);
}
public function offsetGet($offset) {
return isset($this->request[$offset]) ? $this->makeSave->parse($this->request[$offset]) : null;
}
}
Run Code Online (Sandbox Code Playgroud)
使您的Save方法成为一个类
class MakeSafe {
const SAVE_XSS = 1;
const SAVE_SQL = 2;
const SAVE_FILTER_HIGH = 4;
const SAVE_FILTER_LOW = 8;
const SAVE_FILTER = 16;
private $options;
function __construct($options) {
$this->options = $options;
}
function escape($value) {
if ($value = @mysql_real_escape_string($value))
return $value;
$return = '';
for($i = 0; $i < strlen($value); ++ $i) {
$char = $value[$i];
$ord = ord($char);
if ($char !== "'" && $char !== "\"" && $char !== '\\' && $ord >= 32 && $ord <= 126)
$return .= $char;
else
$return .= '\\x' . dechex($ord);
}
return $return;
}
function parse($mixed) {
if (is_string($mixed)) {
$this->options & self::SAVE_XSS and $mixed = htmlspecialchars($mixed, ENT_QUOTES, 'UTF-8');
$this->options & self::SAVE_SQL and $mixed = $this->escape($mixed);
$this->options & self::SAVE_FILTER_HIGH and $mixed = filter_var($mixed, FILTER_SANITIZE_STRING, FILTER_FLAG_ENCODE_HIGH);
$this->options & self::SAVE_FILTER_LOW and $mixed = filter_var($mixed, FILTER_SANITIZE_STRING, FILTER_FLAG_ENCODE_LOW);
$this->options & self::SAVE_FILTER and $mixed = filter_var($mixed, FILTER_SANITIZE_STRING, FILTER_FLAG_ENCODE_HIGH | FILTER_FLAG_ENCODE_LOW);
return $mixed;
}
if (is_array($mixed)) {
$all = array();
foreach ( $mixed as $data ) {
$all[] = $this->parse($data);
}
return $all;
}
return $mixed;
return $this->final;
}
}
Run Code Online (Sandbox Code Playgroud)
结论
我说我知道这已经得到了回答但是我希望这可以帮助别人不要写像你这样的代码......
PS:这也修复了你的PHP警告:非法字符串偏移ERROR
我在这里找到了答案.显然,这条线
return $this->$name[ $this->clean__makesafe_key( $arguments[0] ) ] = $this->clean__makesafe_value( $GLOBALS[ $_name_of_superglobal ][ $arguments[0] ], array(), true );
Run Code Online (Sandbox Code Playgroud)
应该是这样的:
return $this->{$name}[ $this->clean__makesafe_key( $arguments[0] ) ] = $this->clean__makesafe_value( $GLOBALS[ $_name_of_superglobal ][ $arguments[0] ], array(), true );
Run Code Online (Sandbox Code Playgroud)
由于优先权.