前回に続き、ファイルをまとめてアップロードする jQuery のプラグイン「Uploadify」の使い方。今回はCakePHPでの設置の方法を解説したいと思います。
「Uploadify」の設置
設置構成は以下のようにします。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
[www] ├[js] ← ライブラリ用フォルダ │ └[uploadify] ← 本体 └[media] ← アップロード用フォルダ [cakephp] └[app] ├[controller] │ └media_controller.php ├[model] │ └medium.php └[view] └[media] └upform.ctp ← アップロードフォーム |
上記構成で説明します。
前回のアップロードフォルダは「uploads」でしたが、今回は media とします。
ちなみに media は medium の複数形ですので、覚えておくと良いことがあるかも。
DBへの書き込みも行うので、適当にこのようなSQLでテーブル作成。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
CREATE TABLE IF NOT EXISTS `media` ( `id` BIGINT UNSIGNED NOT NULL AUTO_INCREMENT, `created` DATETIME NOT NULL, -- 登録日時 `modified` DATETIME NOT NULL, -- 編集日時 `pic_large` VARCHAR(255) default NULL, -- 等倍画像 `pic_middle` VARCHAR(255) default NULL, -- 中サイズ用画像 `pic_small` VARCHAR(255) default NULL, -- 小サイズ画像 `pic_mobile` VARCHAR(255) default NULL, -- 携帯用画像 `alt` VARCHAR(255) default NULL, -- alt `title` VARCHAR(255) default NULL, -- 代替テキスト `caption` VARCHAR(255) default NULL, -- キャプション `description` VARCHAR(255) default NULL, -- 説明 `width` INT default NULL, -- 幅px `height` INT default NULL, -- 縦px `path` VARCHAR(255) default NULL, -- 絶対パス PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8; |
view
アップロードフォーム(/app/views/upform.ctp)
レイアウトかヘッダ辺りで jQuery と uploadify を読み込んで下さい。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 |
<?php echo '<p class="upform">SELECT FILES ボタンを押し、ファイルを選択して下さい。<br />複数の画像を選択することも可能です。</p>'; echo $form->create('Medium', aa('type','post', 'action','upload')); echo '<div id="queue" style="background-color: #505050; height: 200px; margin-bottom: 10px; padding:10px; overflow: auto; width: 400px;"></div>'; echo $form->file('Medium.upload_file', aa('id','file_upload')); echo $form->end(null); $timestamp = time(); ?> <script type="text/javascript"> $(document).ready(function() { $('#file_upload').uploadify({ 'formData' : { 'timestamp' : '<?php echo $timestamp;?>', 'token' : '<?php echo md5('unique_salt' . $timestamp);?>' }, 'debug' : false, 'uploader' : '/media/upload', 'swf' : '/js/uploadify/uploadify.swf', 'auto' : true, 'queueID' : 'queue', 'fileTypeDesc' : 'Image Files', 'fileTypeExts' : '*.gif; *.jpg; *.png', }); }); </script> |
controller
アップロードフォーム用アクション : upform
こちらは単にページ表示するだけです。
|
1 2 3 4 |
function upform() { // htmlタイトル $this->set('title_for_layout', 'メディアアップロード'); } |
アップロード用アクション
uploadify.php を元に作成しています。
また途中にあるパスは app.php で以下のように設定しています。
PIC_PATH_MEDIA
define(‘PIC_PATH_MEDIA’, WWW_ROOT . ‘media/img/’); // WEBルートから
PIC_DIR_PATH_MEDIA
define(‘PIC_DIR_PATH_MEDIA’, “/” . “media/img/”); // 絶対パス
PIC_WIDTH_MIDDLE、
PIC_WIDTH_SMALL、
PIC_WIDTH_MOBILE には、保存する画像のピクセルサイズを指定しています。
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 |
function upload() { // レイアウトは使用しない。 $this->layout = null; $this->autoLayout = false; // アップロード情報がないなら終了 if ( empty($_FILES) ) { exit(); } // 画像をアップするパス(WWW_ROOTからのパス) $path = $path = PIC_PATH_MEDIA; $verifyToken = md5('unique_salt' . $_POST['timestamp']); $microtime = (microtime()*1000000); if (!empty($_FILES) && $_POST['token'] == $verifyToken) { // $name = $_FILES['Filedata']['name']; $tempFile = $_FILES['Filedata']['tmp_name']; // Validate the file type $fileTypes = array('jpg','jpeg','gif','png'); // File extensions $fileParts = pathinfo($_FILES['Filedata']['name']); // ファイル名がアルファベットのみかをチェック if (preg_match("/^([a-zA-Z0-9\.\-\_])*$/u", $name) == false) { $saveFileName = date("Ymd_His", time()); // 日時で } else { if (preg_match("/\.jpg$/ui", $name) == true) { $ret = explode('.jpg', $name); } elseif (preg_match("/\.gif$/ui", $name) == true) { $ret = explode('.gif', $name); } elseif (preg_match("/\.png$/ui", $name) == true) { $ret = explode('.png', $name); } $saveFileName = $ret[0]; // 拡張子を除いたそのまま } // フォルダ内を検索し、同名ファイルがあれば、保存ファイル名をタイムスタンプとする if (is_file(PIC_PATH_MEDIA . $name) == true) { $saveFileName = date("Ymd_His", time()); // 日時で } // マイクロ秒をファイル名に付加 $saveFileName = $saveFileName . $microtime; if (in_array($fileParts['extension'],$fileTypes)) { // アップロード処理(戻り値:ファイル名) $pic_large = $this->CompImageUpload->copyUploadFilenameNotChange($name, $tempFile, $path, $saveFileName, 1); // 縦横そのまま $pic_middle = $this->CompImageUpload->sizeChangeUploadFilenameNotChange($name, $tempFile, $path, $saveFileName, PIC_WIDTH_MIDDLE, 1, "middle"); $pic_small = $this->CompImageUpload->sizeChangeUploadFilenameNotChange($name, $tempFile, $path, $saveFileName, PIC_WIDTH_SMALL, 1, "small"); $pic_mobile = $this->CompImageUpload->sizeChangeUploadFilenameNotChange($name, $tempFile, $path, $saveFileName, PIC_WIDTH_MOBILE, 1, "mobile"); //echo '1'; if (($pic_large === false) || ($pic_middle === false) || ($pic_small === false) || ($pic_mobile === false)) { $error_message = '画像ファイルが正しくないか、ファイルサイズがオーバーしています。'; $this->makeErrorMessage($error_message); $this->list(); $this->render('list'); return; } // 拡張子を除いたファイル名作成 if (preg_match("/\.jpg$/ui", $pic_large) == true) { $fname = explode('.jpg', $pic_large); } elseif (preg_match("/\.gif$/ui", $pic_large) == true) { $fname = explode('.gif', $pic_large); } elseif (preg_match("/\.png$/ui", $pic_large) == true) { $fname = explode('.png', $pic_large); } //------------------------------------------------------------ // media テーブルここから //------------------------------------------------------------ // トランザクション開始 $this->Medium->begin(); // ID初期化 $this->Medium->id = NULL; // 登録データ成形 $save_media_datas = array( 'Medium' => array( 'pic_large' => $pic_large, 'pic_middle' => $pic_middle, 'pic_small' => $pic_small, 'pic_mobile' => $pic_mobile, 'alt' => $fname[0], 'title' => null, 'caption' => null, 'description' => null, 'path' => PIC_DIR_PATH_MEDIA, ) ); // DB登録実行 if (!$this->Medium->save($save_media_datas, 0)) { $this->Medium->rollback(); // RollBack if ($this->Medium->getDbo()->error !== null) { $message = "メディア登録エラー\n"; $message .= "[SQL ErrorCode] " . $this->Medium->getDbo()->error . "\n"; } // エラーログ作成 $this->_log('メディア登録エラー', __LINE__); // 失敗したらフォームに戻る $this->list(); $this->render('list'); return; } //------------------------------------------------------------ // media テーブルここまで //------------------------------------------------------------ // 確定(Commit) $this->Medium->commit(); } else { echo 'Invalid file type.'; } } } |
CakePHPなので「$_POST」とか「$_FILES」を $this->data で受信したかったのですが、うまく取得できなかったので、「$_POST」「$_FILES」形式で取得しています。
アップロードの処理は独自で作成したコンポーネントを使用しています。
やってることは、tmpデータを指定されたファイル名でサイズそのままと、サイズを変えてコピーするだけです。
戻り値はそれぞれ、ファイルネームを返しています。
戻ってきたら、DBにインサートしているだけ。その辺りは問題ないと思います。
model
Medium.php
最後にモデル。
特にアップロードに関して処理していませんので、以下のように。
|
1 2 3 4 5 |
<?php class Medium extends AppModel { var $name = 'Medium'; } ?> |
と、早足ですが、とりあえず完成。私の環境(ウェブサーバと Windows7 に作ったローカル環境)で稼働しています。
うまく動かないって方は、まずは通常の PHP で動くかどうかを試してから CakePHP にとりかかるのがよろしいかと思います。
ちなみにこの CakePHP 版を作るのに2日掛けてしまいました。
せっかくの力作ですので、何かのお役に立てれば幸いです。
関連するかもしれないポスト


