「fn」というワードはPHP7.4から予約語に!(→アロー関数)

 

「fn」というワードはPHP7.4から予約語になったというのを知るに至った経緯として、$ symfony serveでローカルサーバを立てて

$ symfony serve
                                                                                                                        
 [OK] Web server listening                                                                                              
      The Web server is using PHP FPM 7.3.11                                                                            
      https://127.0.0.1:8000                                         


[Web Server ] Jan 18 18:48:55 |INFO   | PHP    listening path="/usr/sbin/php-fpm" php="7.3.11" port=61746                                              

 

ブラウザで表示確認をすると、以下の500エラーがでました😱

(phpenvでいろんなPHPバージョンを使ってます。)

HTTP 500 Internal Server Error
syntax error, unexpected 'fn' (T_STRING), expecting :: (T_PAAMAYIM_NEKUDOTAYIM)
ParseError
in /Users/xxx/my-project/vendor/laminas/laminas-code/src/Generator/ClassGenerator.php (line 480)
470    /**
471     * @param string $implementedInterface
472     * @return bool
473     */
474    public function hasImplementedInterface($implementedInterface)
475    {
476        $interfaceType = TypeGenerator::fromTypeString($implementedInterface);
477
478        return (bool) array_filter(
479            array_map([TypeGenerator::class, 'fromTypeString'], $this->implementedInterfaces),
480            static fn (TypeGenerator $interface): bool => $interfaceType->equals($interface)
481        );
482    }

 

よーく確認してみると、
symfony php --versionphp --versionのバージョンが違う」
ことに気づきました💦

$ symfony php --version
PHP 7.3.11 (cli) (built: Jun  5 2020 23:50:40) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.11, Copyright (c) 1998-2018 Zend Technologies

$ php --version
PHP 7.4.9 (cli) (built: Dec 26 2020 23:21:06) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.9, Copyright (c), by Zend Technologies
    with Xdebug v3.0.1, Copyright (c) 2002-2020, by Derick Rethans

 

そこで、$ symfony serve でもPHP 7.4.9で動くように設定します。

参照:https://symfony.com/doc/current/setup/symfony_server.html#different-php-settings-per-project

$ cd my-project/

$ echo 7.4.9 > .php-version

$ symfony php --version # PHP 7.3.11 -> 7.4.9に変更完了
PHP 7.4.9 (cli) (built: Dec 26 2020 23:21:06) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
    with Zend OPcache v7.4.9, Copyright (c), by Zend Technologies
    with Xdebug v3.0.1, Copyright (c) 2002-2020, by Derick Rethans


$ symfony serve # PHP 7.4.9でサーバ立てることに成功

                                                                                                                        
 [OK] Web server listening                                                                                              
      The Web server is using PHP FPM 7.4.9                                                                             
      https://127.0.0.1:8000                                                                                     

[Web Server ] Jan 18 18:50:59 |INFO   | PHP    listening path="/Users/xxx/.phpenv/versions/7.4.9/sbin/php-fpm" php="7.4.9" port=62271

お! PHP7.4.9でサーバ立てるようになったみたいです!
と同時にsyntax error, unexpected 'fn' (T_STRING), expecting :: (T_PAAMAYIM_NEKUDOTAYIM)のエラーもなくなりました🎉

めでたし、めでたし👏

 

syntax error, unexpected ‘fn’ (T_STRING), expecting :: (T_PAAMAYIM_NEKUDOTAYIM)の解明

参照:https://www.php.net/manual/ja/tokens.php

 

Google翻訳先生に訳してもらうと、

構文エラー、予期しない '楽しい'(t_string)、予期する::( t_pamaim_nikoodatim)

おそらく fn = 楽しい って訳してくれてます💦

ググっていくと、「fn」はPHP7.4から予約語になったらしいです!

というかアロー関数(無名関数)が使えるようになり、その予約語としてfnを使います。

(風の噂でアロー関数が使えるようになったというのは知っていたのですが書き方まで知らなかったです😅)

