Skip to content

Commit 1faa747

Browse files
authored
Update curl_getinfo() return types
1 parent 275f816 commit 1faa747

File tree

7 files changed

+136
-30
lines changed

7 files changed

+136
-30
lines changed

src/Type/Php/CurlGetinfoFunctionDynamicReturnTypeExtension.php

Lines changed: 49 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
use PHPStan\DependencyInjection\AutowiredService;
99
use PHPStan\Reflection\FunctionReflection;
1010
use PHPStan\Reflection\ReflectionProvider;
11+
use PHPStan\Type\Accessory\AccessoryArrayListType;
1112
use PHPStan\Type\ArrayType;
1213
use PHPStan\Type\Constant\ConstantArrayTypeBuilder;
1314
use PHPStan\Type\Constant\ConstantBooleanType;
@@ -16,6 +17,7 @@
1617
use PHPStan\Type\DynamicFunctionReturnTypeExtension;
1718
use PHPStan\Type\FloatType;
1819
use PHPStan\Type\IntegerType;
20+
use PHPStan\Type\MixedType;
1921
use PHPStan\Type\NullType;
2022
use PHPStan\Type\StringType;
2123
use PHPStan\Type\Type;
@@ -63,8 +65,10 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
6365
$floatType = new FloatType();
6466
$falseType = new ConstantBooleanType(false);
6567
$stringFalseType = TypeCombinator::union($stringType, $falseType);
66-
$integerStringArrayType = new ArrayType($integerType, $stringType);
67-
$nestedStringStringArrayType = new ArrayType($integerType, new ArrayType($stringType, $stringType));
68+
$integerFalseType = TypeCombinator::union($integerType, $falseType);
69+
$stringListType = TypeCombinator::intersect(new ArrayType($integerType, $stringType), new AccessoryArrayListType());
70+
$nestedArrayInListType = TypeCombinator::intersect(new ArrayType($integerType, new ArrayType($stringType, $stringType)), new AccessoryArrayListType());
71+
$mixedType = new MixedType();
6872

