Web Programmerメモ

プログラム開発のメモです

phpbrewでPHP 8をインストール

はじめに

2020/11/26にPHP 8がリリースされました。 www.php.net

自分の場合はローカルPCでphpbrewを利用して、
複数バージョンのPHPをインストールしています。

というわけで今回もphpbrewでPHP 8をインストールすることに。

※phpbrew github.com  

手順

たぶん以下の手順でいけるかと。

  • phpbrew self-update
  • phpbrew known --update
  • phpbrew install 8.0.0 +default +dbs +curl
  • phpbrew switch 8.0.0

すでにphpbrewをインストール済みの場合は、 最初にphpbrew self-updateしてからphpbrew known --updateしないと8.0.0が出てこないです。

また、PCにデフォルトでインストールされているopensslのバージョンが古い場合は、 opensslの最新バージョンをインストールしたうえで、 phpbrew installのオプションに +openssl=/usr/local/Cellar/openssl@x.x/x.xx などして、 opensslのパスを指定する必要になると思います。

以下のようなかんじで、ローカル環境をphp 8.0.0に切り替えました。

php -v         
PHP 8.0.0 (cli) (built: Nov 28 2020 08:39:49) ( NTS )
Copyright (c) The PHP Group
Zend Engine v4.0.0-dev, Copyright (c) Zend Technologies

Codeigniter 4はまだPHP 8に対応してないらしく、、、
php spark serve でローカルサーバが起動しないっす。

% php spark serve       
PHP Deprecated:  Required parameter $userAgent follows optional parameter $body in [path]/vendor/codeigniter4/framework/system/HTTP/IncomingRequest.php on line 161

Deprecated: Required parameter $userAgent follows optional parameter $body in [path]/vendor/codeigniter4/framework/system/HTTP/IncomingRequest.php on line 161


CodeIgniter CLI Tool - Version 4.0.3 - Server-Time: 2020-11-29 09:21:52am

An uncaught Exception was encountered

Type:        ErrorException
Message:     Required parameter $from follows optional parameter $verbs
Filename:    [path]/vendor/codeigniter4/framework/system/Router/RouteCollection.php
Line Number: 1018

8対応してくれるのを待つしかない。。

1582年10月4日の翌日は?

はじめに

以下の記事を読んでたら、
1582/10/4の翌日がほんとに1582/10/15になるかを確かめたくなった。 nagise.hatenablog.jp

というわけで、今回はJavaPHPPythonとGoで検証をしてみた。

結論

Javaのみ1582/10/4の翌日が1582/10/15になった。
PHPPythonとGoは1582/10/4の翌日が1582/10/5だった。  

各言語のバージョン

ローカルPCに入っているバージョンを使用。*1

検証

Java

Javaは内部的にユリウス暦グレゴリオ暦の切り替えを行っている。

ソースコード

import java.util.Calendar;
import java.util.GregorianCalendar;

public class Test {

    public static void main(String[] args) {
        Calendar c = Calendar.getInstance();
        
        c.set(1582, Calendar.OCTOBER, 4);
        System.out.println(c.getTime());
        c.add(Calendar.DAY_OF_MONTH, 1);
        System.out.println(c.getTime());
        
        System.out.println("---------------");
        
        c = new GregorianCalendar(1582, Calendar.OCTOBER, 4);
        System.out.println(c.getTime());
        c.add(Calendar.DAY_OF_MONTH, 1);
        System.out.println(c.getTime());
    }

}

実行

$ java -version
java version "1.8.0_45"
Java(TM) SE Runtime Environment (build 1.8.0_45-b14)
Java HotSpot(TM) 64-Bit Server VM (build 25.45-b02, mixed mode)
$ 
$ javac Test.java
$ java Test
Thu Oct 04 03:29:27 JST 1582
Fri Oct 15 03:29:27 JST 1582
---------------
Thu Oct 04 00:00:00 JST 1582
Fri Oct 15 00:00:00 JST 1582

PHP

Javaみたいなことはやってない。

ソースコード

format('Y-m-d')."\n";
echo $date->modify('+1 days')->format('Y-m-d')."\n";

実行

$ php -v
PHP 7.4.0 (cli) (built: Mar 14 2020 18:05:20) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies
$ 
$ php Test.php 
1582-10-04
1582-10-05

Python

Javaみたいなことはやってない。

ソースコード

import datetime

date = datetime.date(1582, 10, 4)
print(date)
print(date + datetime.timedelta(days=1))

実行

$ python3 --version
Python 3.7.5
$
$ python3 Test.py 
1582-10-04
1582-10-05

