ファイルジラ
先生のおすすめ
パーミッションの設定も変えることが出来る
FFFTPは脆弱性があってやめといたほうがいいらしい
(と先生はいったが2019に有志によってver4で修正されているはずだ)
権限的にできるユーザとできないユーザがいる
たとえば「また貸し」の場合とか
リナックスに登録されたユーザならできても、
サーバの一部をさらに借りているひとは
より権限のあるひとに「おねがい」といわないとできないとか
いろんなアプローチがあるが妥当なやつでやりましょう
よくある情けないアプローチは転送前のファイルの拡張子をみようというやりかた
ほんとは悪いexeファイルなのに拡張子だけjpgに偽装したやつとか楽勝で通ってしまう
バイナリファイルはファイルのタイプによって独特の信号を持っている
そのバイナリ情報を実際にみて特定するというのがありそれが一番妥当
マイムタイプという
それを調べる便利なのがある
マイムコンテントタイプ
echo mime_content_type($_FILES["img"]["temp_name"]);
でた
送信前の拡張子をみるような真似はやめましょう。
嘘で拡張子だけjpgにして送ってもちゃんとpngと出る↓
image/png
$types = ["image/jpeg" => ".jpg","image/png"=>".png","image/gif"=>".gif"];/*連想配列に入れる*/
mimeではjpgファイルの拡張子は「jpeg」
なのでこう表記する
キーに拡張子
値に変更後のやつをいれておく
foreachでぐるぐるまわして調べる
もし同じものをみつけたらOKだからmove_uploaded_fileを実行してよろしい
foreach($types as $key=>$val){
if($type == $key){
move_uploaded_file($_FILES["img"]["tmp_name"],"img/hoge.png");
break;/*ひとつ見つけたらおしまい*/
}
}
新しい名前もちゃんとつけてやらないといけません
現状だと全部hoge.pngになってしまう
送信前のファイル名を使うのはよろしくない。
偽装もはいるかもだし日本語で送るアホもいる
だからアスキーコード万国共通でやりたい
その瞬間の日付時刻のような情報をファイル名に変えるとよろしい
しかし同時刻に送られると上書きされるのでハッシュする必要がある
いまのてきとーに付けられた臨時の名前をハッシュして使いましょう
$filename = "img/".md5($_FILES["img"]["tmp_name"]).$val;/*パスとハッシュしたのと拡張子を文字列結合*/
つまりこうなる
foreach($types as $key=>$val){
if($type == $key){
$filename = "img/".md5($_FILES["img"]["tmp_name"]).$val;/*パスとハッシュしたのと拡張子を文字列結合*/
move_uploaded_file($_FILES["img"]["tmp_name"],$filename);
break;/*ひとつ見つけたらおしまい*/
}
}
スーパーグローバル変数は複数あることが前提なので複数形のFILESらしい
適当に割り振られたファイル名をハッシュしたので、
同じ名前で別の人たちが別のファイルをUPしても上書きされる心配はないらしい
ファイル情報をセッションにおぼえこませて後で参照したい
表示画面を作る時間がおしいからリダイレクトして元のページに表示させよう
upload.php
<?php
session_start();
//print_r($_FILES["img"]);
if($_FILES["img"]["error"] !=0){//多次元配列なのでこう記す
exit();
}
$types = ["image/jpeg" => ".jpg","image/png"=>".png","image/gif"=>".gif"];/*連想配列に入れる*/
$type = mime_content_type($_FILES["img"]["tmp_name"]);
foreach($types as $key=>$val){
if($type == $key){
$filename = "img/".md5($_FILES["img"]["tmp_name"]).$val;/*パスとハッシュしたのと拡張子を文字列結合*/
$_SESSION["filename"]=$filename;
move_uploaded_file($_FILES["img"]["tmp_name"],$filename);
break;/*ひとつ見つけたらおしまい*/
}
}
header("Location: form.php");
?>
form.phpも書き換える
最初に開いたとき画像があるはずないので「あれば」にする
form.php
<?php
session_start();
?>
<!DOCTYPE html>
<html lang="ja">
<head>
<meta charset="utf-8">
<title>uploader</title>
</head>
<body>
<form action="upload.php" method="post" enctype="multipart/form-data">
<input type="file" name="img">
<button type="submit">送信</button>
</form>
<?php
if(!empty($_SESSION["filename"])): ?>
<p><img src="<?php echo $_SESSION["filename"]; ?>" alt="画像"></p>
<?php
endif; ?>
</body>
</html>
というわけで公開領域にアップローダするときは必ずマイムで
これDBでやるときはどうするんだろう
フルパスのファイル名をカラムにいれるのか? マイアイコンとか?