質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

Q&A

解決済

2回答

17566閲覧

phpでアップロードするファイルの拡張子を制限したい。

fearless0603

総合スコア41

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

HTML

HTMLとは、ウェブ上の文書を記述・作成するためのマークアップ言語のことです。文章の中に記述することで、文書の論理構造などを設定することができます。ハイパーリンクを設定できるハイパーテキストであり、画像・リスト・表などのデータファイルをリンクする情報に結びつけて情報を整理します。現在あるネットワーク上のほとんどのウェブページはHTMLで作成されています。

0グッド

4クリップ

投稿2016/03/22 06:39

phpで以下の順序でバリデーションを実施したいです。
1.ファイルが選択されていること
2.拡張子がpdf,jpg,pngのいずれかであること
3.ファイルサイズが2M以下であること

◆補足
・1~3のいずれかのチェックでエラーと判定された場合は後続のチェックを打ち切る
・エラーが見つかった場合はクラス内(グローバル)変数にエラーメッセージを設定する
・戻り値はboolean
→true:エラーなし、false:エラーあり

html

1コード 2 <form action="settle_selectable_detail.php" method="post" enctype="multipart/form-data"> 3 <input type="hidden" name="MAX_FILE_SIZE" value="2097152" /> 4 <!--1024*1024*2 = 2MB,ユーザー側ブラウザにファイルのアップロードの最大サイズを指定する。--> 5 <input type="file" name="upfile" size="30" /> 6 <input type="submit" value="アップロード"> 7 </form> 8 9

php

1コード 2<?php 3 4 if (is_uploaded_file($_FILES["upfile"]["tmp_name"])) { 5 if (move_uploaded_file($_FILES["upfile"]["tmp_name"], "files/" . $_FILES["upfile"]["name"])) { 6 chmod("files/" . $_FILES["upfile"]["name"], 0644); 7 echo $_FILES["upfile"]["name"] . "をアップロードしました。"; 8 } else { 9 echo "ファイルをアップロードできません。"; 10 } 11 } else { 12 echo "ファイルが選択されていません。またはサイズが2MBを超えています"; 13 } 14 ?>

アドバイスお願いします・・・・

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

自分は管理画面などのページでよく使い回すので拡張子のチェックを関数にしています。

PHP