アロー関数は fn (argument_list) => expr という形で記述します。

よって、PHP 7.4まではアロー関数がなかったために以下の該当箇所を、「::」を使うスコープ定義演算子 (::)のことではないですか?と教えてくれたのかもしれません。

static fn (TypeGenerator $interface): bool => $interfaceType->equals($interface)

 

phpenvでPHP7.4系を導入した(configure optionをちょっと深ぼる)

 

実行環境は、macOS Catalina 10.15.7 です。

macOS Big Sur にアップデートしたらどうなるんだろうか….🤔迷ってます

 

(過去記事でphpenvでよく使うコマンドまとめてます。)

phpenvでいろんなPHPバージョンを操る

 

しばらくコードを書いておらず、PHPのバージョンが7.3.7だったので7.4系にバージョンあげますー😅

$ php --version
PHP 7.3.7 (cli) (built: Oct  6 2020 15:27:59) ( NTS )
Copyright (c) 1997-2018 The PHP Group
Zend Engine v3.3.7, Copyright (c) 1998-2018 Zend Technologies
    with Zend OPcache v7.3.7, Copyright (c) 1999-2018, by Zend Technologies
    with Xdebug v2.7.2, Copyright (c) 2002-2019, by Derick Rethans

$ phpenv versionsに7.4系が入ってなかったので、

$ phpenv update

からの

$ phpenv install 7.4.9

を実行したら、

-----------------------------------------
configure: error: Please reinstall the BZip2 distribution
-----------------------------------------

といわれたので、
bzip2をreinstallしてパスも通しましたが解決しませんでした。

ググって以下でinstallしてみました。

$ PHP_RPATHS="/usr/local/opt/bzip2/lib" PHP_BUILD_CONFIGURE_OPTS="--with-bz2=/usr/local/opt/bzip2" phpenv install 7.4.9

そしたら、

-----------------------------------------
configure: error: Please specify the install prefix of iconv with --with-iconv=<DIR>
-----------------------------------------

って言われました。どんどん芋釣で問題出てくる、phpenvあるある。
念のため、iconvもreinstallとパスを通して、以下コマンドで再チャレンジ!

 

!!!解決コマンド!!!!

$ PHP_RPATHS="$(brew --prefix bzip2)" PHP_BUILD_CONFIGURE_OPTS="--with-bz2=$(brew --prefix bzip2) --with-iconv=$(brew --prefix libiconv)"  phpenv install 7.4.9

PHP_RPATHSの指定はなくても良かったかもです🙇‍♂️

\ 🎉7.4系installできたー!🎉 /

[Success]: Built 7.4.9 successfully.
$ phpenv versions
  system
  5.6.1
  7.0.31
  7.1.3
  7.1.30
  7.2.20
  7.3.0
  7.3.7
* 7.4.9 (set by /Users/xxxx/xxxx/.ruby-version)

 

そもそもconfigure optionってなに?

解決できたコマンドは以下ですが、分解して各々の環境変数が何しているか見ていきます。

$ PHP_RPATHS="$(brew --prefix bzip2)" PHP_BUILD_CONFIGURE_OPTS="--with-bz2=$(brew --prefix bzip2) --with-iconv=$(brew --prefix libiconv)"  phpenv install 7.4.9

・PHP_RPATHS

PHP_RPATHS="$(brew --prefix bzip2)" 

そもそもRPATHってなに!?

https://stackoverrun.com/ja/q/2196869 より

-rpath=dir
Add a directory to the runtime library search path. ….

訳)実行中ライブラリの検索パスにディレクトリを追加します。

\ runtime path=rpathってこと?  runtimer? /

 

