Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

[ZF3] Callback handler for PHP 5.4 #5229

Open
wants to merge 4 commits into from

3 participants

@bakura10

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())
@Ocramius Collaborator
Ocramius added a note

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

@bakura10
bakura10 added a note

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

@Ocramius Collaborator
Ocramius added a note

Closure is a class

@bakura10
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
@bakura10 bakura10 referenced this pull request
Open

[ZF3] Clean Stdlib #5230

@weierophinney 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. @bakura10

    Update tests

    bakura10 authored
  2. @bakura10

    Remove useless imports

    bakura10 authored
  3. @bakura10

    DOC update

    bakura10 authored
  4. @bakura10

    Lowercase callable

    bakura10 authored
This page is out of date. Refresh to see the latest.
View
126 library/Zend/Stdlib/CallbackHandler.php
@@ -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;
}
}
View
38 tests/ZendTest/Stdlib/CallbackHandlerTest.php
@@ -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.