見出し画像

PHPで多次元配列を初期化する

ごあいさつ

ご高覧いただきありがとうございます.
ソフトウェアエンジニアのKitaharaです.
本日はPHPで多次元配列を作った話をします!

PHPで多次元配列を作ったきっかけ

PHPのサイトでPythonの分析結果を使いたかった

ことの発端はPythonとPHPを連携させようとしていた時です.
個人で株式情報を自動で集めるサイトを作っていたのですが, そのサイトを作る時にPythonのライブラリを使ってデータ分析した結果を出したいなと思っていました.

制作途中のサイト(公開未定)

(↓ この記事にデータの収集方法が書いてあります)


PythonとPHPを連携させる

PHPにはexec関数という関数があり, 外部プログラムを実行することができます. 公式ドキュメントが分かりやすいので引用させていただきます.

exec
(PHP 4, PHP 5, PHP 7, PHP 8)

exec — 外部プログラムを実行する

説明 ¶
exec(string $command, array &$output = null, int &$result_code = null): string|false
exec() は指定されたコマンド command を実行します。

パラメータ ¶
command
実行するコマンド

output
引数 output が存在する場合、指定した配列は、 コマンドからの出力の各行で埋められます。 \n のような後に続く空白は、この配列には含まれません。 配列に既に何らかの要素が 含まれる場合は、exec() は配列の最後に追加される ことに注意してください。関数が要素を追加することを望まないのなら、 それが exec() に渡される前に、配列の unset() を呼び出してください。

result_code
引数result_codeが、引数 output と共に存在する場合、実行したコマンドの ステータスがこの変数に書かれます。

戻り値 ¶
コマンド結果の最後の行を返します。コマンドを実行し、 一切干渉を受けずに直接コマンドから全てのデータを受けとる必要が あるならば、passthru() 関数を使ってください。

失敗時に false を返します。

実行されたコマンドの出力を取得するには、必ず output パラメータを設定・使用してください。

PHP: Hypertext Preprocessor より引用 太字は著者

pythonスクリプトを実行するには以下の様に記述します
※便宜上pythonスクリプトとphpファイルは同じ階層にあるものとします

# target_python_srcipt.py

print('Hello')

// hoge.php
<?php

$command = 'python target_python_script.py'; // pythonを起動するコマンド
exec($command, $output); // pythonスクリプトが実行され, 出力が$outputに格納される

?>

このコードを実行するとtarget_python_script内での出力 'Hello' が文字列としてphpの配列$outputに格納されます.

問題設定

pythonを実行してpandasのリストをPHPに渡したい

# pandasの表のイメージ
#           Admin2        Date  Case Country/Region Province/State
# 0        Autauga  2020-01-22     0             US        Alabama
# 1        Autauga  2020-01-23     0             US        Alabama
# 2        Autauga  2020-01-24     0             US        Alabama
# 3        Autauga  2020-01-25     0             US        Alabama
# 4        Autauga  2020-01-26     0             US        Alabama
# ...          ...         ...   ...            ...            ...
# 2473075   Weston  2022-01-26  1408             US        Wyoming
# 2473076   Weston  2022-01-27  1426             US        Wyoming
# 2473077   Weston  2022-01-28  1438             US        Wyoming
# 2473078   Weston  2022-01-29  1438             US        Wyoming
# 2473079   Weston  2022-01-30  1438             US        Wyoming

解法:多次元配列の初期化

まずdfの内容をexec関数で出力するためにprintします
下記のコードはpandas.DataFrameを行ごと出力します.

# target_python_script
df = pd.DataFrame(...)
for index, item in df.iterrows():
    [print(i) for i in list(item)]

### return
# index1 column1
# ...
# index1 columnM
# ...
# ...
# ...
# indexN column1
# ...
# indexN columnM

このデータですが, もともと上記の様なデータになっていたので以下の様な配列をphpで初期化することで解決します.

最初多次元配列の初期化で検索してもあんまり記事が出てこなかったのであせりましたが, よくよく考えたら基本文法だけでなんとかなりました.

array(N) {
  [0]=>
    array(M) {
    [0]=>
    string(1) "index1 column1"
    [1]=>
    string(1) "index1 column2"
    ...
    [M]=>
    string(1) "index1 columnM"
  }
  [1]=>
    array(M) {
    [0]=>
    string(1) "index2 column1"
    [1]=>
    string(1) "index2 column2"
    ...
    [M]=>
    string(1) "index2 columnM"
  }
.
.
.
  [N]=>
  array(M) {
    [0]=>
    string(1) "indexN column1"
    [1]=>
    string(1) "indexN column2"
    ...
    [M]=>
    string(1) "indexN columnM"
  }
}

具体的には以下の様に書きます.
PHPではarray_pushを使って要素を追加していきます.

今回は行の数だけ配列の中に配列を入力し, その後二重ループを使って格納していきます. なおiterのところは M*$i + $j でも代用できます.

<?php

$command="python target_python_script.py";
exec($command,$output);

// $output_length は DataFrame の行の数
// M は DataFrame の列の数
$output_length = count($output)/M;
$data = [];

for($i = 1; $i <= $output_length; $i++){
    array_push($data,[]); // array_pushで配列の中に配列を追加
}

$iter = 0;
for ($i = 0; $i < $output_length; $i++){
    for ($j = 1; $j <= M; $j++){ // M は DataFrame の列の数
        array_push($data[$i], $output[$iter]); // array_pushで配列の中の配列に要素を追加
        $iter += 1;
    }
}

?>

おわりに

今回はPHPを使って多次元配列を作成する方法を解説しました!参考になったという方はぜひハートボタンを押していってください!

モチベーションが上がります!

記事内で不明な点等ございましたら気軽にご連絡ください.

Twitter: @kitahara_dev
email: kitahara.main1@gmail.com


この記事が気に入ったらサポートをしてみませんか?