Skip to content

Commit be965d1

Browse files
phpstan-botclaude
andauthored
Declare multiple mysqli_ functions as impure (#5481)
Co-authored-by: Claude Opus 4.6 <noreply@anthropic.com>
1 parent a25e509 commit be965d1

File tree

4 files changed

+258
-0
lines changed

4 files changed

+258
-0
lines changed

bin/functionMetadata_original.php

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -94,6 +94,118 @@
9494
'link' => ['hasSideEffects' => true],
9595
'mkdir' => ['hasSideEffects' => true],
9696
'move_uploaded_file' => ['hasSideEffects' => true],
97+
'mysqli_affected_rows' => ['hasSideEffects' => true],
98+
'mysqli_autocommit' => ['hasSideEffects' => true],
99+
'mysqli_begin_transaction' => ['hasSideEffects' => true],
100+
'mysqli_bind_param' => ['hasSideEffects' => true],
101+
'mysqli_bind_result' => ['hasSideEffects' => true],
102+
'mysqli_change_user' => ['hasSideEffects' => true],
103+
'mysqli_character_set_name' => ['hasSideEffects' => true],
104+
'mysqli_client_encoding' => ['hasSideEffects' => true],
105+
'mysqli_close' => ['hasSideEffects' => true],
106+
'mysqli_commit' => ['hasSideEffects' => true],
107+
'mysqli_connect' => ['hasSideEffects' => true],
108+
'mysqli_connect_errno' => ['hasSideEffects' => true],
109+
'mysqli_connect_error' => ['hasSideEffects' => true],
110+
'mysqli_data_seek' => ['hasSideEffects' => true],
111+
'mysqli_debug' => ['hasSideEffects' => true],
112+
'mysqli_dump_debug_info' => ['hasSideEffects' => true],
113+
'mysqli_errno' => ['hasSideEffects' => true],
114+
'mysqli_error' => ['hasSideEffects' => true],
115+
'mysqli_error_list' => ['hasSideEffects' => true],
116+
'mysqli_escape_string' => ['hasSideEffects' => true],
117+
'mysqli_execute' => ['hasSideEffects' => true],
118+
'mysqli_execute_query' => ['hasSideEffects' => true],
119+
'mysqli_fetch' => ['hasSideEffects' => true],
120+
'mysqli_fetch_all' => ['hasSideEffects' => true],
121+
'mysqli_fetch_array' => ['hasSideEffects' => true],
122+
'mysqli_fetch_assoc' => ['hasSideEffects' => true],
123+
'mysqli_fetch_column' => ['hasSideEffects' => true],
124+
'mysqli_fetch_field' => ['hasSideEffects' => true],
125+
'mysqli_fetch_lengths' => ['hasSideEffects' => true],
126+
'mysqli_fetch_object' => ['hasSideEffects' => true],
127+
'mysqli_fetch_row' => ['hasSideEffects' => true],
128+
'mysqli_field_count' => ['hasSideEffects' => true],
129+
'mysqli_field_seek' => ['hasSideEffects' => true],
130+
'mysqli_field_tell' => ['hasSideEffects' => true],
131+
'mysqli_free_result' => ['hasSideEffects' => true],
132+
'mysqli_get_cache_stats' => ['hasSideEffects' => true],
133+
'mysqli_get_charset' => ['hasSideEffects' => true],
134+
'mysqli_get_client_info' => ['hasSideEffects' => true],
135+
'mysqli_get_client_stats' => ['hasSideEffects' => true],
136+
'mysqli_get_client_version' => ['hasSideEffects' => true],
137+
'mysqli_get_connection_stats' => ['hasSideEffects' => true],
138+
'mysqli_get_host_info' => ['hasSideEffects' => true],
139+
'mysqli_get_links_stats' => ['hasSideEffects' => true],
140+
'mysqli_get_metadata' => ['hasSideEffects' => true],
141+
'mysqli_get_proto_info' => ['hasSideEffects' => true],
142+
'mysqli_get_server_info' => ['hasSideEffects' => true],
143+
'mysqli_get_server_version' => ['hasSideEffects' => true],
144+
'mysqli_get_warnings' => ['hasSideEffects' => true],
145+
'mysqli_info' => ['hasSideEffects' => true],
146+
'mysqli_init' => ['hasSideEffects' => true],
147+
'mysqli_insert_id' => ['hasSideEffects' => true],
148+
'mysqli_kill' => ['hasSideEffects' => true],
149+
'mysqli_more_results' => ['hasSideEffects' => true],
150+
'mysqli_multi_query' => ['hasSideEffects' => true],
151+
'mysqli_next_result' => ['hasSideEffects' => true],
152+
'mysqli_options' => ['hasSideEffects' => true],
153+
'mysqli_param_count' => ['hasSideEffects' => true],
154+
'mysqli_ping' => ['hasSideEffects' => true],
155+
'mysqli_poll' => ['hasSideEffects' => true],
156+
'mysqli_prepare' => ['hasSideEffects' => true],
157+
'mysqli_query' => ['hasSideEffects' => true],
158+
'mysqli_real_connect' => ['hasSideEffects' => true],
159+
'mysqli_real_escape_string' => ['hasSideEffects' => true],
160+
'mysqli_real_query' => ['hasSideEffects' => true],
161+
'mysqli_reap_async_query' => ['hasSideEffects' => true],
162+
'mysqli_refresh' => ['hasSideEffects' => true],
163+
'mysqli_release_savepoint' => ['hasSideEffects' => true],
164+
'mysqli_report' => ['hasSideEffects' => true],
165+
'mysqli_rollback' => ['hasSideEffects' => true],
166+
'mysqli_savepoint' => ['hasSideEffects' => true],
167+
'mysqli_select_db' => ['hasSideEffects' => true],
168+
'mysqli_send_long_data' => ['hasSideEffects' => true],
169+
'mysqli_set_charset' => ['hasSideEffects' => true],
170+
'mysqli_set_local_infile_default' => ['hasSideEffects' => true],
171+
'mysqli_set_local_infile_handler' => ['hasSideEffects' => true],
172+
'mysqli_set_opt' => ['hasSideEffects' => true],
173+
'mysqli_sqlstate' => ['hasSideEffects' => true],
174+
'mysqli_ssl_set' => ['hasSideEffects' => true],
175+
'mysqli_stat' => ['hasSideEffects' => true],
176+
'mysqli_stmt_affected_rows' => ['hasSideEffects' => true],
177+
'mysqli_stmt_attr_get' => ['hasSideEffects' => true],
178+
'mysqli_stmt_attr_set' => ['hasSideEffects' => true],
179+
'mysqli_stmt_bind_param' => ['hasSideEffects' => true],
180+
'mysqli_stmt_bind_result' => ['hasSideEffects' => true],
181+
'mysqli_stmt_close' => ['hasSideEffects' => true],
182+
'mysqli_stmt_data_seek' => ['hasSideEffects' => true],
183+
'mysqli_stmt_errno' => ['hasSideEffects' => true],
184+
'mysqli_stmt_error' => ['hasSideEffects' => true],
185+
'mysqli_stmt_error_list' => ['hasSideEffects' => true],
186+
'mysqli_stmt_execute' => ['hasSideEffects' => true],
187+
'mysqli_stmt_fetch' => ['hasSideEffects' => true],
188+
'mysqli_stmt_field_count' => ['hasSideEffects' => true],
189+
'mysqli_stmt_free_result' => ['hasSideEffects' => true],
190+
'mysqli_stmt_get_result' => ['hasSideEffects' => true],
191+
'mysqli_stmt_get_warnings' => ['hasSideEffects' => true],
192+
'mysqli_stmt_init' => ['hasSideEffects' => true],
193+
'mysqli_stmt_insert_id' => ['hasSideEffects' => true],
194+
'mysqli_stmt_more_results' => ['hasSideEffects' => true],
195+
'mysqli_stmt_next_result' => ['hasSideEffects' => true],
196+
'mysqli_stmt_num_rows' => ['hasSideEffects' => true],
197+
'mysqli_stmt_param_count' => ['hasSideEffects' => true],
198+
'mysqli_stmt_prepare' => ['hasSideEffects' => true],
199+
'mysqli_stmt_reset' => ['hasSideEffects' => true],
200+
'mysqli_stmt_result_metadata' => ['hasSideEffects' => true],
201+
'mysqli_stmt_send_long_data' => ['hasSideEffects' => true],
202+
'mysqli_stmt_sqlstate' => ['hasSideEffects' => true],
203+
'mysqli_stmt_store_result' => ['hasSideEffects' => true],
204+
'mysqli_store_result' => ['hasSideEffects' => true],
205+
'mysqli_thread_id' => ['hasSideEffects' => true],
206+
'mysqli_thread_safe' => ['hasSideEffects' => true],
207+
'mysqli_use_result' => ['hasSideEffects' => true],
208+
'mysqli_warning_count' => ['hasSideEffects' => true],
97209
'ob_clean' => ['hasSideEffects' => true],
98210
'ob_end_clean' => ['hasSideEffects' => true],
99211
'ob_end_flush' => ['hasSideEffects' => true],

resources/functionMetadata.php

Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1392,6 +1392,118 @@
13921392
'msgfmt_parse_message' => ['hasSideEffects' => false],
13931393
'mt_getrandmax' => ['hasSideEffects' => false],
13941394
'mt_rand' => ['hasSideEffects' => true],
1395+
'mysqli_affected_rows' => ['hasSideEffects' => true],
1396+
'mysqli_autocommit' => ['hasSideEffects' => true],
1397+
'mysqli_begin_transaction' => ['hasSideEffects' => true],
1398+
'mysqli_bind_param' => ['hasSideEffects' => true],
1399+
'mysqli_bind_result' => ['hasSideEffects' => true],
1400+
'mysqli_change_user' => ['hasSideEffects' => true],
1401+
'mysqli_character_set_name' => ['hasSideEffects' => true],
1402+
'mysqli_client_encoding' => ['hasSideEffects' => true],
1403+
'mysqli_close' => ['hasSideEffects' => true],
1404+
'mysqli_commit' => ['hasSideEffects' => true],
1405+
'mysqli_connect' => ['hasSideEffects' => true],
1406+
'mysqli_connect_errno' => ['hasSideEffects' => true],
1407+
'mysqli_connect_error' => ['hasSideEffects' => true],
1408+
'mysqli_data_seek' => ['hasSideEffects' => true],
1409+
'mysqli_debug' => ['hasSideEffects' => true],
1410+
'mysqli_dump_debug_info' => ['hasSideEffects' => true],
1411+
'mysqli_errno' => ['hasSideEffects' => true],
1412+
'mysqli_error' => ['hasSideEffects' => true],
1413+
'mysqli_error_list' => ['hasSideEffects' => true],
1414+
'mysqli_escape_string' => ['hasSideEffects' => true],
1415+
'mysqli_execute' => ['hasSideEffects' => true],
1416+
'mysqli_execute_query' => ['hasSideEffects' => true],
1417+
'mysqli_fetch' => ['hasSideEffects' => true],
1418+
'mysqli_fetch_all' => ['hasSideEffects' => true],
1419+
'mysqli_fetch_array' => ['hasSideEffects' => true],
1420+
'mysqli_fetch_assoc' => ['hasSideEffects' => true],
1421+
'mysqli_fetch_column' => ['hasSideEffects' => true],
1422+
'mysqli_fetch_field' => ['hasSideEffects' => true],
1423+
'mysqli_fetch_lengths' => ['hasSideEffects' => true],
1424+
'mysqli_fetch_object' => ['hasSideEffects' => true],
1425+
'mysqli_fetch_row' => ['hasSideEffects' => true],
1426+
'mysqli_field_count' => ['hasSideEffects' => true],
1427+
'mysqli_field_seek' => ['hasSideEffects' => true],
1428+
'mysqli_field_tell' => ['hasSideEffects' => true],
1429+
'mysqli_free_result' => ['hasSideEffects' => true],
1430+
'mysqli_get_cache_stats' => ['hasSideEffects' => true],
1431+
'mysqli_get_charset' => ['hasSideEffects' => true],
1432+
'mysqli_get_client_info' => ['hasSideEffects' => true],
1433+
'mysqli_get_client_stats' => ['hasSideEffects' => true],
1434+
'mysqli_get_client_version' => ['hasSideEffects' => true],
1435+
'mysqli_get_connection_stats' => ['hasSideEffects' => true],
1436+
'mysqli_get_host_info' => ['hasSideEffects' => true],
1437+
'mysqli_get_links_stats' => ['hasSideEffects' => true],
1438+
'mysqli_get_metadata' => ['hasSideEffects' => true],
1439+
'mysqli_get_proto_info' => ['hasSideEffects' => true],
1440+
'mysqli_get_server_info' => ['hasSideEffects' => true],
1441+
'mysqli_get_server_version' => ['hasSideEffects' => true],
1442+
'mysqli_get_warnings' => ['hasSideEffects' => true],
1443+
'mysqli_info' => ['hasSideEffects' => true],
1444+
'mysqli_init' => ['hasSideEffects' => true],
1445+
'mysqli_insert_id' => ['hasSideEffects' => true],
1446+
'mysqli_kill' => ['hasSideEffects' => true],
1447+
'mysqli_more_results' => ['hasSideEffects' => true],
1448+
'mysqli_multi_query' => ['hasSideEffects' => true],
1449+
'mysqli_next_result' => ['hasSideEffects' => true],
1450+
'mysqli_options' => ['hasSideEffects' => true],
1451+
'mysqli_param_count' => ['hasSideEffects' => true],
1452+
'mysqli_ping' => ['hasSideEffects' => true],
1453+
'mysqli_poll' => ['hasSideEffects' => true],
1454+
'mysqli_prepare' => ['hasSideEffects' => true],
1455+
'mysqli_query' => ['hasSideEffects' => true],
1456+
'mysqli_real_connect' => ['hasSideEffects' => true],
1457+
'mysqli_real_escape_string' => ['hasSideEffects' => true],
1458+
'mysqli_real_query' => ['hasSideEffects' => true],
1459+
'mysqli_reap_async_query' => ['hasSideEffects' => true],
1460+
'mysqli_refresh' => ['hasSideEffects' => true],
1461+
'mysqli_release_savepoint' => ['hasSideEffects' => true],
1462+
'mysqli_report' => ['hasSideEffects' => true],
1463+
'mysqli_rollback' => ['hasSideEffects' => true],
1464+
'mysqli_savepoint' => ['hasSideEffects' => true],
1465+
'mysqli_select_db' => ['hasSideEffects' => true],
1466+
'mysqli_send_long_data' => ['hasSideEffects' => true],
1467+
'mysqli_set_charset' => ['hasSideEffects' => true],
1468+
'mysqli_set_local_infile_default' => ['hasSideEffects' => true],
1469+
'mysqli_set_local_infile_handler' => ['hasSideEffects' => true],
1470+
'mysqli_set_opt' => ['hasSideEffects' => true],
1471+
'mysqli_sqlstate' => ['hasSideEffects' => true],
1472+
'mysqli_ssl_set' => ['hasSideEffects' => true],
1473+
'mysqli_stat' => ['hasSideEffects' => true],
1474+
'mysqli_stmt_affected_rows' => ['hasSideEffects' => true],
1475+
'mysqli_stmt_attr_get' => ['hasSideEffects' => true],
1476+
'mysqli_stmt_attr_set' => ['hasSideEffects' => true],
1477+
'mysqli_stmt_bind_param' => ['hasSideEffects' => true],
1478+
'mysqli_stmt_bind_result' => ['hasSideEffects' => true],
1479+
'mysqli_stmt_close' => ['hasSideEffects' => true],
1480+
'mysqli_stmt_data_seek' => ['hasSideEffects' => true],
1481+
'mysqli_stmt_errno' => ['hasSideEffects' => true],
1482+
'mysqli_stmt_error' => ['hasSideEffects' => true],
1483+
'mysqli_stmt_error_list' => ['hasSideEffects' => true],
1484+
'mysqli_stmt_execute' => ['hasSideEffects' => true],
1485+
'mysqli_stmt_fetch' => ['hasSideEffects' => true],
1486+
'mysqli_stmt_field_count' => ['hasSideEffects' => true],
1487+
'mysqli_stmt_free_result' => ['hasSideEffects' => true],
1488+
'mysqli_stmt_get_result' => ['hasSideEffects' => true],
1489+
'mysqli_stmt_get_warnings' => ['hasSideEffects' => true],
1490+
'mysqli_stmt_init' => ['hasSideEffects' => true],
1491+
'mysqli_stmt_insert_id' => ['hasSideEffects' => true],
1492+
'mysqli_stmt_more_results' => ['hasSideEffects' => true],
1493+
'mysqli_stmt_next_result' => ['hasSideEffects' => true],
1494+
'mysqli_stmt_num_rows' => ['hasSideEffects' => true],
1495+
'mysqli_stmt_param_count' => ['hasSideEffects' => true],
1496+
'mysqli_stmt_prepare' => ['hasSideEffects' => true],
1497+
'mysqli_stmt_reset' => ['hasSideEffects' => true],
1498+
'mysqli_stmt_result_metadata' => ['hasSideEffects' => true],
1499+
'mysqli_stmt_send_long_data' => ['hasSideEffects' => true],
1500+
'mysqli_stmt_sqlstate' => ['hasSideEffects' => true],
1501+
'mysqli_stmt_store_result' => ['hasSideEffects' => true],
1502+
'mysqli_store_result' => ['hasSideEffects' => true],
1503+
'mysqli_thread_id' => ['hasSideEffects' => true],
1504+
'mysqli_thread_safe' => ['hasSideEffects' => true],
1505+
'mysqli_use_result' => ['hasSideEffects' => true],
1506+
'mysqli_warning_count' => ['hasSideEffects' => true],
13951507
'net_get_interfaces' => ['hasSideEffects' => false],
13961508
'ngettext' => ['hasSideEffects' => false],
13971509
'nl2br' => ['hasSideEffects' => false],

tests/PHPStan/Rules/Comparison/BooleanOrConstantConditionRuleTest.php

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -384,4 +384,11 @@ public function testBug10305(): void
384384
]);
385385
}
386386

