php.iniの設定
strtotime()関数を使用する
date.timezone = “Asia/Tokyo”
php echoの省略の設定
short_open_tag = on
GD関係のインストール
yum -y install gd gd-devel php-gd
DOMのインストール
DOMDocumentを使ってXMLを操作
yum -y install php-xml
プロフィールの画像を直接取得できればいいかなぁって思い、このプラグインを使ってみました。
最初は、jQueryだけでwebカメラの操作ができるんだって思っていました。
でも実際は、flashとjQueryを組み合わせて使います。
※デスクトップキャプチャソフト等も使えます。
配布元
Ajalog.7z:jQueryでWebカメラを制御する
次の2つがあります。使いたい状況に応じて設定します。
1.はすべての機能が使えます。
2.はcanvasに描画する機能のみです。サーバー側にsaveしたい場合は1.を使います。
の3種類があります。
callbackは各コールバック関数を呼びます。
saveはcallbackと変わりませんが、save(file)を実行するときにデータを指定したファイルパスへ送信します。
streamは配布元を参照して下さい。
他のパラメータは、配布元を参照してください。
キャプチャした画像をcanvasに描画する処理は上記の参考サイトに書いてあるので、ここではサーバー側の処理を行います。
mode:“save”
onSave():画像の保存完了後に呼び出される。
保存画像を表示させるには、
このコールバックの中でページを書き換え処理を入れるか、
リダイレクトを行えばいいと思います。
jQuery関係のファイルは適当な場所で読み込む。
<strong>Webカメラから画像を設定</strong> <div id="jquery_camera"></div> <div id="camerastatus" style="margin-left: 10px;"> <strong>カメラリスト</strong> <ul id="cams"></ul> <div id="status"></div> <button id="btn">キャプチャ</button> </div> <?php $this->Html->scriptStart(array('inline' => false)); ?> $(function(){ var width = 320; var height = 240; $("#jquery_camera").webcam({ width: width, // webcamの横サイズ height: height,// webcamの縦サイズ mode: "save", //swffile: "/swf/jscam_canvas_only.swf", swffile: "/swf/jscam.swf", // captrue(delay)が実行されたとき、残り時間を引数にもち、 // 1秒ごとに呼び出される // e.g. delay = 5のときは remainが5,4,...,1と変化して呼び出される。 onTick: function(remain) { if(0 == remain){ $("#status").text("Cheese!"); }else{ $("#status").text(remain + "seconds remaining..."); } }, // mode:saveの場合 // サーバー側での保存が完了し、サーバーからのレスポンスがくると呼ばれる onSave : function () { //キャプチャした画像をwebcam.saveメソッドで保存すると呼び出される。 $("#status").text("done!!"); var url = "リダイレクト先"; window.location = url; }, // Capture時に呼び出される onCapture: function() { webcam.save('/users/upload/<?= $this->data['User']['id'] ?>'); }, // debug用 debug: function(type, string) { $("#status").html(type + ": " + string); }, // 読み込み完了時 onLoad: function() { var cams = webcam.getCameraList(); for(var i in cams) { $("#cams").append("<li>" + cams[i] + "</li>"); } $("#btn").click(function(){ webcam.capture(); }); } }); }) <?php $this->Html->scriptEnd(); ?>
app/controllers/webcams_controller.php
・・・ function upload($id = null){ $this->laout = ''; $updir = ini_get('upload_tmp_dir'); $str = file_get_contents("php://input"); $filepath = $updir . DS . 'user.jpg'; file_put_contents($filepath, pack("H*", $str)); // これ以降にDBへの登録処理をおこなう // e.g.下の処理はMediaPluginを使った時の処理の例 $this->data['Picture']['title'] = ''; $this->data['Picture']['description'] = ''; $this->data['Picture']['model'] = 'User'; $this->data['Picture']['foreign_key'] = $id; $this->data['Picture']['file'] = $filepath; if($this->Picture->save($this->data)){ @unlink($filepath); exit(); }else{ //失敗時の処理 } ・・・
前にも二重送信防止のことを書きました。
jQueryでの二重送信防止
前の二重送信の防止はjQueryで制御していました。
つまり、クライアント側で送信防止をしていたのです。
でももしかすると、javascriptが有効になっていない場合だってあるかもしれません。
そんなときに、Enterキーを
ケンシロウ並に連打!!!されたら、ひとたまりもありません。
不必要なデータがたくさん登録されてしまいます。。。
そんなときは、サーバ側で防止するしかありません。
流れは以下の感じです。
app/controllers/main_controller.php
function doublesubmit(){ if(!empty($this->data)){ // Tokenの比較 if($this->Session->read('dstoken') == $this->data['Example']['dstoken']){ unset($this->data['Example']['dstoken']); $this->Session->delete('dstoken'); if($this->Example->save($this->data)){ $this->flash('おーけーです', array('controller'=>'main', 'action' => 'doublesubmit') ,5); }else{ $this->flash('えぬじーです', array('controller'=>'main', 'action' => 'doublesubmit'), 5); } }else{ $this->flash('すでに送信済みです', array('controller'=>'main', 'action' => 'doublesubmit'), 5); } } // Tokenの発行&Sessionに保持 $dstoken = $this->_rand(12); //ランダムな文字列を生成する関数用意 $this->Session->write('dstoken', $dstoken); $this->data['Example']['dstoken'] = $dstoken; }
app/views/main/doublesubmit.ctp
<h1>二重送信防止</h1> <?php echo $form->create('Example', array('url' => array('controller' => 'main', 'action' => 'doublesubmit'))); echo $form->input('title', array('type' => 'text')); echo $form->input('place', array('type' => 'text')); echo $form->input('dstoken', array('type' => 'hidden')); echo $form->submit('送信'); echo $form->end(); ?>
ランダムな文字列の生成は下記のサイトのコードを使用させてもらいました。
CakePHPだとSecurityComponentを使えばいいという情報を見つけたが、
せっかくなので自分でコンポーネント化してみることにした。
※まだ動作確認はあまりしていません。。。
app/controllers/components/prevent_double_submit.php
<?php /************************************************ * PreventDoubleSubmitComponent * 二重送信を防止する * Usage * Controller: * $conponentsに追加。$doublesubmitsにオプションの設定をする。 * View: * $this->Form->input('Token.token', array('type' => 'hidden'));を追記する。 * ************************************************/ class PreventDoubleSubmitComponent extends Object{ public $controller = null; public $components = array( 'Session', ); /** * @var * model:string モデル名 * token:string view側のhidden属性に設定するfield名 * auto:bool 自動でtokenの設定&二重送信のチェックをする(true)かどうか * url:array デフォルトは現在のアクセスパス * message:string setFlashに設定する文字列 */ public $option = array( 'model' => 'Token', 'token' => 'token', 'auto' => true, 'url' => array(), 'message' => null, 'token_length' => 10, ); //=============================================== // コールバックメソッド //=============================================== function initialize(&$controller){ $this->controller = &$controller; if(isset($this->controller->doublesubmits)){ $this->option = am($this->option, $this->controller->doublesubmits); } } function startup(&$controller){ if(!empty($this->controller->data)){ extract($this->option); if($this->option['auto']){ if($this->isDoubleSubmit()){ if(!empty($message)){ $this->Session->setFlash($message); } $u = array( 'controller' => $this->controller->params['controller'], 'action' => $this->controller->params['action'], $this->controller->params['pass'], ); if(!empty($url)){ $u = am($u, $url); } unset($this->controller->data); $this->controller->redirect($u); }else{ $this->Session->delete($token); unset($this->controller->data[$model][$token]); } } } } function beforeRender(&$controller){ if($this->option['auto']){ $this->setToken(); } } //=============================================== // メソッド //=============================================== /** * トークンを生成しセットする * @return */ function setToken(){ extract($this->option); $t = $this->rand($token_length); $this->Session->write($token, $t); $this->controller->data[$model][$token] = $t; } /** * 二重送信のチェック * @return bool */ function isDoubleSubmit(){ $ret = false; extract($this->option); if(isset($this->controller->data[$model][$token])){ if($this->Session->read($token) != $this->controller->data[$model][$token]){ $ret = true; } } return $ret; } /** * ランダムな文字列を生成する * @param object $length [optional] * @return string ランダムな文字列 */ function rand($length = 8){ $char = "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_"; mt_srand(); $ret = ""; for($i = 0; $i < $length; $i++){ $ret .= $char{mt_rand(0, strlen($char) - 1)}; } return $ret; } } ?>
【追記 start 2011/04/26】==================================
2重送信のアクセスがときどきあるので、
PreventWSubmitComponentを更新してみました。
修正したものはこちらです。
※CakePHP2.xではセキュリティコンポーネントを使って2重送信の防止ができるのでそちらを利用したほうがいいかもしれません。
【追記 end 2011/04/26】==================================