[TASK] Remove usages of call_user_func() and call_user_func_array()
authorLarry Garfield <larry@garfieldtech.com>
Tue, 4 May 2021 17:03:19 +0000 (12:03 -0500)
committerBenni Mack <benni@typo3.org>
Fri, 7 May 2021 20:14:08 +0000 (22:14 +0200)
Using direct calls and variadics is slightly faster, and usually cleaner to read.

I left in the instant-call call_user_func() instances in the entry point files, as
that's only a single call and is arguably at least no worse than (function() {})().

Resolves: #94060
Releases: master
Change-Id: I95988feadf8522d8d936a273608e0ef2d5ce75b5
Reviewed-on: https://review.typo3.org/c/Packages/TYPO3.CMS/+/69017
Tested-by: Benjamin Franzke <bfr@qbus.de>
Tested-by: core-ci <typo3@b13.com>
Tested-by: Benni Mack <benni@typo3.org>
Reviewed-by: Benjamin Franzke <bfr@qbus.de>
Reviewed-by: crell <larry@garfieldtech.com>
Reviewed-by: Benni Mack <benni@typo3.org>
29 files changed:
typo3/sysext/backend/Classes/Http/RouteDispatcher.php
typo3/sysext/backend/Classes/Tree/Repository/PageTreeRepository.php
typo3/sysext/core/Classes/Configuration/FlexForm/FlexFormTools.php
typo3/sysext/core/Classes/Console/CommandApplication.php
typo3/sysext/core/Classes/DataHandling/DataHandler.php
typo3/sysext/core/Classes/DataHandling/SlugHelper.php
typo3/sysext/core/Classes/Database/RelationHandler.php
typo3/sysext/core/Classes/Http/AbstractApplication.php
typo3/sysext/core/Classes/Http/Dispatcher.php
typo3/sysext/core/Classes/Resource/Driver/LocalDriver.php
typo3/sysext/core/Classes/Resource/Filter/FileExtensionFilter.php
typo3/sysext/core/Classes/Resource/Filter/FileNameFilter.php
typo3/sysext/core/Classes/Resource/Search/Result/DriverFilteredSearchResult.php
typo3/sysext/core/Classes/Utility/ArrayUtility.php
typo3/sysext/core/Classes/Utility/GeneralUtility.php
typo3/sysext/core/Tests/Functional/Error/ErrorHandlerTest.php
typo3/sysext/core/Tests/Functional/IO/PharStreamWrapperInterceptorTest.php
typo3/sysext/core/Tests/Unit/FormProtection/FormProtectionFactoryTest.php
typo3/sysext/core/Tests/Unit/Log/LoggerTest.php
typo3/sysext/core/Tests/Unit/Resource/FileTest.php
typo3/sysext/extbase/Classes/Mvc/Controller/ActionController.php
typo3/sysext/extbase/Classes/Persistence/Generic/LazyLoadingProxy.php
typo3/sysext/extbase/Classes/Property/TypeConverter/ObjectConverter.php
typo3/sysext/extbase/Classes/SignalSlot/Dispatcher.php
typo3/sysext/extbase/Tests/Unit/Property/PropertyMappingConfigurationTest.php
typo3/sysext/filelist/Classes/FileFacade.php
typo3/sysext/frontend/Classes/ContentObject/ContentObjectRenderer.php
typo3/sysext/frontend/Tests/Functional/SiteHandling/AbstractTestCase.php
typo3/sysext/recycler/Classes/Controller/RecyclerModuleController.php

index 67e95aa..a13d078 100644 (file)
@@ -60,7 +60,7 @@ class RouteDispatcher extends Dispatcher
         $targetIdentifier = $route->getOption('target');
         $target = $this->getCallableFromTarget($targetIdentifier);
         $arguments = [$request];
