Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

[ZF3] Callback handler for PHP 5.4 #5229

Open
wants to merge 4 commits into from

3 participants

Michaël Gallego Marco Pivetta Matthew Weier O'Phinney
Michaël Gallego

As ZF3 will be PHP 5.4 only, we can optimize this class quite heavily.

All tests pass (of course Travis fails because of PHP 5.3).

library/Zend/Stdlib/CallbackHandler.php
((43 lines not shown))
*/
- public function __construct($callback, array $metadata = array())
+ public function __construct(Callable $callback, array $metadata = array())
Marco Pivetta Collaborator
Ocramius added a note

callable is an internal type, not a class: should be lowercase

Michaël Gallego
bakura10 added a note

I think both work no? We were using "Closure" for type hint in ZF2 aren't' we?

Marco Pivetta Collaborator
Ocramius added a note

Closure is a class

Michaël Gallego
bakura10 added a note

Ok. I'll change that asap.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Michaël Gallego bakura10 referenced this pull request
Open

[ZF3] Clean Stdlib #5230

Matthew Weier O'Phinney weierophinney added this to the 3.0.0 milestone
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Oct 5, 2013
  1. Michaël Gallego

    Update tests

    bakura10 authored
  2. Michaël Gallego

    Remove useless imports

    bakura10 authored
  3. Michaël Gallego

    DOC update

    bakura10 authored
  4. Michaël Gallego

    Lowercase callable

    bakura10 authored
