LoginSignup
9
20

More than 5 years have passed since last update.

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

Last updated at Posted at 2016-06-15

はじめに

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

ファイルをアップロード

手順的

  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>

終わり

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

9
20
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
9
20