INFINITY BLUE
msgbartop
ご訪問ありがとうございます。『INFINITY BLUE』は、WEB+DB開発の情報や仕事の実績などを紹介しています。
msgbarbottom

2007年11月27日 21時31分(火) cakePHP: h()関数のクオート変換モードのカスタマイズ

cakePHPのクロスサイトスクリプティング対策としてh()関数を使用することが推奨されています。
h()関数はPHP のネイティブ関数htmlspecialchars()の短縮表記です。

検品中にクライアントからシングルクオートも対応してほしいという要望があり、時間もなかったことから、コア部分のcake/basics.php-function h($text) {…}を修正することにしました。
function h($text) {
if (is_array($text)) {
return array_map('h', $text);
}
-return htmlspecialchars($text);
+return htmlspecialchars($text, ENT_QUOTES);
}

今思うと、
function h($text, $mode=ENT_QUOTES) {
if (is_array($text)) {
return array_map('h', $text);
}
-return htmlspecialchars($text);
+return htmlspecialchars($text, $mode);
}
のようにクオート変換モードを設定できるようにしてほうが適切でしたね。

2007年11月27日 20時52分(火) cakePHPでgoogle mapを利用する

2007/11/24現在google map APIは日本の住所検索が未対応となっています。

近い将来対応すると思いますが、それまでは一度住所をgoogle geo code APIとかでジオコードへ変換し、そのジオコードからgoogle map APIで地図を表示しなければなりません。

cakePHPで実現する方法は、The Bakeryに既に2つ投稿されています。

上記二つを参考にして、実際に組み込みました。

※ cakePHP 1.1.18.5850で確認しています。が、自己責任で作業してください。

前準備

  1. GoogleGeoからダウンロードして、app/vendorsかvendorsディレクトリへコピーします
  2. GoogleMapHelperをダウンロードして、google_map.phpとファイル名を変更してapp/views/helpers ディレクトリへコピーします
  3. 上記コピーしたファイルに記述されているAPI KEYを、予め取得した Google Maps API Key(手続き)に変更します。
    class GoogleGeo {
    //your GoogleMaps Api Key
    var $api_key = "取得したAPI KEYを記述";
    class GoogleMapHelper extends Helper {
    var $errors = array();
    var $key = "取得したAPI KEYを記述";

作業

  1. レイアウトテンプレート[例)app/views/layouts/default.thtml]に、google api jsを記述する
    <script src="http://maps.google.com/maps?file=api&v=2&key=API_KEY" language="JavaScript" type="text/javascript" charset="UTF-8"></script>
  2. コントローラ[例)app/controllers/sample_controller.php]にvender()の記述
    vendor('google_geo');
  3. コントローラ[例)app/controllers/sample_controller.php]にヘルパーの記述
    var $helpers = array('GoogleMap');
  4. コントローラ[例)app/controllers/sample_controller.php-index()]に住所をジオコードに変換し、Viewへ渡す処理の記述。
    ジオコード変換する際、住所は都道府県・市区町村・番地までとします。ビル建物名まで渡すと正しく変換できません。
    なお住所の文字コードはUTF-8になります。
    $google = new GoogleGeo($address);
    $geo = $google->geo();
    $this->set('latitude', $geo['latitude']);
    $this->set('longitude', $geo['longitude');
  5. Viewテンプレート[例)app/views/sample/index.thtml]の記述
    // google mapを表示する領域に以下の記述
    < ?php echo $googleMap->div($style = 'width:312px; height:154px' ); ?>
    // google mapを表示する領域の後方へ以下の記述。IEだと前に記述すると表示されないので
    < ?php
    $points[0]['point']['latitude'] = $latitude;
    $points[0]['point']['longitude'] = $longitude;
    $points[0]['point']['title'] = "";
    $points[0]['point']['html'] = "";
    $default = array('type'=>'0','zoom'=>4,'lat'=>$latitude,'long'=>$longitude);
    echo $googleMap->map($default);
    echo $googleMap->addMarkers($points);
    ?>

今回使用したgoogle mapのヘルパーはすべての機能を網羅しているわけではないので、新規作成した方がいいかもしれません。

2007年11月20日 21時05分(火) cakePHP1.1系にcakePHP1.2系のCookieコンポーネントを利用する

cakePHP1.1系にはCookieを制御するコンポーネントの類が用意されていません。

自分でコンポーネントを作ってもいいですが、誰か既に作っているだろうと思いcakePHPのフォーラムで検索したところ 、cakPHP1.2系には標準で用意されていて、1.1系でも利用可能ということがわかりました。

※ cakePHP 1.1.18.5850で確認しています。が、自己責任で作業してください。

準備

  1. cakePHP1.2系のcake/libs/controller/components/cookie.phpをcakePHP1.1系のapp/controllers/componetnts/へコピー

利用の仕方

  1. コントローラで、コンポーネントの宣言
    var $components = array('Cookie');
  2. コントローラのメソッドでの処理
    // 保存期間設定
    $this->cookieTime = time() + 365 * 86400;
    // 適用するドメイン名
    $this->cookieDomain = '.'.$_SERVER['SERVER_NAME'];
    // cookie書き込み
    $this->Cookie->write('Store.id', $store['Store']['id']);
    // cookie読み込み
    $this->Cookie->read('Store.id');

cookieの設定は、まだ他にあります。ソースコードを読んで調べてください。

2007年11月18日 12時33分(日) cakePHP1.1系のSQL文を構築するときのエスケープ

cakePHP1.1系のSQL文を構築するときのエスケープですが、ちょっと手を加える必要があります。

デフォルトでanitize::sql()があるのですが、magic_quotes_gpc ONの時にはエスケープしません。

エスケープといってもaddslashes()しているだけですが。。。

なので、このようにしてエスケープするといいそうです。

[app/controllers/sample_controller.php]
function index($id=null) {

$db = & ConnectionManager::getDataSource($this->モデル名->useDbConfig);

$this->モデル名->query("SELECT * FROM table_name WHERE id = .$this->モデル名->value($id));

}

各コントローラに記述するのは面倒なので、

appModelで記述すればいいかも。

[app/app_model.php]
class AppModel extends Model{
var $db = null;
function __construct() {
parent::__construct();
$this->db =& ConnectionManager::getDataSource($this->useDbConfig);
}
function escape($data=null) {
// ちなみに、このことを知る前はこんな風に記述していました。
// return "'" . mysqli_real_escape_string($this->db->connection, $data) . "'";
return $this->db->value($data);
}
}

[app/controllers/sample_controller.php]
class SampleController extends AppController {
var $uses = array('モデル名');
function index($id=null) {
$this->モデル名->query("SELECT * FROM table_name WHERE id = .$this->モデル名->escape($id));
}
}

2007年11月11日 22時26分(日) cakePHPガイドブック

今年に入ってからPHPフレームワークとしてcakePHPを利用しています。

最近、日本語の書籍としてはじめてcakePHPの本が刊行されました。
CakePHP Users in Japan で有名な方達が著者ですので、内容もしっかりしています。