Skip to content

Commit c578957

Browse files
authored
Refactor BacktraceIgnoreMatcher (#304)
1 parent b326385 commit c578957

8 files changed

Lines changed: 110 additions & 148 deletions

File tree

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@
4040
"yiisoft/files": "^2.0",
4141
"yiisoft/profiler": "^3.0",
4242
"yiisoft/proxy": "^1.0.1",
43-
"yiisoft/strings": "^2.2",
43+
"yiisoft/strings": "^2.5",
4444
"yiisoft/var-dumper": "^1.7"
4545
},
4646
"require-dev": {

src/Collector/Stream/FilesystemStreamProxy.php

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
namespace Yiisoft\Yii\Debug\Collector\Stream;
66

77
use Yiisoft\Strings\CombinedRegexp;
8-
use Yiisoft\Yii\Debug\Helper\BacktraceIgnoreMatcher;
8+
use Yiisoft\Strings\StringHelper;
9+
use Yiisoft\Yii\Debug\Helper\BacktraceMatcher;
910
use Yiisoft\Yii\Debug\Helper\StreamWrapper\StreamWrapper;
1011
use Yiisoft\Yii\Debug\Helper\StreamWrapper\StreamWrapperInterface;
1112

@@ -85,9 +86,10 @@ public static function register(): void
8586
/**
8687
* It's important to trigger autoloader before unregistering the file stream handler
8788
*/
88-
class_exists(BacktraceIgnoreMatcher::class);
89+
class_exists(BacktraceMatcher::class);
8990
class_exists(StreamWrapper::class);
9091
class_exists(CombinedRegexp::class);
92+
class_exists(StringHelper::class);
9193
stream_wrapper_unregister('file');
9294
stream_wrapper_register('file', self::class, STREAM_IS_URL);
9395
self::$registered = true;
@@ -105,8 +107,8 @@ public static function unregister(): void
105107
private function isIgnored(): bool
106108
{
107109
$backtrace = debug_backtrace();
108-
return BacktraceIgnoreMatcher::isIgnoredByClass($backtrace, self::$ignoredClasses)
109-
|| BacktraceIgnoreMatcher::isIgnoredByFile($backtrace, self::$ignoredPathPatterns);
110+
return BacktraceMatcher::matchesClass($backtrace[3], self::$ignoredClasses)
111+
|| BacktraceMatcher::matchesFile($backtrace[3], self::$ignoredPathPatterns);
110112
}
111113

112114
public function stream_open(string $path, string $mode, int $options, ?string &$opened_path): bool

src/Collector/Stream/HttpStreamProxy.php

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@
55
namespace Yiisoft\Yii\Debug\Collector\Stream;
66

77
use Yiisoft\Strings\CombinedRegexp;
8-
use Yiisoft\Yii\Debug\Helper\BacktraceIgnoreMatcher;
8+
use Yiisoft\Strings\StringHelper;
9+
use Yiisoft\Yii\Debug\Helper\BacktraceMatcher;
910
use Yiisoft\Yii\Debug\Helper\StreamWrapper\StreamWrapper;
1011
use Yiisoft\Yii\Debug\Helper\StreamWrapper\StreamWrapperInterface;
1112

@@ -94,9 +95,10 @@ public static function register(): void
9495
/**
9596
* It's important to trigger autoloader before unregistering the file stream handler
9697
*/
97-
class_exists(BacktraceIgnoreMatcher::class);
98+
class_exists(BacktraceMatcher::class);
9899
class_exists(StreamWrapper::class);
99100
class_exists(CombinedRegexp::class);
101+
class_exists(StringHelper::class);
100102
stream_wrapper_unregister('http');
101103
stream_wrapper_register('http', self::class, STREAM_IS_URL);
102104

@@ -303,12 +305,12 @@ public function url_stat(string $path, int $flags): array|false
303305

304306
private function isIgnored(string $url): bool
305307
{
306-
if (BacktraceIgnoreMatcher::doesStringMatchPattern($url, self::$ignoredUrls)) {
308+
if (StringHelper::matchAnyRegex($url, self::$ignoredUrls)) {
307309
return true;
308310
}
309311

310312
$backtrace = debug_backtrace();
311-
return BacktraceIgnoreMatcher::isIgnoredByClass($backtrace, self::$ignoredClasses)
312-
|| BacktraceIgnoreMatcher::isIgnoredByFile($backtrace, self::$ignoredPathPatterns);
313+
return BacktraceMatcher::matchesClass($backtrace[3], self::$ignoredClasses)
314+
|| BacktraceMatcher::matchesFile($backtrace[3], self::$ignoredPathPatterns);
313315
}
314316
}

src/Debugger.php

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -13,9 +13,6 @@
1313
use Yiisoft\Yii\Debug\StartupPolicy\Debugger\DebuggerStartupPolicyInterface;
1414
use Yiisoft\Yii\Debug\Storage\StorageInterface;
1515

16-
/**
17-
* @psalm-type BacktraceType = list<array{file?:string,line?:int,function?:string,class?:class-string,object?:object,type?:string,args?:array}>
18-
*/
1916
final class Debugger
2017
{
2118
/**

src/Helper/BacktraceIgnoreMatcher.php

Lines changed: 0 additions & 53 deletions
This file was deleted.

src/Helper/BacktraceMatcher.php

Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\Yii\Debug\Helper;
6+
7+
use Yiisoft\Strings\StringHelper;
8+
9+
use function in_array;
10+
11+
/**
12+
* `BacktraceMatcher` provides methods to match backtrace items returned by the PHP function `debug_backtrace()`.
13+
*
14+
* @see https://www.php.net/manual/function.debug-backtrace.php
15+
*
16+
* @psalm-type TBacktraceItem = array{
17+
* file?: string,
18+
* line?: int,
19+
* function?: string,
20+
* class?: class-string,
21+
* object?: object,
22+
* type?: string,
23+
* args?:array,
24+
* }
25+
*/
26+
final class BacktraceMatcher
27+
{
28+
/**
29+
* @param string[] $patterns
30+
* @psalm-param TBacktraceItem $backtraceItem
31+
*/
32+
public static function matchesFile(array $backtraceItem, array $patterns): bool
33+
{
34+
$path = $backtraceItem['file'] ?? null;
35+
return $path !== null && StringHelper::matchAnyRegex($path, $patterns);
36+
}
37+
38+
/**
39+
* @param string[] $classes
40+
* @psalm-param TBacktraceItem $backtraceItem
41+
*/
42+
public static function matchesClass(array $backtraceItem, array $classes): bool
43+
{
44+
$class = $backtraceItem['class'] ?? null;
45+
return $class !== null && in_array($class, $classes, true);
46+
}
47+
}

tests/Unit/Helper/BacktraceIgnoreMatcherTest.php

Lines changed: 0 additions & 82 deletions
This file was deleted.
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
<?php
2+
3+
declare(strict_types=1);
4+
5+
namespace Yiisoft\Yii\Debug\Tests\Unit\Helper;
6+
7+
use PHPUnit\Framework\TestCase;
8+
use ReflectionClass;
9+
use stdClass;
10+
use Yiisoft\Yii\Debug\Helper\BacktraceMatcher;
11+
12+
final class BacktraceMatcherTest extends TestCase
13+
{
14+
public function testClassIgnorance(): void
15+
{
16+
$backtrace = debug_backtrace();
17+
18+
$this->assertFalse(BacktraceMatcher::matchesClass($backtrace[3], [self::class]));
19+
$this->assertFalse(BacktraceMatcher::matchesClass($backtrace[3], [stdClass::class]));
20+
21+
$this->assertTrue(BacktraceMatcher::matchesClass($backtrace[0], [self::class]));
22+
$this->assertFalse(BacktraceMatcher::matchesClass($backtrace[0], [stdClass::class]));
23+
}
24+
25+
public function testFileIgnorance(): void
26+
{
27+
$backtrace = debug_backtrace();
28+
$reflection = new ReflectionClass(TestCase::class);
29+
$file = $reflection->getFileName();
30+
31+
$this->assertFalse(BacktraceMatcher::matchesFile($backtrace[2], [preg_quote($file)]));
32+
$this->assertFalse(BacktraceMatcher::matchesFile($backtrace[2], [preg_quote(__FILE__)]));
33+
34+
$this->assertTrue(BacktraceMatcher::matchesFile($backtrace[0], [preg_quote($file)]));
35+
$this->assertTrue(
36+
BacktraceMatcher::matchesFile(
37+
$backtrace[0],
38+
[preg_quote(dirname($file) . DIRECTORY_SEPARATOR) . '*']
39+
)
40+
);
41+
$this->assertFalse(BacktraceMatcher::matchesFile($backtrace[0], [preg_quote(__FILE__)]));
42+
}
43+
44+
public function testEmptyBacktrace(): void
45+
{
46+
$this->assertFalse(BacktraceMatcher::matchesFile([], ['dev/123/456']));
47+
$this->assertFalse(BacktraceMatcher::matchesClass([], ['dev/123/456']));
48+
}
49+
}

0 commit comments

Comments
 (0)