Declare mutually exclusive constant groups for json_encode, json_decode, filter_var, filter_input, openlog and ZipArchive::open flags - #6571
Merged
staabm merged 2 commits intoSep 24, 2026
Conversation
VincentLanglet
approved these changes
Sep 24, 2026
…ecode`, `filter_var`, `filter_input`, `openlog` and `ZipArchive::open` flags - json_encode/json_decode $flags: JSON_INVALID_UTF8_IGNORE and JSON_INVALID_UTF8_SUBSTITUTE are exclusive (IGNORE silently wins) - json_encode $flags: JSON_PARTIAL_OUTPUT_ON_ERROR and JSON_THROW_ON_ERROR are exclusive (partial output makes php-src skip the throw) - filter_var/filter_input $options: FILTER_REQUIRE_SCALAR and FILTER_REQUIRE_ARRAY are exclusive (every input fails) - openlog $flags: LOG_NDELAY and LOG_ODELAY are exclusive - ZipArchive::open $flags: ZipArchive::RDONLY and ZipArchive::OVERWRITE are exclusive (libzip rejects ZIP_RDONLY | ZIP_TRUNCATE) - Not added: FILTER_NULL_ON_FAILURE | FILTER_THROW_ON_FAILURE. FilterVarRule already reports it, so a group here would report it twice. - Checked the other bitmask parameters in the map (preg_*, file, file_put_contents, glob, fnmatch, finfo, stream_socket_*, socket_*, idn_*, openssl_pkcs7_*, iconv_mime_decode, ob_start, DatePeriod, libxml options, and others). Their flags can be combined, or combining them is only redundant, not contradictory. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
staabm
force-pushed
the
create-pull-request/patch-8d54l49
branch
from
September 24, 2026 08:21
42f523c to
ca0457f
Compare
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
PHPStan can already report constants that should not be combined in a bitmask parameter (
argument.exclusiveConstants). Butresources/constantToFunctionParameterMap.phponly listed such groups for a few functions (sort functions,preg_match_all,htmlspecialchars,flock, mysqli, PDO, FilesystemIterator). This PR adds the groups that were missing. For example,json_decode(..., JSON_INVALID_UTF8_IGNORE | JSON_INVALID_UTF8_SUBSTITUTE)from the issue is now reported.Changes
All data changes are in
resources/constantToFunctionParameterMap.php:json_encode/json_decode$flags:JSON_INVALID_UTF8_IGNOREandJSON_INVALID_UTF8_SUBSTITUTE. When both are set, IGNORE wins without any warning.json_encode$flags:JSON_PARTIAL_OUTPUT_ON_ERRORandJSON_THROW_ON_ERROR. With partial output set, php-src never throws, soJSON_THROW_ON_ERRORhas no effect.filter_var/filter_input$options:FILTER_REQUIRE_SCALARandFILTER_REQUIRE_ARRAY. With both set, every input fails.openlog$flags:LOG_NDELAYandLOG_ODELAY. One opens the connection immediately, the other delays it.ZipArchive::open$flags:ZipArchive::RDONLYandZipArchive::OVERWRITE. libzip rejectsZIP_RDONLY | ZIP_TRUNCATEwithZIP_ER_RDONLY.Not added:
FILTER_NULL_ON_FAILURE | FILTER_THROW_ON_FAILURE:FilterVarRule(filterVar.nullOnFailureAndThrowOnFailure) already reports this. A group here would report it a second time.preg_*,file,file_put_contents,glob,fnmatch,finfo*,stream_socket_*,socket_*,idn_*,openssl_pkcs7_*,iconv_mime_decode*,ob_start,msg_receive,debug_backtrace,dns_get_record,DatePeriod, and the libxml options. I went through them and found no flags that contradict each other. Some combinations are only redundant, e.g.FILEINFO_MIMEtogether withFILEINFO_MIME_TYPE, orDNS_ALLtogether with specific record types.Root cause
The exclusive-group check (
ParameterAllowedConstants::check(), whichFunctionCallParametersCheckreports) was already in place. The map simply had no exclusive-group data for these parameters.Test
tests/PHPStan/Rules/Functions/data/bug-15306.php(CallToFunctionParametersRuleTest::testBug15306) coversjson_decode,json_encode,filter_var,filter_inputandopenlog. It includes cases that must be reported and valid combinations that must not be.tests/PHPStan/Rules/Methods/data/bug-15306.php(CallMethodsRuleTest::testBug15306) coversZipArchive::open.Fixes phpstan/phpstan#15306
🤖 Generated with Claude Code