Laravel の tinker で日本語が入力できなくて困ったけどなんとかなった話


TL;DR

手元(?) の Amazon Linux 2 や CentOS 7 でのこと。

Laravel の tinker 1 含む psysh 2 や PHP の対話シェル 3 などで日本語入力ができなかった。

libedit を新しいものに差し替えて解消した。

おわり

環境

環境1(CentOS7)
$ cat /etc/redhat-release
CentOS Linux release 7.6.1810 (Core)


$ php -v
PHP 7.2.10 (cli) (built: Sep 11 2018 11:22:20) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.10, Copyright (c) 1999-2018, by Zend Technologies


$ php artisan --version
Laravel Framework 5.5.44
環境2(AmazonLinux2)
$ cat /etc/system-release
Amazon Linux release 2 (Karoo)


$ php -v
PHP 7.2.15 (cli) (built: Feb  7 2019 20:10:03) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.2.0, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.2.15, Copyright (c) 1999-2018, by Zend Technologies


$ php artisan --version
Laravel Framework 5.5.44

発生事象

echo '日清どん兵衛'; を実行したいが、
入力しても、コピー&ペーストしても日本語文字列が消えてしまう。

対話シェル
$ php -a
Interactive shell

php > echo '';
psysh
$ php artisan tinker
Psy Shell v0.9.9 (PHP 7.2.14 — cli) by Justin Hileman
>>> echo '';

タブ補完やヒストリは機能する。

ターミナルや php.ini の設定を疑ったが、特段問題はなかった。

調査

$ php artisan tinker --quiet
>>> readline_info();
=> [
     "line_buffer" => "readline_info();\n",
     "point" => 0,
     "end" => 0,
     "library_version" => "EditLine wrapper",
     "readline_name" => "",
     "attempted_completion_over" => 0,
   ]
$ yum info -q libedit.x86_64
# 略


$ ldd `which php` | perl -nwlE'/(.*libedit\.so.\d+)/&&say$1'
    libedit.so.0 => /lib64/libedit.so.0


$ file /lib64/libedit.so.0
/lib64/libedit.so.0: symbolic link to `libedit.so.0.0.42'

(´・ω・`)

libedit 更新

もしもインストールしていなければ、先に gccncurses-devel 4 を導入する。

$ sudo yum install -y gcc.x86_64
$ sudo yum install -y ncurses-devel.x86_64

Editline Library (libedit) からソースコードを入手し、コンパイルする。

$ curl https://www.thrysoee.dk/editline/libedit-20190324-3.1.tar.gz -O

$ tar zxvf libedit-20190324-3.1.tar.gz

$ cd libedit-20190324-3.1/

$ ./configure

$ make

$ sudo cp -i ./src/.libs/libedit.so.0.0.60 /lib64/
rootで作業(雑)
# cd /lib64/

# unlink libedit.so.0

# ln -s libedit.so.0.0.60 libedit.so.0

確認

対話シェル
$ php -a
Interactive shell

php > echo '日清どん兵衛';
日清どん兵衛
psysh
$ php artisan tinker -q
>>> echo '日清どん兵衛';
日清どん兵衛⏎

(๑•̀ㅂ•́)و✧

完走した感想

Google 先生に訊いても同様の事象で困っている人はいないし、

古いバージョンの PHP や、 mbstring や readline が無いといったもの、Windows での話や ターミナルの設定の話などが沢山ヒットし、正解にたどり着けずに困りました。

参考と注釈