Skip to content

Commit 64d7ac8

Browse files
johnbillionondrejmirtes
authored andcommitted
Narrow the type for the preg_replace_callback() callable.
1 parent ef39c54 commit 64d7ac8

File tree

4 files changed

+74
-2
lines changed

4 files changed

+74
-2
lines changed

resources/functionMap.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8833,7 +8833,7 @@
88338833
'preg_match_all' => ['0|positive-int|false|null', 'pattern'=>'string', 'subject'=>'string', '&w_subpatterns='=>'array', 'flags='=>'int', 'offset='=>'int'],
88348834
'preg_quote' => ['string', 'str'=>'string', 'delim_char='=>'string'],
88358835
'preg_replace' => ['string|array|null', 'regex'=>'string|array', 'replace'=>'string|array', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'],
8836-
'preg_replace_callback' => ['string|array|null', 'regex'=>'string|array', 'callback'=>'callable', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'],
8836+
'preg_replace_callback' => ['string|array|null', 'regex'=>'string|array', 'callback'=>'callable(array<int|string, string>):string', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'],
88378837
'preg_replace_callback_array' => ['string|array|null', 'pattern'=>'array<string,callable>', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int'],
88388838
'preg_split' => ['array<int, string>|false', 'pattern'=>'string', 'subject'=>'string', 'limit='=>'?int', 'flags='=>'int'],
88398839
'prev' => ['mixed', '&rw_array_arg'=>'array|object'],

resources/functionMap_php74delta.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,7 @@
4343
'password_algos' => ['array<int, string>'],
4444
'password_hash' => ['string|false', 'password'=>'string', 'algo'=>'string|null', 'options='=>'array'],
4545
'password_needs_rehash' => ['bool', 'hash'=>'string', 'algo'=>'string|null', 'options='=>'array'],
46-
'preg_replace_callback' => ['string|array|null', 'regex'=>'string|array', 'callback'=>'callable', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int', 'flags='=>'int'],
46+
'preg_replace_callback' => ['string|array|null', 'regex'=>'string|array', 'callback'=>'callable(array<int|string, string>):string', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int', 'flags='=>'int'],
4747
'preg_replace_callback_array' => ['string|array|null', 'pattern'=>'array<string,callable>', 'subject'=>'string|array', 'limit='=>'int', '&w_count='=>'int', 'flags='=>'int'],
4848
'sapi_windows_set_ctrl_handler' => ['bool', 'callable'=>'callable(int):void', 'add='=>'bool'],
4949
'ReflectionProperty::getType' => ['?ReflectionType'],

tests/PHPStan/Rules/Functions/CallToFunctionParametersRuleTest.php

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -630,6 +630,28 @@ public function testArrayWalkArrowFunctionCallback(): void
630630
]);
631631
}
632632

633+
public function testPregReplaceCallback(): void
634+
{
635+
$this->analyse([__DIR__ . '/data/preg_replace_callback.php'], [
636+
[
637+
'Parameter #2 $callback of function preg_replace_callback expects callable(array<int|string, string>): string, Closure(string): string given.',
638+
6,
639+
],
640+
[
641+
'Parameter #2 $callback of function preg_replace_callback expects callable(array<int|string, string>): string, Closure(string): string given.',
642+
13,
643+
],
644+
[
645+
'Parameter #2 $callback of function preg_replace_callback expects callable(array<int|string, string>): string, Closure(array): void given.',
646+
20,
647+
],
648+
[
649+
'Parameter #2 $callback of function preg_replace_callback expects callable(array<int|string, string>): string, Closure(): void given.',
650+
25,
651+
],
652+
]);
653+
}
654+
633655
public function testUasortCallback(): void
634656
{
635657
$this->analyse([__DIR__ . '/data/uasort.php'], [
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
<?php declare(strict_types = 1);
2+
3+
// Incorrect
4+
$string = preg_replace_callback(
5+
'#pattern#',
6+
function(string $string): string {
7+
return $string;
8+
},
9+
'subject'
10+
);
11+
$string = preg_replace_callback(
12+
'#pattern#',
13+
function(string $string) {
14+
return $string;
15+
},
16+
'subject'
17+
);
18+
$string = preg_replace_callback(
19+
'#pattern#',
20+
function(array $matches) {},
21+
'subject'
22+
);
23+
$string = preg_replace_callback(
24+
'#pattern#',
25+
function() {},
26+
'subject'
27+
);
28+
29+
// Correct
30+
$string = preg_replace_callback(
31+
'#pattern#',
32+
function(array $matches): string {
33+
return $matches[0];
34+
},
35+
'subject'
36+
);
37+
$string = preg_replace_callback(
38+
'#pattern#',
39+
function(array $matches) {
40+
return $matches[0];
41+
},
42+
'subject'
43+
);
44+
$string = preg_replace_callback(
45+
'#pattern#',
46+
function() {
47+
return 'Hello';
48+
},
49+
'subject'
50+
);

0 commit comments

Comments
 (0)