Skip to content

SubStrUsedAsStrPos ​

info on by default quick-fix

Group: Control flow · PhpStorm name: SubStrUsedAsStrPosInspection

Checking a prefix by cutting it out with substr($s, 0, …) and comparing the piece is the long way of asking "does $s start with this?". The idiomatic form is a position search compared strictly against 0 (strpos($s, $prefix) === 0), or its case-insensitive variant when the cut piece was case-folded first.

Example ​

php
<?php
function routes($uri, $base, $enc) {
    $r = [];
    $r[] = substr($uri, 0, strlen($base)) == $base;
    $r[] = '/api' !== substr($uri, 0, 4);
    $r[] = \mb_substr($uri, 0, mb_strlen($base)) === $base;
    $r[] = mb_substr($uri, 0, mb_strlen($base, $enc), $enc) != $base;
    $r[] = mb_strtolower(substr($uri, 0, 4)) === 'get:';
    $r[] = strtoupper(mb_substr($uri, 0, mb_strlen('POST'))) == 'POST';

    $r[] = substr($uri, 1, strlen($base)) == $base;
    $r[] = substr($uri, 0, strpos($uri, '?')) == $base;
    $r[] = substr($uri, 0, 3) == $base;
    $r[] = substr($uri, 0, 5) == '/api';
    $r[] = mb_substr($uri, 0, strlen($base)) == $base;
    $r[] = strtoupper(substr($uri, 0, strlen($base))) == $base;
    $r[] = trim(substr($uri, 0, strlen($base))) == $base;
    $r[] = (substr($uri, 0, strlen($base))) == $base;
    $r[] = substr($uri, 0, strlen($base)) < $base;
    $r[] = substr($uri, 0) == $base;
    return $r;
}
php
<?php
function routes($uri, $base, $enc) {
    $r = [];
    $r[] = strpos($uri, $base) === 0;
    $r[] = strpos($uri, '/api') !== 0;
    $r[] = \mb_strpos($uri, $base) === 0;
    $r[] = mb_strpos($uri, $base, 0, $enc) !== 0;
    $r[] = stripos($uri, 'get:') === 0;
    $r[] = mb_stripos($uri, 'POST') === 0;

    $r[] = substr($uri, 1, strlen($base)) == $base;
    $r[] = substr($uri, 0, strpos($uri, '?')) == $base;
    $r[] = substr($uri, 0, 3) == $base;
    $r[] = substr($uri, 0, 5) == '/api';
    $r[] = mb_substr($uri, 0, strlen($base)) == $base;
    $r[] = strtoupper(substr($uri, 0, strlen($base))) == $base;
    $r[] = trim(substr($uri, 0, strlen($base))) == $base;
    $r[] = (substr($uri, 0, strlen($base))) == $base;
    $r[] = substr($uri, 0, strlen($base)) < $base;
    $r[] = substr($uri, 0) == $base;
    return $r;
}

Reported:

  • line 4: Use 'strpos($uri, $base) === 0' instead.
  • line 5: Use 'strpos($uri, '/api') !== 0' instead.
  • line 6: Use '\mb_strpos($uri, $base) === 0' instead.
  • line 7: Use 'mb_strpos($uri, $base, 0, $enc) !== 0' instead.
  • line 8: Use 'stripos($uri, 'get:') === 0' instead.
  • line 9: Use 'mb_stripos($uri, 'POST') === 0' instead.

Options ​

OptionTypeDefaultEffect
(none)Operand order of the fix follows the global comparison style (regular default / yoda).

Configure ​

In custos.json:

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

Suppress ​

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

php
// @custos-ignore SubStrUsedAsStrPos

/**
 * @noinspection SubStrUsedAsStrPosInspection
 */

Released under the MIT License. Rule catalogue modelled on Php Inspections (EA Extended); independent clean-room implementation.