This page is out of date. Refresh to see the latest.
126 library/Zend/Stdlib/CallbackHandler.php
View
@@ -9,58 +9,39 @@
namespace Zend\Stdlib;
-use Closure;
-use ReflectionClass;
-
/**
* CallbackHandler
*
- * A handler for a event, event, filterchain, etc. Abstracts PHP callbacks,
+ * A handler for a event, event, filter chain, etc. Abstracts PHP callbacks,
* primarily to allow for lazy-loading and ensuring availability of default
* arguments (currying).
*/
class CallbackHandler
{
/**
- * @var string|array|callable PHP callback to invoke
+ * @var callable PHP callback to invoke
*/
protected $callback;
/**
* Callback metadata, if any
+ *
* @var array
*/
protected $metadata;
/**
- * PHP version is greater as 5.4rc1?
- * @var bool
- */
- protected static $isPhp54;
-
- /**
* Constructor
*
- * @param string|array|object|callable $callback PHP callback
- * @param array $metadata Callback metadata
+ * @param callable $callback PHP callback
+ * @param array $metadata Callback metadata
*/
- public function __construct($callback, array $metadata = array())
+ public function __construct(callable $callback, array $metadata = array())
{
- $this->metadata = $metadata;
- $this->registerCallback($callback);
- }
+ $this->metadata = $metadata;
- /**
- * Registers the callback provided in the constructor
- *
- * @param callable $callback
- * @throws Exception\InvalidCallbackException
- * @return void
- */
- protected function registerCallback($callback)
- {
- if (!is_callable($callback)) {
- throw new Exception\InvalidCallbackException('Invalid callback provided; not callable');
+ if (is_string($callback) && strpos($callback, '::') !== false) {
+ $callback = explode('::', $callback, 2);
}
$this->callback = $callback;
@@ -85,53 +66,26 @@ public function getCallback()
public function call(array $args = array())
{
$callback = $this->getCallback();
-
- // Minor performance tweak, if the callback gets called more than once
- if (!isset(static::$isPhp54)) {
- static::$isPhp54 = version_compare(PHP_VERSION, '5.4.0rc1', '>=');
- }
-
$argCount = count($args);
- if (static::$isPhp54 && is_string($callback)) {
- $result = $this->validateStringCallbackFor54($callback);
-
- if ($result !== true && $argCount <= 3) {
- $callback = $result;
- // Minor performance tweak, if the callback gets called more
- // than once
- $this->callback = $result;
- }
- }
-
// Minor performance tweak; use call_user_func() until > 3 arguments
// reached
switch ($argCount) {
case 0:
- if (static::$isPhp54) {
- return $callback();
- }
- return call_user_func($callback);
+ return $callback();
case 1:
- if (static::$isPhp54) {
- return $callback(array_shift($args));
- }
- return call_user_func($callback, array_shift($args));
+ return $callback(array_shift($args));
case 2:
$arg1 = array_shift($args);
$arg2 = array_shift($args);
- if (static::$isPhp54) {
- return $callback($arg1, $arg2);
- }
- return call_user_func($callback, $arg1, $arg2);
+
+ return $callback($arg1, $arg2);
case 3:
$arg1 = array_shift($args);
$arg2 = array_shift($args);
$arg3 = array_shift($args);
- if (static::$isPhp54) {
- return $callback($arg1, $arg2, $arg3);
- }
- return call_user_func($callback, $arg1, $arg2, $arg3);
+
+ return $callback($arg1, $arg2, $arg3);
default:
return call_user_func_array($callback, $args);
}
@@ -165,54 +119,6 @@ public function getMetadata()
*/
public function getMetadatum($name)
{
- if (array_key_exists($name, $this->metadata)) {
- return $this->metadata[$name];
- }
- return null;
- }
-
- /**
- * Validate a static method call
- *
- * Validates that a static method call in PHP 5.4 will actually work
- *
- * @param string $callback
- * @return true|array
- * @throws Exception\InvalidCallbackException if invalid
- */
- protected function validateStringCallbackFor54($callback)
- {
- if (!strstr($callback, '::')) {
- return true;
- }
-
- list($class, $method) = explode('::', $callback, 2);
-
- if (!class_exists($class)) {
- throw new Exception\InvalidCallbackException(sprintf(
- 'Static method call "%s" refers to a class that does not exist',
- $callback
- ));
- }
-
- $r = new ReflectionClass($class);
- if (!$r->hasMethod($method)) {
- throw new Exception\InvalidCallbackException(sprintf(
- 'Static method call "%s" refers to a method that does not exist',
- $callback
- ));
- }
- $m = $r->getMethod($method);
- if (!$m->isStatic()) {
- throw new Exception\InvalidCallbackException(sprintf(
- 'Static method call "%s" refers to a method that is not static',
- $callback
- ));
- }
-
- // returning a non boolean value may not be nice for a validate method,
- // but that allows the usage of a static string callback without using
- // the call_user_func function.
- return array($class, $method);
+ return isset($this->metadata[$name]) ? $this->metadata[$name] : null;
}
}
38 tests/ZendTest/Stdlib/CallbackHandlerTest.php
View
@@ -56,7 +56,7 @@ public function testCallShouldInvokeCallbackWithSuppliedArguments()
public function testPassingInvalidCallbackShouldRaiseInvalidCallbackExceptionDuringInstantiation()
{
- $this->setExpectedException('Zend\Stdlib\Exception\InvalidCallbackException');
+ $this->setExpectedException('Exception');
$handler = new CallbackHandler('boguscallback');
}
@@ -72,53 +72,39 @@ public function testCallShouldReturnTheReturnValueOfTheCallback()
public function testStringCallbackResolvingToClassDefiningInvokeNameShouldRaiseException()
{
- $this->setExpectedException('Zend\Stdlib\Exception\InvalidCallbackException');
+ $this->setExpectedException('Exception');
$handler = new CallbackHandler('ZendTest\\Stdlib\\SignalHandlers\\Invokable');
}
public function testStringCallbackReferringToClassWithoutDefinedInvokeShouldRaiseException()
{
- $this->setExpectedException('Zend\Stdlib\Exception\InvalidCallbackException');
+ $this->setExpectedException('Exception');
$class = new SignalHandlers\InstanceMethod();
$handler = new CallbackHandler($class);
}
public function testCallbackConsistingOfStringContextWithNonStaticMethodShouldNotRaiseExceptionButWillRaiseEStrict()
{
- $handler = new CallbackHandler(array('ZendTest\\Stdlib\\SignalHandlers\\InstanceMethod', 'handler'));
$error = false;
set_error_handler(function ($errno, $errstr) use (&$error) {
$error = true;
}, E_STRICT);
- $handler->call();
+
+ $handler = new CallbackHandler(array('ZendTest\\Stdlib\\SignalHandlers\\InstanceMethod', 'handler'));
+
restore_error_handler();
+
$this->assertTrue($error);
}
public function testStringCallbackConsistingOfNonStaticMethodShouldRaiseException()
{
+ $this->setExpectedException('Exception');
$handler = new CallbackHandler('ZendTest\\Stdlib\\SignalHandlers\\InstanceMethod::handler');
-
- if (version_compare(PHP_VERSION, '5.4.0rc1', '>=')) {
- $this->setExpectedException('Zend\Stdlib\Exception\InvalidCallbackException');
- $handler->call();
- } else {
- $error = false;
- set_error_handler(function ($errno, $errstr) use (&$error) {
- $error = true;
- }, E_STRICT);
- $handler->call();
- restore_error_handler();
- $this->assertTrue($error);
- }
}
public function testStringStaticCallbackForPhp54()
{
- if (version_compare(PHP_VERSION, '5.4.0rc1', '<=')) {
- $this->markTestSkipped('Requires PHP 5.4');
- }
-
$handler = new CallbackHandler('ZendTest\\Stdlib\\SignalHandlers\\InstanceMethod::staticHandler');
$error = false;
set_error_handler(function ($errno, $errstr) use (&$error) {
@@ -132,10 +118,6 @@ public function testStringStaticCallbackForPhp54()
public function testStringStaticCallbackForPhp54WithMoreThan3Args()
{
- if (version_compare(PHP_VERSION, '5.4.0rc1', '<=')) {
- $this->markTestSkipped('Requires PHP 5.4');
- }
-
$handler = new CallbackHandler('ZendTest\\Stdlib\\SignalHandlers\\InstanceMethod::staticHandler');
$error = false;
set_error_handler(function ($errno, $errstr) use (&$error) {
@@ -147,9 +129,9 @@ public function testStringStaticCallbackForPhp54WithMoreThan3Args()
$this->assertSame('staticHandler', $result);
}
- public function testCallbackToClassImplementingOverloadingButNotInvocableShouldRaiseException()
+ public function testCallbackToClassImplementingOverloadingButNotInvokableShouldRaiseException()
{
- $this->setExpectedException('Zend\Stdlib\Exception\InvalidCallbackException');
+ $this->setExpectedException('Exception');
$handler = new CallbackHandler('foo', array( 'ZendTest\\Stdlib\\SignalHandlers\\Overloadable', 'foo' ));
}
Something went wrong with that request. Please try again.