6973
$componentTypesPairedConstants = [
7074
'CURLINFO_EFFECTIVE_URL' => $stringType,
@@ -76,41 +80,42 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
7680
'CURLINFO_STARTTRANSFER_TIME' => $floatType,
7781
'CURLINFO_REDIRECT_COUNT' => $integerType,
7882
'CURLINFO_REDIRECT_TIME' => $floatType,
79-
'CURLINFO_REDIRECT_URL' => $stringType,
83+
'CURLINFO_REDIRECT_URL' => $stringFalseType,
8084
'CURLINFO_PRIMARY_IP' => $stringType,
8185
'CURLINFO_PRIMARY_PORT' => $integerType,
8286
'CURLINFO_LOCAL_IP' => $stringType,
8387
'CURLINFO_LOCAL_PORT' => $integerType,
84-
'CURLINFO_SIZE_UPLOAD' => $integerType,
85-
'CURLINFO_SIZE_DOWNLOAD' => $integerType,
86-
'CURLINFO_SPEED_DOWNLOAD' => $integerType,
87-
'CURLINFO_SPEED_UPLOAD' => $integerType,
88+
'CURLINFO_SIZE_UPLOAD' => $floatType,
89+
'CURLINFO_SIZE_DOWNLOAD' => $floatType,
90+
'CURLINFO_SPEED_DOWNLOAD' => $floatType,
91+
'CURLINFO_SPEED_UPLOAD' => $floatType,
8892
'CURLINFO_HEADER_SIZE' => $integerType,
8993
'CURLINFO_HEADER_OUT' => $stringFalseType,
9094
'CURLINFO_REQUEST_SIZE' => $integerType,
9195
'CURLINFO_SSL_VERIFYRESULT' => $integerType,
9296
'CURLINFO_CONTENT_LENGTH_DOWNLOAD' => $floatType,
9397
'CURLINFO_CONTENT_LENGTH_UPLOAD' => $floatType,
9498
'CURLINFO_CONTENT_TYPE' => $stringFalseType,
95-
'CURLINFO_PRIVATE' => $stringFalseType,
99+
'CURLINFO_PRIVATE' => $mixedType,
96100
'CURLINFO_RESPONSE_CODE' => $integerType,
101+
'CURLINFO_HTTP_CODE' => $integerType,
97102
'CURLINFO_HTTP_CONNECTCODE' => $integerType,
98103
'CURLINFO_HTTPAUTH_AVAIL' => $integerType,
99104
'CURLINFO_PROXYAUTH_AVAIL' => $integerType,
100105
'CURLINFO_OS_ERRNO' => $integerType,
101106
'CURLINFO_NUM_CONNECTS' => $integerType,
102-
'CURLINFO_SSL_ENGINES' => $integerStringArrayType,
103-
'CURLINFO_COOKIELIST' => $integerStringArrayType,
107+
'CURLINFO_SSL_ENGINES' => $stringListType,
108+
'CURLINFO_COOKIELIST' => $stringListType,
104109
'CURLINFO_FTP_ENTRY_PATH' => $stringFalseType,
105110
'CURLINFO_APPCONNECT_TIME' => $floatType,
106-
'CURLINFO_CERTINFO' => $nestedStringStringArrayType,
111+
'CURLINFO_CERTINFO' => $nestedArrayInListType,
107112
'CURLINFO_CONDITION_UNMET' => $integerType,
108113
'CURLINFO_RTSP_CLIENT_CSEQ' => $integerType,
109114
'CURLINFO_RTSP_CSEQ_RECV' => $integerType,
110115
'CURLINFO_RTSP_SERVER_CSEQ' => $integerType,
111-
'CURLINFO_RTSP_SESSION_ID' => $integerType,
116+
'CURLINFO_RTSP_SESSION_ID' => $stringFalseType,
112117
'CURLINFO_HTTP_VERSION' => $integerType,
113-
'CURLINFO_PROTOCOL' => $stringType,
118+
'CURLINFO_PROTOCOL' => $integerType,
114119
'CURLINFO_PROXY_SSL_VERIFYRESULT' => $integerType,
115120
'CURLINFO_SCHEME' => $stringType,
116121
'CURLINFO_CONTENT_LENGTH_DOWNLOAD_T' => $integerType,
@@ -127,6 +132,18 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
127132
'CURLINFO_REDIRECT_TIME_T' => $integerType,
128133
'CURLINFO_STARTTRANSFER_TIME_T' => $integerType,
129134
'CURLINFO_TOTAL_TIME_T' => $integerType,
135+
'CURLINFO_EFFECTIVE_METHOD' => $stringType,
136+
'CURLINFO_PROXY_ERROR' => $integerType,
137+
'CURLINFO_REFERER' => $stringFalseType,
138+
'CURLINFO_RETRY_AFTER' => $integerType,
139+
'CURLINFO_CAINFO' => $stringFalseType,
140+
'CURLINFO_CAPATH' => $stringFalseType,
141+
'CURLINFO_POSTTRANSFER_TIME_T' => $integerFalseType,
142+
'CURLINFO_QUEUE_TIME_T' => $integerFalseType,
143+
'CURLINFO_USED_PROXY' => $integerFalseType,
144+
'CURLINFO_HTTPAUTH_USED' => $integerFalseType,
145+
'CURLINFO_PROXYAUTH_USED' => $integerFalseType,
146+
'CURLINFO_CONN_ID' => $integerFalseType,
130147
];
131148