-        return call_user_func_array($target, $arguments);
+        return $target(...$arguments);
     }
 
     /**
index 5a08271..5fa6116 100644 (file)
@@ -155,7 +155,7 @@ class PageTreeRepository
             return;
         }
         foreach ($tree['_children'] as $k => &$childPage) {
-            if (!call_user_func_array($callback, [$childPage])) {
+            if (!$callback($childPage)) {
                 unset($tree['_children'][$k]);
                 continue;
             }
index 03fc558..ac09704 100644 (file)
@@ -882,7 +882,7 @@ class FlexFormTools
      */
     protected function executeCallBackMethod($methodName, array $parameterArray)
     {
-        return call_user_func_array([$this->callBackObj, $methodName], $parameterArray);
+        return $this->callBackObj->$methodName(...$parameterArray);
     }
 
     /***********************************
index 3a637e9..6951904 100644 (file)
@@ -110,7 +110,7 @@ class CommandApplication implements ApplicationInterface
         $exitCode = $this->application->run($input, $output);
 
         if ($execute !== null) {
-            call_user_func($execute);
+            $execute();
         }
 
         exit($exitCode);
index 49a0126..c7d7101 100644 (file)
@@ -6182,7 +6182,7 @@ class DataHandler implements LoggerAwareInterface
                 if (!empty($remapAction['func'])) {
                     $callable = [$this, $remapAction['func']];
                     if (is_callable($callable)) {
-                        $newValue = call_user_func_array($callable, $remapAction['args']);
+                        $newValue = $callable(...$remapAction['args']);
                     }
                 }
                 // If array is returned, check for maxitems condition, if string is returned this was already done:
@@ -6252,7 +6252,7 @@ class DataHandler implements LoggerAwareInterface
         if ($this->remapStackActions) {
             foreach ($this->remapStackActions as $action) {
                 if (isset($action['callback'], $action['arguments'])) {
-                    call_user_func_array($action['callback'], $action['arguments']);
+                    $action['callback'](...$action['arguments']);
                 }
             }
         }
index 88359ee..d5fca08 100644 (file)
@@ -382,7 +382,7 @@ class SlugHelper
         $newValue = $slug;
         $counter = 0;
         while (
-            !call_user_func($isUnique, $newValue, $state)
+            !$isUnique($newValue, $state)
             && ++$counter < 100
         ) {
             $newValue = $this->sanitize($rawValue . '-' . $counter);
index 4984ca7..0539964 100644 (file)
@@ -1409,7 +1409,7 @@ class RelationHandler
             $purgedItemIds = [];
             $callable =[$this, $purgeCallback];
             if (is_callable($callable)) {
-                $purgedItemIds = call_user_func($callable, $itemTableName, $itemIds);
+                $purgedItemIds = $callable($itemTableName, $itemIds);
             }
 
             $removedItemIds = array_diff($itemIds, $purgedItemIds);
index 0b2d2d2..3e77c6d 100644 (file)
@@ -97,7 +97,7 @@ abstract class AbstractApplication implements ApplicationInterface, RequestHandl
                 ServerRequestFactory::fromGlobals()
             );
             if ($execute !== null) {
-                call_user_func($execute);
+                $execute();
             }
         } catch (ImmediateResponseException $exception) {
             $response = $exception->getResponse();
index 0542d02..7d62375 100644 (file)
@@ -50,12 +50,12 @@ class Dispatcher implements DispatcherInterface
         $targetIdentifier = $request->getAttribute('target');
         $target = $this->getCallableFromTarget($targetIdentifier);
         $arguments = [$request];
-        return call_user_func_array($target, $arguments);
+        return $target(...$arguments);
     }
 
     /**
      * Creates a callable out of the given parameter, which can be a string, a callable / closure or an array
-     * which can be handed to call_user_func_array()
+     * which can be invoked as a function.
      *
      * @param array|string|callable $target the target which is being resolved.
      * @return callable
index c150418..6cf4e87 100644 (file)
@@ -422,9 +422,9 @@ class LocalDriver extends AbstractHierarchicalFilesystemDriver implements Stream
     {
         foreach ($filterMethods as $filter) {
             if (is_callable($filter)) {
-                $result = call_user_func($filter, $itemName, $itemIdentifier, $parentIdentifier, [], $this);
-                // We have to use -1 as the „don't include“ return value, as call_user_func() will return FALSE
-                // If calling the method succeeded and thus we can't use that as a return value.
+                $result = $filter($itemName, $itemIdentifier, $parentIdentifier, [], $this);
+                // We use -1 as the "don't include“ return value, for historic reasons,
+                // as call_user_func() used to return FALSE if calling the method failed.
                 if ($result === -1) {
                     return false;
                 }
index efac558..a173104 100644 (file)
@@ -84,8 +84,8 @@ class FileExtensionFilter
     /**
      * Entry method for use as filelist filter.
      *
-     * We have to use -1 as the „don't include“ return value, as call_user_func() will return FALSE
-     * if calling the method failed and thus we can't use that as a return value.
+     * We use -1 as the "don't include“ return value, for historic reasons,
+     * as call_user_func() used to return FALSE if calling the method failed.
      *
      * @param string $itemName
      * @param string $itemIdentifier
index d47232b..fc46389 100644 (file)
@@ -32,8 +32,8 @@ class FileNameFilter
     /**
      * Filter method that checks if a file/folder name starts with a dot (e.g. .htaccess)
      *
-     * We have to use -1 as the „don't include“ return value, as call_user_func() will return FALSE
-     * If calling the method succeeded and thus we can't use that as a return value.
+     * We use -1 as the "don't include“ return value, for historic reasons,
+     * as call_user_func() used to return FALSE if calling the method failed.
      *
      * @param string $itemName
      * @param string $itemIdentifier
index befbf85..019c382 100644 (file)
@@ -142,8 +142,8 @@ class DriverFilteredSearchResult implements FileSearchResultInterface
                     continue;
                 }
                 $result = $filter($itemName, $itemIdentifier, $parentIdentifier, [], $this->driver);
-                // We have to use -1 as the „don't include“ return value, as call_user_func() will return FALSE
-                // If calling the method succeeded and thus we can't use that as a return value.
+                // We use -1 as the "don't include“ return value, for historic reasons,
+                // as call_user_func() used to return FALSE if calling the method failed.
                 if ($result === -1) {
                     $matches = false;
                 }
index 6b63872..c3657c2 100644 (file)
@@ -698,7 +698,7 @@ class ArrayUtility
                 $keepItems = array_flip($keepItems);
                 foreach ($array as $key => $value) {
                     // Get the value to compare by using the callback function:
-                    $keepValue = isset($getValueFunc) ? call_user_func($getValueFunc, $value) : $value;
+                    $keepValue = isset($getValueFunc) ? $getValueFunc($value) : $value;
                     if (!isset($keepItems[$keepValue])) {
                         unset($array[$key]);
                     }
@@ -862,7 +862,7 @@ class ArrayUtility
                 $array[$key] = self::filterRecursive($value, $callback);
             }
 
-            if (!call_user_func($callback, $value)) {
+            if (!$callback($value)) {
                 unset($array[$key]);
             }
         }
index 8e128d8..cbe3ea3 100644 (file)
@@ -623,15 +623,12 @@ class GeneralUtility
             $ipad = str_repeat(chr(54), $hashBlocksize);
             if (strlen($secret) > $hashBlocksize) {
                 // Keys longer than block size are shorten
-                $key = str_pad(pack('H*', call_user_func($hashAlgorithm, $secret)), $hashBlocksize, "\0");
+                $key = str_pad(pack('H*', $hashAlgorithm($secret)), $hashBlocksize, "\0");
             } else {
                 // Keys shorter than block size are zero-padded
                 $key = str_pad($secret, $hashBlocksize, "\0");
             }
-            $hmac = call_user_func($hashAlgorithm, ($key ^ $opad) . pack('H*', call_user_func(
-                $hashAlgorithm,
-                ($key ^ $ipad) . $input
-            )));
+            $hmac = $hashAlgorithm(($key ^ $opad) . pack('H*', $hashAlgorithm(($key ^ $ipad) . $input)));
         }
         return $hmac;
     }
index 1ac6d99..596f3b0 100644 (file)
@@ -113,7 +113,7 @@ class ErrorHandlerTest extends FunctionalTestCase
             {
                 // process errors
                 if ($this->existingHandler !== null) {
-                    return call_user_func($this->existingHandler, $code, $message, $file, $line, $context);
+                    return ($this->existingHandler)($code, $message, $file, $line, $context);
                 }
 
                 return false;
index 3bf3ad6..14a3e53 100644 (file)
@@ -213,7 +213,7 @@ class PharStreamWrapperInterceptorTest extends FunctionalTestCase
 
         self::assertSame(
             $expectation,
-            call_user_func($functionName, 'phar://' . $path)
+            $functionName('phar://' . $path)
         );
     }
 
@@ -282,7 +282,7 @@ class PharStreamWrapperInterceptorTest extends FunctionalTestCase
         self::expectExceptionCode(1539625084);
 
         $path = $this->instancePath . '/' . $path;
-        call_user_func($functionName, 'phar://' . $path);
+        $functionName('phar://' . $path);
     }
 
     /**
index fc1326b..9bb65d2 100644 (file)
@@ -90,8 +90,8 @@ class FormProtectionFactoryTest extends UnitTestCase
             $this->createMock(Registry::class)
         ];
         self::assertSame(
-            call_user_func_array([FormProtectionFactory::class, 'get'], $arguments),
-            call_user_func_array([FormProtectionFactory::class, 'get'], $arguments)
+            FormProtectionFactory::get(...$arguments),
+            FormProtectionFactory::get(...$arguments)
         );
     }
 
index 57d0926..12693d9 100644 (file)
@@ -159,7 +159,7 @@ class LoggerTest extends UnitTestCase
         $logger = new Logger('test.core.log');
         $writer = new WriterFixture();
         $logger->addWriter(LogLevel::DEBUG, $writer);
-        call_user_func([$logger, $shorthandMethod], 'test message');
+        $logger->$shorthandMethod('test message');
         self::assertNotEmpty($writer->getRecords());
     }
 
index 7582c16..cd45928 100644 (file)
@@ -74,7 +74,7 @@ class FileTest extends UnitTestCase
         ];
         $fixture = new File($properties, $this->storageMock);
         foreach ($properties as $key => $value) {
-            self::assertEquals($value, call_user_func([$fixture, 'get' . $key]));
+            self::assertEquals($value, $fixture->{'get' . $key}());
         }
     }
 
index d23877d..2b8e111 100644 (file)
@@ -472,10 +472,8 @@ abstract class ActionController implements ControllerInterface
         $actionInitializationMethodName = 'initialize' . ucfirst($this->actionMethodName);
         /** @var callable $callable */
         $callable = [$this, $actionInitializationMethodName];
