0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Psalm/phar】Notice: Uninitialized string offset: 0 in ... で Cannot locate エラー

Posted at

PsalmCannot locate エラー

composer require psalm/phar でインストールした pharpsalm を実行すると、Notice: Uninitialized string offset: 0 ... command_functions.php ...Cannot locate エラーが出るようになりました。

以前までは動いていたと思ったのですが、気付いたらエラーが出ていました。特に Psalm の issues にも上がっておらず、ググりまくっても解決策が見つからなかったので、自分のググラビリティ/備忘録として。

TL; DR

psalm のコマンド引数で、空のオプションを渡していませんか。

空の引数を渡している
$ use_alter=''
$ ./vendor/bin/psalm \
  --config="$(pwd)/tests/conf/psalm.xml" \
  --root="$(pwd)" \
  "$use_alter"   # <--- !! w/quote
Notice: Uninitialized string offset: 0 in phar:///workspaces/SampleApp/vendor/psalm/phar/psalm.phar/src/command_functions.php on line 178
Notice: Uninitialized string offset: 0 in phar:///workspaces/SampleApp/vendor/psalm/phar/psalm.phar/src/command_functions.php on line 184
Notice: Uninitialized string offset: 0 in phar:///workspaces/SampleApp/vendor/psalm/phar/psalm.phar/src/command_functions.php on line 202
Cannot locate 

クォートで変数を囲うと、変数の中身が空の場合でもオプションとして渡してしまうので、クォートせずに指定するか if 文で分岐します。

$ use_alter=''
$ ./vendor/bin/psalm \
  --config="$(pwd)/tests/conf/psalm.xml" \
  --root="$(pwd)" \
  $use_alter   # <--- !! w/out quote
Scanning files...
Analyzing files...

░░░
------------------------------
No errors found!
------------------------------

Checks took 5.92 seconds and used 171.358MB of memory
Psalm was able to infer types for 100% of the codebase

TS; DR

各種テストを実行するシェル・スクリプトで、psalm の自動補完/修正機能オプション --alter を条件によって付けたり付けなかったりしたかったので、変数にオプションを入れて指定していました。

run-tests.sh
# !/bin/bash
...
# psalm の追加オプション指定
use_alter=''
isFlagSet 'psalter' && {
  use_alter='--alter'
}

# psalm の実行
./vendor/bin/psalm \
  --config=$path_file_conf_psalm \
  --root=$path_dir_parent \
  $use_alter || {
    echo >&2 'Psalm check failed.'
  }
...

あるときから、シェル・スクリプトの静的解析ツールの「ShellCheck」を使うようになりました。

この shellcheck の解析内容には「変数をダブル・クォーテーションで囲う」(SC2086)と言うルールがあります。これはシェルの場合、変数内にスペースが含まれていた場合、クォーテーションで囲わないと複数の引数として展開してしまうためです。

$ hoge='fuga piyo'
$ ./myCommand $hoge    #<- ./myCommand 'fuga' 'piyo' と同等
$ ./myCommand "$hoge"  #<- ./myCommand 'fuga piyo' と同等

このことは、「スペース入りディレクトリのあるパス」を扱う時など意図しない(見つけづらい)エラーを起こします。

「まぁ、そうだよな」と、盲目的に修正して(変数をクォートで囲って)いたのですが、逆の**「引数の値が空でも『空の値』として渡してしまう」と言うパターン**を失念しておりました。このことが原因でエラーが発生していたのですが、気づくのに時間がかなりかかってしまいました。

$user_alterは空
$ # NG
$ ./vendor/bin/psalm \
  --config="${path_file_conf_psalm}" \
  --root="${path_dir_app_root}" \
  "$use_alter"
Notice: Uninitialized string offset: 0 in phar:///workspaces/SampleApp/vendor/psalm/phar/psalm.phar/src/command_functions.php on line 178
Notice: Uninitialized string offset: 0 in phar:///workspaces/SampleApp/vendor/psalm/phar/psalm.phar/src/command_functions.php on line 184
Notice: Uninitialized string offset: 0 in phar:///workspaces/SampleApp/vendor/psalm/phar/psalm.phar/src/command_functions.php on line 202
Cannot locate

$ # OK
$ ./vendor/bin/psalm \
  --config="${path_file_conf_psalm}" \
  --root="${path_dir_app_root}" \
  $use_alter
Scanning files...
Analyzing files...

░░░
------------------------------
No errors found!
------------------------------

Checks took 5.92 seconds and used 171.358MB of memory
Psalm was able to infer types for 100% of the codebase
バージョン情報
$ ./vendor/bin/psalm --version
Psalm 4.3.1@2feba22a005a18bf31d4c7b9bdb9252c73897476

$ php -v
PHP 7.3.25 (cli) (built: Dec 11 2020 09:22:30) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.25, Copyright (c) 1998-2018 Zend Technologies
    with Xdebug v3.0.1, Copyright (c) 2002-2020, by Derick Rethans
0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?