■Go

Javaみたいなことはやってない。

ソースコード

package main

import(
    "fmt"
    "time"
)

func main() {
    t := time.Date(1582, 10, 4, 0, 0, 0, 0, time.Local)
    fmt.Println(t)

    t = t.AddDate(0, 0, 1)
    fmt.Println(t)
}

実行

$ go version
go version go1.13 darwin/amd64
$ 
$ go run Test.go
1582-10-04 00:00:00 +0900 JCST
1582-10-05 00:00:00 +0900 JCST

終わりに

しょうもないことに時間を使ってしまったと反省。

なお、Perlでも試そうとしたが、CPANモジュールをインストールできなくて諦めた。
(また今度、気が向いたときにやる)

*1:最新バージョンじゃない

composerでCodeIgniter 4をインストール〜ローカルサーバ起動

はじめに

先日、CodeIgniter 4正式版がリリースされたので、
数年前から4devで作って運用していたものをそろそろ4正式版ベースに移行したいと思った。

CodeIgniter 4のインストール&セットアップ

インストール方法は公式サイトに何通りかのやり方を書いているが、 codeigniter4.github.io

今回は先にGithub上にリポジトリを作っていたので、

Adding CodeIgniter4 to an Existing Project
https://codeigniter4.github.io/userguide/installation/installing_composer.html#adding-codeigniter4-to-an-existing-project

の手順に沿ってインストールした。

$ composer require codeigniter4/framework
Using version ^4.0 for codeigniter4/framework
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Your requirements could not be resolved to an installable set of packages.

  Problem 1
    - codeigniter4/framework v4.0.2 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - codeigniter4/framework v4.0.1 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - codeigniter4/framework 4.0.0 requires ext-intl * -> the requested PHP extension intl is missing from your system.
    - Installation request for codeigniter4/framework ^4.0 -> satisfiable by codeigniter4/framework[4.0.0, v4.0.1, v4.0.2].

  To enable extensions, verify that they are enabled in your .ini files:
    - /Users/[myuser]/.phpbrew/php/php-7.4.0/etc/php.ini
    - /Users/[myuser]/.phpbrew/php/php-7.4.0/var/db/iconv.ini
  You can also run `php --ini` inside terminal to see which files are used by PHP in CLI mode.

Installation failed, deleting ./composer.json.

うぐっ。見慣れないエラーが。。

$ phpbrew ext install intl
===> Installing intl extension...
Log stored at: /Users/[myuser]/.phpbrew/build/php-7.4.0/ext/intl/build.log
Changing directory to /Users/[myuser]/.phpbrew/build/php-7.4.0/ext/intl
===> Phpize...
===> Configuring...
Error: Command failed: ./configure --with-php-config=/Users/[myuser]/.phpbrew/php/php-7.4.0/bin/php-config >> /Users/[myuser]/.phpbrew/build/php-7.4.0/ext/intl/build.log 2>&1 returns:

php-intlのインストールも失敗。いったい何事。。 というわけでログを調べる。

~/.phpbrew/build/php-7.4.0/ext/intl/build.log

checking if debug is enabled... no
checking if zts is enabled... no
checking for gawk... no
checking for nawk... no
checking for awk... awk
checking if awk is broken... no
checking whether to enable internationalization support... yes, shared
checking for icu-uc >= 50.1 icu-io icu-i18n... no
configure: error: Package requirements (icu-uc >= 50.1 icu-io icu-i18n) were not met:

No package 'icu-uc' found
No package 'icu-io' found
No package 'icu-i18n' found

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables ICU_CFLAGS
and ICU_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

icuとやらをインストールすればいいんかな(=よく分かっていない)。

icu4cをインストール

やってみたところ既にインストール済みだった。
念のためupgradeをして、ログの助言通りPKG_CONFIG_PATHを設定。

$ brew install icu4c
Updating Homebrew...
Error: icu4c 63.1 is already installed
To upgrade to 66.1, run `brew upgrade icu4c`
$ brew upgrade icu4c
(以下省略)
$ export PKG_CONFIG_PATH="/usr/local/opt/icu4c/lib/pkgconfig"

気を取り直してphp-intlをインストール

$ phpbrew ext install intl
(中略)
[*] intl extension is enabled.
Done.

はい。いけました。(icu4cのupgradeは不要だったかもしれない)

改めてCodeIgniter 4をインストール

今度こそ!

まずはcomposerでインストール

