【PHP】入力→確認→PDOで登録。を同一ページで

## はじめに
PHPを勉強しはじめたばかりの素人メモです。
お目汚しすいません。
助言を頂けますと、とてもうれしいです。
よろしくお願いします。

## コード
同一ページ内で、
入力→確認（画像プレビューあり）→PDOでデータベースに登録（mysql）をします。

```php:sample.php
<?php
session_start();
    $name = '';
    $pass = '';
    $errors = array();
// エラー確認
if(!empty($_POST)) {
    if (!isset($_POST['name']) || $_POST['name'] === '') {
        $errors['name'] = 'ニックネームが入力されていません';
    } else {
    $name = htmlspecialchars($_POST['name'], ENT_QUOTES);
    }
    if (!isset($_POST['password']) || $_POST['password'] === '') {
        $errors['password'] = 'パスワードが入力されていません';
    } else {
        if (strlen($_POST['password']) < 4){
        $errors['passwordlength'] = 'パスワードは４文字以上で入力してください。';
        } else {
        $password = htmlspecialchars($_POST['password'], ENT_QUOTES);
        }
    }
    if (!isset($_POST['password2']) || $_POST['password2'] === '') {
        $errors['password2'] = '確認用パスワードを入力してください。';
    } else {
        $password2 = htmlspecialchars($_POST['password2'], ENT_QUOTES);
        if ($password != $password2){
           $errors['password12'] = 'パスワードが一致していません。';
        } else {

// パスワード
           $options = [
            'cost' => 9,
            'salt' => mcrypt_create_iv(22, MCRYPT_DEV_URANDOM),
        ];
        $pass = password_hash("$password", PASSWORD_BCRYPT, $options)."\n";
        }
    }
}
 // 画像をリサイズして保存
if (isset($_FILES['upfile']['error']) && is_int($_FILES['upfile']['error'])) {
    try {
        // $_FILES['upfile']['error'] の値を確認
        switch ($_FILES['upfile']['error']) {
            case UPLOAD_ERR_OK: // OK
                break;
            case UPLOAD_ERR_NO_FILE:   // ファイル未選択
                throw new RuntimeException('ファイルが選択されていません');
            case UPLOAD_ERR_INI_SIZE:  // php.ini定義の最大サイズ超過
            case UPLOAD_ERR_FORM_SIZE: // フォーム定義の最大サイズ超過
                throw new RuntimeException('ファイルサイズが大きすぎます');
            default:
                throw new RuntimeException('その他のエラーが発生しました');
        }
$info = @getimagesize($_FILES['upfile']['tmp_name']);
            if (!$info = @getimagesize($_FILES['upfile']['tmp_name'])) {
                throw new RuntimeException("[{$k}] 有効な画像ファイルを指定してください");
            }
            if (!in_array($info[2], [IMAGETYPE_GIF, IMAGETYPE_JPEG, IMAGETYPE_PNG], true)) {
                throw new RuntimeException("未対応の画像形式です");
            }
// 画像処理に使う関数名
            $create = str_replace('/', 'createfrom', $info['mime']);
            $output = str_replace('/', '', $info['mime']);
// 縦横比を維持、120 * 120 以下に収まるサイズを求める
            if ($info[0] >= $info[1]) {
                $dst_w = 120;
                $dst_h = ceil(120 * $info[1] / max($info[0], 1));
            } else {
                $dst_w = ceil(120 * $info[0] / max($info[1], 1));
                $dst_h = 120;
            }
// リサンプリング先画像リソースを生成
            $dst = imagecreatetruecolor($dst_w, $dst_h);
// 元画像リソースを生成
            if (!$src = @$create($_FILES['upfile']['tmp_name'])) {
                throw new RuntimeException("画像リソースの生成に失敗しました");
            }
// getimagesize関数で得られた情報も利用してリサンプリング
            imagecopyresampled($dst, $src, 0, 0, 0, 0, $dst_w, $dst_h, $info[0], $info[1]);
ob_start();
  $output ($dst);
  $content = base64_encode(ob_get_contents());
ob_end_clean();
imagedestroy($dst);
  $_SESSION['content'] = $content;
        $msg = ['green', 'ファイルは正常に読み込まれています。'];
    } catch (RuntimeException $e) {
        $msg = ['red', $e->getMessage()];
    }
}
// リライトするときの設定
if(isset($_GET['action']) && $_GET['action'] === 'edit'){
 $name = $_SESSION['name'];
}
// エラーがなかったら、
if(count($errors) === 0){
    $_SESSION['name'] = $name;
    $_SESSION['password'] = $pass;
    }
//　登録ボタンが押されたらインサート処理開始
if(!empty($_POST['register'])){
    require_once 'dbmanager.php';
    try{
        $pdo = getDb(); 
        $sql = 'INSERT INTO members(name,password,picture) VALUES(:name, :password, :picture)';
        $stmt = $pdo->prepare($sql);
        $stmt->bindParam(':name', $_SESSION['name'], PDO::PARAM_STR);
        $stmt->bindParam(':password', $_SESSION['password'], PDO::PARAM_STR);
        $stmt->bindParam(':picture', $_SESSION['content'], PDO::PARAM_STR);
        $stmt->execute();
         header('Location: thanks.php');
    } catch (PDOException $e) {
        echo $e->getMessage();
    }
}
?>

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
  <title>登録画面</title>
</head>
<body>
<?php
// エラーメッセージ表示
echo "<ul>";
foreach($errors as $value){
echo"<li>";
echo $value;
echo"</li>";
}
echo "</ul>";
?>
<?php if (!isset($_POST['submit']) || $_POST['submit'] === '') : ?>
<form enctype="multipart/form-data" method="post" action="">
<dl>
<dt>ニックネーム<span class="required">必須</span></dt>
<dd><input type="text" name="name" size="35" maxlength="255" value="<?php if(isset($name)){ echo $name; } ?>">
</dd>
<dt>ログインパスワード<span class="required">必須</span></dt>
<dd><input type="password" name="password" size="10" maxlength="20" value=""></dd>
<dt>確認用パスワード<span class="required">必須</span></dt>
<dd><input type="password" name="password2" size="10" maxlength="20" value=""></dd>
<dt>プロフィール画像など(GIF, JPEG, PNGのみ対応)</dt>
<dd><input type="file" name="upfile" /></dd>
<p><input type="submit" value="submit" name="submit"/></p>
</dl>
  </form>
<?php elseif( count($errors) > 0) : ?>
<form enctype="multipart/form-data" method="post" action="">
<dl>
<dt>ニックネーム<span class="required">必須</span></dt>
<dd><input type="text" name="name" size="35" maxlength="255" value="<?php if(isset($name)){ echo $name; } ?>">
</dd>
<dt>ログインパスワード<span class="required">必須</span></dt>
<dd><input type="password" name="password" size="10" maxlength="20" value=""></dd>
<dt>確認用パスワード<span class="required">必須</span></dt>
<dd><input type="password" name="password2" size="10" maxlength="20" value=""></dd>
<dt>プロフィール画像など(GIF, JPEG, PNGのみ対応)</dt>
<dd><input type="file" name="upfile" /></dd>
<p><input type="submit" value="submit" name="submit"/></p>
</dl>
  </form>
<?php else: ?>
<form action="" method="post" enctype="multipart/form-data">
<dl>
<dt>ニックネーム<span class="required">必須</span></dt>
<dd><?php if(isset($name)){ echo $name; } ?></dd>
<dt>ログインパスワード<span class="required">必須</span></dt>
<dd>【表示されません】</dd>
<dt>プロフィール画像など</dt>
<dd>
<?php if (isset($info)): ?>
<img src="data:<?php echo$info[mime] ?>;base64,<?php echo $content;?>" alt="sample" /><br>
<?php endif; ?>
<?php if (isset($msg)): ?>
    <span style="color:<?=$msg[0]?>;"><?=$msg[1]?></span>
<?php endif; ?>
</dd></dl>
<div><a href="?action=edit">&laquo;&nbsp;書き直す</a>|<input type="submit" name="register" value="登録する" /></div>
</form>
<?php endif; ?>

</body>
</html>
```
## こんな感じ
入力画面
![form1.png](https://qiita-image-store.s3.amazonaws.com/0/62818/f232d44e-2ddf-e29f-9690-34a285c5f870.png)
エラー
![form2.png](https://qiita-image-store.s3.amazonaws.com/0/62818/3662a275-8931-d7ec-f7bb-683c7e154747.png)
確認画面
![form3.png](https://qiita-image-store.s3.amazonaws.com/0/62818/12aaa3f8-e7d9-4951-6380-9d581e629c6d.png)

## 参考サイト
『file_get_contens(URL)で取得した画像をPHPで表示したい』　http://q.hatena.ne.jp/1313160119
『file_get_contentsで画像やFlashを表示とか』　http://d.hatena.ne.jp/m0r1/20090412/1239512576
『PHPについての質問です。フォームの確認画面で入力した画像をプレビュー表示させるにはどのようにすればいいですか？』　http://detail.chiebukuro.yahoo.co.jp/qa/question_detail/q12141865207
『画像アップロード処理サンプル集』　http://qiita.com/mpyw/items/73ee77a9535cc65eff1e
『PHP+MySQLで簡易画像アップローダ』　http://qiita.com/mpyw/items/117ab6a88fd58d911c34
『【PHP】mysqlに画像を保存する』　http://startnews24.com/?p=15970
『[PHP]GDで作った画像をファイル化せずに直接<img>タグで表示する』　http://php-archive.net/php/data-uri-scheme/

## 最後まで理解できなかったこと……
リサイズした画像データをどう取り出せばよいのか、理解できていません。
一応、データベースに格納できたし、出力もできましたが、もっとスマートな方法があるはず……絶対この方法はおかしい。

```php:view.php
<?php
require_once 'dbmanager.php';
$pdo = getDb();
$sql = "select picture from members where id = 36";
$stmt = $pdo->prepare($sql);
$stmt->execute();
$row = $stmt->fetch(PDO::FETCH_ASSOC);
$img = $row['picture'];
?>
<img src="data:image/jpeg;base64,<?php echo $img;?>" alt="sample" /><br>
```

このように画像を表示しましたが……。

## 感動したこと
（言われてみれば当たり前なことだけれど）画像データが文字列で取り出せるってことにものすっごく感動しました。

## 最後に
どこに問題があるのか分からないど素人が書きました。
いるとは思いませんが、念のため。絶対にこのまま使用しないでください。
理解力が全然足りておらず、セキュリティ的に問題がたくさんあると思われますので。

こうすれば良いや、これはセキュリティ的にヤバい、などご助言いただけるととてもとても嬉しいです。よろしくお願いします。
（写真はhttps://unsplash.com/さまからお借りしました。）