Disable echo and print in PHP

This may seem like a funny question, but in fact it is not so, I would like to disable echo, printand other functions that can be outputted to a buffer, for example readfile.

The reason I would like to do this is to prevent the client from using echoor printoutside the rules of my application, forcing them to compile their contents and send it to the output class so that the entire buffer is managed.

Now I know that I can set the output buffer at the beginning of my script and throw out any content, but this will not include such things as headerand set_cookie, therefore, my question can be interpreted as How can I manage the buffer for the answer chapter

Is there any possible way to control all aspects of PHP output, such as assigning a callback to the main buffer, and not just the response body?

+5
source share
4 answers

In the end, there is no effective way to achieve this, because at least echoit is not a function, but a language construct that cannot be disabled. You can play with output buffering ( ob_start()etc.), but this will not prevent another code from disabling output buffering again.

, , , " ". , " ", . , .

+6

:

    function trace($message) {
      $echo = true;
      if ($echo)
      echo $message . "<br>";
    }

( " " ); , , $echo false,

+2

, - , . . , : , , , .

  • , , ( - ).

    token_get_all() , T_ECHO T_PRINT ( ). -, , (eval(), , :// ..). .

    T_INCLUDE, T_INCLUDE_ONCE, T_REQUIRE T_REQUIRE_ONCE. (, PHP, , ), .

  • PHP ADB, , . , , . , set_cookie() header(), . - , , .

    class YourApplicationControllingClass {
    
        final protected function callUserCode($pathToUserCodeFile) {
            // We want this to be a local variable so there no way to get to it
            // with PHP Reflection
            $suspender = new SuspendFunctions();
    
            ob_start();
    
            // You may need to add more here, this is just my superficial pass
            $suspender->suspend("ob_clean", "ob_end_clean", "ob_end_flush", "ob_flush", 
                    "ob_get_clean", "ob_get_contents", "ob_get_flush", "ob_get_length",
                    "ob_get_level", "ob_get_status", "ob_implicit_flush", "ob_list_handlers",
                    "ob_start", "output_add_rewrite_var", "output_reset_rewrite_vars",
                    "set_cookie", "set_raw_cookie", "header_register_callback", "header",
                    "header_remove", "http_response_code", "register_shutdown_function",
                    "register_tick_function", "unregister_tick_function", "set_error_handler",
                    "restore_error_handler", "set_exception_handler", "restore_exception_handler"
                    );
    
            $this->callUserCodeSandbox($pathToUserCodeFile);
            // Restore our original execution environment
            $suspender->resume();
    
            $content = ob_get_clean();
            // If you want to be aggressive, check to see if they produced any output
            // and blacklist them if they even try.
            if ($content !== '') $this->blacklistUserCode($pathToUserCodeFile);
        }
    
        private function callUserCodeSandbox($pathToUserCodeFile) {
            require($pathToUserCodeFile);
        }
    }
    
    final class SuspendFunctions {
        private $suspendedFunctions = array();
    
        /**
        * Suspends certain functions from being executable.
        * @param string $function,... Names of functions to suspend, you may pass multiple
        * @return void
        */
        function suspend($function) {
            $functions = func_get_args();
            foreach($functions as $function) {
                // Make sure we don't double-suspend a function
                if (isset($this->suspendedFunctions[$function])) continue;
    
                // Make new names unguessable, and make it very unlikely that we end up with a collision.
                $newName = '_'.md5($function.microtime(true).mt_random());
    
                // Rename to the unguessable name
                rename_function($function, $newName);
    
                // Keep a record for ourselves what this new name is so we can resume later
                $this->suspendedFunctions[$function] = $newName;
            }
        }
    
        /**
        * Resumes functions for calling
        */
        function resume() {
            foreach($this->suspendedFunctions as $function=>$newName) {
                rename($newName, $function);
                unset($this->suspendedFunctions[$function]);
            }
        }
    }
    

, , (, , , ). PHP , . PHP " ", , . , , , , . ( ).

+1

Besides editing and recompiling, I don’t think you can disable the functions that output. For functions that bypass output buffering, your SOL.

However, you can use built-in output buffering to control output without a header. The best part is the possibility of nesting:

ob_start();
echo 'The first output!',"\n";

ob_start();
echo 'The second output.';

$output2 = ob_get_clean();

ob_flush();

echo $output2;

will output:

The first output!
The second output.
0
source

All Articles