$ composer require codeigniter4/framework
Using version ^4.0 for codeigniter4/framework
./composer.json has been created
Loading composer repositories with package information
Updating dependencies (including require-dev)
Package operations: 5 installs, 0 updates, 0 removals
  - Installing laminas/laminas-zendframework-bridge (1.0.3): Downloading (100%)         
  - Installing laminas/laminas-escaper (2.6.1): Downloading (100%)         
  - Installing psr/log (1.1.3): Downloading (100%)         
  - Installing kint-php/kint (3.3): Downloading (100%)         
  - Installing codeigniter4/framework (v4.0.2): Downloading (100%)         
kint-php/kint suggests installing kint-php/kint-twig (Provides d() and s() functions in twig templates)
kint-php/kint suggests installing kint-php/kint-js (Provides a simplified dump to console.log())
kint-php/kint suggests installing symfony/polyfill-mbstring (Replacement for ext-mbstring if missing)
kint-php/kint suggests installing symfony/polyfill-iconv (Replacement for ext-iconv if missing)
kint-php/kint suggests installing symfony/polyfill-ctype (Replacement for ext-ctype if missing)
Writing lock file
Generating autoload files
1 package you are using is looking for funding.
Use the `composer fund` command to find out more!

はい。いけました。

setup

これは公式ドキュメントに書いている通り、手動作業が必要。
https://codeigniter4.github.io/userguide/installation/installing_composer.html#set-up

ソースコードのコピー

rsync -arvz vendor/codeigniter4/framework/app ./
rsync -arvz vendor/codeigniter4/framework/public ./
rsync -arvz vendor/codeigniter4/framework/tests ./
rsync -arvz vendor/codeigniter4/framework/writable ./
cp -p vendor/codeigniter4/framework/env ./
cp -p vendor/codeigniter4/framework/phpunit.xml.dist ./
cp -p vendor/codeigniter4/framework/spark ./
cp -p vendor/codeigniter4/framework/.gitignore ./

※公式ドキュメントには書いてないけど、 .gitignore にいろいろ書かれているのでコピーしたほうがよいと思う。

systemディレクトリのパス修正

app/Config/Paths.php

public $systemDirectory = __DIR__ . '/../../vendor/codeigniter4/framework/system';

ローカルサーバ起動

4devのときは php serve.php でローカルサーバを起動していたのだが、
コマンドが変わっていた。

$ php spark serve

CodeIgniter CLI Tool - Version 4.0.2 - Server-Time: 2020-04-26 07:46:28am