-        if (method_exists($this, $actionInitializationMethodName)) {
-            // todo: replace method_exists with is_callable or even both
-            //       method_exists alone does not guarantee that $callable is actually callable
-            call_user_func($callable);
+        if (is_callable($callable)) {
+            $callable();
         }
         $this->mapRequestArgumentsToControllerArguments();
         $this->controllerContext = $this->buildControllerContext();
index 0a3c2c3..673acb0 100644 (file)
@@ -147,7 +147,7 @@ class LazyLoadingProxy implements \Iterator, LoadingStrategyInterface
         }
         /** @var callable $callable */
         $callable = [$realInstance, $methodName];
-        return call_user_func_array($callable, $arguments);
+        return $callable(...$arguments);
     }
 
     /**
index 0793d0d..7aa3e99 100644 (file)
@@ -257,7 +257,7 @@ class ObjectConverter extends AbstractTypeConverter
                     throw new InvalidTargetException('Missing constructor argument "' . $parameterName . '" for object of type "' . $objectType . '".', 1268734872);
                 }
             }
-            return call_user_func_array([$this->objectManager, 'get'], array_merge([$objectType], $constructorArguments));
+            return $this->objectManager->get(...[$objectType, ...$constructorArguments]);
         }
         return $this->objectManager->get($objectType);
     }
index 0cb95f5..724d262 100644 (file)
@@ -144,7 +144,7 @@ class Dispatcher implements SingletonInterface
                 $preparedSlotArguments[] = $signalClassName . '::' . $signalName;
             }
 
-            $slotReturn = call_user_func_array($callable, $preparedSlotArguments);
+            $slotReturn = $callable(...$preparedSlotArguments);
 
             if ($slotReturn) {
                 if (!is_array($slotReturn)) {
index 5ed579c..a2eceb1 100644 (file)
@@ -223,7 +223,7 @@ class PropertyMappingConfigurationTest extends UnitTestCase
      */
     public function respectiveMethodsProvideFluentInterface($methodToTestForFluentInterface, array $argumentsForMethod = [])
     {
-        $actualResult = call_user_func_array([$this->propertyMappingConfiguration, $methodToTestForFluentInterface], $argumentsForMethod);
+        $actualResult = $this->propertyMappingConfiguration->$methodToTestForFluentInterface(...$argumentsForMethod);
         self::assertSame($this->propertyMappingConfiguration, $actualResult);
     }
 
