CakePHP:コントローラ:DevloperController.php
class DevloperController extends AppController {
public $name = 'Devloper';
public $uses = ['Devloper'];
function index() {
$csrf_token = CrudBaseU::getCsrfToken('developer_edit');
$this->set([
'csrf_token' => $csrf_token,
]);
}
/**
* 〇〇 | Ajax 非同期通信
* @return string
*/
public function ajax_reg(){
$this->autoRender = false;//ビュー(ctp)を使わない。
// CSRFトークンによるセキュリティチェック
if(CrudBaseU::checkCsrfToken('developer_edit') == false){
return '不正なアクションを検出しました。';
}
// 通信元から送信されてきたパラメータを取得する。
$param_json = $_POST['key1'];
$param=json_decode($param_json,true);//JSON文字を配列に戻す
//データ加工や取得
$res = ['success'=>1,'yagi'=>'山羊','kani'=>'蟹','same'=>'鮫'];
// JSONに変換し、通信元に返す。
$json_str = json_encode($res, JSON_HEX_TAG | JSON_HEX_QUOT | JSON_HEX_AMP | JSON_HEX_APOS);
return $json_str;
}
}
<?php
$this->assign('script', $this->Html->script(['Devloper/index',]));
//※jqueryはdefalut.ctpにてインクルード済み
?>
<div id="err"></div>
<input type="hidden" id="csrf_token" value='<?php echo $csrf_token; ?>' />
class Animal{
regAction(){
let sendData={neko_name:'cat&dog%',same:{hojiro:'ホオジロザメ',shumoku:'シュモクザメ'}};
// データ中の「&」と「%」を全角の&と%に一括エスケープ(&記号や%記号はPHPのJSONデコードでエラーになる)
sendData = this._escapeAjaxSendData(sendData);
// sendData = this._ampTo26(sendData); // PHPのJSONデコードでエラーになるので、&を%26に一括変換する
let fd = new FormData();
let send_json = JSON.stringify(sendData);//データをJSON文字列にする。
fd.append( "key1", send_json );
// CSRFトークンを取得
let csrf_token = jQuery('#csrf_token').val();
fd.append( "csrf_token", csrf_token );
let ajax_url = "developer/ajax_reg";
// AJAX
jQuery.ajax({
type: "post",
url: ajax_url,
data: fd,
cache: false,
dataType: "text",
processData: false,
contentType : false,
})
.done((res_json, type) => {
let res;
try{
res =jQuery.parseJSON(res_json);//パース
}catch(e){
jQuery("#err").append(res_json);
return;
}
console.log(res);
})
.fail((jqXHR, statusText, errorThrown) => {
let errElm = jQuery('#err');
errElm.append('アクセスエラー');
errElm.append(jqXHR.responseText);
alert(statusText);
});
}
/**
* データ中の「&」と「%」を全角の&と%に一括エスケープ
*
* @note
* PHPのJSONデコードでエラーになるので、&記号をエスケープ。%記号も後ろに数値がつくとエラーになるのでエスケープ
* これらの記号はMySQLのインポートなどでエラーになる場合があるのでその予防。
* @param mixed data エスケープ対象 :文字列、オブジェクト、配列を指定可
* @returns エスケープ後
*/
_escapeAjaxSendData(data){
if (typeof data == 'string'){
data = data.replace(/&/g, '&');
data = data.replace(/%/g, '%');
return data;
}else if (typeof data == 'object'){
for(var i in data){
data[i] = this._escapeAjaxSendData(data[i]);
}
return data;
}else{
return data;
}
}
/**
* Ajax送信データ用エスケープ。実体参照(< > & &)を記号に戻す。
*
* @param any data エスケープ対象 :文字列、オブジェクト、配列を指定可
* @returns エスケープ後
*/
_escapeForAjax(data){
if (typeof data == 'string'){
if ( data.indexOf('&') != -1) {
data = data.replace(/</g,'<').replace(/>/g,'>').replace(/&/g,'&');
return encodeURIComponent(data);
}else{
return data;
}
}else if (typeof data == 'object'){
for(var i in data){
data[i] = _escapeForAjax(data[i]);
}
return data;
}else{
return data;
}
}
/**
* データ中の「&」と「%」を一括エスケープ
* @note
* PHPのJSONデコードでエラーになるので、&記号をエスケープ。%記号も後ろに数値がつくとエラーになるのでエスケープ
*
* @param mixed data エスケープ対象 :文字列、オブジェクト、配列を指定可
* @returns エスケープ後
*/
_ampTo26(data){
if (typeof data == 'string'){
if ( data.indexOf('&') != -1) {
return data.replace(/&/g, '%26');
}else if(data.indexOf('%') != -1){
return data.replace(/%/g, '%25');;
}else{
return data;
}
}else if (typeof data == 'object'){
for(var i in data){
data[i] = _ampTo26(data[i]);
}
return data;
}else{
return data;
}
}
}
CrudBaseU.php
class CrudBaseU{
/**
* CSRFトークンを取得
* セッションまわりの処理も行う。
* @return string CSRFトークン
*/
public static function getCsrfToken($page_code)
{
$ses_key = $page_code . '_csrf_token'; // セッションキーを組み立て
$csrf_token = self::random();
$_SESSION[$ses_key] = $csrf_token;
return $csrf_token;
}
/**
* ランダム文字列を作成
* @param number $length
* @return string
*/
public static function random($length = 8)
{
return base_convert(mt_rand(pow(36, $length - 1), pow(36, $length) - 1), 10, 36);
}
/**
* CSRFトークンによるセキュリティチェック
* @return boolean true:無問題 , false:不正アクションを確認!
*/
public static function checkCsrfToken($page_code){
// Ajaxによって送信されてきたCSRFトークンを取得。なければfalseを返す。
$csrf_token = null;
if(!empty($_POST['_token'])) $csrf_token = $_POST['_token'];
if($csrf_token == null){
if(!empty($_POST['csrf_token'])) $csrf_token = $_POST['csrf_token'];
}
if($csrf_token == null){
if(!empty($_GET['_token'])) $csrf_token = $_GET['_token'];
}
if($csrf_token == null){
if(!empty($_GET['csrf_token'])) $csrf_token = $_GET['csrf_token'];
}
if($csrf_token == null) return false;
// セッションキーを組み立て
$ses_key = $page_code . '_csrf_token';
$ses_csrf_token = $_SESSION[$ses_key];
if($csrf_token == $ses_csrf_token){
return true;
}
return false;
}
}
<?php echo $this->element('xxx');?>
index.ctp
<?php echo $this->element('animal',array( 'animal_name'=>'ラクダ' )); ?>
animal.ctp
<div> 動物の名前は<strong><?php echo $animal_name;?></strong>です。 </div>
class DemoController extends AppController { public $name = 'Demo'; public $components=null;//ログイン認証不要 public function test_c(){ $this->autoRender = false;//ビュー(ctp)を使わない。 $this->header('Access-Control-Allow-Origin: *'); $this->header('Access-Control-Allow-Methods: POST'); $referer=$_SERVER['HTTP_REFERER'];//リファラ取得 $json_param=$_POST['key1']; return 'hello world '.$json_param; } }※クロスドメインでも遷移元URLであるリファラを取得できる。
$this->header('Access-Control-Allow-Origin: *'); $this->header('Access-Control-Allow-Headers: Origin, X-Requested-With, Content-Type, Accept'); $this->header('Access-Control-Allow-Methods: POST');
var data={'neko':'ネコ','same':{'hojiro':'ホオジロザメ','shumoku':'シュモクザメ'},'xxx':111}; var json_str = JSON.stringify(data);//データをJSON文字列にする。 var url="http://example.org/cake_demo/demo/test_c"; //☆AJAX非同期通信 $.ajax({ type: "POST", url: url, data: "key1="+json_str, cache: false, dataType: "text", success: function(str_json, type) { alert(str_json); }, error: function(xmlHttpRequest, textStatus, errorThrown){ $('#xxx').html(xmlHttpRequest.responseText);//詳細エラーの出力 alert(textStatus); } });
header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: POST'); $json_param=$_POST['key1']; echo 'hello world2 '.$json_param;
public function redirect_with_param(){ $text1='やぎ'; $text2='yagi'; $this->redirect(array( 'controller' => 'test1', 'action' => 'redirect_with_param2', $text1, $text2, )); }
public function redirect_with_param2($t1=null,$t2=null){ Debugger::dump($t1); Debugger::dump($t2); }出力
'やぎ' 'yagi'リダイレクト先のURLは以下のようになっている。
http://amaraimusi.sakura.ne.jp/sample/cake_smp/cakephp/test1/redirect_with_param2/%E3%82%84%E3%81%8E/yagiサンプル 参考1 参考2
echo $this->Html->link( 'TOPへ', '/pages/index', array('class' => 'btn btn-primary', 'target' => '_blank') );HTMLソース
<a href="/shch/pages/index" class="btn btn-primary" target="_blank">TOPへ</a>
echo $this->Form->button('ボタン1', array( 'type' => 'button', 'class' => 'btn btn-primary', 'onclick'=>"alert('Hello world!')", ));HTMLソース
<button type="button" class="btn btn-primary" onclick="alert('Hello world!')">ボタン1</button>
echo $this->Form->submit('検索', array( 'name' => 'search', 'class'=>'btn btn-success', ));HTMLソース
<input name="search" class="btn btn-success" type="submit" value="検索">
echo $this->element('sql_dump');本来ctpファイル内で使うものであるが、コントローラやモデルでも使える。
$sqlLog = $this->モデル名->getDataSource()->getLog();
debug($sqlLog);
http://localhost/cake_demo/animal/neko.html
バグ
...Cake/Cache/CacheEngine.php on line 60
発生原因
PHP5.2系からPHP5.3,PHP5.4,PHP5.6に変更すると発生。修正方法
app/Config/core.phpを開き、タイムゾーンの設定をする。//date_default_timezone_set('UTC'); ↓ date_default_timezone_set( 'Asia/Tokyo');
class EmailConfig { // Gmailによる送信例 public $gmail = array( 'host' => 'ssl://smtp.gmail.com', 'port' => 465, 'username' => '○○○○@gmail.com', //送信元メールアドレス 'password' => '○○○○', // パスワード 'transport' => 'Smtp', 'tls' => true ); }
App::uses( 'CakeEmail', 'Network/Email'); $email = new CakeEmail( 'gmail'); $email->from( array( '○○○○@gmail.com' => 'Sender')); // 送信元メールアドレス $email->to( '○○○○@gmail.com'); // 送信先 $email->subject( 'テストの件です'); // タイトル $email->send( 'メール内容です。いろはにほへとちりぬるをわかよたれそつねならむ');