Edited at

PHPで画像をアップロードする

More than 3 years have passed since last update.


はじめに

個人的なメモです。断片的な情報なのでよくわからないかもしれません。


ファイルをアップロード


手順的


  1. フォームなどからファイルをPOSTやPUTする。

  2. フォームから連携された$_FILESからファイル名を取得

  3. move_uploaded_fileでファイルを任意の位置に移動

<?php

function upload(){
//<input type="file" name="image">なので$_FILES['image']になる
move_uploaded_file($_FILES['image']['tmp_name'],ファイルの移動先);
}
?>

<!DOCTYPE html>
<html lang="ja">
<body>
<form action="" method="POST" enctype="multipart/form-data">
<input type="file" name="image">
<input type="submit" value="upload">
</form>
</body>
</html>


画像のファイル名を生成

ファイルをアップロード時に、アップロードされたファイル名ではなく、ハッシュ化されたファイル名を付けたい場合がある。

その場合は下記のようのな方法がある。


sprintfを使って画像のファイル名を生成


sprintfとは

フォーマットされた文字列を返す。

ベースとなる文字列($format)を指定の引数($str,$num)で置き換える感じでしょうか。


php

$format = '%sさんが、%d歳になりました。';

$str = '佐藤';
$num = 40;

echo sprintf($format, $str,$num);//佐藤さんが、40歳になりました。


$formatの%s(string)、%d(integer)はそれぞれ変数の型を指定しています。

他にも沢山あるので、詳しくは下記を参照


sprintf


javascriptのときも文字の置き換えで同じようなことをやってましたが、

sprintfのほうが簡単に思えました。


js

var format = '%sさんが、%d歳になりました。';

var str = '佐藤';
var num = 40;

format = format.replace('%s',str).replace('%d',num);

console.log(format);//佐藤さんが、40歳になりました。



挿入される型と、挿入する型が違う場合

型を指定しているので、挿入する変数の型が異なる場合は正しく処理されません。

%d(integer)にstringを入れていみます。


php

$format = '%sさんが、%d歳になりました。';

$str = '佐藤';
$num = 40;

echo sprintf($format,$num,$str);//40さんが、0歳になりました。



挿入位置の順番と、引数の順番が異なる場合

置換文字列の位置が、引数の順番と異なる場合先の書いたやり方だと上手く動きません。

そんな時は、置換文字列の指定の仕方を少し変更します。

$format = '%2$sさんが、%1$d歳になりました。';

$str = '佐藤';
$num = 40;

echo sprintf($format,$num,$str);//佐藤さんが、40歳になりました。

同じ変数を複数使う場合も上記の方法で対応できます。

$format = '%2$sさんが、%1$d歳になりました。%1$d歳なのに、これだとヤバイです。';

$str = '佐藤';
$num = 40;

echo sprintf($format,$num,$str);//佐藤さんが、40歳になりました。40歳なのに、これだとヤバイです。


画像のファイル名を生成

$format = '%s_%s.%s';

$time = time();
$sha1 = sha1(uniqid(mt_rand(),true));

//$extはファイル連携時に取得した拡張子
$file_path = sprintf($format,$time,$sha1,$ext);

//こんな感じの文字列ができる
//1465616468_b4185a37d1fa98b2eaf888ca229091d89e4e5f42.jpg


アップロードしたファイルタイプを取得

exif_imagetype(ファイル名);

exif_imagetypeで取得できる値(他にも沢山あります)


定数

1
IMAGETYPE_GIF

2
IMAGETYPE_JPEG

3
IMAGETYPE_PNG


新しい画像を、縦横サイズを指定して作成する


手順


  1. imagecreatefromgif()、imagecreatefromjpeg()、imagecreatefrompng()で新しい画像をファイル作成する

  2. imagecreatetruecolor()でTrueColorイメージを作成する

  3. imagecopyresampled()で、手順1で作成した画像ファイルを手順2で作成したイメージにコピーする

  4. 画像を出力する。


手順1

画像ファイルを作成

imagecreatefromgif({ファイルもしくはURL});

imagecreatefromjpeg({ファイルもしくはURL});
imagecreatefrompng({ファイルもしくはURL});


手順2

TrueColorイメージを作成

imagecreatetruecolor (画像の幅 , 画像の高さ);


手順3

イメージの矩形の部分 を別のイメージにコピーする。

imagecopyresampled (

コピー先の画像,
コピー元の画像,
コピー先のx座標,
コピー先のy座標,
コピー元のx座標,
コピー元のy座標,
コピー先の幅,
コピー先の高さ,
コピー元の幅,
コピー元の高さ
)


手順4

画像をファイルに出力する。

imagegif(image, filename);

imagejpeg(image, filename);
imagepng(image, filename);

//image ・・・imagecreatetruecolor() のような画像作成関数が返す画像リソース
//filename ・・・保存するファイルへのパス 

$imagType = exif_imagetype($_FILES['image']['tmp_name']);

$imageFileName = $_FILES['image']['tmp_name'];

switch (imagType) {
case IMAGETYPE_GIF:
$srcImage = imagecreatefromgif($savePath);
break;
case IMAGETYPE_JPEG:
$srcImage = imagecreatefromjpeg($savePath);
break;
case IMAGETYPE_PNG:
$srcImage = imagecreatefrompng($savePath);
break;
}

$thumbHeight = round($height * THUMBNAIL_WIDTH / $width);

$thumbImage = imagecreatetruecolor(THUMBNAIL_WIDTH, $thumbHeight);

imagecopyresampled($thumbImage,$srcImage,0,0,0,0,THUMBNAIL_WIDTH,$thumbHeight,$width,$height);
switch (imagType) {
case IMAGETYPE_GIF:
imagegif($thumbImage,THUMBNAIL_DIR . '/' . imageFileName);
break;
case IMAGETYPE_JPEG:
imagejpeg($thumbImage,THUMBNAIL_DIR . '/' . imageFileName);
break;
case IMAGETYPE_PNG:
imagepng($thumbImage,THUMBNAIL_DIR . '/' . imageFileName);
break;
}


ディレクトリ内のファイル(画像)を取得して表示


手順


  1. opendirでディレクトリを開く(ディレクトリのハンドルを取得)

  2. readdirでディレクトリの中のファイルを取得(ディレクトリハンドルからエントリを読み込む)

  3. 取得したファイルをエスケープして表示

$images = [];

$dir = opendir(ディレクトリのパス);

while(false !==($file = readdir($dir))){
if($file === '.' || $file === '..'){
continue;
}
$images[] = file;
}

<body>
<?php foreach ($images as $image):?>
<img src="<?php echo htmlspecialchars($image, ENT_QUOTES, 'UTF-8'); ?>">
<?php endforeach;?>
</body>


終わり

まだまだ理解が浅いです。