Pythonの出力をPHPでWeb上に表示

PHP
Pexels / Pixabay
この記事は約6分で読めます。

こんにちは。

やらしみずです。

今回の趣旨

今回、みかんの品種を判断するAPIを作成したのですが、コマンドライン上でのみ動くようなものとなっていて、とてもじゃないけど他の人には見せられない、、、

ということで、Web上に表示してグラフィカルに操作できて、まぁギリギリアプリっていえなくはないかな!ってレベルにしました。
で、その時色々発見があったので、備忘録として書いておきます。
pythonはかけるけど、Webへの繋げ方がわからなーいと困っている皆さんの手助けになれば幸いですたい。
※そんなに技術力高い人間ではないので、わかりずらかったり間違っていた時はガンガン行ってください。頑張って修正します。

環境

PC:Mac
言語:python(3.6.6),php(7.1.7),html

その他:Apache(MAMP)
→試してないけど、Windowsでもそんなに変わらないと思う。

早速本題

今回私が作成したpythonコードからの出力は

こんな感じで、みかんの品種を判断するコード(predict.py)に引数としてjpgの画像を渡すと、その画像がなんの画像かを出力してくれるのが、僕の作ったコードです。

で、これを最終的に

localhost

こんな感じにしました。
(見た目のツッコミはコメント欄にて受け付けます、、、)

ではでは早速備忘録を書いていきましょう。

HTML側のコード

PHP側のコード

画像の受け取り

画像の受け取りについては、index.html上で作成したフォームからPOSTで受け取るのですが、今回は書きません。
多分この類の記事は探したらいっぱいあるので笑

PHPのexec関数

結論からいうと、pythonのコードをコマンドライン上からではなく外部から呼び出す場合には、PHPの「exec()」関数を使います。
参照:exec()関数

使い方は、
exec(実行する命令,出力結果を入れる,実行後ステータス);
のように3つの引数をつけます。

※参照を見た人は飛ばして大丈夫です。
・実行する命令(ここ重要!)
Macだったらターミナル、Windowsだったらコマンドプロンプトのあの画面で入力する内容をそのままここにかけばOKです。
なお実行する命令は、上記の「update.php」を見てもらえばわかる通り、$cmd=’命令’;などで先に書いておいた方がいいです。

・出力結果をいれる(詳しくは解説しません)
命令を実行した後に出力されたものを全て配列として入れます。
引数の後ろ二つはなくても動きますが、のちにテストなどをすることを考えたら入れておいた方がべたー。

・実行後ステータス(詳しくは解説しません)
命令が正常に終了したかどうかを、0(成功)と1(失敗)で出力します。

つまづきポイント

これを使って今回はpythonを動かそうとしているので、「$cmd = python hogehoge.py hogehoge」のような形にして一つ目の引数を入れます。
ただ、ここで注意をしなくてはいけないのが、pythonのパッケージについてです。
僕の環境で「$cmd = python hogehoge.py hogehoge」のようにコードをかいたら、なんどもエラーが発生しました。

エラー1

このエラーを見てこのページに飛んできた人もいるかもしれませんね。

このエラー自体は、pythonがimportするパッケージを見つけられないというエラーなので、同じディレクトリにパッケージを持って来ればOKー

エラー2

と思いきや、Numpyなどを使おうとしていた人は、こんな感じなエラーが出てきたかもしません。

とか

ちなみに私はNumpyを使おうとしていたので両方出ました笑

最終的な回避方法

この方法が一番いい方法なのかはさておいて、私はこの問題をこのように回避しました。

どうやら、phpからpythonを読んだ場合と、コマンドラインからpythonを読んだ場合では参照されるpythonが異なるよう。(どっかで設定できるのか?)
そして、pythonのimport文でパッケージをimportをするためには、anacondaでインストールしたpythonならanaconda上にあるpythonのフルパスを、そのほかの方法でインストールしたのであれば、そのpythonをどうにかして見つけて、そのフルパスを入力する。
この方法なら、anacondaのパッケージ管理機能をちゃんとつかえる見たい。

今回はNumpyをimportしてたから、こんな感じなエラーが吐かれたけど、吐かれないんだったらpythonのコードと同じディレクトリにimportするパッケージを入れておいて、直接読み込むのもありかもしれない。というか、ほかのところに移植することとか考えたら、そっちの方がいいのかもしれない。
やり方わからんけど。

Python側のコード

このコードの76行目のコードで、みかんの種類とどのくらいの確率でその種類があっているかを出力しています。
ただ、このままだと問題が発生します。

エラー内容

→文字コードエラー??
pythonの出力をphp側でこの出力を受け取った時、文字コードエラーで表示がされない!!

回避方法

文字コードエラーについては理解できたらまたアップするけど、とりあえず僕がやった回避方法は73,74行目のコードの通り、文字のエンコードを行います。

predict.py
出力をUTF-8にエンコードする

php
エンコードされた出力から不要なものを取り除く
hex2bin()を使って、16進数表記のUTF-8を日本語にデコードする

って感じです。

もっとスマートな方法があるのかもしれないですけど、とりあえず今回出力を見たら、python側でエンコードしたもの(レモン)が「b’\xe3\x83\xac\xe3\x83\xa2\xe3\x83\xb3’」で、php(html)側の標準のエンコード結果が「e383ace383a2e383b3」だったので、phpの方に形合わせて見たらええんちゃう??ってことで合わせて見たらしっかりと出力されました。やったね。
(何を抜いたかは見たらわかると思うので省略)

最後に

ちなみに作成したみかんAPIはもっとコードを綺麗にして、ビジュアルも綺麗になったらGithubとかにあげたり、ここに記事に載せようと思うので、コードを見たい人は少々お待ちをー^^
あ、もし今のクソみたいな状態のコードでも欲しかったら連絡してください笑

初めて開発日記っぽい日記をかけた気がする笑
ちゃんと定期的に更新できるように頑張らないとなー

あ、あともし文字コードエラー(Unicodeエラー)の解決方法を知っていて、説明できるぜってひとがいたらぜひコメント欄に書いて欲しいです^^
いろんなサイト見たけどわっかりずらくて笑

じゃ、今日はこれまで、バイなら。

PS.
今回書いた記事は、完全に自分自身への備忘録だったので、僕以外の人が見たらなんのコードかわからないものをしようしてしまいました。
また機会があれば、簡単なファイルを一緒につくって行って理解を深められるような記事を書きたいと思います。

コメント