Skip to content

Commit 5e20c36

Browse files
Add multi-variant overloads for PDOStatement::fetchAll() in function signature map
- Replace the single `PDOStatement::fetchAll` signature (which combined all parameter types into one union) with proper multi-variant overloads matching `PDO::query` and `PDOStatement::setFetchMode` patterns - Add variant '1 for FETCH_COLUMN mode (int $mode, int $colno) - Add variant '2 for FETCH_CLASS mode (int $mode, string $classname, ?array $ctorargs) - Add variant '3 for FETCH_FUNC mode (int $mode, callable $callback) - Update both base functionMap.php and functionMap_php80delta.php - Verified PDO::query and PDOStatement::setFetchMode already had correct overloads
1 parent ca00199 commit 5e20c36

4 files changed

Lines changed: 47 additions & 2 deletions

File tree

resources/functionMap.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7833,7 +7833,10 @@
78337833
'PDOStatement::errorInfo' => ['array'],
78347834
'PDOStatement::execute' => ['bool', 'bound_input_params='=>'?array'],
78357835
'PDOStatement::fetch' => ['mixed', 'how='=>'int', 'orientation='=>'int', 'offset='=>'int'],
7836-
'PDOStatement::fetchAll' => ['array|false', 'how='=>'int', 'fetch_argument='=>'int|string|callable', 'ctor_args='=>'?array'],
7836+
'PDOStatement::fetchAll' => ['array|false', 'how='=>'int'],
7837+
'PDOStatement::fetchAll\'1' => ['array|false', 'fetch_column'=>'int', 'colno'=>'int'],
7838+
'PDOStatement::fetchAll\'2' => ['array|false', 'fetch_class'=>'int', 'classname'=>'string', 'ctorargs='=>'?array'],
7839+
'PDOStatement::fetchAll\'3' => ['array|false', 'fetch_func'=>'int', 'callback'=>'callable'],
78377840
'PDOStatement::fetchColumn' => ['string|null|false|int', 'column_number='=>'int'],
78387841
'PDOStatement::fetchObject' => ['mixed', 'class_name='=>'string', 'ctor_args='=>'?array'],
78397842
'PDOStatement::getAttribute' => ['mixed', 'attribute'=>'int'],

