|
| 1 | +--TEST-- |
| 2 | +Repeated include must not increase memory - anonymous class |
| 3 | +--SKIPIF-- |
| 4 | +<?php |
| 5 | +// TODO test should pass even without opcache, but fixes are needed |
| 6 | +// related bug tracker https://bugs.php.net/bug.php?id=76982 |
| 7 | +if (!extension_loaded('Zend OPcache') || !(opcache_get_status() ?: [])['opcache_enabled']) { |
| 8 | + die('skip test currently requires opcache enabled'); |
| 9 | +} |
| 10 | +?> |
| 11 | +--FILE-- |
| 12 | +<?php |
| 13 | + |
| 14 | +// new anonymous class declared and included multiple times always has a new class name, |
| 15 | +// this test accounts for that and tests if an anonymous class declared in a closure |
| 16 | +// invoked once does not increase memory consumption |
| 17 | + |
| 18 | +final class AnonymousClassNameCache |
| 19 | +{ |
| 20 | + /** @var array<string, string> */ |
| 21 | + private static $classNameByFxHash = []; |
| 22 | + |
| 23 | + private function __construct() |
| 24 | + { |
| 25 | + } |
| 26 | + |
| 27 | + public static function get_class(\Closure $createAnonymousClassFx): string |
| 28 | + { |
| 29 | + $fxRefl = new \ReflectionFunction($createAnonymousClassFx); |
| 30 | + $fxHash = $fxRefl->getFileName() . ':' . $fxRefl->getStartLine() . '-' . $fxRefl->getEndLine(); |
| 31 | + |
| 32 | + if (!isset(self::$classNameByFxHash[$fxHash])) { |
| 33 | + self::$classNameByFxHash[$fxHash] = get_class($createAnonymousClassFx()); |
| 34 | + } |
| 35 | + |
| 36 | + return self::$classNameByFxHash[$fxHash]; |
| 37 | + } |
| 38 | +} |
| 39 | + |
| 40 | +$classNamePrev = null; |
| 41 | +$m = -1; |
| 42 | +$mDiff = -1; |
| 43 | +$mPrev = 0; |
| 44 | +for ($i = 0; $i < (PHP_OS_FAMILY === 'Windows' ? 1_000 /* include is slow on Windows */ : 20_000); $i++) { |
| 45 | + require __DIR__ . '/anonymous_class.inc'; |
| 46 | + if ($classNamePrev !== null && $className !== $classNamePrev) { |
| 47 | + echo 'Class name is different: ' . $className . ' vs ' . $classNamePrev . ' (' . $i . ' iteration)' . "\n"; |
| 48 | + exit(1); |
| 49 | + } |
| 50 | + $classNamePrev = $className; |
| 51 | + assert($className::verify() === 'ok'); |
| 52 | + $m = memory_get_usage(); |
| 53 | + $mDiff = $m - $mPrev; |
| 54 | + if ($mPrev !== 0 && $mDiff !== 0) { |
| 55 | + echo 'Increased memory detected: ' . $mDiff . ' B (' . $i . ' iteration)' . "\n"; |
| 56 | + exit(1); |
| 57 | + } |
| 58 | + $mPrev = $m; |
| 59 | +} |
| 60 | +echo 'done'; |
| 61 | + |
| 62 | +?> |
| 63 | +--EXPECT-- |
| 64 | +done |
0 commit comments