Posts tagged ec
CakePHP コントローラのflash メソッド
2データを更新した後などに「更新しました」などのメッセージを簡単に出せるのがコントローラのflash メソッド。
コントローラで、
$this->flash('更新しました', '/users');
などとすることにより、メッセージを簡単に出せる。
2つ目の引数は飛び先URL を指定できる。
ちなみにこの flash メソッドは下記のようになっています。
/cake/libs/controller/controller.php
function flash($message, $url, $pause = 1) { $this->autoRender = false; $this->autoLayout = false; $this->set('url', $this->base . $url); $this->set('message', $message); $this->set('pause', $pause); $this->set('page_title', $message); if (file_exists(VIEWS . 'layouts' . DS . 'flash.thtml')) { $flash = VIEWS . 'layouts' . DS . 'flash.thtml'; } elseif ($flash = fileExistsInPath(LIBS . 'view' . DS . 'templates' . DS . "layouts" . DS . 'flash.thtml')) { } $this->render(null, false, $flash); }
上のソースを見ると分かるように、この flash メソッドのレイアウトは
$layout = "hoge";
とか指定しても指定したレイアウトでは表示されません。
flash メソッドでは flash.thtml というレイアウトを使用することしかできません。
/app/views/layouts/flash.thtml
を探してなければ、
/cake/libs/view/templates/layouts/flash.thtml
のデフォルトのレイアウトを使用します。
また、デフォルトの flash.thtml は
<html xmlns="http://www.w3.org/1999/xhtml"> <head> <title><?php echo $page_title?></title> <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /> <?php if(Configure::read() == 0) { ?> <meta http-equiv="Refresh" content="<?php echo $pause?>;url=<?php echo $url?>"/> <?php } ?> <style><!-- P { text-align:center; font:bold 1.1em sans-serif } A { color:#444; text-decoration:none } A:HOVER { text-decoration: underline; color:#44E } --></style> </head> <body> <p><a href="<?php echo $url?>"><?php echo $message?></a></p> </body> </html>
のようになっていて、
DEBUG モードで DEBUG = 0 を指定していると meta タグを利用して勝手に画面遷移します。DEBUG モードが 0 以外の場合はメッセージをクリックすると指定したURLに画面遷移します。
非常にシンプルなレイアウトですので、使用するときは、
/app/views/layouts/flash.thtml
にコピーしてカスタマイズした方がよいでしょう。
CakePHP ヘルパーからコンポーネントへのアクセス方法
1ヘルパーからコンポーネントへのアクセス方法が分からず
教えていただいたのでメモ。
例えば HogeComponent にアクセスしたいヘルパーに
$this->view->controller->HogeComponent->method();
というように書けば、HogeComponent の method にアクセスできる。
これで、ヘルパーがかなり使いやすくなりました。
PHP で大きいJPEGやPNGファイルをPHPで扱うときのメモリエラー回避方法
0GD でメモリエラー
に書かれているように GD で JPEG や PNG の大きな画像を扱うときに
Fatal error: Allowed memory size of 16777216 bytes exhausted (tried to allocate 11648 bytes) in ...
というようなエラーが出てしまいます。
上のエラーがは私が EOS5D で撮影した 2912×4368とかなり大きな画像です。
大きさで制限するのも一つの方法ですが、どうしても大きな画像を取り込みリサイズしなければいけないときなどのために以下の方法もあります。
PHP: imagecreatefromjpeg – Manual
PHP に割り当てられているメモリの範囲で必要なメモリを計算して
ini_set('memory_limit', 'xxM')
と設定しれくれます。
function setMemoryForImage( $filename ){ $imageInfo = getimagesize($filename); $MB = 1048576; // number of bytes in 1M $K64 = 65536; // number of bytes in 64K $TWEAKFACTOR = 1.5; // Or whatever works for you $memoryNeeded = round( ( $imageInfo[0] * $imageInfo[1] * $imageInfo['bits'] * $imageInfo['channels'] / 8 + $K64 ) * $TWEAKFACTOR ); //ini_get('memory_limit') only works if compiled with "--enable-memory-limit" also //Default memory limit is 8MB so well stick with that. //To find out what yours is, view your php.ini file. $memoryLimit = 8 * $MB; if (function_exists('memory_get_usage') && memory_get_usage() + $memoryNeeded > $memoryLimit) { $newLimit = $memoryLimitMB + ceil( ( memory_get_usage() + $memoryNeeded - $memoryLimit ) / $MB ); ini_set( 'memory_limit', $newLimit . 'M' ); return true; }else return false; } }
CakePHP グローバル関数
0PHP のネイティブ関数の短縮表記には下記のようなものがあります。
a() => array()
e() => echo()
low() => strtolower()
up => strtoupper()
r() => str_replace()
am() => array_merge()
h() => htmlspecialchars()
このような短縮表記の関数を独自に定義して開発に使用されている方も多いと思いますが、CakePHP として定義されていると使用しやすいですね。(特に複数人で開発しているときなど、標準であると助かります。)
このほかにも CakePHP には便利な関数が定義されています。
- debug($var, $showHtml);
- DEBUGレベルが0以外のときに、$varが出力される。
print '<pre>';
print_r($var);
print '</pre>';
のようなことをしてくれます。$showHtmlが TRUE ならブラウザで見やすいように出力してくれます。 - aa(‘a’,'b’)
- 連想配列を作成する。
array('a'=>'b')
をやってくれます。 - h($mixed)
- 文字列を指定して htmlspecialchars をやってくれるが、配列も指定できる。
配列を指定すると再帰的に h() を呼び出している。 - pr($var)
- print_r をブラウザでみやすいように <pre> で囲んでくれます。
echo "<pre>";
print_r($var);
echo "</pre>" - env($key)
- 環境変数を取得できます。
一番の特徴は PHP_SELF, DOCUMENTO_ROOT をサポートしていないサーバでも動作をエミュレートして値を返してくれます。コードを再配布するときには重宝しそうです。 - params($mixed)
- 文字列を返してくれます。
配列なら一番最初の値、文字列なら文字列、値がなければ NULL を返します。 - setUri()
- 現在のURI を返してくれます。
- file_get_contents()
file_put_contents() - この関数が実装されていない PHP4.3 未満のためにエミュレートされています。
- stripsslashes_deep($array)
- $array は配列を指定。配列の全ての値に対して再帰的に stripslashes を行います。
- countdim($array)
- $array の配列の次元数を返します。
- LogError($message)
- CakeLog::write を実行します。
- fileExistsInPath($file)
- 現在のinclude パスから $file で指定されたファイル名があるか探します。
見つかればそのパスを返し、見つからなければ false を返します。 - ife($condition, $var1, $var2)
- $condition が true なら $var1 を返し、false なら $var2 を返す。
使用しすぎると読みにくいコードになりかねませんが、うまく使用すれば開発効率が上がりそうです。
日本語マニュアル:Chapter 11. Cake のグローバル定数とグローバル関数
CakePHP でビューでメール本文を作成する方法
0前回の記事でメール用のビューを管理する方法を書きましたが、
今回はビューを使用してメール本文を作成する方法です。
前提として
- メール用のレイアウト名は /app/views/layouts/email.thtml で管理
- メール本文に使用するビューは /app/views/email/hoge.thtml
だとすると
ob_start();
という感じで、$body に本文が入ります。
$this->render(null, 'email', '/path/to/app/views/email/hoge.thtml');
$body = ob_get_clean();
ちなみにレイアウトを指定しないと default.thtml が使用されHTMLタグが入ってしまいます。
emial.thtml で
ここにメールの共通ヘッダなどなど <?php echo $content_for_layout; ?> ----------------------------------- ここに署名などなど -----------------------------------
としておけば、HTMLタグも入らずに署名やヘッダなども読み込めてよいかと思います。
CakePHP でコントローラ名以外の view を指定する方法
3CakePHP では HogeController::foo() に対するビューは
/app/views/hoge/foo.thtml
になります。
このときに、/app/views/hoge/foo2.thtml というビューを使用したいときは
HogeController::foo() で
$this->render('foo2');
と指定すればOKです。
今回違うコントローラ名で管理しているビューを使用できないものかと
/cake/libs/view/view.php
を調べてみたところ
$this->render(null, 'layout', '/path/to/app/views/email/register.thtml');
という方法で
/app/views/email/register.thtml
のビューを HogeController::foo() から使用できました。
render の第3引数に絶対パスで使用したいビューを指定すればOKです。
第1引数でビュー名を指定しますが、第3引数が指定されていると無視されます。
また、レイアウトは第2引数でそのまま指定できます。
あまり他のコントローラのビューを使用することはないと思いますが、
例えば、メール送信時に使用するビューを
/app/views/email/
などのディレクトリ名で管理するなどが用途として考えられます。
PEAR の DB から MDB2 への移行メモ
0やっとMDB2 へ移行したので、その時のメモ。
DBからMDB2への移行は結構いろいろなサイトで書かれていますね。
PHPのテクメモ | pearのDBとMDB2の違い
DB-2-MDB2
これらを参考にさせていただいたのですが、
私はよくプレイスホルダをよく使用しています。
$db->getOne('SELECT * FROM users WHERE id=?", array($id));
MDB2では queryOneメソッドではプレイスホルダが使用できないので(queryRow,queryAllなども同様)移行に手間がかかってしまいます。
少し調べてみると下記のようにすることにより、MDB2 でもプレイスホルダが使用でき、しかも getOne や getAll などのメソッド名もそのまま使用できます。
$db->getOne('SELECT * FROM users WHERE id=?", array($id));
$mdb2->getOne('SELECT * FROM users WHERE id=?", null, array($id));
ただ、
require_once 'MDB2.php';
require_once 'MDB2/Extended.php';
と Extended をロードする必要があります。
CakePHP SQL を書いて実行する方法
1CakePHP ではSQL を書かなくてもだいたいなんでもできるのですが、
ちょこっとSQLを書いて実行したいことがあり調べたメモです。
/cake/libs/model/model_php5.php
を眺めていると findBySqlメソッドがありました。
引数はSQLを文字列で受け取ります。
これだ!っと思ったらただ単に
function findBySql($sql) {
return $this->query($sql);
}
となっている。。。
queryメソッドにSQLを投げればいいんですね。
$sql = "SELECT NOW()";
$foo = $this->HogeModel->query($sql);
CakePHP 入力フォームで確認画面を表示する方法
3フォームを入力後、すぐに保存ではなく一度確認画面を表示させたい場合のやり方。
こちらに詳しいやり方が書いてあります。
http://www12.atwiki.jp/nezox/pages/6.html
ポイントは
- 入力フォームで
<input type="hidden" name="mode" value="confirm">
とする。
- コントローラの add アクションでバリデーションチェック後に
if (@$_POST["mode"]=="confirm") { // 確認画面を表示する $this->render('confirm'); } else { // 保存処理 if ($this->User->save($this->data)) { $this->flash('Your post has been saved.', '/users'); } }
- 確認画面の view を confirm.thtml を作成
<h1>確認画面</h1> <form action="<?php echo $html->url('/users/add'); ?>" method="post"> ログインID: <?php echo $html->tagValue('Users/login_id'); ? <?php echo $html->hidden('Users/login_id', array('value'=>$html->tagValue('Users/login_id'))); ?> <input type="button" value="戻る" onclick="history.back();"> <input type="submit" value="新規登録"> </form>