PHPでシェルコマンドを実行する

どうも、いなっぺです。
最近、サーバ側を便利に操作するためにシェルスクリプトPHPで書いたのでそれについて書いてきます。
今回書くことはlinux環境でmysqlへデータをinsertする処理について。
やりたいことはhogeディレクトリ内のファイルの中身を取り出してinsertするというもの。
下準備

$ mkdir hoge
$ cd hoge
$ touch test1.md
$ touch test2.md
$ echo hoge >> test1.md
$ echo hogehoge >> test2.md

まずはexec()をつかいます。
これはPHPで外部プログラムを実行する、つまりシェルコマンドをPHPから使えるんですね。
そして実行したシェルコマンドの結果を配列で受け取ってくれます。

$ vim sell.php

<?php
    $command = 'ls ~/hoge'; //実行したいシェルコマンド
    $output = []; //実行結果を受け取る配列
    $ret = null; //実行したコマンドのステータスがはいる  

    exec($command, $output, $ret);  
    var_dump($odutput);

出力結果は

$ php sell.php

array(2) {
  [0]=>
  string(8) "test1.md"
  [1]=>
  string(8) "test2.md"
}

となります。

ここまででファイル名を配列に格納することができました。つぎにファイルの中身を取得していきます。
ファイルの中身を取得するにはshell_exec()を使います。
先ほどのexec()との違いは実行した結果を配列ではなくそのまま返すところです。

<?php
    $content = []; //ファイルの中身を格納する配列の用意
    foreach ($output as $file_name) {
        $contnt[] = shell_exec('cat ~/hoge/'.$file_name);
    }
    var_dump($content);

出力結果

array(2) {
  [0]=>
  string(4) "hoge"
  [1]=>
  string(8) "hogehoge"
}

はい、これでファイルの中身も取れました。
次はこれをDBにinsertしていきます。
DBはすでに用意されていると仮定します。

<?php
    $dsn = 'mysql:dbname=voyage_challenge;host=localhost';
    $user = 'root';
    $password = '12345';

    try {
        $dbh = new PDO($dsn, $user, $password);
        $sql = 'insert into t_test set file_name =:file_name, content =:content';
        $i = 0;
        foreach ($output as $file_name) {
            $sth = $dbh->prepare($sql);
            $sth->bindValue(':file_name', $file_name, \PDO::PARAM_STR);
            $sth->bindValue(':content', $content[$i], \PDO::PARAM_STR);
            $sth->execute();
            $i++;
        }
    } catch (PDOException $e) {
        print('Connection failed:'.$e->getMessage());
        die();
    }
    $dbh = null;

はいこれで終了ですね。
これでとりあえずディレクトリ内のファイルを読み取ってDBに格納する処理の完成です。
PHPをつかってLinuxを操作できる。使い方によっては本当に便利なことが出来そうですね。
今回はこのあたりで。

一応、全コード

<?php
    $command = 'ls ~/hoge'; //実行したいシェルコマンド
    $output = []; //実行結果を受け取る配列
    $ret = null; //実行したコマンドのステータスがはいる  

    exec($command, $output, $ret);

    $content = []; //ファイルの中身を格納する配列の用意
    foreach ($output as $file_name) {
        $contnt[] = shell_exec('cat ~/hoge/'.$file_name);
    }

    $dsn = 'mysql:dbname=voyage_challenge;host=localhost';
    $user = 'root';
    $password = '12345';

    try {
        $dbh = new PDO($dsn, $user, $password);
        $sql = 'insert into t_test set file_name =:file_name, content =:content';
        $i = 0;
        foreach ($output as $file_name) {
            $sth = $dbh->prepare($sql);
            $sth->bindValue(':file_name', $file_name, \PDO::PARAM_STR);
            $sth->bindValue(':content', $content[$i], \PDO::PARAM_STR);
            $sth->execute();
            $i++;
        }
    } catch (PDOException $e) {
        print('Connection failed:'.$e->getMessage());
        die();
    }
    $dbh = null;