PHP ファイルのアップロード機能作成

PHP

PHPでファイルのアップロード機能を作成する

最小限のコードです。

アップロードをするフォーム
upload.php

 <html>
 <head>
 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 <title>sample</title>
 </head>
 <body>
 <!-- データのエンコード方式である enctype は、必ず以下のようにしなければなりません -->
 <form enctype="multipart/form-data" action="after_submit.php" method="POST">
 このファイルをアップロード: <input name="userfile" type="file" />
 <input type="submit" value="ファイルを送信" />
 </form>
 </body>
 </html>

送信先ファイル↓

 <?php
 $file = "http://test".$_FILES["userfile"]["tmp_name"];
 $file_fix = "/home/user/public_html/test/pdf/hyou.pdf";
 if ( $_FILES["userfile"]["size"] == 0 ) {
   echo "ファイルはアップロードされてません!! アップロードファイルを指定してください。<br>";
 } else {
   echo 'ファイルはアップロードされているはずです。<br>';
 }
 if (is_uploaded_file($_FILES["userfile"]["tmp_name"])){
   echo 'ファイルがアップロードされています。<br>';
   //アップロードされたファイルを新しい位置に配置する
   if (move_uploaded_file($_FILES["userfile"]["tmp_name"], $file_fix)) {
     //ファイルやディレクトリのアクセス権を変更する
     echo 'アップロードしました。<br>URLはこちら:<a href="http://test/pdf/hyou.pdf">'.$file_fix.'</a><br>' ;
   } else {
     echo "ファイルをアップロードできません。<br>";
   }
 } else {
   echo "ファイルが選択されていません。";
 }
 ?> 

このコードを書いたあとに、サーバー側のパーミッション(アクセス権)を「777」に変更してください。
この方法でアップロードできると思います。

PHP ハイフン区切りの日付をスラッシュ区切りに変更

PHP

PHP ハイフン区切りの日付をスラッシュ区切りに変更

たとえばハイフン区切りでわたってきている日付

 2011-9-21

をスラッシュ区切り

 2011/9/21

にしたいなぁという時です。

 <?php
 $ymd = explode ( '-' , '2011-9-21');
 $slashed_ymd = date('/Y/m/d',mktime(0,0,0, $ymd[1],$ymd[2],$ymd[0]));
 ?>

maketimeは最後の引数が月・日・年の順番なので注意しましょう!

PHP データベースをCSVファイルに出力

PHP
MySQL

PHP データベースの中身をCSVファイルに出力し、ユーザーにダウンロードさせる

データベースのクエリの出力結果をCSVファイルに出力し、ユーザーにダウンロードさせたい場合があると思います。
サンプルコードとして置いておきます。

 //POSTで出力したいSQL文を渡す
 //csv_output_sqlというnameでPOST
 if ($_POST['csv_output_sql']){
 	
 	$csv_output_sql=$_POST['csv_output_sql'];
 	$datas = $db->query($csv_output_sql); //ここはDBに接続して、うまくデータを取ってきてください
 	
 	$file = 'test.csv';
 		
 	file_put_contents($file, $datas);
 	header('Content-Disposition: attachment; filename="'. $file . '"');
 	header('Content-Type: text/csv;');
 	
 	//$datasのフィールド名を、CSVの1行目として出力します
 	
 	$field_names=array_keys($datas);
 	$converted_field_names=make_csv_line($field_names);
 	print $converted_field_names;
 	foreach ($datas as $each_data) {
 		
 		$data= make_csv_line($each_data);
 		
 		//データの文字コード変換が必要な場合、ここで変換します。
 		//ここではUTF-8からSJISへ変換しています。
 		
 		$data_converted=mb_convert_encoding($data, "SJIS", "UTF-8");
 		print $data_converted;
 		

}

 

//PHP がバイナリデータを誤認識し、コード変換することの無いようにします。
mb_http_output(‘pass’);

 }
 
 function make_csv_line($values){
 	foreach($values as $i =>$value){
 		if ((strpos($value, ',')  !== false) ||
            (strpos($value, '"')  !== false) ||
            (strpos($value, ' ')  !== false) ||
            (strpos($value, "\t") !== false) ||
            (strpos($value, "\n") !== false) ||
            (strpos($value, "\r") !== false)) {
            $values[$i] = '"' . str_replace('"', '""', $value) . '"';
        }
 		
 	}
 	return implode(',',$values)."\n";
 }

