Skip to content

Commit 72f4b58

Browse files
authored
str_split returns an empty array since PHP 8.2
1 parent a6950a1 commit 72f4b58

File tree

5 files changed

+57
-6
lines changed

5 files changed

+57
-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: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5138,6 +5138,14 @@ public function testArrayFunctions(
51385138

51395139
public function dataFunctions(): array
51405140
{
5141+
$strSplitDefaultReturnType = 'non-empty-array<int, string>|false';
5142+
if (PHP_VERSION_ID >= 80000) {
5143+
$strSplitDefaultReturnType = 'non-empty-array<int, string>';
5144+
}
5145+
if (PHP_VERSION_ID >= 80200) {
5146+
$strSplitDefaultReturnType = 'array<int, string>';
5147+
}
5148+
51415149
return [
51425150
[
51435151
'string',
@@ -5328,15 +5336,15 @@ public function dataFunctions(): array
53285336
'$gettimeofdayBenevolent',
53295337
],
53305338
[
5331-
PHP_VERSION_ID < 80000 ? 'non-empty-array<int, string>|false' : 'non-empty-array<int, string>',
5339+
$strSplitDefaultReturnType,
53325340
'$strSplitConstantStringWithoutDefinedParameters',
53335341
],
53345342
[
53355343
'array{\'a\', \'b\', \'c\', \'d\', \'e\', \'f\'}',
53365344
'$strSplitConstantStringWithoutDefinedSplitLength',
53375345
],
53385346
[
5339-
'non-empty-array<int, string>',
5347+
PHP_VERSION_ID < 80200 ? 'non-empty-array<int, string>' : 'array<int, string>',
53405348
'$strSplitStringWithoutDefinedSplitLength',
53415349
],
53425350
[
@@ -5352,15 +5360,15 @@ public function dataFunctions(): array
53525360
'$strSplitConstantStringWithFailureSplitLength',
53535361
],
53545362
[
5355-
PHP_VERSION_ID < 80000 ? 'non-empty-array<int, string>|false' : 'non-empty-array<int, string>',
5363+
$strSplitDefaultReturnType,
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+
$strSplitDefaultReturnType,
53645372
'$strSplitConstantStringWithVariableStringAndVariableSplitLength',
53655373
],
53665374
// parse_url

0 commit comments

Comments
 (0)