From 3283e2f7b80b7c4e5d417402bd956bb98a1be12d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bartosz=20Dziewo=C5=84ski?= Date: Sun, 17 Apr 2016 08:45:00 +0200 Subject: [PATCH] Optimize 'rcount()' function Starting with PHP 5.4, preg_match_all() allows omitting the '$matches' argument. This lets PHP avoid computing them, just count the matches. I'm not sure how various versions of HHVM handle this, so I made it just test whether this works rather than check version numbers. Change-Id: Ib27505c8355109c6e6a9f1c4631281a0f0caaa75 --- AbuseFilter.parser.php | 16 ++++++++++++++-- 1 file changed, 14 insertions(+), 2 deletions(-) diff --git a/AbuseFilter.parser.php b/AbuseFilter.parser.php index 6a0d3821a..f5c4f1f80 100644 --- a/AbuseFilter.parser.php +++ b/AbuseFilter.parser.php @@ -606,6 +606,8 @@ class AbuseFilterParser { public static $funcCache = array(); + private static $hasSmartPregMatchAll = null; + /** * Create a new instance * @@ -616,6 +618,11 @@ class AbuseFilterParser { if ( $vars instanceof AbuseFilterVariableHolder ) { $this->mVars = $vars; } + if ( self::$hasSmartPregMatchAll === null ) { + // Starting with PHP 5.4, preg_match_all() allows omitting the '$matches' argument. + $r = new ReflectionFunction( 'preg_match_all' ); + self::$hasSmartPregMatchAll = $r->getNumberOfRequiredParameters() === 2; + } } public function resetState() { @@ -1567,9 +1574,14 @@ class AbuseFilterParser { $needle = preg_replace( '!(\\\\\\\\)*(\\\\)?/!', '$1\/', $needle ); $needle = "/$needle/u"; - $matches = array(); + if ( self::$hasSmartPregMatchAll ) { + // Omit the '$matches' argument to avoid computing them, just count. + $count = preg_match_all( $needle, $haystack ); + } else { + $matches = array(); + $count = preg_match_all( $needle, $haystack, $matches ); + } - $count = preg_match_all( $needle, $haystack, $matches ); if ( $count === false ) { throw new AFPUserVisibleException( 'regexfailure',