index 32741b6..c4d2814 100644 (file)
@@ -98,7 +98,7 @@ class FileFacade
         $uid = 0;
         $method = 'getMetadata';
         if (is_callable([$this->resource, $method])) {
-            $metadata = call_user_func([$this->resource, $method]);
+            $metadata = $this->resource->$method();
 
             if (isset($metadata['uid'])) {
                 $uid = (int)$metadata['uid'];
@@ -123,7 +123,7 @@ class FileFacade
     {
         $method = 'getReadablePath';
         if (is_callable([$this->resource->getParentFolder(), $method])) {
-            return call_user_func([$this->resource->getParentFolder(), $method]);
+            return $this->resource->getParentFolder()->$method();
         }
 
         return '';
@@ -176,7 +176,7 @@ class FileFacade
     {
         $method = 'checkActionPermission';
         if (is_callable([$this->resource, $method])) {
-            return call_user_func_array([$this->resource, $method], ['read']);
+            return $this->resource->$method('read');
         }
 
         return false;
@@ -189,7 +189,7 @@ class FileFacade
     {
         $method = 'checkActionPermission';
         if (is_callable([$this->resource, $method])) {
-            return call_user_func_array([$this->resource, $method], ['write']);
+            return $this->resource->$method('write');
         }
 
         return false;
@@ -202,7 +202,7 @@ class FileFacade
     {
         $method = 'checkActionPermission';
         if (is_callable([$this->resource, $method])) {
-            return call_user_func_array([$this->resource, $method], ['replace']);
+            return $this->resource->$method('replace');
         }
 
         return false;
@@ -215,7 +215,7 @@ class FileFacade
     {
         $method = 'checkActionPermission';
         if (is_callable([$this->resource, $method])) {
-            return call_user_func_array([$this->resource, $method], ['rename']);
+            return $this->resource->$method('rename');
         }
 
         return false;
@@ -228,7 +228,7 @@ class FileFacade
     {
         $method = 'checkActionPermission';
         if (is_callable([$this->resource, $method])) {
-            return call_user_func_array([$this->resource, $method], ['copy']);
+            return $this->resource->$method('copy');
         }
 
         return false;
@@ -241,7 +241,7 @@ class FileFacade
     {
         $method = 'checkActionPermission';
         if (is_callable([$this->resource, $method])) {
-            return call_user_func_array([$this->resource, $method], ['move']);
+            return $this->resource->$method('move');
         }
 
         return false;
@@ -254,7 +254,7 @@ class FileFacade
     {
         $method = 'checkActionPermission';
         if (is_callable([$this->resource, $method])) {
-            return call_user_func_array([$this->resource, $method], ['delete']);
+            return $this->resource->$method('delete');
         }
 
         return false;
index fc14ca9..e532f83 100644 (file)
@@ -5181,11 +5181,7 @@ class ContentObjectRenderer implements LoggerAwareInterface
                 $callable = [$classObj, $methodName];
                 if (is_object($classObj) && method_exists($classObj, $parts[1]) && is_callable($callable)) {
                     $classObj->cObj = $this;
-                    $content = call_user_func_array($callable, [
-                        $content,
-                        $conf,
-                        $this->getRequest()
-                    ]);
+                    $content = $callable($content, $conf, $this->getRequest());
                 } else {
                     $this->getTimeTracker()->setTSlogMessage('Method "' . $parts[1] . '" did not exist in class "' . $parts[0] . '"', 3);
                 }
index df63f37..3af7974 100644 (file)
@@ -106,7 +106,7 @@ abstract class AbstractTestCase extends FunctionalTestCase
             array_map(
                 function (array $values) use ($template, $callback) {
                     if ($callback !== null) {
-                        $values = call_user_func($callback, $values);
+                        $values = $callback($values);
                     }
                     return vsprintf($template, $values);
                 },
index 5ebd100..8701d60 100644 (file)
@@ -123,7 +123,7 @@ class RecyclerModuleController
         $action = 'index';
         $this->initializeView($action);
 
-        $result = call_user_func_array([$this, $action . 'Action'], [$request]);
+        $result = $this->{$action . 'Action'}($request);
         if ($result instanceof ResponseInterface) {
             return $result;
         }