resources/functionMap_php80delta.php

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,10 @@
9797
'opcache_get_configuration' => ['array{directives: array{\'opcache.enable\': bool, \'opcache.enable_cli\': bool, \'opcache.use_cwd\': bool, \'opcache.validate_timestamps\': bool, \'opcache.validate_permission\': bool, \'opcache.validate_root\'?: bool, \'opcache.dups_fix\': bool, \'opcache.revalidate_path\': bool, \'opcache.log_verbosity_level\': int, \'opcache.memory_consumption\': int, \'opcache.interned_strings_buffer\': int, \'opcache.max_accelerated_files\': int, \'opcache.max_wasted_percentage\': float, \'opcache.consistency_checks\': int, \'opcache.force_restart_timeout\': int, \'opcache.revalidate_freq\': int, \'opcache.preferred_memory_model\': string, \'opcache.blacklist_filename\': string, \'opcache.max_file_size\': int, \'opcache.error_log\': string, \'opcache.protect_memory\': bool, \'opcache.save_comments\': bool, \'opcache.record_warnings\': bool, \'opcache.enable_file_override\': bool, \'opcache.optimization_level\': int, \'opcache.lockfile_path\'?: string, \'opcache.mmap_base\'?: string, \'opcache.file_cache\': string, \'opcache.file_cache_only\': bool, \'opcache.file_cache_consistency_checks\': bool, \'opcache.file_cache_fallback\'?: bool, \'opcache.file_update_protection\': int, \'opcache.opt_debug_level\': int, \'opcache.restrict_api\': string, \'opcache.huge_code_pages\'?: bool, \'opcache.preload\': string, \'opcache.preload_user\'?: string, \'opcache.cache_id\'?: string, \'opcache.jit\'?: string, \'opcache.jit_buffer_size\'?: int, \'opcache.jit_debug\'?: int, \'opcache.jit_bisect_limit\'?: int, \'opcache.jit_blacklist_root_trace\'?: int, \'opcache.jit_blacklist_side_trace\'?: int, \'opcache.jit_hot_func\'?: int, \'opcache.jit_hot_loop\'?: int, \'opcache.jit_hot_return\'?: int, \'opcache.jit_hot_side_exit\'?: int, \'opcache.jit_max_exit_counters\'?: int, \'opcache.jit_max_loop_unrolls\'?: int, \'opcache.jit_max_polymorphic_calls\'?: int, \'opcache.jit_max_recursive_calls\'?: int, \'opcache.jit_max_recursive_returns\'?: int, \'opcache.jit_max_root_traces\'?: int, \'opcache.jit_max_side_traces\'?: int, \'opcache.jit_prof_threshold\'?: int}, version: array{version: non-empty-string, opcache_product_name: non-empty-string}, blacklist: list<string>}|false'],
9898
'parse_str' => ['void', 'encoded_string'=>'string', '&w_result'=>'array'],
9999
'password_hash' => ['non-empty-string', 'password'=>'string', 'algo'=>'string|int|null', 'options='=>'array'],
100-
'PDOStatement::fetchAll' => ['array', 'how='=>'int', 'fetch_argument='=>'int|string|callable', 'ctor_args='=>'?array'],
100+
'PDOStatement::fetchAll' => ['array', 'mode='=>'int'],
101+
'PDOStatement::fetchAll\'1' => ['array', 'mode'=>'int', 'column'=>'int'],
102+
'PDOStatement::fetchAll\'2' => ['array', 'mode'=>'int', 'class'=>'string', 'constructorArgs='=>'?array'],
103+
'PDOStatement::fetchAll\'3' => ['array', 'mode'=>'int', 'callback'=>'callable'],
101104
'PhpToken::tokenize' => ['list<PhpToken>', 'code'=>'string', 'flags='=>'int'],
102105
'PhpToken::is' => ['bool', 'kind'=>'string|int|string[]|int[]'],
103106
'PhpToken::isIgnorable' => ['bool'],

tests/PHPStan/Rules/Methods/CallMethodsRuleTest.php

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4062,6 +4062,16 @@ public function testBug14549(): void
40624062
]);
40634063
}
40644064

4065+
#[RequiresPhp('>= 8.0.0')]
4066+
public function testBug5509(): void
4067+
{
4068+
$this->checkThisOnly = false;
4069+
$this->checkNullables = true;
4070+
$this->checkUnionTypes = true;
4071+
$this->checkExplicitMixed = true;
4072+
$this->analyse([__DIR__ . '/data/bug-5509.php'], []);
4073+
}
4074+
40654075
public function testBug11894(): void
40664076
{
40674077
$this->checkThisOnly = false;
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php // lint >= 8.0
2+
3+
namespace Bug5509;
4+
5+
class Foo
6+
{
7+
public function test(\PDOStatement $stmt): void
8+
{
9+
// FETCH_CLASS with class name and constructor args - should not error
10+
$stmt->fetchAll(\PDO::FETCH_CLASS, \stdClass::class, [new \stdClass]);
11+
12+
// FETCH_CLASS with just class name - should not error
13+
$stmt->fetchAll(\PDO::FETCH_CLASS, \stdClass::class);
14+
15+
// FETCH_COLUMN with column number - should not error
16+
$stmt->fetchAll(\PDO::FETCH_COLUMN, 0);
17+
18+
// FETCH_FUNC with callable - should not error
19+
$stmt->fetchAll(\PDO::FETCH_FUNC, function () {
20+
return 'test';
21+
});
22+
23+
// No args - should not error
24+
$stmt->fetchAll();
25+
26+
// With just mode - should not error
27+
$stmt->fetchAll(\PDO::FETCH_ASSOC);
28+
}
29+
}

0 commit comments

Comments
 (0)