ZipFirstEntryTreatedAsMissing
warning native on by default quick-fix PHP ≥ 5.3Group: Probable bugs
Distinguish a missing ZIP entry from index zero.
Example
<?php
$z=new ZipArchive(); if (!$z->locateName("settings.json")) { echo "missing"; }Reported:
- line 2: Distinguish a missing ZIP entry from index zero.
Detection
- Report a resolved ZipArchive::locateName call whose result is the whole condition of an
if,elseif,whileordo/while, either directly, negated once with!, or through a plain=assignment in that condition. Zero is a valid index. Highlight the negation when there is one, otherwise the condition expression (including the assignment). - Resolve builtin functions, extension classes, method receivers, constants and named arguments. Follow unchanged locals and aliases only within the same bounded lexical scope. Require a reachable path; merge branch facts only when all incoming paths establish them.
- Emit one finding at the violating operation, not one per evidence statement. Rebinding, writes, by-reference escape, unresolved calls that can mutate relevant state, and exhausted analysis budgets remove proof.
- Report a loose comparison (
==,!=,<>) of that call, or of a plain=assignment of it, with thefalseconstant on either side, wherever the comparison appears. Highlight the whole comparison. Strict false comparisons, comparisons with other values and later separate comparisons are excluded.
Exceptions (no report)
Preserve assignment precedence in negated conditions: the repaired comparison surrounds an unparenthesized assignment before comparing its result with false.
- Exclude shadowed builtins, unresolved receivers, incomplete syntax and unknown prerequisite facts. An extension function name alone does not prove an application function is that builtin.
- A dominating valid guard or repair described in Detection prevents the finding. Both legacy noinspection and custos-ignore forms suppress this ID.
- A compound assignment in the condition (
.=,??=,+=and the like) is not reported: its value is the combined or pre-existing value, not the lookup result. - A doubled negation, another unary operator, or a call that is only one operand of a larger condition is not reported.
Fix
Replace !call with call === false and positive call truthiness with call !== false, wrapping an unparenthesized assignment in parentheses first. For a loose comparison replace only the operator: == becomes ===, != and <> become !==. The call is evaluated exactly once either way.
Report without a fix when:
- the call is nullsafe, or its receiver chain contains a nullsafe access: a short-circuited chain yields null, which the original condition treats as missing but a strict comparison with false does not;
- a comment sits between the
!and its operand, since the rewrite would drop it.
All edits use exact byte ranges and preserve comments and evaluation order. Offer no fix when its stated prerequisites cannot be proven or the replacement is unsupported by the configured PHP version.
PHP versions
Requires PHP 5.3 or later and the referenced extension API. Respect method-specific introduction versions within PHP 5.3–8.5; unsupported optional APIs cannot establish facts. Named arguments require PHP 8.0 or later.
Configure
In custos.json:
{
"rules": {
"ZipFirstEntryTreatedAsMissing": {
"enabled": false
}
}
}Suppress
Before the statement or declaration (or the first statement of the file):
// @custos-ignore ZipFirstEntryTreatedAsMissing