Changeset View
Changeset View
Standalone View
Standalone View
src/moduleutils/PhutilBootloader.php
| Show First 20 Lines • Show All 209 Lines • ▼ Show 20 Lines | final class PhutilBootloader { | ||||
| public function loadLibrarySource($library, $source) { | public function loadLibrarySource($library, $source) { | ||||
| $path = $this->getLibraryRoot($library).'/'.$source; | $path = $this->getLibraryRoot($library).'/'.$source; | ||||
| $this->executeInclude($path); | $this->executeInclude($path); | ||||
| } | } | ||||
| private function executeInclude($path) { | private function executeInclude($path) { | ||||
| // Include the source using `include_once`, but convert any warnings or | // Include the source using `include_once`, but convert any warnings or | ||||
| // errors into exceptions. | // recoverable errors into exceptions. | ||||
| // Some messages, including "Declaration of X should be compatible with Y", | // Some messages, including "Declaration of X should be compatible with Y", | ||||
| // do not cause `include_once` to return an error code. Use | // do not cause `include_once` to return an error code. Use | ||||
| // error_get_last() to make sure we're catching everything in every PHP | // error_get_last() to make sure we're catching everything in every PHP | ||||
| // version. | // version. | ||||
| // (Also, the severity of some messages changed between versions of PHP.) | // (Also, the severity of some messages changed between versions of PHP.) | ||||
| // Note that we may enter this method after some earlier, unrelated error. | // Note that we may enter this method after some earlier, unrelated error. | ||||
| // In this case, error_get_last() will return information for that error. | // In this case, error_get_last() will return information for that error. | ||||
| // In PHP7 and later we could use error_clear_last() to clear that error, | // In PHP7 and later we could use error_clear_last() to clear that error, | ||||
| // but the function does not exist in earlier versions of PHP. Instead, | // but the function does not exist in earlier versions of PHP. Instead, | ||||
| // check if the value has changed. | // check if the value has changed. | ||||
| // Some parser-like errors, including "class must implement all abstract | |||||
| // methods", cause PHP to fatal immediately with an E_ERROR. In these | |||||
amckinley: "immediately" | |||||
| // cases, include_once() does not throw and never returns. We leave | |||||
| // reporting enabled for these errors since we don't have a way to do | |||||
| // anything more graceful. | |||||
| // See also T12190. | // See also T12190. | ||||
| $old_last = error_get_last(); | $old_last = error_get_last(); | ||||
| try { | try { | ||||
| $old = error_reporting(0); | $old = error_reporting(E_ERROR); | ||||
| $okay = include_once $path; | $okay = include_once $path; | ||||
| error_reporting($old); | error_reporting($old); | ||||
| } catch (Exception $ex) { | } catch (Exception $ex) { | ||||
| throw $ex; | throw $ex; | ||||
| } catch (ParseError $throwable) { | } catch (ParseError $throwable) { | ||||
| // NOTE: As of PHP7, syntax errors may raise a ParseError (which is a | // NOTE: As of PHP7, syntax errors may raise a ParseError (which is a | ||||
| // Throwable, not an Exception) with a useless message (like "syntax | // Throwable, not an Exception) with a useless message (like "syntax | ||||
| // error, unexpected ':'") and a trace which ends a level above this. | // error, unexpected ':'") and a trace which ends a level above this. | ||||
| ▲ Show 20 Lines • Show All 82 Lines • Show Last 20 Lines | |||||
"immediately"