Search code examples
phpsuperglobals

Is it possible to trigger an error when $_POST or another superglobal is accessed?


I have this framework project kind of on the backburner where I want to enforce the use of an Input class to access all superglobals like $_POST, $_GET and $_SERVER. A recent question here reminded me about it.

The class will do a little cleanup of the keys to make sure there's nothing malicious or unexpected, and provide a way to access items without the hassle of using isset() each time. It may do other things depending on configuration, and will possibly clear the superglobals as well. I also don't like the fact that superglobals are not read-only, I want to enforce integrity in the values. I want this class to be used exclusively, and want to warn developers when it is not used.

My question is this, and I fear the answer is "No":

Is it possible to to trigger an error when one of the superglobals is accessed? For example:

$myvar = $_POST['key'];
// Prints "Error: POST cannot be accessed directly, use the Input class instead"

Or when writing to superglobals?:

$_POST['key'] = 'myvalue';
// Prints "Error: POST data cannot be modified"

Solution

  • You can use ArrayAccess

    Example 1 :

    $_POST = new SUPER($_POST);
    $_POST['hello'] = "Hello World"; // This would trigger error ;
    

    Example 2 : a.php?var=1&var2=2

    $_GET = new SUPER($_GET);
    echo $_GET['var'] ; // returns 1
    echo $_GET['var2'] ; // returns 2
    
    $_GET['var3'] = 2 ; //return error
    

    Class Used

    class SUPER implements \ArrayAccess {
        private $request = array();
    
        public function __construct(array $array) {
            $this->request = $array;
        }
    
        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->request[$offset] : null;
        }
    }