function make_csv_line()に関しては、下記のサイトを参考にさせて頂きました。
http://php.find-info.ru/php/006/learnphp5-CHP-10-SECT-4.html

文字化けが発生する場合は

株式会社の㈱などが文字化けする場合

 $data_converted=mb_convert_encoding($data, "SJIS-win", "UTF-8");

と文字コードの変換先をSJIS-winを指定してみてください。

さて、もう一歩進んで、こういう場合に頭が痛いのがデータベースには日付がエポックタイムスタンプで入っている場合です。
エポックタイムスタンプで出力しても、CSVではうまく表示されませんし、ユーザーには何のことかわかりませんよね。[huh]

日付のフィールドだけPOSTで飛ばせば日付をエポックタイムスタンプから日付へ変換するようにしておきます。
日付のフィールドが複数あることを想定しています。

 //日付の項目がPOSTされていれば、日付をエポックタイムスタンプから日付へ変換
 //convert_date_fieldというnameで日付にしたいフィールド名をPOST
 if ($_POST['convert_date_field']){
     $convert_date_fields=$_POST['convert_date_field'];
     foreach($convert_date_fields as $convert_date_field){
  	 $datas->fields[$convert_date_field]=strftime('%y/%m/%d',$datas->fields[$convert_date_field]);
      }
  }

上記のループをforeach文の中に入れておけば、エポックタイムスタンプを通常のユーザーが見てわかる日付になります。

*エラーが表示される場合

Warning: file_put_contents : failed to open stream: Permission denied in
というような文字列が表示される場合は、ディレクトリのパーミッションを、書き込みが可能なように変更してください。

適宜カスタマイズして使ってください。

PHP デフォルトのタイムゾーンを変更する

PHP

PHP デフォルトのタイムゾーンを変更する

PHPのデフォルトのタイムゾーンを編集するには、php.iniの次の場所を変更します。

 date.timezone = Asia/Tokyo

これが、Europeとか違うタイムゾーンになっていると、dateなどの関数の結果が変わってくるので、ちゃんと東京にしておいた方がよいです。

他のアジア圏の設定はこちら
http://www.php.net/manual/ja/timezones.asia.php

PHP ディレクトリ内のファイル、サブディレクトリを一括消去

PHP

PHP ディレクトリ内のファイル、サブディレクトリを一度に消去する

あるディレクトリの中に、ファイルが複数、その中にディレクトリがあったとします。
それを、一番上のディレクトリを指定して中身を消去する方法です。

unlinkはファイルの消去、rmdirはディレクトリが空でないとできないので、上記のようなことはPHPでは一発でできません。
(シェルを使って消したほうが簡単かも)
下記のスクリプトは、下記のPHP本家サイトから借用しました。
http://www.php.net/manual/ja/function.unlink.php

Jon Hassallさん、ありがとう!!

 <?php
 /**
  * Recursively delete a directory
  *
  * @param string $dir Directory name
  * @param boolean $deleteRootToo Delete specified top-level directory as well
  * $dirは消去したい一番上のディレクトリ
  *  $deleteRootTooは一番上のディレクトリを消去したい場合にtrueを設定
  */
 function unlinkRecursive($dir, $deleteRootToo)
 {
     if(!$dh = @opendir($dir))
     {
         return;
     }
     while (false !== ($obj = readdir($dh)))
     {
         if($obj == '.' || $obj == '..')
         {
             continue;
          }  
 
         if (!@unlink($dir . '/' . $obj))
         {
            unlinkRecursive($dir.'/'.$obj, true);
        }
    }
 
    closedir($dh);
   
    if ($deleteRootToo)
    {
        @rmdir($dir);
    }
   
    return;
 }
 ?>