387+
public function testBug14473(): void
388+
{
389+
$this->treatPhpDocTypesAsCertain = true;
390+
391+
$this->analyse([__DIR__ . '/data/bug-14473.php'], []);
392+
}
393+
387394
}
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?php declare(strict_types = 1);
2+
3+
namespace Bug14473;
4+
5+
$link = mysqli_connect('host', 'user', 'pass', 'database') or die('Could not connect: ' . mysqli_connect_error());
6+
7+
// (assume long-running code that can cause the connection to time out)
8+
9+
$link = mysqli_connect('host', 'user', 'pass', 'database') or die('Could not reconnect: ' . mysqli_connect_error());
10+
11+
// okay, so let's make certain that the connection is closed
12+
mysqli_close($link);
13+
14+
$link = mysqli_connect('host', 'user', 'pass', 'database') or die('Could not reconnect: ' . mysqli_connect_error());
15+
16+
// close it and destroy the variable
17+
mysqli_close($link);
18+
unset($link);
19+
20+
$link = mysqli_connect('host', 'user', 'pass', 'database') or die('Could not reconnect: ' . mysqli_connect_error());
21+
22+
// close, destroy ...
23+
mysqli_close($link);
24+
unset($link);
25+
26+
// ... and assign to a different variable
27+
$newLink = mysqli_connect('host', 'user', 'pass', 'database') or die('Could not reconnect: ' . mysqli_connect_error());

0 commit comments

Comments
 (0)