アシアルブログ

アシアルの中の人が技術と想いのたけをつづるブログです

print_r の出力文字列を配列に戻すunprint_r関数を作ってみた

こんにちは。松田です。

みなさんは print_r関数使ってますか?
社内のシステムや簡単なログが欲しい時など、まあ結果が見れればいいや、というぐらいのシステムだと、そのまま入力結果をprint_rしてメールに貼り付けて送信したりしますよね?
そして作っているときはそれでいいものの、後で実際に集計しろとか言われてうわ意外と数あるなあとかserializeしてればよかったなあとかDB入れてれば良かったとか思っても、すでにどうしようもない場合がありますよね。

そんなときに使えるかもしれない unprint_r 関数を作ってみました。
print_rの出力結果文字列を渡すと、配列形式で返してくれます。



<?php
function unprint_r($str, $num=0) {  $data_list = array();
  $str_list = explode("\n", $str);
  $add_list = array();
  $indent = ' {' . ($num*8 + 4) . '}';
  $pattern = '/^' . $indent . '\[.+\] => .*$/';
  $flag = false;  foreach ($str_list as $value) {
    if (preg_match('/^' .' {' . ($num*8) . '}' . '(Array|\()$/', $value)) {
      continue;
    }   
    if (preg_match('/^' .' {' . ($num*8) . '}' . '\)$/', $value)) {
      break;
    }   
    if (preg_match($pattern, $value, $matches)) {
      $flag = true;
      if (count($add_list)) {
        $data_list[] = join("\n", $add_list);
      }   
      $add_list = array();
      $add_list[] = $value;
    } else {
      if ($flag) {
        $add_list[] = $value;
      }   
    }   
  }
  $data_list[] = join("\n", $add_list);

  $result_list = array();
  foreach ($data_list as $data) {
    $pattern = '/'. $indent . '\[(.+?)\] => (.*)/s';
    preg_match($pattern, $data, $matches);
    $key   = $matches[1];
    $value = $matches[2];
    if (strstr($value, 'Array')) {
      $result_list[$key] = unprint_r($data, $num+1);
    } else {
      $result_list[$key] = $value;
    }   
  }
  return $result_list;
}

// 使用例 
$str = <<<STR
Array
(
    [aaa] => あがががあが
    [bbb] => Array
        (
            [0] => おぼぼぼっぼ
            [1] => じょじょっじょじょ
        )

)
STR;

$result = unprint_r($str);
print_r($result);




特定の場合に特定の文字列が来る場合や、下のようないやらしい配列の出力結果以外はある程度うまくいくんじゃないかと思います。


<?php
$a = array('[]][] => [] => [' => '[][] => [[]]');
print_r($a);
/* 出力結果
Array
(
    [[]][] => [] => [] => [][] => [[]]
)
*/

使用機会は限りなく低いと思いますが、ネタながら以外と時間がかかっているので思い出したらつかってみてください。
そして作りながら自分の正規表現の力の無さにガックリきたので、誰かもっときれいに作ってください。