PHP: Illegal string-offset

匿名 (未验证) 提交于 2019-12-03 01:05:01

问题:

My open-source project was working just fine, until I started to work on it after 6 month of break. Updated to latest XAMPP, and start getting tons of weird errors, one of which is as:

I have Input class, with a caller method as:

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

This piece of code, works like this: you ask certain superglobal value from it, and it returns clean version of it, on-demand:

server("SERVER_NAME"); ?> 

Easy right? Well, after I updated PHP with XAMPP, it just doesn't work [edit: it works, with the Warning message] - error is:

PHP Warning:  Illegal string offset 'SERVER_NAME' in S:\...\kernel\input.php on line 159 

line, which corresponds to line of code:

return $this->$name[ $this->clean__makesafe_key( $arguments[0] ) ] = $this->clean__makesafe_value( $GLOBALS[ $_name_of_superglobal ][ $arguments[0] ], array(), true ); 

which is stupid: $_name_of_superglobal = "_SERVER" there, and $arguments[0] = "SERVER_NAME" and overall assignment is string which gets cleaned.

WHAT MIGHT BE THE PROBLEM THERE? I am totally lost here!

回答1:

Introduction

I know this has been answered but Illegal string offset ERROR is not the only issue i see here. I belive they are better ways to introduce the flexibility you want and also still make elements save without all that complexity and using of $GLOBALS.

You can start by looking at :

Quick Review

$input = new Input();                          server("SERVER_NAME");       ^                  ^           ^       |                  |           |     variable             |           |                      Variable        |                                   Variable  

Am not sure what stops you from just using

    $_SERVER['SERVER_NAME'] = makeSave($_SERVER['SERVER_NAME']);                                   ^                                   |- I guess this is what you want to introduce  

Assumption - You want fexibility

Lest assume you want flexibility and also recursion then your class call can be as flexible as :

print_r($input->SERVER_NAME);            | print_r($input['SERVER_NAME']);          |----- Would Produce same result  print_r($input->SERVER_NAME());          | 

If this is the kind of flexibility you want the i would consider you combine __get , __call and ArrayAccess altogether ...

Lets Imagine

Now back to your format

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

They would all output

See Live DEMO

Your INPUT class modified

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

Make your Save method a class

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 = 32 && $ord 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;     } } 

Conclusion

Has i said i know this has been answered but i hope this helps someone else not to write code like yours ...

PS : This has also fixed your PHP Warning: Illegal string offset ERROR



回答2:

I found my answer here. Apparently, the line

return $this->$name[ $this->clean__makesafe_key( $arguments[0] ) ] = $this->clean__makesafe_value( $GLOBALS[ $_name_of_superglobal ][ $arguments[0] ], array(), true ); 

should be like:

return $this->{$name}[ $this->clean__makesafe_key( $arguments[0] ) ] = $this->clean__makesafe_value( $GLOBALS[ $_name_of_superglobal ][ $arguments[0] ], array(), true ); 

due to the precedence.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!