メヘンニミン

たくさんの言語に触れたい.走り書きで見る整理ブログです.

アップロードファイルを保存せず中身を出力するには?

論文修正しながらTipsさん.

ファイルアップロード

PHPはForm関係とか大好きですよね.以下はtxtファイルをアップロードするFormです.

<form name="testForm" method="post" action="upload.php" target="_blank" enctype="multipart/form-data">
  <input type="text" name="textForm" value="入力できるテキスト" />
  <input type="file" name="fileForm" size="30" accept="text/plain" /> //これ!
  <input type="submit" value="送信" />
</form>

この場合,action先では$_POST['textForm']に加えて$_FILES['fileForm']が使用できます.例外処理をいっぱいしてあげて…
PHP - ファイルアップロードの例外処理はこれぐらいしないと気が済まない - Qiita
PHP: エラーメッセージの説明 - Manual

<?php
$name = "fileForm";
try{
  if(!isset($_FILES[$name])){
    throw new RuntimeException('ページ遷移が不正です.');
  } else {
    if(!isset($_FILES['upfile']['error']) || !is_int($_FILES['upfile']['error'])){
        throw new RuntimeException('パラメータが不正です.');
    } else if($_FILES[$name]['error'] !== UPLOAD_ERR_OK){
      // エラーの発生
      switch($_FILES[$name]['error']){
        case UPLOAD_ERR_INI_SIZE:
        case UPLOAD_ERR_FORM_SIZE: throw new RuntimeException('ファイルサイズが大きすぎます.');
        case UPLOAD_ERR_FORM_SIZE: throw new RuntimeException('ファイルサイズが超えています.');
        case UPLOAD_ERR_NO_FILE:   throw new RuntimeException('ファイルが選択されていません.');
        default: throw new RuntimeException('エラーが発生しました.');
      }
    } else {
      // まぁOK
      $file_name = $_FILES[$name]["name"]; // 'test.txt'
      $file_type = $_FILES[$name]["type"]; // 'text/plain'
      $file_size = $_FILES[$name]["size"]; // 数値
      $file_tmp_name = $_FILES[$name]["tmp_name"]; // '/tmp/php{ランダム文字列}'
      
      if (!move_uploaded_file($file_tmp_name, 'upload/'.$file_name)){
        throw new RuntimeException('ファイル保存時にエラーが発生しました.');
      }
      // ここでやっと確定!!
      echo 'ファイルは正常にアップロードされました.';
    }
  }
} catch (RuntimeException $e) {
    echo $e->getMessage();
}
?>

これでサーバにアップロード保存ができました.

ファイルの読み込み

早速一行ずつ読み込んで,(web上に)出力してみます.

<?php
$fileName = 'upload/test.txt';
try{
  if(! ($fp = fopen($fileName, "r") )) throw new RuntimeException('ファイルを開けませんでした.');
  
  while(!feof($fp)){
    $load = fgets($fp, 4096); // 1行ずつ取り出す
    print $load."<br />";
  }
  fclose($fp);
} catch (RuntimeException $e) {
    echo $e->getMessage();
}
?>

以上を組み合わせる

本題です.これ,単に出力したいだけでも毎回アップロード(move_uploaded_file)を挟むのでしょうか.調べてみると非常にシンプルな問題でしたが,意外と記述の少ない内容だったので…
How does one upload a .txt file in PHP and have it read line by line on another page? - Stack Overflow
[PHP]簡単なCSVファイル読込み方法 | HappyQuality


注目はここ!

<?php $file_tmp_name = $_FILES[$name]["tmp_name"]; // '/tmp/php{ランダム文字列}' ?>

上記Formの仕組みですが,move_uploaded_file()を実行する前に,既にPHPサーバ側で一時的ファイルをアップロードしてくれています.ここを参照しましょう.

<?php
if($fp = fopen("upload/test.txt")){ //アップロード済みのファイルを開く場合  } 
if($fp = fopen($_FILES[$name]["tmp_name")){ //一時的ファイルを開く場合 }
?>

持ち込み系出力ツールにどうぞ

サーバにファイルを保存しないので,ユーザが持っているデータの分析や加工結果をプレビューしたい!ということには使えそうです.

f:id:enlosph:20141030143806p:plain
ファイルを用意したら…

f:id:enlosph:20141030143809p:plain
解析して出力!という具合で.


# こういうしょーもないTipsとか数学とかの話題も書きたいんですが,そんな時間あるんですか.