wikipediaさん(https://en.wikipedia.org/wiki/Rpath)にも同じようなことが書いてある👀

configure optionにも--disable-rpathというオプションがあって、以下のような記述がされていたので、なんか解釈あってそう。

–disable-rpath

実行時にライブラリの検索パスを追加できないようにします。

 

 

・PHP_BUILD_CONFIGURE_OPTS

PHP_BUILD_CONFIGURE_OPTS="--with-bz2=$(brew --prefix bzip2) --with-iconv=$(brew --prefix libiconv)"

そのままですが、ビルド時のconfigure optionを指定できるみたいです。

--with-bz2 …bzip2を有効にし、bzip2の場所を指定をします。

--with-iconv …iconvの場所を指定できます。

 

 

参考:

https://qiita.com/kunit/items/c30147f99a48ebb159d5

https://qiita.com/hnw/items/c227d58528c147de15dd

https://www.ritolab.com/entry/211#aj_5_5

 

まとめ

PHP書いてるけど、こういうmake系は全然わかりません😭まだまだです💦

rpath=replace pathなのかと思ってた。

 

phpenvでいろんなPHPバージョンを操る

 

どうも、PHP大好きなんでPHPの記事ばっかで、すみません。

PHPってバージョンごとに書き方違うし、
レガシーな業務ではPHP5系だけど、個人ではPHP7系使いたいってことがよくあります。
そんなとき、composerで管理しちゃえばいいんですが、phpenv使ってバージョン切り替えできるとpsyshでも試せるので良いです!
そこで、phpenvでのバージョン切り替え方法をいっつも忘れてしまうので備忘録として書きます。

phpenvとphp-buildの導入

以下の記事を参考に導入しました。
phpenvとは別に、php-buildが必要なのを知らず私は導入に手こずりました^^;
https://qiita.com/ispern/items/97e3e6d910eb98b5de75

PHPのバージョンを切り替える

今回はグローバルのPHPバージョンを切り替える方法を記載します。
ローカルの場合はglobalの部分をlocalに置換すれば大体行けると思います。(多分)

▼現在のバージョンを確認

$ php -v
PHP 7.1.30 (cli) (built: Jul  4 2019 21:55:42) ( NTS )
...

 

▼現在適用されているphp.ini(設定ファイル)の確認
現在、phpenvで7.1.30が適用されいることがわかります。

$ php --ini
Configuration File (php.ini) Path: /Users/use_name/.phpenv/versions/7.1.30/etc
Loaded Configuration File:         /Users/use_name/.phpenv/versions/7.1.30/etc/php.ini
Scan for additional .ini files in: 
...

 

▼phpenvでインストールされているバージョン一覧と適用中バージョンの確認
*がついているのが、現在適用中のバージョンになります。
7.1.30の他に7.2.20を導入しています。

$ phpenv versions
  system
* 7.1.30 (set by /Users/user_name/.phpenv/version)
  7.2.20

 

▼phpenvでインストール可能なバージョンリスト一覧を表示

$ phpenv install -l
Available versions:
  5.2.17
...
  7.3.6
  7.3.7
...

 

▼バージョンを指定して、インストールをする。
今回は新たに、v5.6.1を入れます。
!!!時間かかります!!!

$ phpenv install 5.6.40
[Info]: Loaded extension plugin
[Info]: Loaded apc Plugin.
[Info]: Loaded composer Plugin.
...

 

インストールし終わったら、、、
▼インストール済みの一覧にあるか確認します。
5.6.1が新しく追加されています。

$ phpenv versions
  system
  5.6.1
* 7.1.30 (set by /Users/user_name/.phpenv/version)
  7.2.20

 

▼hashの更新をします。
!!!rehash忘れがちなので、忘れずに!!!

$ phpenv rehash

 

▼グローバルのPHPバージョンを切り替えます。

$ phpenv global 5.6.1

 

▼現在のバージョンを確認します。
見事に5.6.1に切り替えれています\(^^)/

$ phpenv versions
  system
* 5.6.1 (set by /Users/user_name/.phpenv/version)
  7.1.30
  7.2.20
$ php -v
PHP 5.6.1 (cli) (built: Jul 14 2019 18:29:23)
...

参考:https://www.aiship.jp/knowhow/archives/25452

まとめ

phpenvってpyenvって打ち間違えますよね!!!?
わたしだけですか?
(多分、みんなそうなはず)

 

これほしい!