Skip to content

EmptySplCollectionExtraction ​

error native on by default PHP ≥ 5.3

Group: Probable bugs

Check that the collection contains an element.

Example ​

Finding:

php
<?php
$q = new SplQueue(); $q->dequeue();

Reported:

  • line 2: Check that the collection contains an element.

Detection ​

  • Track exact builtin SplQueue, SplStack, SplDoublyLinkedList, SplHeap and SplPriorityQueue size from construction, insert/push/unshift/enqueue and extract/pop/shift/dequeue. Report a removal or top/bottom read when the collection is proven empty.
  • Emit one finding per violating operation. Flow facts require a reachable path with no intervening mutation, escaped alias or unknown call involving the tracked value. When the proof is inconclusive, nothing is reported.
  • The history of a call inside a while, do, for or foreach loop covers the whole body of the outermost enclosing loop that does not itself construct the collection, because code written after the call runs before it on the next pass. Within that replayed part an insertion or any unmodeled use discards the proof; an earlier-turn removal may also prevent an exact ordered replay. Unknown receivers of matching mutators prevent a proof when they cannot be distinguished from the tracked collection. A statement label before the call extends the history to the end of the scope in the same way.

Exceptions (no report) ​

Only a fully modeled, bounded history proves emptiness. Array writes, unmodeled methods, conditional insertions and calls receiving the collection discard that proof.

  • Unknown initial collection, aliases escaping or custom method behavior prevent empty proof. Merely potentially empty collections are excluded. The collection variable may appear only as the receiver of a method call or as the target of a plain assignment: any other occurrence (call argument, assigned value stored in a variable, property or array element, array literal item, by-reference binding, array-style write, return, yield, iteration) counts as an escape.
  • Exclude shadowed builtin symbols, unresolved required types, incomplete syntax and unsupported PHP versions.
  • No report when an isEmpty() or count() test on the same receiver, earlier in the scope, controls whether the call runs and holds only for a collection with an element: isEmpty() false, or count() compared with an integer so that zero is excluded (> 0, >= 1, !== 0, === 1, 0 <, a truthy count(), and the failing side of < 1, <= 0 or === 0). The test may be negated, parenthesized, compared with true/false, combined through &&/and and ||/or (a conjunction that holds or a disjunction that failed), or kept in a local read later. It controls the call:
    • in the matching branch of an if/elseif/else chain, of a ternary (including the short ?: form) or of a match (true) arm;
    • in the right operand of &&/and or ||/or;
    • in the body or step of a while or for loop whose condition (the last one of a for) is the test;
    • after an if whose branch for an empty collection always leaves, with or without other arms.

Fix ​

No automatic fix. Choosing a repair requires runtime information, error-handling policy or a semantic decision.

PHP versions ​

Minimum PHP 5.3.

Configure ​

In custos.json:

json
{
  "rules": {
    "EmptySplCollectionExtraction": {
      "enabled": false
    }
  }
}

Suppress ​

Before the statement or declaration (or the first statement of the file):

php
// @custos-ignore EmptySplCollectionExtraction

Released under the MIT License. Native rules and rules modeled on Php Inspections (EA Extended); independent clean-room implementation.