CodeIgniter development server started on http://localhost:8080
Press Control-C to stop.
[Sun Apr 26 21:46:28 2020] PHP 7.4.0 Development Server (http://localhost:8080) started

spark”ってちょっとかっこいいな。

f:id:gayou:20200426214851p:plain

初回の画面も(4devに比べて)いいかんじになりました。

PHP 7.4:Trying to access array offset on value of type bool

概要

PHP 7.4にバージョンアップすると、
Trying to access array offset on value of type bool のExceptionが発生するようになった。

問題のコード

mb_regex_encoding("UTF-8");
mb_ereg_search_init($text, "[가-힣]+");
if (mb_ereg_search()) {
    $hangul = mb_ereg_search_getregs(); //get first result
    $text = str_replace($hangul[0], $hc->conv2kana($hangul[0], true), $text);
    do {
        $hangul = mb_ereg_search_regs();//get next result
        $text = str_replace($hangul[0], $hc->conv2kana($hangul[0], true), $text);  //←ここでエラーが発生
    } while($hangul);
}

これは何をやっているかというと、
$text からハングルの文字列を順に抜き出して、自前モジュールでカタカナに変換している。

do - whileの中で mb_ereg_search_regs関数で順に抜き出していって、
抜き出せるものがなくなったらループから抜ける。

このコードはphp 7.3までは特に問題なく動いていた。

何が問題か

エラーメッセージのとおり、
bool型の変数に対して配列インデックスでアクセスしているのが問題っぽい。

mb_ereg_search_regs() 関数は抜き出せるものがない場合、FALSEを返す仕様である。 https://www.php.net/manual/ja/function.mb-ereg-search-regs.php

do-whileの中でmb_ereg_search_regs() は最後はFALSEを返すので、
$hangul = FALSE; が代入され、

それに対して $hangul[0] のように配列アクセスをしているので今回のエラーが発生したようだ。

対処

とりあえずやっつけで回避。

mb_regex_encoding("UTF-8");
mb_ereg_search_init($text, "[가-힣]+");
if (mb_ereg_search()) {
    $hangul = mb_ereg_search_getregs(); //get first result
    $text = str_replace($hangul[0], $hc->conv2kana($hangul[0], true), $text);
    do {
        $hangul = mb_ereg_search_regs();//get next result
        if ($hangul !== false) {
            $text = str_replace($hangul[0], $hc->conv2kana($hangul[0], true), $text);
        }
    } while($hangul);
}

本当はそもそもdo-while構文を使わずに書き直した方がよいのでは、と思っているが。

mecab-koで簡易的な韓日機械翻訳を作る

個人開発って楽しいですね!
本件は ひとり開発 Advent Calendar 2019 - Qiita 7日目にエントリーしています。

はじめに

私は海外野球のニュース記事を読みたいがために、自分用の機械翻訳を作ってます。
現在は韓国語のみで、あくまで野球ニュース用です。
f:id:gayou:20191207110840g:plain

まあ精度はよくないですが、野球用語や独特の表現を訳すところにフォーカスしており、
後述しますがmecab-koという韓国語用の形態素解析ツールを利用しています。
https://bitbucket.org/eunjeon/mecab-ko/

2月にとりあえず作って以降、定期的に辞書をいじっては訳を改善、、
また辞書をいじったり、追加したりして訳を改善している最中です。
正直言って、ルールベースはやるもんじゃないなと思いました


経緯

私は海外野球の情報(特に順位表や試合速報・結果)をよく見ていて、
主に以下のサイトをよく見ます。

サイト 国/地域 言語 URL
MLB アメリ 英語 https://www.mlb.com/
CPBL 台湾 中国語(繁体字 http://www.cpbl.com.tw/
KBO 韓国 韓国語 https://www.koreabaseball.com/
WBSC 国際大会 英語など6ヶ国語 https://www.wbsc.org/

ブログやtwitterなどで日本語で情報発信してくれている方もいて大変助かってますが、
なるべく一次情報を情報収集したい願望があります。

Google翻訳などのWEBサービスは野球に特化しているわけではないので、
ちょいちょい野球用語や独特の言い回しの訳が変なときがあって、
どうしても????ってなるときがあるんですよね。

たとえば以下、(自分で作った翻訳プログラムの運用中に書いたツイートしたものですが)

野球の試合中、しかも9回裏に試合の勝敗が決まる重要な場面でギターを出す人はいないです。
ここは「先発パク・ジヌの力投と9回裏ソン・シホンのサヨナラ打が出て~」と訳すのが的確です。

振り逃げホイル、、、なんて聞いたことないので、NAVERでダイジェスト映像を見たところ、
捕逸”(捕手がボールをキャッチし損ねて後ろに逸らすこと)でした。

※ダイジェスト映像はこちら(サムネに写っている選手は、元ソフトバンクイ・デホsports.news.naver.com

とまあ他にもありますが、”捕逸”のように一般的でない用語や表現はどのジャンルにもあると思います。

そんなこんなで、海外野球のニュース記事を日本語で読みたいがために、
野球ニュース用の機械翻訳を作ろうと思いたったのでした。


目標

自分で作るにあたって、ゆるっとした目標を立てました。

  • 野球独特の用語や表現はちゃんと訳したい
  • てにをは が多少おかしいのは気にしない
  • 野球ニュース以外の文章は正しく訳せなくていい

要はがんばりすぎないことです。はい。
こればっかりやってて家のこと何もしなかったら、うちの奥さんも黙ってはいないでしょう。


検討

韓国語を選択した理由

なんとなくですが一番難易度が低そうな予感がしたからです。

  • 英語は、、、読めないこともない(すみません嘘です)
  • 中国語は、、、漢字なので雰囲気で読んでる(読めてないです)
  • ハングルは、、、さっぱりわからない(自分の語学レベルでは暗号にしか見えない)
  • 英語と中国語の訳には言葉の並び替えが必要だ(どうしたらいいんだろう)
  • そういえば韓国語と日本語は語順が同じなので、並び替え処理とか書かなくてもなんかできそう
  • 形態素解析すれば、あとはそれを順に日本語に置換していくだけでできそう! *1

という風に考えてました。

で、どうやって作るのか

基本的には何の知識もないのでいろいろ調べたんですが、
以下の方法であれば自分でもできそうだと思いました。

  1. テキストをmeba-koで形態素解析する
  2. 形態素の品詞と訳語を順にくっつけていく
    • ※動詞を過去形や否定文にするなど、いくつか訳語調整
  3. 文章完成!

近年の主流はニューラルネットワークのようですが、
まずは上に書いたような簡単なルールで作ることにしました。 *2


詳細

mecab-ko

mecab-koはmecabを韓国語用にカスタマイズが入ったものです。
(本家mecabだと意図した分割ができなかったです)
辞書はmecab-ko-dicを使っています。
https://bitbucket.org/eunjeon/mecab-ko/src/master/README.md
https://bitbucket.org/eunjeon/mecab-ko-dic/src/master/README.md

mecab-koのインストール方法は、以前Qiitaに書いたことがあります。
qiita.com

事前準備

形態素解析の辞書(mecab-ko-dic)に各形態素の訳語を付加します。
辞書に訳語を持たせておくと、形態素解析と一緒に日本語訳の情報もくっついてきます。

訳語の収集にはGoogleスプレッドシートのgoogletranslate関数を使わせてもらいました。

元の辞書は品詞別の44ファイルに全部で81万word収録されているので、
スプレッドシートも1シートにおさまらないどころか、1ファイルに入りきれないので何ファイルかに分割する必要があるし、
あとgoogletranslate関数の戻りをひたすら待ちます(全word分実行し終わるのに待ち時間長め)。

スプレッドシートでひたすら単語の訳を収集 f:id:gayou:20191206002808p:plain

ただしスクショにあるように収集した訳語はよく分からないのが多く、、
訳語を集めるのには向いてなかったかもです。

形態素解析〜訳文生成

コマンド実行でやるならmecabコマンドです。

$ cat [テキスト] | mecab

私の場合は、

  • ブラウザでテキストを入力
  • AjaxでWEBサーバにテキストを送信
  • WEBサーバでテキストを受け取ったら、mecabへ渡して形態素解析
  • mecabの戻り値を取得し、行ごとにごにょにょ処理

なんてことをしてます。

たとえば以下の文章を形態素解析にかけると

두산 베어스가 1차전에서 짜릿한 끝내기 승리를 거뒀다.

以下のような結果が返ってきます。

두산    NNP,*,T,두산,*,*,*,*,斗山,トゥサン
베어스   NNP,인명,F,베어스,*,*,*,*,ベアーズ
가 JKS,*,F,가,*,*,*,*,が
1   SN,*,*,*,*,*,*,*
차 NNBC,*,F,차,*,*,*,*,次,回
전 NNG,*,T,전,*,*,*,*,戦,{multiple}
에서  JKB,*,F,에서,*,*,*,*,で,から,{multiple}
짜릿  XR,*,T,짜릿,*,*,*,*,ぴりっと,鮮やか
한 XSA+ETM,*,T,한,Inflect,XSA,ETM,하/XSA/*+ᆫ/ETM/*,した,な,{multiple}
끝내기 승리    NNG,*,T,끝내기 승리,*,*,*,*,サヨナラ勝利
를 JKO,*,T,를,*,*,*,*,を
거뒀  VV+EP,*,T,거뒀,Inflect,VV,EP,거두/VV/*+었/EP/*,おさめ
다 EF,*,F,다,*,*,*,*,た
.   SF,*,*,*,*,*,*,*,.,1794,3560,3518,SF,*,*,*,*,*,*,*,。
EOS

辞書にあらかじめ日本語訳の列を追加していたので、
形態素から日本語訳を取得することができます。

あとはこの日本語訳を順につなげていくだけです。
といっても↑の例は簡単なケースですが、動詞の変化系(〜した、〜できた、〜できなかった、〜して、〜しない、〜せずに などなど)の場合は愚直にロジックを書いて変形させてます(めんどくさいので他になんかいいやり方ないかなと、、)。

他にも同音異義語もあるので、これは今は前後の形態素の品詞などで判断して訳語を決めているものもあります。 *3  

運用:訳文の調整

ルールのロジックはいろいろ書いてますが基本的には辞書が重要だと考えてます。

たとえば、最初に例としてあげた以下のような文章。

形態素解析では「끝내」と「기타」の2つに分割されていますが、
ここでは「끝내기」(最後の、サヨナラ)と「타」(打)の2つに分割されて欲しいのです。
※いちおうmecab-ko-dicには「끝내기」「타」の2つの単語は定義されていますが

辞書で定義されているコスト値を調整することで意図したところで分割されるようにするのもよいのですが、 今回は「끝내기타(サヨナラ打)」を一語として新たに辞書に登録しました。

「끝내」という単語にはいろいろ意味を持っており、
”ついに”、”最後”、”終わる”、”素晴らしい”、”最高”、”サヨナラ”などの意味があるようです。
また「기타」という単語は、一般的には”その他”、”ギター”の意味のようです。
どうやら”犠打”は一般的ではなさそうです。
で、このケースの場合はもちろん「素晴らしいギター」ではなく、
最後の犠打→(試合を終える犠打)→サヨナラ犠打 という表現が適切です。
ただし「끝내」「기타」の訳を変えるのではなく、
「끝내기타(サヨナラ犠打)」を一語として新たに辞書に登録することで野球らしい訳になるようにしました。
※2020/10/22 サヨナラ犠打ではなかったので辞書を修正しました。  

他にも野球用語や、外国人選手名なども新しく辞書登録しています。 ※一部辞書抜粋

블론세이브,,,,NNG,*,F,블론세이브,*,*,*,*,(ブラウンセーブ),セーブ失敗
끝내기타,,,,NNG,*,F,끝내기타,*,*,*,*,サヨナラ犠打
굿바이 안타,,,,NNG,*,F,굿바이 안타,*,*,*,*,サヨナラ安打
끝내기쇼,,,,NNG,*,F,끝내기쇼,*,*,*,*,サヨナラ勝利

現在は300語ほど辞書に追加したり、既存の訳を修正したりもします。

単語の意味を調べるときは以下の2サイトを便利に使わせてもらってます。 www.kpedia.jp https://ja.dict.naver.com/main.nhnja.dict.naver.com

やればやるほどだんだんとルールが増えていっているので、
そのうち整合性が取れなくなりそうです。
というわけで、ルールベースはやるもんじゃないなと思いました


システム構成

基本的に自分が使いたいもの、慣れているものを使っています。

サーバ環境

サーバはGCPを利用しています。

基本的に月額費用ゼロです。*4
メモリが少ない(630MB)ですがmecab-koや後述のwebサーバを動かすには十分です。

アプリケーション

Nginx Unitは設定が簡単で素敵です。 www.nginx.com

今後

他言語への対応

韓国語のメンテはほどほどにして、中国語か英語に取り組みたいです。

ルールベースは正直しんどいので、統計的な手法を取り入れてみたいのですが、野球翻訳に向いてる?対訳データがない *5 ので、、、やっぱりルールベースなかあ、と。

また、ツールもいろいろあるのでどれを使うかは悩みます。
個人的には注目しているツールはJieba、Enju、StanfordCoreNLPです。

サーバはOracle Cloudへ移行したい

構文解析ツールを使おうとするとメモリが足りないので、
Oracle Cloudへの移行を検討中です。 Always Freeなインスタンス(メモリ1GB)は2つまで作れます。 www.oracle.com

それにしても無料枠があるなんていい時代になりました。
ケチなおっさんなんだと思われても仕方ないですが別にいいです。
きっちり使いこなしたいと思います。

開発言語はPythonJava

ライブラリが比較的そろっているPythonJavaで作れたらなと考えてます。
Goも気になります。

余談ですが、Nginx Unitはパスごとにどの言語で動かすかの設定が割と楽です。

今は試しにですが、

って設定をしています。以下がunit.jsonの設定内容。

{
    "listeners": {
        "*:8000": {
            "pass": "routes"
        }
    },
    "routes": [
        {
            "match": {
                "uri": "/api/ko/*"
            },
            "action": {
                "pass": "applications/translate-ko"
            }
        },
        {
            "match": {
                "uri": "/api/zh/*"
            },
             "action": {
                "pass": "applications/translate-zh"
            }
        }
    ],

    "applications": {
        "translate-ko": {
            "type": "php",
            "processes": 1,
            "root": "[path]",
            "index": "index.php"
        },
        "translate-zh": {
            "type": "python 3.6",
            "processes": 1,
            "path": "[path]",
            "module": "wsgi"
        }
    }
}

まだまだ雑な設定ですが、別途php-fpmとかuwsgiを準備、設定する必要がなくて便利です。

最後に

私がやっている個人開発は、
自分の困っていることを解決するための手段だったり、
新しいソフトウェア・ライブラリを試すためだったりします。

今回アドベントカレンダーにエントリしている都合、
他の方の個人開発の記事を見ていますが、
みんなそれぞれやっていることが違って楽しいですね。  

Qiita ひとり開発 Advent Calendar 2019は7日目はこれで終わりです。
明日8日目は u1and0さんの「開発環境の紹介 (VM->Docker with tmux, vim)」です。

qiita.com

*1:実際やってみるとそんなに単純にはいかないです

*2:一度、Tensorflowでseq2seqという手法でやろうとして、全然理解が追いつかなくて諦めました

*3:韓国語に詳しいわけではないので、正しいやり方ではないと思います

*4:10月にオーストラリアへの転送量で1円課金されたことあります

*5:WBSCのニュースが多国語配信なので集める手はありますが、見た感じ各国語それぞれ多少リライトが入っていることがあるので、データの整備には手間がかかりそう

phpbrewでPHP 7.4を入れるのにいろいろつまづいた

はじめに

2019/11/28にPHP 7.4正式版がリリースされた。
https://www.php.net/releases/7_4_0.php
https://www.php.net/ChangeLog-7.php#7.4.0

Macbook AirにphpbrewでPHP 7.4をインストールするのにいろいろ苦労したので、
記録を残しておこうと思う。

手順

うまくいったのは以下の手順。

1:openssl, libxml2, pkg-config入れる

  • OpenSSLのバージョンは1.1以上にする
  • libxml2も最新版にする
  • pkg-configも入れとく
$ brew install openssl
$ brew install libxml2
$ brew install pkg-config

OSデフォルトのOpenSSLが0.9.8の場合、1.0.2をインストールしてパスを貼り替えていても、PHP 7.4インストール時に1.0.2以上が必要って怒られた。
ビルドログに沿って.bashrcにOPENSSL_CFLAGS, OPENSSL_LIBSなど設定したが、うまくいかず。

途中でopenssl 1.0.2を強制削除する暴挙をとったところ、インストール済みのphp7.3が起動できなくなり、
さらにはphpbrewも使えない、7.3をuninstallできないなどなど環境を壊してしまったので、結局phpbrewを一度綺麗に削除して最初からやり直した。。
(※教訓:brew uninstall openssl --force とかやらない)

2:oniguruma(正規表現ライブラリ)

brewでインストールする

$ brew install oniguruma

3:パスの追加

openssl, libxml2のパスを追加

export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"
export PATH="/usr/local/opt/libxml2/bin:$PATH"

4:環境変数の追加

いろいろ苦労したが、以下の環境変数を追加したら7.4のビルドとインストールができた。

export PKG_CONFIG_PATH="/usr/local/opt/openssl@1.1/lib/pkgconfig"
export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"
export PHP_BUILD_CONFIGURE_OPTS="--with-openssl=$(brew --prefix openssl) --with-libxml-dir=$(brew --prefix libxml2)"

source ~/.bachrc を実行して設定を反映するのを忘れずに。

4:PHP 7.4をインストール

phpbrewでPHP 7.4をインストール

$ phpbrew update
$ phpbrew known
Read local release list (last update: 2019-11-29 12:36:17 UTC).
You can run `phpbrew update` or `phpbrew known --update` to get a newer release list.
7.4: 7.4.0 ...
7.3: 7.3.12, 7.3.11, 7.3.10, 7.3.9, 7.3.8, 7.3.7, 7.3.6, 7.3.5 ...
7.2: 7.2.25, 7.2.24, 7.2.23, 7.2.22, 7.2.21, 7.2.20, 7.2.19, 7.2.18 ...
7.1: 7.1.33, 7.1.32, 7.1.31, 7.1.30, 7.1.29, 7.1.28, 7.1.27, 7.1.26 ...
7.0: 7.0.33, 7.0.32, 7.0.31, 7.0.30, 7.0.29, 7.0.28, 7.0.27, 7.0.26 ...
5.6: 5.6.40, 5.6.39, 5.6.38, 5.6.37, 5.6.36, 5.6.35, 5.6.34, 5.6.33 ...
5.5: 5.5.38, 5.5.37, 5.5.36, 5.5.35, 5.5.34, 5.5.33, 5.5.32, 5.5.31 ...
5.4: 5.4.45, 5.4.44, 5.4.43, 5.4.42, 5.4.41, 5.4.40, 5.4.39, 5.4.38 ...

$ phpbrew install 7.4.0 +default

バージョン切り替え

$ phpbrew switch php-7.4.0
$ php -v
PHP 7.4.0 (cli) (built: Dec  1 2019 01:39:20) ( NTS )
Copyright (c) The PHP Group
Zend Engine v3.4.0, Copyright (c) Zend Technologies

めでたしめでたし!  
 
 
 
 
 


※以下余談

以上、あっさり書いたけど、何かとインストールには苦労した。

インストール途中でいろいろつまづいたこと

元々OpenSSLはバージョン1.0.2rをインストールしていたのだが、
phpbrewでPHP 7.4をインストールすると今までに見たことないエラーが・・・

$ phpbrew install 7.4.0 +default

Error: Configure failed:
The last 5 lines in the log file:
installed software in a non-standard prefix.

Alternatively, you may set the environment variables OPENSSL_CFLAGS

and OPENSSL_LIBS to avoid the need to call pkg-config.

See the pkg-config man page for more details.

ググってみたところGithubのissueのページがヒット。

github.com

phpbrewのバグみたいなことが書かれているが、
ビルドログに出た内容を対策していけばなんとかならんかと。

OpenSSL

ビルドログを見たところ以下のようなメッセージが出力されていた。

checking for openssl >= 1.0.1... no
configure: error: Package requirements (openssl >= 1.0.1) were not met:

Requested 'openssl >= 1.0.1' but version of OpenSSL is 0.9.8zg

Consider adjusting the PKG_CONFIG_PATH environment variable if you
installed software in a non-standard prefix.

Alternatively, you may set the environment variables OPENSSL_CFLAGS
and OPENSSL_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

いやいや、たしかにOpenSSLはOSデフォルトは0.9.8だが、今は1.0.2を入れてパスも通しているし。

$ openssl version
OpenSSL 1.0.2r  26 Feb 2019
$ which openssl
/usr/local/opt/openssl/bin/openssl

デフォルトで入っていたOpenSSLは以下。

$ /usr/bin/openssl version
OpenSSL 0.9.8zg 14 July 2015

ということなので Package requirements (openssl >= 1.0.1) were not met: なエラー出ても困る。
ログに出ている通り、OPENSSL_CFLAGSとOPENSSL_LIBSを設定すればいいんかなと。

~/.bashrc

export OPENSSL_CFLAGS=-I/usr/local/opt/openssl/include
export OPENSSL_LIBS=-L/usr/local/opt/openssl/lib

を追記して、 source ~/.bashrc で反映。 再びPHP 7.4をインストールする。

$ phpbrew install 7.4.0 +default

Error: Configure failed:
The last 5 lines in the log file:
installed software in a non-standard prefix.

Alternatively, you may set the environment variables ONIG_CFLAGS
and ONIG_LIBS to avoid the need to call pkg-config.
See the pkg-config man page for more details.

今度は違うエラー。。ONIG ??ってなんだ?
ググってみたところ、onigurumaという正規表現ライブラリに関するものらしい。

↓の記事を見ている限りだと、onigurumaが今まで同梱されていたものが7.4から外部ライブラリ参照に変わった様子。(裏付け確認はしてない)

tekitoh-memdhoi.info

onigurumaインストール

これはbrewであっさりインストールできる。

$ brew install oniguruma

それにしても鬼車って名前いいな。

再びPHP 7.4をインストール開始したところ、今度はビルドが始まりそこそこ時間がかかり始めた。
これはうまくいくだろうと思い、うちの子を公園に連れて行くために小一時間ほど外出。

そして帰ってきて見ると、、

$ phpbrew install 7.4.0 +default

Error: Make failed:
The last 5 lines in the log file:
      _php_openssl_capture_peer_certs in xp_ssl.o

      ...

ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [sapi/cli/php] Error 1

インストールできてないし、またみたことないエラーが。 ググって見たけどよくわからん。

途中、libxml2を更新してみたところ同時にOpenSSLが1.1に更新されたのだが事象は改善せず。
何かの記事でopensslを再インストールするとよい、みたいなのをちらっと見かけたので、 前述のbrew uninstall openssl --forceとかやってしまったところ、 phpが実行できなくなってしまい詰んだ。

$ phpbrew install 7.4.0 +default
dyld: Library not loaded: /usr/local/opt/openssl/lib/libcrypto.1.0.0.dylib
  Referenced from: /Users/gayou/.phpbrew/php/php-7.3.3/bin/php
  Reason: image not found
Trace/BPT trap: 5

こうなるともうどうしようもなくなったので、
phpbrewを一度綺麗に削除してインストールし直す。

もう一度最初からphp 7.4をインストールしようとしたが、それでもエラーが発生。
ビルドログに以下のような情報が出ていたので、

 _php_openssl_capture_peer_certs in xp_ssl.o
      ...
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)

Warning: Refusing to link macOS-provided software: openssl@1.1
If you need to have openssl@1.1 first in your PATH run:
  echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.bash_profile

For compilers to find openssl@1.1 you may need to set:
  export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib"
  export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"

For pkg-config to find openssl@1.1 you may need to set:
  export PKG_CONFIG_PATH=/usr/local/opt/openssl@1.1/lib/pkgconfig

ログに書いているようにパスの設定や環境変数を設定しておくと、
PHP 7.4を無事にインストールすることができた。