Skip to content

Commit 032ae7d

Browse files
committed
str_split returns an empty array since PHP 8.2
1 parent a6950a1 commit 032ae7d

File tree

5 files changed

+61
-6
lines changed

5 files changed

+61
-6
lines changed

resources/functionMap_php82delta.php

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
<?php // phpcs:ignoreFile
2+
3+
/**
4+
* Copied over from https://github.com/phan/phan/blob/8866d6b98be94b37996390da226e8c4befea29aa/src/Phan/Language/Internal/FunctionSignatureMap_php80_delta.php
5+
* Copyright (c) 2015 Rasmus Lerdorf
6+
* Copyright (c) 2015 Andrew Morrison
7+
*/
8+
9+
/**
10+
* This contains the information needed to convert the function signatures for php 8.0 to php 7.4 (and vice versa)
11+
*
12+
* This has two sections.
13+
* The 'new' section contains function/method names from FunctionSignatureMap (And alternates, if applicable) that do not exist in php7.4 or have different signatures in php 8.0.
14+
* If they were just updated, the function/method will be present in the 'added' signatures.
15+
* The 'old' signatures contains the signatures that are different in php 7.4.
16+
* Functions are expected to be removed only in major releases of php.
17+
*
18+
* @see FunctionSignatureMap.php
19+
*
20+
* @phan-file-suppress PhanPluginMixedKeyNoKey (read by Phan when analyzing this file)
21+
*/
22+
return [
23+
'new' => [
24+
'str_split' => ['array<int,string>', 'str'=>'string', 'split_length='=>'positive-int'],
25+
],
26+
'old' => [
27+
28+
]
29+
];

src/Php/PhpVersion.php

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,4 +196,9 @@ public function deprecatesDynamicProperties(): bool
196196
return $this->versionId >= 80200;
197197
}
198198

199+
public function strSplitReturnsEmptyArray(): bool
200+
{
201+
return $this->versionId >= 80200;
202+
}
203+
199204
}

src/Reflection/SignatureMap/FunctionSignatureMapProvider.php

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -204,6 +204,15 @@ public function getSignatureMap(): array
204204
$signatureMap = $this->computeSignatureMap($signatureMap, $php81MapDelta);
205205
}
206206

207+
if ($this->phpVersion->getVersionId() >= 80200) {
208+
$php82MapDelta = require __DIR__ . '/../../../resources/functionMap_php82delta.php';
209+
if (!is_array($php82MapDelta)) {
210+
throw new ShouldNotHappenException('Signature map could not be loaded.');
211+
}
212+
213+
$signatureMap = $this->computeSignatureMap($signatureMap, $php82MapDelta);
214+
}
215+
207216
$this->signatureMap = $signatureMap;
208217
}
209218

src/Type/Php/StrSplitFunctionReturnTypeExtension.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -90,15 +90,15 @@ public function getTypeFromFunctionCall(FunctionReflection $functionReflection,
9090

9191
$stringType = $scope->getType($functionCall->getArgs()[0]->value);
9292

93-
return TypeTraverser::map($stringType, static function (Type $type, callable $traverse) use ($encoding, $splitLength, $scope): Type {
93+
return TypeTraverser::map($stringType, function (Type $type, callable $traverse) use ($encoding, $splitLength, $scope): Type {
9494
if ($type instanceof UnionType || $type instanceof IntersectionType) {
9595
return $traverse($type);
9696
}
9797

9898
if (!$type instanceof ConstantStringType) {
9999
$returnType = new ArrayType(new IntegerType(), new StringType());
100100

101-
return $encoding === null
101+
return $encoding === null && !$this->phpVersion->strSplitReturnsEmptyArray()
102102
? TypeCombinator::intersect($returnType, new NonEmptyArrayType())
103103
: $returnType;
104104
}

tests/PHPStan/Analyser/LegacyNodeScopeResolverTest.php

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5328,15 +5328,19 @@ public function dataFunctions(): array
53285328
'$gettimeofdayBenevolent',
53295329
],
53305330
[
5331-
PHP_VERSION_ID < 80000 ? 'non-empty-array<int, string>|false' : 'non-empty-array<int, string>',
5331+
match (true) {
5332+
PHP_VERSION_ID >= 80200 => 'array<int, string>',
5333+
PHP_VERSION_ID >= 80000 => 'non-empty-array<int, string>',
5334+
default => 'non-empty-array<int, string>|false',
5335+
},
53325336
'$strSplitConstantStringWithoutDefinedParameters',
53335337
],
53345338
[
53355339
'array{\'a\', \'b\', \'c\', \'d\', \'e\', \'f\'}',
53365340
'$strSplitConstantStringWithoutDefinedSplitLength',
53375341
],
53385342
[
5339-
'non-empty-array<int, string>',
5343+
PHP_VERSION_ID < 80200 ? 'non-empty-array<int, string>' : 'array<int, string>',
53405344
'$strSplitStringWithoutDefinedSplitLength',
53415345
],
53425346
[
@@ -5352,15 +5356,23 @@ public function dataFunctions(): array
53525356
'$strSplitConstantStringWithFailureSplitLength',
53535357
],
53545358
[
5355-
PHP_VERSION_ID < 80000 ? 'non-empty-array<int, string>|false' : 'non-empty-array<int, string>',
5359+
match (true) {
5360+
PHP_VERSION_ID >= 80200 => 'array<int, string>',
5361+
PHP_VERSION_ID >= 80000 => 'non-empty-array<int, string>',
5362+
default => 'non-empty-array<int, string>|false',
5363+
},
53565364
'$strSplitConstantStringWithInvalidSplitLengthType',
53575365
],
53585366
[
53595367
'array{\'a\'|\'g\', \'b\'|\'h\', \'c\'|\'i\', \'d\'|\'j\', \'e\'|\'k\', \'f\'|\'l\'}',
53605368
'$strSplitConstantStringWithVariableStringAndConstantSplitLength',
53615369
],
53625370
[
5363-
PHP_VERSION_ID < 80000 ? 'non-empty-array<int, string>|false' : 'non-empty-array<int, string>',
5371+
match (true) {
5372+
PHP_VERSION_ID >= 80200 => 'array<int, string>',
5373+
PHP_VERSION_ID >= 80000 => 'non-empty-array<int, string>',
5374+
default => 'non-empty-array<int, string>|false',
5375+
},
53645376
'$strSplitConstantStringWithVariableStringAndVariableSplitLength',
53655377
],
53665378
// parse_url

0 commit comments

Comments
 (0)