プロが教える店舗&オフィスのセキュリティ対策術

環境【cakePHP2.5, PHP5.5】

ファイルアップロードの進捗状況を取得してプログレスバーを表示したいのですが、うまくいかず困っております。

現状の方式は以下です(関連部分だけ抜粋)

●cakePHPのViewファイル(アップロードForm)
<?php echo $this->Form->create('Model', array('type' => 'file')); ?> //Form作成
<?php echo $this->Form->hidden(ini_get('session.upload_progress.name'), array('value' => 'example')); ?> //PHPのアップロード状況取得設定
<?php echo $this->Form->file('upload_file'); ?> //ファイル選択
<?php echo $this->Form->submit('アップロード', array('div' => false, 'escape' => false));//submit

●Viewファイル内のjavascript(submitイベントを取得してajax通信)
$(function() {
$('#FormName').submit( function(event) {
$.ajax({
url:'/controller/action',
success:function (data, textStatus) {
$('#progress').html(data);
},
error:function (err) {
console.log('ajax通信失敗:'+err);
},
});
});
});

●cakePHPのアクション
※アップロード処理は省略
public function action() {

if ($this->request->is('ajax')) {
//$_SESSIONキーから進捗状況を取得
$key = ini_get("session.upload_progress.prefix").'example';
$data = $_SESSION[$key];
//パーセンテージ計算
$progressData = round(($data["bytes_processed"]/$data["content_length"])*100);
//結果表示用の変数に値を入れ、更新用のViewをrender
$this->set(compact('progressData'));
$this->render('/Elements/ajax/progress','ajax');
}
}

renderしているエレメントはアップロードViewファイルの中で指定しています。


大きく問題は2つあります。

1 ajax通信が動かない

 cakePHPのアクションはキックしていますが(ログを吐かせて確認)、errorが返ってきます(errの中身は[ object Object ])。

 ただし、submitイベント内ではなく、たとえば<input type=button>のonClickイベント関数の中に入れてやると正常に通信できます。
 また、他にも数カ所ajax通信を行っている箇所がありますが、そちらは特に問題なく通信できています

 なお、ajax通信部分をsetIntervalや関数に入れてSetTimeoutの中に含めると、アクションをキックすらできず何も動かない感じになります(なぜ…)

 submitとajax通信は同時には出来ないものなのでしょうか?


2 ajax通信から$_SESSIONのupload_progress関連の値が取れない

 ファイルアップロード中にcakePHPのアクションに普通にアクセス(GET)すると、アップロード状況が取得できるのですが、ajaxからこのアクションにアクセスすると値が取れない($_SESSION内にこのキーと値が存在しない)状態になります。

 1の問題と絡んでいるような気もしますが、なぜajax通信のときだけ取得できないのか、原因が分からず困っております。


cakePHPでファイルアップロードの進捗を表示する機能をつくられている方など、なにかヒントを頂ければと思います。

なにとぞよろしくお願いします。

A 回答 (1件)

■submitでAjaxがアウト



そもそも、非同期通信であるAjaxと、同期通信であるフォーム送信を一度に行ってもマトモに動く訳がない。

$(function() {
$('#FormName').submit( function(event) {
event.preventDefault(); // submitイベント止める。<a>リンクのクリックイベントでも同じ。
$.ajax({
url:'/controller/action',
success:function (data, textStatus) {
$('#progress').html(data);
},
error:function (err) {
console.log('ajax通信失敗:'+err);
},
});
});
});


■ファイルアップロード進捗

jsのTimerイベント? そんな物を使うと非同期コールバックなど一切戻らない。
jQuery使ってファイルアップロードやるなら、クライアントサイドは同じなので。以下の記事がズバリ。
プログレスバー表示は適当なものを。

ttp://takuya-1st.hatenablog.jp/entry/20121101/1351754417
    • good
    • 0
この回答へのお礼

ありがとうございます。

ご紹介の方法にて一応できました。jsからアップロードしないと進捗率は取得できないんですね。

でも同期通信と非同期通信は同時には出来ないとなると、PHPの5.4から有効になった session.upload_progressの値はどうやって利用すればいいんですかね。別ウィンドウの別リクエストとして取得するしかないのでしょうか。

お礼日時:2014/10/10 14:28

お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!