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

## TL;DR

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

Laravel の tinker [^tinker] 含む psysh [^psysh] や PHP の対話シェル [^interactive] などで日本語入力ができなかった。

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

おわり :whale2: 

## 環境

```:環境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 更新

もしもインストールしていなければ、先に `gcc` や `ncurses-devel` [^ncurses-devel] を導入する。

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

[Editline Library (libedit)](https://www.thrysoee.dk/editline/) からソースコードを入手し、コンパイルする。

```
$ 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 での話や ターミナルの設定の話などが沢山ヒットし、正解にたどり着けずに困りました。

## 参考と注釈

* [I just discovered today that php -a (interactive) simply discards certain letters, can't type them, can't copy/paste, can't even load from file.](https://www.reddit.com/r/PHP/comments/3ugzpz/i_just_discovered_today_that_php_a_interactive/)
* [PsySH のタブ補完が動かない - Qiita](https://qiita.com/masam10/items/d2fe007e3422ac9a400e)
* [MySQLのCLIで日本語が入力できない - たむたむの日記](https://blog.orz.at/2018/08/30/mysql-editline/)


[^tinker]: [Laravel 5.5 Artisanコンソール](https://readouble.com/laravel/5.5/ja/artisan.html)
[^psysh]: [psysh](https://psysh.org/)
[^interactive]: [PHP マニュアル > 機能 > コマンドラインの使用法](http://php.net/manual/ja/features.commandline.interactive.php)
[^ncurses-devel]: [Error configuring libedit #3751](https://github.com/spack/spack/issues/3751)