132149
foreach ($componentTypesPairedConstants as $constantName => $type) {
@@ -156,7 +173,7 @@ private function createAllComponentsReturnType(): Type
156173
$integerType = new IntegerType();
157174
$floatType = new FloatType();
158175
$stringOrNullType = TypeCombinator::union($stringType, new NullType());
159-
$nestedStringStringArrayType = new ArrayType($integerType, new ArrayType($stringType, $stringType));
176+
$nestedArrayInListType = TypeCombinator::intersect(new ArrayType($integerType, new ArrayType($stringType, $stringType)), new AccessoryArrayListType());
160177

161178
$componentTypesPairedStrings = [
162179
'url' => $stringType,
@@ -181,14 +198,31 @@ private function createAllComponentsReturnType(): Type
181198
'redirect_time' => $floatType,
182199
'redirect_url' => $stringType,
183200
'primary_ip' => $stringType,
184-
'certinfo' => $nestedStringStringArrayType,
201+
'certinfo' => $nestedArrayInListType,
185202
'primary_port' => $integerType,
186203
'local_ip' => $stringType,
187204
'local_port' => $integerType,
188205
'http_version' => $integerType,
189206
'protocol' => $integerType,
190207
'ssl_verifyresult' => $integerType,
191208
'scheme' => $stringType,
209+
'appconnect_time_us' => $integerType,
210+
'queue_time_us' => $integerType,
211+
'connect_time_us' => $integerType,
212+
'namelookup_time_us' => $integerType,
213+
'pretransfer_time_us' => $integerType,
214+
'redirect_time_us' => $integerType,
215+
'starttransfer_time_us' => $integerType,
216+
'posttransfer_time_us' => $integerType,
217+
'total_time_us' => $integerType,
218+
'request_header' => $stringType,
219+
'effective_method' => $stringType,
220+
'capath' => $stringType,
221+
'cainfo' => $stringType,
222+
'used_proxy' => $integerType,
223+
'httpauth_used' => $integerType,
224+
'proxyauth_used' => $integerType,
225+
'conn_id' => $integerType,
192226
];
193227
foreach ($componentTypesPairedStrings as $componentName => $componentValueType) {
194228
$builder->setOffsetValueType(new ConstantStringType($componentName), $componentValueType);

tests/PHPStan/Analyser/nsrt/curl_getinfo.php

Lines changed: 16 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -9,15 +9,17 @@ class Foo
99
{
1010
public function bar()
1111
{
12+
$curlGetInfoType = '(array{url: string, content_type: string|null, http_code: int, header_size: int, request_size: int, filetime: int, ssl_verify_result: int, redirect_count: int, total_time: float, namelookup_time: float, connect_time: float, pretransfer_time: float, size_upload: float, size_download: float, speed_download: float, speed_upload: float, download_content_length: float, upload_content_length: float, starttransfer_time: float, redirect_time: float, redirect_url: string, primary_ip: string, certinfo: list<array<string, string>>, primary_port: int, local_ip: string, local_port: int, http_version: int, protocol: int, ssl_verifyresult: int, scheme: string, appconnect_time_us: int, queue_time_us: int, connect_time_us: int, namelookup_time_us: int, pretransfer_time_us: int, redirect_time_us: int, starttransfer_time_us: int, posttransfer_time_us: int, total_time_us: int, request_header: string, effective_method: string, capath: string, cainfo: string, used_proxy: int, httpauth_used: int, proxyauth_used: int, conn_id: int}|false)';
13+
1214
$handle = new CurlHandle();
1315
assertType('mixed', curl_getinfo());
1416
assertType('mixed', CURL_GETINFO());
1517
assertType('mixed', CuRl_GeTiNfO());
1618
assertType('false', curl_getinfo($handle, 'Invalid Argument'));
17-
assertType('(array{url: string, content_type: string|null, http_code: int, header_size: int, request_size: int, filetime: int, ssl_verify_result: int, redirect_count: int, total_time: float, namelookup_time: float, connect_time: float, pretransfer_time: float, size_upload: float, size_download: float, speed_download: float, speed_upload: float, download_content_length: float, upload_content_length: float, starttransfer_time: float, redirect_time: float, redirect_url: string, primary_ip: string, certinfo: array<int, array<string, string>>, primary_port: int, local_ip: string, local_port: int, http_version: int, protocol: int, ssl_verifyresult: int, scheme: string}|false)', curl_getinfo($handle, PHP_INT_MAX));
19+
assertType($curlGetInfoType, curl_getinfo($handle, PHP_INT_MAX));
1820
assertType('false', curl_getinfo($handle, PHP_EOL));
19-
assertType('(array{url: string, content_type: string|null, http_code: int, header_size: int, request_size: int, filetime: int, ssl_verify_result: int, redirect_count: int, total_time: float, namelookup_time: float, connect_time: float, pretransfer_time: float, size_upload: float, size_download: float, speed_download: float, speed_upload: float, download_content_length: float, upload_content_length: float, starttransfer_time: float, redirect_time: float, redirect_url: string, primary_ip: string, certinfo: array<int, array<string, string>>, primary_port: int, local_ip: string, local_port: int, http_version: int, protocol: int, ssl_verifyresult: int, scheme: string}|false)', curl_getinfo($handle));
20-
assertType('(array{url: string, content_type: string|null, http_code: int, header_size: int, request_size: int, filetime: int, ssl_verify_result: int, redirect_count: int, total_time: float, namelookup_time: float, connect_time: float, pretransfer_time: float, size_upload: float, size_download: float, speed_download: float, speed_upload: float, download_content_length: float, upload_content_length: float, starttransfer_time: float, redirect_time: float, redirect_url: string, primary_ip: string, certinfo: array<int, array<string, string>>, primary_port: int, local_ip: string, local_port: int, http_version: int, protocol: int, ssl_verifyresult: int, scheme: string}|false)', curl_getinfo($handle, null));
21+
assertType($curlGetInfoType, curl_getinfo($handle));
22+
assertType($curlGetInfoType, curl_getinfo($handle, null));
2123
assertType('string', curl_getinfo($handle, CURLINFO_EFFECTIVE_URL));
2224
assertType('string', curl_getinfo($handle, 1048577)); // CURLINFO_EFFECTIVE_URL int value without using constant
2325
assertType('false', curl_getinfo($handle, 12345678)); // Non constant non CURLINFO_* int value
@@ -29,38 +31,39 @@ public function bar()
2931
assertType('float', curl_getinfo($handle, CURLINFO_STARTTRANSFER_TIME));
3032
assertType('int', curl_getinfo($handle, CURLINFO_REDIRECT_COUNT));
3133
assertType('float', curl_getinfo($handle, CURLINFO_REDIRECT_TIME));
32-
assertType('string', curl_getinfo($handle, CURLINFO_REDIRECT_URL));
34+
assertType('string|false', curl_getinfo($handle, CURLINFO_REDIRECT_URL));
3335
assertType('string', curl_getinfo($handle, CURLINFO_PRIMARY_IP));
3436
assertType('int', curl_getinfo($handle, CURLINFO_PRIMARY_PORT));
3537
assertType('string', curl_getinfo($handle, CURLINFO_LOCAL_IP));
3638
assertType('int', curl_getinfo($handle, CURLINFO_LOCAL_PORT));
37-
assertType('int', curl_getinfo($handle, CURLINFO_SIZE_UPLOAD));
38-
assertType('int', curl_getinfo($handle, CURLINFO_SIZE_DOWNLOAD));
39-
assertType('int', curl_getinfo($handle, CURLINFO_SPEED_DOWNLOAD));
40-
assertType('int', curl_getinfo($handle, CURLINFO_SPEED_UPLOAD));
39+
assertType('float', curl_getinfo($handle, CURLINFO_SIZE_UPLOAD));
40+
assertType('float', curl_getinfo($handle, CURLINFO_SIZE_DOWNLOAD));
41+
assertType('float', curl_getinfo($handle, CURLINFO_SPEED_DOWNLOAD));
42+
assertType('float', curl_getinfo($handle, CURLINFO_SPEED_UPLOAD));
4143
assertType('int', curl_getinfo($handle, CURLINFO_HEADER_SIZE));
4244
assertType('string|false', curl_getinfo($handle, CURLINFO_HEADER_OUT));
4345
assertType('int', curl_getinfo($handle, CURLINFO_REQUEST_SIZE));
4446
assertType('int', curl_getinfo($handle, CURLINFO_SSL_VERIFYRESULT));
4547
assertType('float', curl_getinfo($handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD));
4648
assertType('float', curl_getinfo($handle, CURLINFO_CONTENT_LENGTH_UPLOAD));
4749
assertType('string|false', curl_getinfo($handle, CURLINFO_CONTENT_TYPE));
48-
assertType('string|false', curl_getinfo($handle, CURLINFO_PRIVATE));
50+
assertType('mixed', curl_getinfo($handle, CURLINFO_PRIVATE));
4951
assertType('int', curl_getinfo($handle, CURLINFO_RESPONSE_CODE));
52+
assertType('int', curl_getinfo($handle, CURLINFO_HTTP_CODE));;
5053
assertType('int', curl_getinfo($handle, CURLINFO_HTTP_CONNECTCODE));
5154
assertType('int', curl_getinfo($handle, CURLINFO_HTTPAUTH_AVAIL));
5255
assertType('int', curl_getinfo($handle, CURLINFO_PROXYAUTH_AVAIL));
5356
assertType('int', curl_getinfo($handle, CURLINFO_OS_ERRNO));
5457
assertType('int', curl_getinfo($handle, CURLINFO_NUM_CONNECTS));
55-
assertType('array<int, string>', curl_getinfo($handle, CURLINFO_SSL_ENGINES));
56-
assertType('array<int, string>', curl_getinfo($handle, CURLINFO_COOKIELIST));
58+
assertType('list<string>', curl_getinfo($handle, CURLINFO_SSL_ENGINES));
59+
assertType('list<string>', curl_getinfo($handle, CURLINFO_COOKIELIST));
5760
assertType('string|false', curl_getinfo($handle, CURLINFO_FTP_ENTRY_PATH));
5861
assertType('float', curl_getinfo($handle, CURLINFO_APPCONNECT_TIME));
59-
assertType('array<int, array<string, string>>', curl_getinfo($handle, CURLINFO_CERTINFO));
62+
assertType('list<array<string, string>>', curl_getinfo($handle, CURLINFO_CERTINFO));
6063
assertType('int', curl_getinfo($handle, CURLINFO_CONDITION_UNMET));
6164
assertType('int', curl_getinfo($handle, CURLINFO_RTSP_CLIENT_CSEQ));
6265
assertType('int', curl_getinfo($handle, CURLINFO_RTSP_CSEQ_RECV));
6366
assertType('int', curl_getinfo($handle, CURLINFO_RTSP_SERVER_CSEQ));
64-
assertType('int', curl_getinfo($handle, CURLINFO_RTSP_SESSION_ID));
67+
assertType('string|false', curl_getinfo($handle, CURLINFO_RTSP_SESSION_ID));
6568
}
6669
}

tests/PHPStan/Analyser/nsrt/curl_getinfo_7.3.php

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@
55
use CurlHandle;
66
use function PHPStan\Testing\assertType;
77

8-
class Foo {
8+
class Foo
9+
{
910
public function bar()
1011
{
1112
$handle = new CurlHandle();
1213
assertType('int', curl_getinfo($handle, CURLINFO_CONTENT_LENGTH_DOWNLOAD_T));
1314
assertType('int', curl_getinfo($handle, CURLINFO_CONTENT_LENGTH_UPLOAD_T));
1415
assertType('int', curl_getinfo($handle, CURLINFO_HTTP_VERSION));
15-
assertType('string', curl_getinfo($handle, CURLINFO_PROTOCOL));
16+
assertType('int', curl_getinfo($handle, CURLINFO_PROTOCOL));
1617
assertType('int', curl_getinfo($handle, CURLINFO_PROXY_SSL_VERIFYRESULT));
1718
assertType('string', curl_getinfo($handle, CURLINFO_SCHEME));
1819
assertType('int', curl_getinfo($handle, CURLINFO_SIZE_DOWNLOAD_T));
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
<?php // lint >= 8.2
2+
3+
namespace CurlGetinfo82;
4+
5+
use CurlHandle;
6+
use function PHPStan\Testing\assertType;
7+
8+
class Foo
9+
{
10+
public function bar()
11+
{
12+
$handle = new CurlHandle();
13+
assertType('string', curl_getinfo($handle, CURLINFO_EFFECTIVE_METHOD));
14+
assertType('int', curl_getinfo($handle, CURLINFO_PROXY_ERROR));
15+
assertType('string|false', curl_getinfo($handle, CURLINFO_REFERER));
16+
assertType('int', curl_getinfo($handle, CURLINFO_RETRY_AFTER));
17+
}
18+
}
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
<?php // lint >= 8.3
2+
3+
namespace CurlGetinfo83;
4+
5+
use CurlHandle;
6+
use function PHPStan\Testing\assertType;
7+
8+
class Foo
9+
{
10+
public function bar()
11+
{
12+
$handle = new CurlHandle();
13+
assertType('string|false', curl_getinfo($handle, CURLINFO_CAINFO));
14+
assertType('string|false', curl_getinfo($handle, CURLINFO_CAPATH));
15+
}
16+
}
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
<?php // lint >= 8.4
2+
3+
namespace CurlGetinfo84;
4+
5+
use CurlHandle;
6+
use function PHPStan\Testing\assertType;
7+
8+
class Foo
9+
{
10+
public function bar()
11+
{
12+
$handle = new CurlHandle();
13+
assertType('int|false', curl_getinfo($handle, CURLINFO_POSTTRANSFER_TIME_T));
14+
}
15+
}
Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<?php // lint >= 8.5
2+
3+
namespace CurlGetinfo85;
4+
5+
use CurlHandle;
6+
use function PHPStan\Testing\assertType;
7+
8+
class Foo
9+
{
10+
public function bar()
11+
{
12+
$handle = new CurlHandle();
13+
assertType('int|false', curl_getinfo($handle, CURLINFO_QUEUE_TIME_T));
14+
assertType('int|false', curl_getinfo($handle, CURLINFO_USED_PROXY));
15+
assertType('int|false', curl_getinfo($handle, CURLINFO_HTTPAUTH_USED));
16+
assertType('int|false', curl_getinfo($handle, CURLINFO_PROXYAUTH_USED));
17+
assertType('int|false', curl_getinfo($handle, CURLINFO_CONN_ID));
18+
}
19+
}

0 commit comments

Comments
 (0)