Posts tagged http
CakePHP HtmlHelper::tagValue のHTMLエスケープ処理
1view でモデルの値などを出力する際に
$html->tagValue("Model/hoge");
とすれと、HTMLエスケープ処理をしてくれるので便利です。
ただ、
CakePHP 1.1.15.5144以降はHtmlHelper#tagValueに注意 | Shin x blog
に書かれているように、CakePHP のバージョン1.1.15.5144 からエスケープするかのフラグが追加されたようです。
以前はエスケープしないを選択できなかったので、それはそれで不便な点もありました。
MOONGIFT ブログ ? CakePHP覚書(HTML Helpler)
しかし今回の変更で注意しなければいけないのは、デフォルトでエスケープされていたのがデフォルトでエスケープ処理されなくなったことです。
cake/libs/view/helpers/html.php
function tagValue($fieldName, $escape = false)
以前のようにエスケープ処理させるには
$html->tagValue("Model/hoge", true);
とする必要があります。
また、
ちなみに1.2.0.5147ではtagValueがdeprecatedになっており、代わりにvalueメソッドを使うようになるようです。
ということになるようです。
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
にコピーしてカスタマイズした方がよいでしょう。
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 キャッシュファイルの使用
1CakePHP でキャッシュを使用するときに便利なグローバル関数があります。
- cache($path, $data, $expires, $target)
- $data のデータをキャッシュします。
キャッシュする場所は
$target==”cache” なら /app/tmp/cache/ + $path
$target==”public” なら /webroot/ + $path
になります。$target を指定しなければ $target==”cache” です。
$expires はキャッシュの有効期間です。
内部で
$expires = strtotime($expires, time());
が行われるので、strtotime の Data input formats 形式に準拠したものでなければいけません。
デフォルトは $expires = ‘+1 day’ です。 - clearCache($params, $type, $ext)
- $paramsが文字列でキャッシュディレクトリかファイル名にマッチする場合はキャッシュから削除されます。
$params が配列の場合は配列内の文字列全てに対して上記の処理が行われます。
対象のディレクトリは $type で指定します。
$type のデフォルトは ‘views’ です。
対象ディレクトリは /app/tmp/cache/ + $type になります。
cache 関数で ‘public’ を指定した場合のクリアはこの関数ではできないようです。
結構簡単にキャッシュ処理ができそうです。
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 のグローバル定数とグローバル関数
阪神岡田監督の黄色い時計が気になる
0今年のタイガースの不甲斐なさも気になるが、テレビ中継を見ていて岡田監督がアップになったときの黄色い時計も気になる。。。
なんか子供がつけるような黄色いベルトで文字盤に緑色まで見える。かなり派手だ。
うちの相方なんか「阪神グッズじゃないの?」とか言っているし。それは絶対ないだろうな。
で、調べてみたところスイス製の時計でした。
ゾディアックのシードラゴンという商品のようです。
価格も25,000円前後と岡田監督がしている時計としては割りとお手ごろですね。
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タグも入らずに署名やヘッダなども読み込めてよいかと思います。
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 入力フォームで確認画面を表示する方法
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>