From d42d0492fe5f17e4eadfe339a02ea7d05b0b1198 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Sun, 21 Oct 2012 18:30:48 +0100 Subject: [PATCH 01/24] Added composer.json. Fixes #38 and #32 Signed-off-by: Alex Bilbie --- composer.json | 31 +++++++++++++++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 composer.json diff --git a/composer.json b/composer.json new file mode 100644 index 0000000..fbfcf72 --- /dev/null +++ b/composer.json @@ -0,0 +1,31 @@ +{ + "name": "JosephLenton/PHPError", + "description": "Better error reporting for PHP, and prettier too!", + "version": "1.0.0", + "homepage": "https://github.com/JosephLenton/PHP-Error", + "license": "BSD", + "require": { + "php": ">=5.3.0" + }, + "repositories": [ + { + "type": "git", + "url": "https://github.com/JosephLenton/PHP-Error" + } + ], + "keywords": [ + "php", + "error", + "reporting" + ], + "authors": [ + { + "name": "Joseph Lenton", + "homepage": "http://www.playmycode.com/", + "role": "Developer" + } + ], + "autoload": { + "files": ["src/php_error.php"] + } +} \ No newline at end of file From 12869734587e123e8fcc01ee33ea21e1673dca22 Mon Sep 17 00:00:00 2001 From: Alex Bilbie Date: Tue, 6 Nov 2012 18:43:59 +0000 Subject: [PATCH 02/24] Update composer.json Correct name and license parameters --- composer.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/composer.json b/composer.json index fbfcf72..1e18964 100644 --- a/composer.json +++ b/composer.json @@ -1,9 +1,9 @@ { - "name": "JosephLenton/PHPError", + "name": "joseph-lenton/php-error", "description": "Better error reporting for PHP, and prettier too!", "version": "1.0.0", "homepage": "https://github.com/JosephLenton/PHP-Error", - "license": "BSD", + "license": "BSD-3-Clause", "require": { "php": ">=5.3.0" }, From 2b995d0f64b1364ca6c66f65290160884a206b53 Mon Sep 17 00:00:00 2001 From: Shaine Hatch Date: Wed, 23 Jan 2013 15:59:27 -0700 Subject: [PATCH 03/24] Remove trailing whitespace --- src/php_error.php | 310 +++++++++++++++++++++++----------------------- 1 file changed, 155 insertions(+), 155 deletions(-) diff --git a/src/php_error.php b/src/php_error.php index fa55cd5..e67217f 100644 --- a/src/php_error.php +++ b/src/php_error.php @@ -1,12 +1,12 @@ nor the * names of its contributors may be used to endorse or promote products * derived from this software without specific prior written permission. - * + * * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE @@ -28,7 +28,7 @@ * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. - * + * * Uses: * JSMin-php https://github.com/rgrove/jsmin-php/ * jQuery http://jquery.com/ @@ -36,55 +36,55 @@ /** * PHP Error - * + * * --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- - * + * * WARNING! It is downright _DANGEROUS_ to use this in production, on * a live website. It should *ONLY* be used for development. - * + * * PHP Error will kill your environment at will, clear the output * buffers, and allows HTML injection from exceptions. - * + * * In future versions it plans to do far more then that. - * + * * If you use it in development, awesome! If you use it in production, * you're an idiot. - * + * * --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- - * + * * = Info - * + * * A small API for replacing the standard PHP errors, with prettier * error reporting. This will change the error reporting level, and this * is deliberate, as I believe in strict development errors. - * + * * simple usage: - * + * * \php_error\reportErrors(); - * + * * Advanced example: - * + * * There is more too it if you want more customized error handling. You * can pass in options, to customize the setup, and you get back a * handler you can alter at runtime. - * + * * $handler = new \php_error\ErrorHandler( $myOptions ); * $handler->turnOn(); - * + * * There should only ever be one handler! This is an (underdstandable) * limitation in PHP. It's because if an exception or error is raised, * then there is a single point of handling it. - * + * * = INI Options - * + * * - php_error.force_disabled When set to a true value (such as on), * this forces this to be off. * This is so you can disable this script * in your production servers ini file, * incase you accidentally upload this there. - * + * * --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- --- - * + * * @author Joseph Lenton | https://github.com/josephlenton */ @@ -117,14 +117,14 @@ /* * These are used as token identifiers by PHP. - * + * * If they are missing, then they should never pop out of PHP, * so we just give them their future value. - * + * * They are primarily here so I don't have to alter the 5.3 * compliant code. Instead I can delete pre-5.3 code (this * code), in the future. - * + * * As long as the value is unique, and does not clash with PHP, * then any number could be used. That is why they start counting * at 100,000. @@ -161,7 +161,7 @@ * check that display errors is on * and ensure we are *not* a command line script. */ - $_php_error_is_ini_enabled = + $_php_error_is_ini_enabled = ! @get_cfg_var( 'php_error.force_disabled' ) && ! @get_cfg_var( 'php_error.force_disable' ) && @ini_get('display_errors') === '1' && @@ -172,10 +172,10 @@ /** * This is shorthand for turning off error handling, * calling a block of code, and then turning it on. - * + * * However if 'reportErrors' has not been called, * then this will silently do nothing. - * + * * @param callback A PHP function to call. * @return The result of calling the callback. */ @@ -191,19 +191,19 @@ function withoutErrors( $callback ) { /** * Turns on error reporting, and returns the handler. - * + * * If you just want error reporting on, then don't bother * catching the handler. If you're building something * clever, like a framework, then you might want to grab * and use it. - * + * * Note that calling this a second time will replace the * global error handling with a new error handler. * The existing one will be turned off, and the new one * turned on. - * + * * You can't use two at once! - * + * * @param options Optional, options declaring how PHP Error should be setup and used. * @return The ErrorHandler used for reporting errors. */ @@ -227,18 +227,18 @@ class ErrorHandler * {closure}() * blah::foo() * foo() - * + * * It is: * a closure * or a method or function * followed by parenthesis '()' - * + * * a function is 'namespace function' * a method is 'namespace class::function', or 'namespace class->function' * the whole namespace is optional * namespace is made up of an '\' and then repeating 'namespace\' * both the first slash, and the repeating 'namespace\', are optional - * + * * 'END' matches it at the end of a string, the other one does not. */ const REGEX_METHOD_OR_FUNCTION_END = '/(\\{closure\\})|(((\\\\)?(\b[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*\\\\)*)?\b[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*(::[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*)?)\\(\\)$/'; @@ -253,7 +253,7 @@ class ErrorHandler * where the error is reported. This is the number * of lines around the line in question, * including that line. - * + * * So '9' will be the error line + 4 lines above + 4 lines below. */ const NUM_FILE_LINES = 13; @@ -271,7 +271,7 @@ class ErrorHandler /** * At the time of writing, scalar type hints are unsupported. * By scalar, I mean 'string' and 'integer'. - * + * * If they do get added, this is here as a trap to turn scalar * type hint warnings on and off. */ @@ -428,7 +428,7 @@ class ErrorHandler T_DECLARE => 'syntax-keyword', T_DEFAULT => 'syntax-keyword', T_DO => 'syntax-keyword', - + T_ELSE => 'syntax-keyword', T_ELSEIF => 'syntax-keyword', T_ENDDECLARE => 'syntax-keyword', @@ -445,7 +445,7 @@ class ErrorHandler T_FUNCTION => 'syntax-keyword', T_GLOBAL => 'syntax-keyword', T_GOTO => 'syntax-keyword', - + T_IF => 'syntax-keyword', T_IMPLEMENTS => 'syntax-keyword', T_INSTANCEOF => 'syntax-keyword', @@ -508,7 +508,7 @@ class ErrorHandler /** * A list of methods which are known to call the autoloader, * but should not error, if the class is not found. - * + * * They are allowed to fail, so we don't store a class not * found exception if they do. */ @@ -539,7 +539,7 @@ private static function isIIS() { strpos($_SERVER['_FCGI_X_PIPE_'], 'IISFCGI') !== false ); } - + /** * This attempts to state if this is *not* a PHP request, * but it cannot say if it *is* a PHP request. It achieves @@ -583,7 +583,7 @@ private static function isNonPHPRequest() { /** * Looks up a description for the symbol given, * and if found, it is returned. - * + * * If it's not found, then the symbol given is returned. */ private static function phpSymbolToDescription( $symbol ) { @@ -596,9 +596,9 @@ private static function phpSymbolToDescription( $symbol ) { /** * Attempts to syntax highlight the code snippet done. - * + * * This is then returned as HTML, ready to be dumped to the screen. - * + * * @param code An array of code lines to syntax highlight. * @return HTML version of the code given, syntax highlighted. */ @@ -702,13 +702,13 @@ private static function syntaxHighlight( $code ) { /** * Splits a given function name into it's 'class, function' parts. * If there is no class, then null is returned. - * + * * It also returns these parts in an array of: array( $className, $functionName ); - * + * * Usage: - * + * * list( $class, $function ) = ErrorHandler::splitFunction( $name ); - * + * * @param name The function name to split. * @return An array containing class and function name. */ @@ -750,7 +750,7 @@ private static function newArgument( $name, $type=false, $isPassedByReference=fa ( $klass ? array( "\\$klass", $functionName ) : $functionName ), - $name->name, + $name->name, true ); @@ -840,12 +840,12 @@ private static function syntaxHighlightFunctionMatch( $match, &$stackTrace, $hig * Returns the values given, as HTML, syntax highlighted. * It's a shorter, slightly faster, more no-nonsense approach * then 'syntaxHighlight'. - * + * * This is for syntax highlighting: * - fun( [args] ) * - class->fun( [args] ) * - class::fun( [args] ) - * + * * Class and type can be null, to denote no class, but are not optional. */ private static function syntaxHighlightFunction( $class, $type, $fun, &$args=null ) { @@ -921,7 +921,7 @@ private static function syntaxHighlightFunction( $class, $type, $fun, &$args=nul /** * Checks if the item is in options, and if it is, then it is removed and returned. - * + * * If it is not found, or if options is not an array, then the alt is returned. */ private static function optionsPop( &$options, $key, $alt=null ) { @@ -1012,7 +1012,7 @@ private static function setFoldersInner( &$newFolders, &$newLongest, $folder ) { $count = count( $parts ); $newLongest = max( $newLongest, $count ); - + if ( isset($newFolders[$count]) ) { $folds = &$newFolders[$count]; $folds[]= $parts; @@ -1026,10 +1026,10 @@ private static function getRequestHeaders() { return getallheaders(); } else { $headers = array(); - + foreach ( $_SERVER as $key => $value ) { if ( strpos($key, 'HTTP_') === 0 ) { - $key = str_replace( " ", "-", ucwords(strtolower( str_replace("_", " ", substr($key, 5)) )) ); + $key = str_replace( " ", "-", ucwords(strtolower( str_replace("_", " ", substr($key, 5)) )) ); $headers[ $key ] = $value; } } @@ -1045,7 +1045,7 @@ private static function getResponseHeaders() { /* * Merge the headers_list into apache_response_headers. - * + * * This is because sometimes things are in one, which are * not present in the other. */ @@ -1137,58 +1137,58 @@ public static function identifyTypeHTML( $arg, $recurseLevels=1 ) { /** * = Options = - * + * * All options are optional, and so is passing in an options item. * You don't have to supply any, it's up to you. - * + * * Note that if 'php_error.force_disable' is true, then this object * will try to look like it works, but won't actually do anything. - * + * * All options can also be passed in from 'php.ini'. You do this * by setting it with 'php_error.' prefix. For example: - * + * * php_error.catch_ajax_errors = On * php_error.error_reporting_on = E_ALL | E_STRICT - * + * * Includes: * = Types of errors this will catch = * - catch_ajax_errors When on, this will inject JS Ajax wrapping code, to allow this to catch any future JSON errors. Defaults to true. * - catch_supressed_errors The @ supresses errors. If set to true, then they are still reported anyway, but respected when false. Defaults to false. * - catch_class_not_found When true, loading a class that does not exist will be caught. This defaults to true. - * + * * = Error reporting level = * - error_reporting_on value for when errors are on, defaults to all errors * - error_reporting_off value for when errors are off, defaults to php.ini's error_reporting. - * + * * = Setup Details = * - application_root When it's working out hte stack trace, this is the root folder of the application, to use as it's base. * Defaults to the servers root directory. - * + * * A relative path can be given, but lets be honest, an explicit path is the way to guarantee that you * will get the path you want. My relative might not be the same as your relative. - * - * - snippet_num_lines The number of lines to display in the code snippet. + * + * - snippet_num_lines The number of lines to display in the code snippet. * That includes the line being reported. - * + * * - server_name The name for this server, defaults to "$_SERVER['SERVER_NAME']" - * + * * - ignore_folders This is allows you to highlight non-framework code in a stack trace. * An array of folders to ignore, when working out the stack trace. * This is folder prefixes in relation to the application_root, whatever that might be. * They are only ignored if there is a file found outside of them. * If you still don't get what this does, don't worry, it's here cos I use it. - * + * * - application_folders Just like ignore, but anything found in these folders takes precedence * over anything else. - * + * * - background_text The text that appeares in the background. By default this is blank. * Why? You can replace this with the name of your framework, for extra customization spice. - * + * * - html_only By default, PHP Error only runs on ajax and HTML pages. * If this is false, then it will also run when on non-HTML * pages too, such as replying with images of JavaScript * from your PHP. Defaults to true. - * + * * @param options Optional, an array of values to customize this handler. * @throws Exception This is raised if given an options that does *not* exist (so you know that option is meaningless). */ @@ -1209,7 +1209,7 @@ public function __construct( $options=null ) { /* * Deal with the options. - * + * * They are removed one by one, and any left, will raise an error. */ @@ -1300,11 +1300,11 @@ public function isOff() { /** * Turns error reporting on. - * + * * This will use the strictest error reporting available, or the * level you pass in when creating this using the 'error_reporting_on' * option. - * + * * @return This error reporting handler, for method chaining. */ public function turnOn() { @@ -1316,11 +1316,11 @@ public function turnOn() { /** * Turns error reporting off. - * + * * This will use the 'php.ini' setting for the error_reporting level, * or one you have passed in if you used the 'error_reporting_off' * option when creating this. - * + * * @return This error reporting handler, for method chaining. */ public function turnOff() { @@ -1333,19 +1333,19 @@ public function turnOff() { * Allows you to run a callback with strict errors turned off. * Standard errors still apply, but this will use the default * error and exception handlers. - * + * * This is useful for when loading libraries which do not * adhere to strict errors, such as Wordpress. - * + * * To use: - * + * * withoutErrors( function() { * // unsafe code here * }); - * + * * This will use the error_reporting value for when this is * turned off. - * + * * @param callback A PHP function to call. * @return The result of calling the callback. */ @@ -1364,16 +1364,16 @@ public function withoutErrors( $callback ) { return $callback(); } } - + /** - * This is the shutdown function, which should *only* be called + * This is the shutdown function, which should *only* be called * via 'register_shutdown_function'. - * + * * It's exposed because it has to be exposed. */ public function __onShutdown() { global $_php_error_is_ini_enabled; - + if ( $_php_error_is_ini_enabled ) { if ( $this->isOn() ) { $error = error_get_last(); @@ -1409,21 +1409,21 @@ private function propagateTurnOff() { $this->lastGlobalErrorHandler = null; } } - + /** * This is intended to be used closely with 'onShutdown'. * It ensures that output buffering is turned on. - * + * * Why? The user may output content, and *then* hit an error. * We cannot replace the page if this happens, * because they have already outputted information. - * + * * So we buffer the page, and then output at the end of the page, * or when an error strikes. */ private function startBuffer() { global $_php_error_is_ini_enabled; - + if ( $_php_error_is_ini_enabled && !$this->isBufferSetup ) { $this->isBufferSetup = true; @@ -1461,7 +1461,7 @@ private function startBuffer() { /** * Turns off buffering, and discards anything buffered * so far. - * + * * This will return what has been buffered incase you * do want it. However otherwise, it will be lost. */ @@ -1477,7 +1477,7 @@ private function discardBuffer() { /** * Flushes the internal buffer, * outputting what is left. - * + * * @param append Optional, extra content to append onto the output buffer. */ private function flushBuffer() { @@ -1491,7 +1491,7 @@ private function flushBuffer() { * This will finish buffering, and output the page. * It also appends the magic JS onto the beginning of the page, * if enabled, to allow working with Ajax. - * + * * Note that if PHP Error has been disabled in the php.ini file, * or through some other option, such as running from the command line, * then this will do nothing (as no buffering will take place). @@ -1525,7 +1525,7 @@ public function endBuffer() { ob_start(); } - if ( + if ( !$this->isAjax && $this->catchAjaxErrors && (!$this->htmlOnly || !ErrorHandler::isNonPHPRequest()) @@ -1552,7 +1552,7 @@ public function endBuffer() { /** * Calls the given method on this object, * captures it's output, and then returns it. - * + * * @param method The name of the method to call. * @return All of the text outputted during the method call. */ @@ -1602,14 +1602,14 @@ private function getFolderType( $root, $file ) { /** * Finds the file named, and returns it's contents in an array. - * + * * It's essentially the same as 'file_get_contents'. However * this will add caching at this PHP layer, avoiding lots of * duplicate calls. - * + * * It also splits the file into an array of lines, and makes * it html safe. - * + * * @param path The file to get the contents of. * @return The file we are after, as an array of lines. */ @@ -1641,9 +1641,9 @@ private function getFileContents( $path ) { /** * Reads out the code from the section of the line, * which is at fault. - * + * * The array is in a mapping of: array( line-number => line ) - * + * * If something goes wrong, then null is returned. */ private function readCodeFile( $errFile, $errLine ) { @@ -1655,7 +1655,7 @@ private function readCodeFile( $errFile, $errLine ) { $searchUp = ceil( $numLines*0.75 ); $searchDown = $numLines - $searchUp; - + $countLines = count( $lines ); /* @@ -1738,14 +1738,14 @@ private function readCodeFile( $errFile, $errLine ) { /** * Attempts to remove the root path from the path given. * If the path can't be removed, then the original path is returned. - * + * * For example if root is 'C:/users/projects/my_site', * and the file is 'C:/users/projects/my_site/index.php', * then the root is removed, and we are left with just 'index.php'. - * + * * This is to remove line noise; you don't need to be told the * 'C:/whatever' bit 20 times. - * + * * @param root The root path to remove. * @param path The file we are removing the root section from. */ @@ -1764,7 +1764,7 @@ private function removeRootPath( $root, $path ) { /** * Parses, and alters, the errLine, errFile and message given. - * + * * This includes adding syntax highlighting, removing duplicate * information we already have, and making the error easier to * read. @@ -1794,7 +1794,7 @@ private function improveErrorMessage( $ex, $code, $message, $errLine, $errFile, /* * This is for calling a function that doesn't exist. - * + * * The message contains a long description of where this takes * place, even though we are already told this through line and * file info. So we cut it out. @@ -1915,7 +1915,7 @@ private function improveErrorMessage( $ex, $code, $message, $errLine, $errFile, /* * Unexpected symbol errors. * For example 'unexpected T_OBJECT_OPERATOR'. - * + * * This swaps the 'T_WHATEVER' for the symbolic representation. */ } else if ( $code === 4 ) { @@ -1925,7 +1925,7 @@ private function improveErrorMessage( $ex, $code, $message, $errLine, $errFile, $semiColonError = false; if ( strpos($message, 'syntax error,') === 0 && $errLine > 2 ) { $lines = ErrorHandler::getFileContents( $errFile ); - + $line = $lines[$errLine-1]; if ( preg_match( ErrorHandler::REGEX_MISSING_SEMI_COLON_FOLLOWING_LINE, $line ) !== 0 ) { $content = rtrim( join( "\n", array_slice($lines, 0, $errLine-1) ) ); @@ -2073,11 +2073,11 @@ private function improveErrorMessage( $ex, $code, $message, $errLine, $errFile, * The code above can prioritize a location in the stack trace, * this is 'stackSearchI'. So we should start our search from there, * and work down the stack. - * + * * This is built in a way so that when it reaches the end, it'll loop * back round to the beginning, and check the traces we didn't check * last time. - * + * * If stackSearchI was not altered, then it just searches from top * through to the bottom. */ @@ -2110,7 +2110,7 @@ private function improveErrorMessage( $ex, $code, $message, $errLine, $errFile, /** * Parses the stack trace, and makes it look pretty. - * + * * This includes adding in the syntax highlighting, * highlighting the colours for the files, * and padding with whitespace. @@ -2172,7 +2172,7 @@ private function parseStackTrace( $code, $message, $errLine, $errFile, &$stackTr trim( $contents[$trace['line']-1] ) ); } - } + } $trace['info'] = $info; @@ -2302,7 +2302,7 @@ private function logError( $message, $file, $line, $ex=null ) { /** * Given a class name, which can include a namespace, * this will report that it is not found. - * + * * This will also report it as an exception, * so you will get a full stack trace. */ @@ -2325,11 +2325,11 @@ public function reportException( $ex ) { /** * The entry point for handling an error. - * + * * This is the lowest entry point for error reporting, * and for that reason it can either take just error info, * or a combination of error and exception information. - * + * * Note that this will still log errors in the error log * even when it's disabled with ini. It just does nothing * more than that. @@ -2559,7 +2559,7 @@ private function generateFileLineSets( $srcErrFile, $srcErrLine, &$stackTrace ) /* * Even if disabled, we still act like reporting is on, * if it's turned on. - * + * * We just don't do anything. */ private function setEnabled( $isOn ) { @@ -2570,7 +2570,7 @@ private function setEnabled( $isOn ) { if ( $_php_error_is_ini_enabled ) { /* * Only turn off, if we're moving from on to off. - * + * * This is so if it's turned off without turning on, * we don't change anything. */ @@ -2580,7 +2580,7 @@ private function setEnabled( $isOn ) { } /* * Always turn it on, even if already on. - * + * * This is incase it was messed up in some way * by the user. */ @@ -2597,7 +2597,7 @@ private function runDisableErrors() { error_reporting( $this->defaultErrorReportingOff ); @ini_restore( 'html_errors' ); - + if ( ErrorHandler::isIIS() ) { @ini_restore( 'log_errors' ); } @@ -2606,14 +2606,14 @@ private function runDisableErrors() { /* * Now the actual hooking into PHP's error reporting. - * + * * We enable _ALL_ errors, and make them all exceptions. * We also need to hook into the shutdown function so * we can catch fatal and compile time errors. */ private function runEnableErrors() { global $_php_error_is_ini_enabled; - + if ( $_php_error_is_ini_enabled ) { $catchSurpressedErrors = &$this->catchSurpressedErrors; $self = $this; @@ -2630,10 +2630,10 @@ private function runEnableErrors() { function( $code, $message, $file, $line, $context ) use ( $self, &$catchSurpressedErrors ) { /* * DO NOT! log the error. - * + * * Either it's thrown as an exception, and so logged by the exception handler, * or we return false, and it's logged by PHP. - * + * * Also DO NOT! throw an exception, instead report it. * This is because if an operation raises both a user AND * fatal error (such as require), then the exception is @@ -2652,7 +2652,7 @@ function( $code, $message, $file, $line, $context ) use ( $self, &$catchSurpress return false; } }, - $this->defaultErrorReportingOn + $this->defaultErrorReportingOn ); set_exception_handler( function($ex) use ( $self ) { @@ -2678,7 +2678,7 @@ function( $code, $message, $file, $line, $context ) use ( $self, &$catchSurpress * This is done for two reasons: * - functions like 'class_exists' will run the autoloader, and we shouldn't error on them * - on PHP 5.3.0, the class loader registered functions does *not* return closure objects, so we can't do anything clever. - * + * * So we watch, but don't touch. */ spl_autoload_register( function($className) use ( $self, &$classException, &$autoloaderFuns ) { @@ -2730,12 +2730,12 @@ private function displayJSInjection() { (function( window ) { if ( window.XMLHttpRequest ) { - /** + /** * A method wrapping helper function. - * + * * Wraps the method given, from the old prototype to the new * XMLHttpRequest prototype. - * + * * This only happens if the old one actually has that prototype. * If the browser doesn't support a prototype, then it doesn't * get wrapped. @@ -2778,10 +2778,10 @@ private function displayJSInjection() { /* * Certain properties will error when read, * and which ones do vary from browser to browser. - * + * * I've found both Chrome and Firefox will error * on _different_ properties. - * + * * So every read needs to be wrapped in a try/catch, * and just hope it doesn't error. */ @@ -2863,7 +2863,7 @@ private function displayJSInjection() { } var iBody = iDoc.getElementsByTagName("body")[0]; - iBody.innerHTML = response; + iBody.innerHTML = response; var iHead = iDoc.getElementsByTagName("head")[0]; // re-run the script tags @@ -2897,7 +2897,7 @@ private function displayJSInjection() { /* * Retry Handler. - * + * * Clear this, make a new (real) XMLHttpRequest, * and then re-run everything. */ @@ -2919,7 +2919,7 @@ private function displayJSInjection() { /* * The close handler. - * + * * When closed, the response is cleared, * and then the request finishes with null info. */ @@ -2950,7 +2950,7 @@ private function displayJSInjection() { /* * Placed inside a timeout, incase the document doesn't exist yet. - * + * * Can happen if the page ajax's straight away. */ setTimeout( function() { @@ -2963,7 +2963,7 @@ private function displayJSInjection() { /** * The middle man http request object. - * + * * Acts just like a normal one, but will show errors if they * occur instead of running the result. */ @@ -2978,7 +2978,7 @@ private function displayJSInjection() { /** * With a buggy XMLHttpRequest, it's possible to accidentally run the error handler * multiple times. - * + * * This is a flag to only do it once, to keep the code more defensive. */ var errorOnce = true, @@ -3012,7 +3012,7 @@ private function displayJSInjection() { /* * Success ! \o/ - * + * * Pass any state change on to the parent caller, * unless we hit an ajaxy error. */ @@ -3072,7 +3072,7 @@ private function displayJSInjection() { /* * Private fields are stored underneath the unhappy face, * to localize them. - * + * * Access becomes: * this.__.fieldName */ @@ -3148,7 +3148,7 @@ private function displayError( $message, $errLine, $errFile, $errFileType, $stac if ( isset($_SERVER['QUERY_STRING']) ) { $requestUrl = str_replace( $_SERVER['QUERY_STRING'], '', $_SERVER['REQUEST_URI'] ); $requestUrlLen = strlen( $requestUrl ); - + // remove the '?' if it's there (I suspect it isn't always, but don't take my word for it!) if ( $requestUrlLen > 0 && substr($requestUrl, $requestUrlLen-1) === '?' ) { $requestUrl = substr( $requestUrl, 0, $requestUrlLen-1 ); @@ -3201,7 +3201,7 @@ function() use ( $fileLines = $fileLinesSet->getLines(); $show = $fileLinesSet->isShown(); $highlightLine = $fileLinesSet->getLine(); - + // calculate last line number length end($fileLines); $maxLineNumber = key($fileLines); @@ -3237,7 +3237,7 @@ function() use ( ",next:"htmltag"},{token:"meta.tag",regex:">"},{token:"text",regex:"(?:media|type|href)"},{token:"string",regex:'=".*?"'},{token:"paren.lparen",regex:"{",next:"cssdeclaration"},{token:"keyword",regex:"#[A-Za-z0-9-_.]+"},{token:"variable",regex:"\\.[A-Za-z0-9-_.]+"},{token:"constant",regex:"[A-Za-z0-9]+"}],cssdeclaration:[{token:"support.type",regex:"[-a-zA-Z]+",next:"cssvalue"},{token:"paren.rparen",regex:"}",next:"css"}],cssvalue:[{token:"text",regex:":"},{token:"constant",regex:"#[0-9a-zA-Z]+"},{token:"text",regex:"[-_0-9a-zA-Z\"' ,%]+"},{token:"text",regex:";",next:"cssdeclaration"}]},this.embedRules(f,"doc-",[f.getEndRule("start")])};d.inherits(h,g),b.PhpHighlightRules=h}),ace.define("ace/mode/doc_comment_highlight_rules",["require","exports","module","ace/lib/oop","ace/mode/text_highlight_rules"],function(a,b,c){var d=a("../lib/oop"),e=a("./text_highlight_rules").TextHighlightRules,f=function(){this.$rules={start:[{token:"comment.doc.tag",regex:"@[\\w\\d_]+"},{token:"comment.doc",merge:!0,regex:"\\s+"},{token:"comment.doc",merge:!0,regex:"TODO"},{token:"comment.doc",merge:!0,regex:"[^@\\*]+"},{token:"comment.doc",merge:!0,regex:"."}]}};d.inherits(f,e),f.getStartRule=function(a){return{token:"comment.doc",merge:!0,regex:"\\/\\*(?=\\*)",next:a}},f.getEndRule=function(a){return{token:"comment.doc",merge:!0,regex:"\\*\\/",next:a}},b.DocCommentHighlightRules=f}),ace.define("ace/mode/matching_brace_outdent",["require","exports","module","ace/range"],function(a,b,c){var d=a("../range").Range,e=function(){};(function(){this.checkOutdent=function(a,b){return/^\s+$/.test(a)?/^\s*\}/.test(b):!1},this.autoOutdent=function(a,b){var c=a.getLine(b),e=c.match(/^(\s*\})/);if(!e)return 0;var f=e[1].length,g=a.findMatchingBracket({row:b,column:f});if(!g||g.row==b)return 0;var h=this.$getIndent(a.getLine(g.row));a.replace(new d(b,0,b,f-1),h)},this.$getIndent=function(a){var b=a.match(/^(\s+)/);return b?b[1]:""}}).call(e.prototype),b.MatchingBraceOutdent=e}),ace.define("ace/mode/behaviour/cstyle",["require","exports","module","ace/lib/oop","ace/mode/behaviour"],function(a,b,c){var d=a("../../lib/oop"),e=a("../behaviour").Behaviour,f=function(){this.add("braces","insertion",function(a,b,c,d,e){if(e=="{"){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);return g!==""?{text:"{"+g+"}",selection:!1}:{text:"{}",selection:[1,1]}}if(e=="}"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j=="}"){var k=d.$findOpeningBracket("}",{column:h.column+1,row:h.row});if(k!==null)return{text:"",selection:[1,1]}}}else if(e=="\n"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j=="}"){var l=d.findMatchingBracket({row:h.row,column:h.column+1});if(!l)return null;var m=this.getNextLineIndent(a,i.substring(0,i.length-1),d.getTabString()),n=this.$getIndent(d.doc.getLine(l.row));return{text:"\n"+m+"\n"+n,selection:[1,m.length,1,m.length]}}}}),this.add("braces","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=="{"){var g=d.doc.getLine(e.start.row),h=g.substring(e.end.column,e.end.column+1);if(h=="}")return e.end.column++,e}}),this.add("parens","insertion",function(a,b,c,d,e){if(e=="("){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);return g!==""?{text:"("+g+")",selection:!1}:{text:"()",selection:[1,1]}}if(e==")"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j==")"){var k=d.$findOpeningBracket(")",{column:h.column+1,row:h.row});if(k!==null)return{text:"",selection:[1,1]}}}}),this.add("parens","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=="("){var g=d.doc.getLine(e.start.row),h=g.substring(e.start.column+1,e.start.column+2);if(h==")")return e.end.column++,e}}),this.add("brackets","insertion",function(a,b,c,d,e){if(e=="["){var f=c.getSelectionRange(),g=d.doc.getTextRange(f);return g!==""?{text:"["+g+"]",selection:!1}:{text:"[]",selection:[1,1]}}if(e=="]"){var h=c.getCursorPosition(),i=d.doc.getLine(h.row),j=i.substring(h.column,h.column+1);if(j=="]"){var k=d.$findOpeningBracket("]",{column:h.column+1,row:h.row});if(k!==null)return{text:"",selection:[1,1]}}}}),this.add("brackets","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&f=="["){var g=d.doc.getLine(e.start.row),h=g.substring(e.start.column+1,e.start.column+2);if(h=="]")return e.end.column++,e}}),this.add("string_dquotes","insertion",function(a,b,c,d,e){if(e=='"'||e=="'"){var f=e,g=c.getSelectionRange(),h=d.doc.getTextRange(g);if(h!=="")return{text:f+h+f,selection:!1};var i=c.getCursorPosition(),j=d.doc.getLine(i.row),k=j.substring(i.column-1,i.column);if(k=="\\")return null;var l=d.getTokens(g.start.row),m=0,n,o=-1;for(var p=0;pg.start.column)break;m+=l[p].value.length}if(!n||o<0&&n.type!=="comment"&&(n.type!=="string"||g.start.column!==n.value.length+m-1&&n.value.lastIndexOf(f)===n.value.length-1))return{text:f+f,selection:[1,1]};if(n&&n.type==="string"){var q=j.substring(i.column,i.column+1);if(q==f)return{text:"",selection:[1,1]}}}}),this.add("string_dquotes","deletion",function(a,b,c,d,e){var f=d.doc.getTextRange(e);if(!e.isMultiLine()&&(f=='"'||f=="'")){var g=d.doc.getLine(e.start.row),h=g.substring(e.start.column+1,e.start.column+2);if(h=='"')return e.end.column++,e}})};d.inherits(f,e),b.CstyleBehaviour=f}),ace.define("ace/mode/folding/cstyle",["require","exports","module","ace/lib/oop","ace/range","ace/mode/folding/fold_mode"],function(a,b,c){var d=a("../../lib/oop"),e=a("../../range").Range,f=a("./fold_mode").FoldMode,g=b.FoldMode=function(){};d.inherits(g,f),function(){this.foldingStartMarker=/(\{|\[)[^\}\]]*$|^\s*(\/\*)/,this.foldingStopMarker=/^[^\[\{]*(\}|\])|^[\s\*]*(\*\/)/,this.getFoldWidgetRange=function(a,b,c){var d=a.getLine(c),f=d.match(this.foldingStartMarker);if(f){var g=f.index;if(f[1])return this.openingBracketBlock(a,f[1],c,g);var h=a.getCommentFoldRange(c,g+f[0].length);return h.end.column-=2,h}if(b!=="markbeginend")return;var f=d.match(this.foldingStopMarker);if(f){var g=f.index+f[0].length;if(f[2]){var h=a.getCommentFoldRange(c,g);return h.end.column-=2,h}var i={row:c,column:g},j=a.$findOpeningBracket(f[1],i);if(!j)return;return j.column++,i.column--,e.fromPoints(j,i)}}}.call(g.prototype)}),ace.define("ace/mode/folding/fold_mode",["require","exports","module","ace/range"],function(a,b,c){var d=a("../../range").Range,e=b.FoldMode=function(){};(function(){this.foldingStartMarker=null,this.foldingStopMarker=null,this.getFoldWidget=function(a,b,c){var d=a.getLine(c);return this.foldingStartMarker.test(d)?"start":b=="markbeginend"&&this.foldingStopMarker&&this.foldingStopMarker.test(d)?"end":""},this.getFoldWidgetRange=function(a,b,c){return null},this.indentationBlock=function(a,b,c){var e=/\S/,f=a.getLine(b),g=f.search(e);if(g==-1)return;var h=c||f.length,i=a.getLength(),j=b,k=b;while(++bj){var m=a.getLine(k).length;return new d(j,h,k,m)}},this.openingBracketBlock=function(a,b,c,e,f){var g={row:c,column:e+1},h=a.$findClosingBracket(b,g,f);if(!h)return;var i=a.foldWidgets[h.row];return i==null&&(i=this.getFoldWidget(a,h.row)),i=="start"&&h.row>g.row&&(h.row--,h.column=a.getLine(h.row).length),d.fromPoints(g,h)}}).call(e.prototype)}) + ace.define("ace/theme/twilight",["require","exports","module","ace/lib/dom"],function(a,b,c){b.isDark=!0,b.cssClass="ace-twilight",b.cssText=".ace-twilight .ace_editor { border: 2px solid rgb(159, 159, 159);}.ace-twilight .ace_editor.ace_focus { border: 2px solid #327fbd;}.ace-twilight .ace_gutter { background: #232323; color: #E2E2E2;}.ace-twilight .ace_print_margin { width: 1px; background: #232323;}.ace-twilight .ace_scroller { background-color: #141414;}.ace-twilight .ace_text-layer { color: #F8F8F8;}.ace-twilight .ace_cursor { border-left: 2px solid #A7A7A7;}.ace-twilight .ace_cursor.ace_overwrite { border-left: 0px; border-bottom: 1px solid #A7A7A7;}.ace-twilight .ace_marker-layer .ace_selection { background: rgba(221, 240, 255, 0.20);}.ace-twilight.multiselect .ace_selection.start { box-shadow: 0 0 3px 0px #141414; border-radius: 2px;}.ace-twilight .ace_marker-layer .ace_step { background: rgb(102, 82, 0);}.ace-twilight .ace_marker-layer .ace_bracket { margin: -1px 0 0 -1px; border: 1px solid rgba(255, 255, 255, 0.25);}.ace-twilight .ace_marker-layer .ace_active_line { background: rgba(255, 255, 255, 0.031);}.ace-twilight .ace_gutter_active_line { background-color: rgba(255, 255, 255, 0.031);}.ace-twilight .ace_marker-layer .ace_selected_word { border: 1px solid rgba(221, 240, 255, 0.20);}.ace-twilight .ace_invisible { color: rgba(255, 255, 255, 0.25);}.ace-twilight .ace_keyword, .ace-twilight .ace_meta { color:#CDA869;}.ace-twilight .ace_constant, .ace-twilight .ace_constant.ace_other { color:#CF6A4C;}.ace-twilight .ace_constant.ace_character, { color:#CF6A4C;}.ace-twilight .ace_constant.ace_character.ace_escape, { color:#CF6A4C;}.ace-twilight .ace_invalid.ace_illegal { color:#F8F8F8;background-color:rgba(86, 45, 86, 0.75);}.ace-twilight .ace_invalid.ace_deprecated { text-decoration:underline;font-style:italic;color:#D2A8A1;}.ace-twilight .ace_support { color:#9B859D;}.ace-twilight .ace_support.ace_constant { color:#CF6A4C;}.ace-twilight .ace_fold { background-color: #AC885B; border-color: #F8F8F8;}.ace-twilight .ace_support.ace_function { color:#DAD085;}.ace-twilight .ace_storage { color:#F9EE98;}.ace-twilight .ace_variable { color:#AC885B;}.ace-twilight .ace_string { color:#8F9D6A;}.ace-twilight .ace_string.ace_regexp { color:#E9C062;}.ace-twilight .ace_comment { font-style:italic;color:#5F5A60;}.ace-twilight .ace_variable { color:#7587A6;}.ace-twilight .ace_xml_pe { color:#494949;}.ace-twilight .ace_meta.ace_tag { color:#AC885B;}.ace-twilight .ace_entity.ace_name.ace_function { color:#AC885B;}.ace-twilight .ace_markup.ace_underline { text-decoration:underline;}.ace-twilight .ace_markup.ace_heading { color:#CF6A4C;}.ace-twilight .ace_markup.ace_list { color:#F9EE98;}.ace-twilight .ace_indent-guide { background: url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAACCAYAAACZgbYnAAAAEklEQVQImWMQERH5zzBz5sz/AA5EBAYqeZXWAAAAAElFTkSuQmCC) right repeat-y;}";var d=a("../lib/dom");d.importCssString(b.cssText,b.cssClass)}) + Date: Sun, 24 Mar 2013 00:49:01 +0000 Subject: [PATCH 17/24] #68 changed display_line_numbers behaviour * display_line_numbers now works again, turning line numbers on or off. * It has been changed from defaulting to 'false', to 'true'. --- src/php_error.php | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/php_error.php b/src/php_error.php index 3f66a83..76604f9 100644 --- a/src/php_error.php +++ b/src/php_error.php @@ -1279,7 +1279,7 @@ public function __construct( $options=null ) { $this->backgroundText = ErrorHandler::optionsPop( $options, 'background_text' , '' ); $this->numLines = ErrorHandler::optionsPop( $options, 'snippet_num_lines' , ErrorHandler::NUM_FILE_LINES ); - $this->displayLineNumber = ErrorHandler::optionsPop( $options, 'display_line_numbers' , false ); + $this->displayLineNumber = ErrorHandler::optionsPop( $options, 'display_line_numbers' , true ); $this->htmlOnly = !! ErrorHandler::optionsPop( $options, 'html_only', true ); @@ -3279,7 +3279,7 @@ function() use (
$fileLinesSet ) { $id = $fileLinesSet->getHTMLID(); @@ -3552,6 +3552,9 @@ function displayHTML( Closure $head, $body=null, $javascript=null ) { .background { line-height: 18px; } + #error-editor.no-line-nums .ace_gutter { + display: none; + } h1, h2 { From 197b7e496b4859772ad4763b424c5c36b87520bb Mon Sep 17 00:00:00 2001 From: Joseph Lenton Date: Sun, 24 Mar 2013 00:59:57 +0000 Subject: [PATCH 18/24] made the warning in the Readme.md file more prominent The latest changes makes PHP Error even less unsafe in production, so I made the warning more prominent. --- Readme.md | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/Readme.md b/Readme.md index ce8e3e9..3b67717 100644 --- a/Readme.md +++ b/Readme.md @@ -17,6 +17,20 @@ This requires no changes to your JavaScript, and works with existing JS librarie Check out the [project homepage](http://phperror.net) for a live demo. +Do not use on a live site! +-------------------------- + +To help make development easier, this __deliberately__ makes your code unsafe. +External requests are allowed to change your code, it shows more about your site, +gives you more info, and makes trivial errors fatal. +All of that is awesome if you want to fix bugs in less time, +but in production, it is totally unsafe. + +**seriously, only use this for development!** + +In case you forget, +you can disable this in production using the 'php_error.force_disabled' php.ini option (see below). + Features -------- * trivial to use, it's just one file @@ -55,16 +69,6 @@ Documentation ### [php.ini settings](https://github.com/JosephLenton/PHP-Error/wiki/php.ini) -Do not use on a live site! --------------------------- - -This is intended for __development only__. It shows more about your site, gives you more info, and makes trivial errors fatal. -All of that is awesome if you want to debug quicker, and force high quality standards. - -On a production server, that sucks, and is potentially unsafe. - -In case you forget, you can disable this in production using the 'php_error.force_disabled' php.ini option (see below). - Advanced Features ----------------- From 8c472eb82c8b2c10bd9af42c2132359580360ca2 Mon Sep 17 00:00:00 2001 From: Joseph Lenton Date: Sun, 24 Mar 2013 01:10:19 +0000 Subject: [PATCH 19/24] saving changes now also works for ajax requests too --- src/php_error.php | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/src/php_error.php b/src/php_error.php index 76604f9..a72bf88 100644 --- a/src/php_error.php +++ b/src/php_error.php @@ -2977,7 +2977,7 @@ private function displayJSInjection() { */ var retry = iDoc.getElementById('ajax-retry'); if ( retry ) { - retry.onclick = function() { + var retryFun = function() { var methodCalls = self.__.methodCalls; initializeXMLHttpRequest.call( self ); @@ -2990,6 +2990,9 @@ private function displayJSInjection() { return false; }; + retry.onclick = retryFun; + + iframe.__php_error_retry = retryFun; /* * The close handler. @@ -3428,8 +3431,25 @@ function() use ( $saveUrl ) { } } + var retryFun = null; + if ( window.top !== window ) { + var arrFrames = parent.document.getElementsByTagName("IFRAME"); + + for (var i = 0; i < arrFrames.length; i++) { + if (arrFrames[i].contentWindow === window) { + retryFun = arrFrames[i].__php_error_retry; + } + } + } + + if ( retryFun === null ) { + retryFun = function() { + document.location.reload( true ); + } + } + if ( ! hasChanges ) { - document.location.reload(true); + retryFun(); } else { $.ajax({ type: "POST", @@ -3441,7 +3461,7 @@ function() use ( $saveUrl ) { }, success: function(res, status, xhr) { - document.location.reload(true); + retryFun(); }, beforeSend: function(xhr) { From cf94bf344699f2e38b73de4ca3f0357089abe7b2 Mon Sep 17 00:00:00 2001 From: Joseph Lenton Date: Sun, 24 Mar 2013 16:49:53 +0000 Subject: [PATCH 20/24] added noscript warning for editor --- src/php_error.php | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/src/php_error.php b/src/php_error.php index a72bf88..8c7cea9 100644 --- a/src/php_error.php +++ b/src/php_error.php @@ -3282,7 +3282,14 @@ function() use (
+
+ +
+
+ $fileLinesSet ) { $id = $fileLinesSet->getHTMLID(); @@ -3898,12 +3905,20 @@ function displayHTML( Closure $head, $body=null, $javascript=null ) { #error-editor { width: 100%; - height: 450px; position: relative; margin: 0 0 36px 0; } + #error-editor { + height: 450px; + } + #noscript-editor { + width: 100%; + line-height: 400px; + font-size: 32px; + text-align: center; + } #error-editor-ace { top: 0; bottom: 0; From d11c8f8313630d96a30d3f7765050501e10c85df Mon Sep 17 00:00:00 2001 From: Joseph Lenton Date: Mon, 25 Mar 2013 05:40:02 +0000 Subject: [PATCH 21/24] removed the ErrorException, as it's included in PHP 5.3 ErrorException is included in PHP 5.3, and as PHP Error requires 5.3 due to namespaces, it makes less sense to fake the class now. --- src/php_error.php | 40 ++++++++++++++-------------------------- 1 file changed, 14 insertions(+), 26 deletions(-) diff --git a/src/php_error.php b/src/php_error.php index 8c7cea9..419c2a9 100644 --- a/src/php_error.php +++ b/src/php_error.php @@ -90,8 +90,7 @@ namespace php_error; - use \php_error\ErrorException, - \php_error\FileLinesSet, + use \php_error\FileLinesSet, \php_error\ErrorHandler, \php_error\JSMin, @@ -99,6 +98,7 @@ use \Closure, \Exception, + \ErrorException, \InvalidArgumentException; use \ReflectionMethod, @@ -2372,7 +2372,7 @@ private function logError( $message, $file, $line, $ex=null ) { * so you will get a full stack trace. */ public function reportClassNotFound( $className ) { - throw new ErrorException( "Class '$className' not found", E_ERROR, E_ERROR, __FILE__, __LINE__ ); + throw new \ErrorException( "Class '$className' not found", E_ERROR, 0, __FILE__, __LINE__ ); } /** @@ -2542,9 +2542,15 @@ private function getStackTrace( $ex, $code, $errFile, $errLine ) { $errFile = $ex->getFile(); $errLine = $ex->getLine(); - $code = method_exists($ex, 'getSeverity') ? - $ex->getSeverity() : - $ex->getCode() ; + $code = $ex->getCode(); + + if ( method_exists($ex, 'getSeverity') ) { + $severity = $ex->getSeverity(); + + if ( $code === 0 && $severity !== 0 && $severity !== null ) { + $code = $severity; + } + } } return array( $ex, $stackTrace, $code, $errFile, $errLine ); @@ -2718,7 +2724,7 @@ function( $code, $message, $file, $line, $context ) use ( $self, &$catchSurpress * When using an @, the error reporting drops to 0. */ if ( error_reporting() !== 0 || $catchSurpressedErrors ) { - $ex = new ErrorException( $message, $code, $code, $file, $line ); + $ex = new \ErrorException( $message, $code, 0, $file, $line ); $self->reportException( $ex ); } @@ -2787,7 +2793,7 @@ function( $code, $message, $file, $line, $context ) use ( $self, &$catchSurpress } if ( $error ) { - $classException = new ErrorException( "Class '$className' not found", E_ERROR, E_ERROR, __FILE__, __LINE__ ); + $classException = new \ErrorException( "Class '$className' not found", E_ERROR, 0, __FILE__, __LINE__ ); } } } ); @@ -4375,24 +4381,6 @@ function displayHTML( Closure $head, $body=null, $javascript=null ) { } } - /** - * This is a carbon copy of \ErrorException. - * However that is only supported in PHP 5.1 and above, - * so this allows PHP Error to work in PHP 5.0. - * - * A thin class that wraps up an error, into an exception. - */ - class ErrorException extends Exception - { - public function __construct( $message, $code, $severity, $file, $line ) - { - parent::__construct( $message, $code, null ); - - $this->file = $file; - $this->line = $line; - } - } - /** * Code is outputted multiple times, for each file involved. * This allows us to wrap up a single set of code. From 8046d6ce4b96b01cf02c00c19b7cf5605fd1113b Mon Sep 17 00:00:00 2001 From: Joseph Lenton Date: Mon, 25 Mar 2013 06:08:27 +0000 Subject: [PATCH 22/24] changed the default tokens, to include new ones for PHP 5.4 and 5.5 This has added tokens for the keywords: * insteadof * trait * __trait__ * yield * finally --- src/php_error.php | 43 +++++++++++++++++++++++++------------------ 1 file changed, 25 insertions(+), 18 deletions(-) diff --git a/src/php_error.php b/src/php_error.php index 419c2a9..3953ec3 100644 --- a/src/php_error.php +++ b/src/php_error.php @@ -129,23 +129,20 @@ * then any number could be used. That is why they start counting * at 100,000. */ - if ( ! defined('T_DIR') ) { - define( 'T_DIR', 100001 ); - } - if ( ! defined('T_GOTO') ) { - define( 'T_GOTO', 100002 ); - } - if ( ! defined('T_NAMESPACE') ) { - define( 'T_NAMESPACE', 100003 ); - } - if ( ! defined('T_NS_C') ) { - define( 'T_NS_C', 100004 ); - } - if ( ! defined('T_NS_SEPARATOR') ) { - define( 'T_NS_SEPARATOR', 100005 ); - } - if ( ! defined('T_USE') ) { - define( 'T_USE', 100006 ); + + $missingIdentifier = array( + 'T_INSTEADOF', + 'T_TRAIT', + 'T_TRAIT_C', + 'T_YIELD', + 'T_FINALLY' + ); + + $counter = 100001; + foreach ( $missingIdentifier as $id ) { + if ( ! defined($id) ) { + define( $id, $counter++ ); + } } /* @@ -347,6 +344,7 @@ class ErrorHandler 'T_EXTENDS' => 'extends', 'T_FILE' => '__FILE__', 'T_FINAL' => 'final', + 'T_FINALLY' => 'finally', 'T_FOR' => 'for', 'T_FOREACH' => 'foreach', 'T_FUNCTION' => 'function', @@ -360,6 +358,7 @@ class ErrorHandler 'T_INCLUDE' => 'include', 'T_INCLUDE_ONCE' => 'include_once', 'T_INSTANCEOF' => 'instanceof', + 'T_INSTEADOF' => 'insteadof', 'T_INT_CAST' => 'int cast', 'T_INTERFACE' => 'interface', 'T_ISSET' => 'isset', @@ -410,6 +409,8 @@ class ErrorHandler 'T_SWITCH' => 'switch', 'T_THROW' => 'throw', 'T_TRY' => 'try', + 'T_TRAIT' => 'trait', + 'T_TRAIT_C' => '__trait__', 'T_UNSET' => 'unset', 'T_UNSET_CAST' => 'unset cast', 'T_USE' => 'use', @@ -417,7 +418,8 @@ class ErrorHandler 'T_VARIABLE' => 'variable', 'T_WHILE' => 'while', 'T_WHITESPACE' => 'whitespace', - 'T_XOR_EQUAL' => "'^='" + 'T_XOR_EQUAL' => "'^='", + 'T_YIELD' => 'yield' ); private static $syntaxMap = array( @@ -452,6 +454,7 @@ class ErrorHandler T_EXTENDS => 'syntax-keyword', T_FINAL => 'syntax-keyword', + T_FINALLY => 'syntax-keyword', T_FOR => 'syntax-keyword', T_FOREACH => 'syntax-keyword', T_FUNCTION => 'syntax-keyword', @@ -461,6 +464,7 @@ class ErrorHandler T_IF => 'syntax-keyword', T_IMPLEMENTS => 'syntax-keyword', T_INSTANCEOF => 'syntax-keyword', + T_INSTEADOF => 'syntax-keyword', T_INTERFACE => 'syntax-keyword', T_LOGICAL_AND => 'syntax-keyword', @@ -475,10 +479,12 @@ class ErrorHandler T_STATIC => 'syntax-keyword', T_SWITCH => 'syntax-keyword', T_THROW => 'syntax-keyword', + T_TRAIT => 'syntax-keyword', T_TRY => 'syntax-keyword', T_USE => 'syntax-keyword', T_VAR => 'syntax-keyword', T_WHILE => 'syntax-keyword', + T_YIELD => 'syntax-keyword', // __VAR__ type magic constants T_CLASS_C => 'syntax-literal', @@ -488,6 +494,7 @@ class ErrorHandler T_LINE => 'syntax-literal', T_METHOD_C => 'syntax-literal', T_NS_C => 'syntax-literal', + T_TRAIT_C => 'syntax-literal', T_DNUMBER => 'syntax-literal', T_LNUMBER => 'syntax-literal', From 9918dd5eeec527846d43c92a4c9880bfcdd0de14 Mon Sep 17 00:00:00 2001 From: Joseph Lenton Date: Mon, 5 Aug 2013 20:13:00 +0100 Subject: [PATCH 23/24] fixed issue with slashes not being escaped, when replacement code is uploaded --- src/php_error.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/php_error.php b/src/php_error.php index 3953ec3..1796913 100644 --- a/src/php_error.php +++ b/src/php_error.php @@ -1370,7 +1370,7 @@ public function turnOn() { $files = $_POST[ErrorHandler::POST_FILE_LOCATION]; foreach ( $files as $file => $content ) { - @file_put_contents($file, $content); + @file_put_contents( $file, stripcslashes($content) ); } exit(0); From 08d5aacda02352ca72198e3f5161d83338e26389 Mon Sep 17 00:00:00 2001 From: JosephLenton Date: Tue, 11 Dec 2018 01:19:28 +0000 Subject: [PATCH 24/24] Updates --- Readme.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Readme.md b/Readme.md index 3b67717..b874b71 100644 --- a/Readme.md +++ b/Readme.md @@ -1,6 +1,8 @@ PHP Error | Improve Error Reporting for PHP =========================================== +**THIS IS NO LOBGER MAINTAINED, Please leave me alone.** + PHP errors are not good enough for development, it's as simple as that. This aims to solve this. ![Better Error Message](http://i.imgur.com/1G77I.png) @@ -15,8 +17,6 @@ If the server errors during an ajax request, then the request is paused, and the This requires no changes to your JavaScript, and works with existing JS libraries such as jQuery. -Check out the [project homepage](http://phperror.net) for a live demo. - Do not use on a live site! -------------------------- @@ -46,7 +46,7 @@ Features Getting Started --------------- - * [Download](http://phperror.net/download/php_error.php), it's just one file. + * Download, it's just one file. * Place it in your project. * import php_error.php * call \php_error\reportErrors()