diff --git a/src/Hprose/Future/CallableWrapper.php b/src/Hprose/Future/CallableWrapper.php index 0fcfa48c..579d2839 100644 --- a/src/Hprose/Future/CallableWrapper.php +++ b/src/Hprose/Future/CallableWrapper.php @@ -25,7 +25,7 @@ class CallableWrapper extends Wrapper { public function __invoke() { $obj = $this->obj; return all(func_get_args())->then(function($args) use ($obj) { - if (class_exists("\\Generator")) { + if (HaveGenerator) { return co(call_user_func_array($obj, $args)); } return call_user_func_array($obj, $args); diff --git a/src/Hprose/Future/Wrapper.php b/src/Hprose/Future/Wrapper.php index 51059d24..659364ea 100644 --- a/src/Hprose/Future/Wrapper.php +++ b/src/Hprose/Future/Wrapper.php @@ -21,8 +21,6 @@ namespace Hprose\Future; -use ReflectionMethod; - class Wrapper { protected $obj; public function __construct($obj) { @@ -31,7 +29,7 @@ public function __construct($obj) { public function __call($name, array $arguments) { $method = array($this->obj, $name); return all($arguments)->then(function($args) use ($method, $name) { - if (class_exists("\\Generator")) { + if (HaveGenerator) { return co(call_user_func_array($method, $args)); } return call_user_func_array($method, $args); diff --git a/src/Hprose/HandlerManager.php b/src/Hprose/HandlerManager.php index bc27be82..77e78107 100644 --- a/src/Hprose/HandlerManager.php +++ b/src/Hprose/HandlerManager.php @@ -39,7 +39,7 @@ public function __construct() { $this->defaultInvokeHandler = function(/*string*/ $name, array &$args, stdClass $context) use ($self) { try { $result = $self->invokeHandler($name, $args, $context); - if (class_exists("\\Generator")) { + if (HaveGenerator) { return Future\co($result); } else { @@ -56,7 +56,7 @@ public function __construct() { $this->defaultBeforeFilterHandler = function(/*string*/ $request, stdClass $context) use ($self) { try { $result = $self->beforeFilterHandler($request, $context); - if (class_exists("\\Generator")) { + if (HaveGenerator) { return Future\co($result); } else { @@ -73,7 +73,7 @@ public function __construct() { $this->defaultAfterFilterHandler = function(/*string*/ $request, stdClass $context) use ($self) { try { $result = $self->afterFilterHandler($request, $context); - if (class_exists("\\Generator")) { + if (HaveGenerator) { return Future\co($result); } else { @@ -114,7 +114,7 @@ protected function getNextInvokeHandler(Closure $next, /*callable*/ $handler) { try { $array = array($name, &$args, $context, $next); $result = call_user_func_array($handler, $array); - if (class_exists("\\Generator")) { + if (HaveGenerator) { return Future\co($result); } else { @@ -133,7 +133,7 @@ protected function getNextFilterHandler(Closure $next, /*callable*/ $handler) { return function(/*string*/ $request, stdClass $context) use ($next, $handler) { try { $result = call_user_func($handler, $request, $context, $next); - if (class_exists("\\Generator")) { + if (HaveGenerator) { return Future\co($result); } else { @@ -149,7 +149,7 @@ protected function getNextFilterHandler(Closure $next, /*callable*/ $handler) { }; } public function addInvokeHandler(/*callable*/ $handler) { - if ($handler == null) return; + if ($handler == null) return null; $this->invokeHandlers[] = $handler; $next = $this->defaultInvokeHandler; for ($i = count($this->invokeHandlers) - 1; $i >= 0; --$i) { @@ -169,7 +169,7 @@ public function addBeforeFilterHandler(/*callable*/ $handler) { return $this; } public function addAfterFilterHandler(/*callable*/ $handler) { - if ($handler == null) return; + if ($handler == null) return null; $this->afterFilterHandlers[] = $handler; $next = $this->defaultAfterFilterHandler; for ($i = count($this->afterFilterHandlers) - 1; $i >= 0; --$i) { diff --git a/src/Hprose/Http/Service.php b/src/Hprose/Http/Service.php index 587cb452..55dc8df9 100644 --- a/src/Hprose/Http/Service.php +++ b/src/Hprose/Http/Service.php @@ -137,7 +137,10 @@ public function handle($request = null, $response = null) { } } elseif ($this->isPost($context)) { + ob_start(); + ob_implicit_flush(0); $result = $this->defaultHandle($this->readRequest($context), $context); + @ob_end_clean(); } else { $result = $this->doFunctionList(); diff --git a/src/Hprose/Service.php b/src/Hprose/Service.php index a9ce52d9..198a6a69 100644 --- a/src/Hprose/Service.php +++ b/src/Hprose/Service.php @@ -67,12 +67,42 @@ abstract class Service extends HandlerManager { public $onUnsubscribe = null; private $topics = array(); private $nextid = 0; + + /** + * Last ErrorException + * + * @var null|ErrorException + */ + public static $lastError = null; + + /** + * trace error + * + * @var bool + */ + protected static $trackError = false; + + /** + * @var null|callable + */ + protected static $_lastErrorHandler = null; + public function __construct() { parent::__construct(); $this->errorTypes = error_reporting(); register_shutdown_function(array($this, 'fatalErrorHandler')); $this->addMethod('getNextId', $this, '#', array('simple' => true)); + self::$_lastErrorHandler = set_error_handler(array($this, 'errorHandler'), $this->errorTypes); + } + + public function errorHandler($errno, $errstr, $errfile, $errline) { + if (self::$trackError) { + self::$lastError = new ErrorException($errstr, 0, $errno, $errfile, $errline); + } else if (self::$_lastErrorHandler){ + call_user_func(self::$_lastErrorHandler, $errno, $errstr, $errfile, $errline); + } } + public function getNextId() { if (function_exists('com_create_guid')) { return trim(com_create_guid(), '{}'); @@ -544,24 +574,20 @@ protected function delay($milliseconds, $data) { } } public function defaultHandle($request, stdClass $context) { - $error = null; - set_error_handler(function($errno, $errstr, $errfile, $errline) use (&$error) { - $error = new ErrorException($errstr, 0, $errno, $errfile, $errline); - }, $this->errorTypes); - ob_start(); - ob_implicit_flush(0); - $context->clients = $this; - $context->methods = $this->calls; + self::$trackError = true; + self::$lastError = null; + $context->clients = $this; + $context->methods = $this->calls; $beforeFilterHandler = $this->beforeFilterHandler; - $response = $beforeFilterHandler($request, $context); - $self = $this; - return $response->then(function($result) use ($self, &$error, $context) { - @ob_end_clean(); - restore_error_handler(); - if ($error === null) { + $response = $beforeFilterHandler($request, $context); + $self = $this; + + return $response->then(function($result) use ($self, $context) { + Service::$trackError = false; + if (Service::$lastError === null) { return $result; } - return $self->endError($error, $context); + return $self->endError(Service::$lastError, $context); }); } private static function getDeclaredOnlyMethods($class) { @@ -629,7 +655,7 @@ public function addFunction($func, $alias = '', array $options = array()) { if (!array_key_exists($name, $this->calls)) { $this->names[] = $alias; } - if (class_exists("\\Generator")) { + if (HaveGenerator) { if (is_array($func)) { $f = new ReflectionMethod($func[0], $func[1]); } diff --git a/src/Hprose/functions.php b/src/Hprose/functions.php index bbd7f49d..0e546450 100644 --- a/src/Hprose/functions.php +++ b/src/Hprose/functions.php @@ -24,3 +24,5 @@ function deferred() { return new Deferred(); } + +define('HaveGenerator', class_exists("\\Generator", false)); \ No newline at end of file diff --git a/src/init.php b/src/init.php index c43265c7..82106586 100644 --- a/src/init.php +++ b/src/init.php @@ -2,9 +2,9 @@ require_once __DIR__ . '/Throwable.php'; require_once __DIR__ . '/TypeError.php'; +require_once __DIR__ . '/Hprose/functions.php'; require_once __DIR__ . '/Hprose/Future/functions.php'; require_once __DIR__ . '/Hprose/Promise/functions.php'; -require_once __DIR__ . '/Hprose/functions.php'; require_once __DIR__ . '/functions.php'; // Deprecated