1<? 2 function chk_ext( $chk_name, $allow_exts=array( "png", "pdf", "jpg" ) ) { 3 //使用出来ない拡張子のチェック 4 $ext_err = true;//エラーフラグは初期値 真 5 $exts = preg_split( "/[.]/", $chk_name );// ファイル名を.で分割する。 6 if( count( $exts ) < 2 ) return false; 7 $ext = $exts[ count( $exts ) - 1 ];//.で分割した最後のブロックの文字列を取得する 8 foreach( $allow_exts as $val ) { 9 if( !empty( $val ) ) { 10 //$len = strlen( $val ); 11 //if( strncasecmp( strtoupper($val), strtoupper($ext), $len ) == 0 ) { 12 if( strcasecmp( $val, $ext ) == 0 ) { //修正しました(2016/03/23/01:22) 13 $ext_err = false;//エラーフラグ 偽に変更 14 break; 15 } 16 } 17 } 18 $ret = !$ext_err;//戻り値はエラーフラグを反転 19 return $ret; 20 } 21 //ファイル名の拡張子チェックテスト 22 $err_text = ""; 23 if( !chk_ext( $_FILES["upfile"]["name"] ) ) { 24 $err_text .= "認められていない拡張子です。"; 25 } 26?>

その他にファイルのアップロード時に検証した方が良い項目は以下のようなものがあります。

A. 日本語がファイル名に含まれていないか?
B. ファイル名にA-Za-z_-. 以外の文字が含まれていないか?
C. POST時にエラーが発生していないか?
D. ファイル名が空でないか?
E. 不正なパスを表す文字列がファイル名に含まれていないか?( / や ../ など )
F. ファイルサイズが0バイトより大きく指定値以内か?
G. 本当にアップロードされたファイルなのか?(is_uploaded_file()で確認します)
H. 既存ファイルが存在していないか?(削除して上書きする、またはエラーとするか?)

・A,B,Eについて

  1. POST時にファイル名に指定の英数字と記号以外の文字が含まれていないか及び、
    拡張子が存在しているかのチェックをjavascriptで行います。(拡張子のチェックは手抜きでPHPのみです)

HTML

1<script type="text/javascript"> 2<!-- 3function selOk( ) { 4 var str = document.form1.upfile.value; 5 if( str.match(/[^A-Za-z0-9_\-\.]+/) ) { 6 alert("ファイル名に英数字._-以外の文字が含まれています。"); 7 return false; 8 } 9 var ext_i = str.lastIndexOf( ".", str ); 10 if( ext_i <= 0 ) { 11 alert("ファイル名に拡張子がありません"); 12 return false; 13 } 14 return true; 15} 16--> 17</script>

submitボタンをクリックした時に呼び出してチェックします。

HTML

1<input name="SubmitFile" type="submit" value="アップロード" onClick="return selOk()"> 2
  1. POST後にPHPで同様にチェックします。

PHP

1<? 2 function is_ansi( $str ) { 3 //英数字._-だけかチェックします 4 if( strlen( $str ) <= 0 ) return false; 5 if( preg_match( "/[^A-Za-z0-9_\.\-]/", $str ) ) { 6 return false; 7 } else { 8 return true; 9 } 10 } 11 //ファイル名のチェック 12 $userfile = basename( $_FILES['upfile']['name'] ); 13 if( !is_ansi( $userfile ) ) { 14 $err_text .= "ファイル名に英数字._-以外の文字列が含まれています。"; 15 } 16?> 17

・Cについて
エラー情報の $_FILES['upfile']['error']の値が0より大きい場合はエラーになります。

・Fについて
$_FILES['upfile']['size']をチェックします。
サーバーのphp.iniの設定が2Mバイトになっているかも確認してみてください。

PHP

1<? 2 $MAXSIZE = 2097152; 3 if( ( $_FILES['upfile']['size'] > 0 ) && ( $_FILES['upfile']['size'] < $MAXSIZE ) ) { 4 //サイズがOKな場合の処理 5?>

move_uploaded_file()のコピー先の指定は安全の為にフルパスで記述するほうが良いかと思います。
纏めるとこんな感じになります。

PHP

1<? 2 $MAXSIZE = 2097152; 3 $save_dir = "/home/sample-net/public_html/images/"; 4 $info = ""; 5 $err_text = ""; 6 if( !empty( $_FILES['upfile']['name'] ) && empty( $_FILES['upfile']['error'] ) ) { 7 if( ( $_FILES['upfile']['size'] > 0 ) && ( $_FILES['upfile']['size'] < $MAXSIZE ) ) { 8 if( is_uploaded_file( $_FILES['upfile']['tmp_name'] ) ) { 9 //元のファイル名を取得 10 $userfile = basename( $_FILES['upfile']['name'] ); 11 if( chk_ext( $userfile ) && is_ansi( $userfile ) ) { 12 //保存先ファイル名のフルパスを作成 13 $dest_name = $save_dir . $userfile; 14 $tmpfile = $_FILES['upfile']['tmp_name']; 15 if( !file_exists( $dest_name ) ) { 16 //ファイルのコピー処理 17 if( !move_uploaded_file( $tmpfile, $dest_name ) ) { 18 $err_txt .= "ファイルコピーに失敗しました $userfile...$tmpfile > $dest_name<br>\n"; 19 } else { 20 $info .= "アップロードに成功しました $userfile ... $dest_name<br>\n"; 21 chmod( $dest_name, 0644 ); 22 } 23 } else { 24 $err_text .= "既存のファイルです。<br>\n"; 25 } 26 } else { 27 $err_text .= "ファイル拡張子が認められない形式かファイル名に半角英数字._-以外が含まれています。<br>\n"; 28 } 29 } else { 30 $err_text .= "ファイルがアップロードされていません。<br>\n"; 31 } 32 } else { 33 $err_text .= "ファイルサイズが指定サイズ外です。<br>\n"; 34 } 35 } else { 36 $err_text .= "ファイルアップロードエラーです。<br>\n"; 37 } 38?> 39 40//formタグの直前あたりにテキストを表示します 41<? 42 if( !empty( $info ) )print $info; 43 if( !empty( $err_text ) )print $err_text; 44?>

・Hについて
file_exists( )関数で既存ファイルが無いかチェックし、上書きするならunlink()関数を呼びます。

PHP

1<? 2 if( file_exists( $dest_name ) ) { 3 if( unlink( $dest_name ) ) { 4 $info .= "既存の同名ファイルを削除しました。<br>\n"; 5 } 6 } 7?>

(これだけ書くとエディタのプレビューが重くなるのは困ったものです。)
動作確認環境 Windows8.1 Pro Firefox 45.0.1

投稿2016/03/22 14:50

編集2016/03/22 16:24
chinyato

総合スコア241

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

0

完璧ではないけどこんな感じかな?
細かい変数名とかは自分で修正お願いします。。。

PHP

1<?php 2if (is_uploaded_file($_FILES["upfile"]["tmp_name"])) { 3 // ファイルが選択されている場合拡張子チェック 4 $fileType = pathinfo($_FILES["upfile"]["name"], PATHINFO_EXTENSION); 5 if ($fileType == 'pdf' || $fileType == 'jpg' || $fileType == 'png') { 6 // 拡張子がpdfまたはjpgまたはpngの場合ファイルサイズチェック 7 if ($_FILES['upfile']['size'] < 2097152) { 8 echo 'ok!'; 9 } else { 10 echo 'ファイルサイズが大きすぎます!'; 11 } 12 } else { 13 // pdf jpg png 以外の場合 14 echo "拡張子はpdf,jpg,pngです!!!"; 15 } 16} else { 17 // ファイルが選択されていない場合 18 echo "ファイルが選択されていません。"; 19}

投稿2016/03/22 12:36

編集2016/03/22 12:38
test0001

総合スコア224

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問