スマートフォンやhtml5+CSS3など新技術に四苦八苦。jQuery、AjaxなどJavaScriptも難しいですね。そんなWebに悩む人のネタ帳です。

SQL文を書く知識はあるので、そのままSQLを書いてしまえばよいのですが、CakePHPを活用する上でモデルのルールに従った記述方法を知っておくことも重要です。

そこで、この記事では「このSQL文はCakePHPではどのように実装するんだっけ?」となった場面で役に立つようなメモを書き溜めていきたいと思います。
ちなみに、これらの動作はMySQL5.1、CakePHP1.3.9で確認済みです。

limit句でselect結果を絞り込む

SQLではlimit句を用いる事で、select結果の数を絞り込む事ができます。例えば、以下のようにオフセットを5、データ数を3とした場合、条件に合うデータの6番目から3つのレコードを取得できます。(オフセットは0が1番目を示すため)

SELECT
	*
FROM
	SAMPLE
LIMIT
	5, 3
;

これをCakePHPでは以下のように記述します。

$res = $this->Sample->find('all', array(
	'offset' => 5,
	'limit' => 3,
));

サイトの移動、または、ページの移動が発生した場合に、PHPのheader関数を使って旧URLから新URLへリダイレクトさせるのはよく使う方法ですが、改めて使い方を確認します。

例えば新サイト「http://helog.jp/」へリダイレクトさせる場合、私はこれまで以下のように処理を書いていました。

header("Location: http://helog.jp/"); 

実際アクセスするとリダイレクトされるので、一見、問題ないように思います。
しかし、上記のままでは302リダイレクトとして処理されてしまいます。302は一時的に移動した場合に用いられ、Googleなど検索エンジンは旧サイトのURLを残してしまいます。

301リダイレクトとして恒久的に移動、つまり、検索エンジンなどに新URLをインデックスしてもらうためには、以下のようにします。

header("HTTP/1.1 301 Moved Permanently"); 
header("Location: http://helog.jp/"); 

また、header関数では同一の処理を以下のようにして1行で記述することもできるようです。

例えば、PHPでフォームを構築する場合など複数のボタンを設置して、それぞれサーバ処理を分けたい場合があります。

具体的には、メールフォームで「送信してもよろしいですか?」といった確認画面では、「入力フォームに戻る」と「送信する」ボタンがあり、それぞれでサーバ処理を分岐させます。
複数のsubmitボタンがある場合に、サーバ側でどのボタンが押されたかを取得したいときに、どのような処理が適当なのかを考えてみます。

ちなみにこれから示す全てのコードは比較のために簡略化してあり、動作確認はとっていません。

JavaScriptでポストするデータを分ける

これまで私は、主にJavaScriptでPOSTするデータを操作し、サーバ側でその内容を判定することで、処理を分岐していました。

<a href="javascript:void(0);"><img onclick="back(); return false;" src="back.jpg" alt="戻る" /></a>
<a href="javascript:void(0);"><img onclick="send(); return false;" src="send.jpg" alt="送信" /></a>

JSの処理の中身は省略しますが、関数back()とsend()で異なるパラメータを設定してsubmitします。そうすると、そのデータがPOSTされるので、PHP側でデータ内容を判定して処理を分岐すればいいわけです。
JSではPOSTで送信するデータを自由に加工できるので、この方法では複雑な処理も可能になります。

Webサイトを構築する場合、フォントを指定します。例えば、Windowsでは通常「MS Pゴシック」を指定します。

何のために指定するのかというと、いかなる環境においても、なるべくサイトデザインに沿った、同じような見た目を保持するためです。
「MS Pゴシック」を指定するということは、Google ChromeやFirefoxなどブラウザに関係なく、OSのシステムフォントに「MS Pゴシック」がインストールされている場合に、それで表示するということです。

システムフォントに「MS Pゴシック」が存在することが前提なので、MacやLinuxなど、他のOSでは意図しないフォントで表示されてしまいます。
そのため、各OSに標準でインストールされているシステムフォントを考慮して、優先順位をつけてCSSでフォント指定をすることが一般的です。

body{
    font-family: "MS Pゴシック",arial,helvetica,clean,sans-serif;
}

つまり、これまではシステムフォントの都合上、全ての環境で同じフォントで表現するといったことが不可能だったわけです。

Firefoxのバージョン5が発表されたばかりですが、段階的にバージョン9までアップデートするそうです。
便利になることは良いことですが、制作の立場からすると互換性が心配です。

現在、私の環境ではFirefox3.6を使用していますが、とりあえず確認環境を残すという意味で、Firefox5を共存させてみたいと思います。

なぜFirefox4ではないかというと、どうもFirefox5が公開されている現段階で、Firefox4は入手できないようです。
次世代ブラウザ Firefox – 旧バージョンのダウンロード

プロファイルを分ける

Firefoxではユーザー毎に使用状況を保持するために、プロファイルを使用しています。
プロファイルの一覧はスタートメニューより「ファイル名を指定して事項」から「firefox.exe -ProfileManager」を実行すると確認できます。
また、このとき、ブラウザのFirefoxは閉じておくようにしましょう。

技術的に古い情報かもしれませんが、最近体験したことを書き留めておきます。

これまで、データを外部に持ち運ぶなんてことがほとんどなかったので、USBメモリを使う機会もありませんでした。
しかし、つい先日、どうしてもクライアント先に媒体経由でデータを納品しなければならないという事があったので、USBメモリを使ったのですが、クライアント先のPCでUSBメモリを認識してくれないという問題が発生しました。

クライアント先で使えなかったUSBメモリ

USBメモリは16GBのTOSHIBA製のものを購入しました。最近は大容量かつ安価なメモリが増えましたね。購入後は自身のPCでフォーマットしました。フォーマットをした環境はWindows 7、形式は「exFAT」です。

それまで「exFAT」という名を聞いたことがなかったのですが、大容量向けということだったので「16GBだしこっちのほうがいいのかな」と特に気にせずフォーマットしました。
しかし、クライアント先で使えなかった理由はここにあったようです。

「exFAT」とは

exFATとは先ほども述べたように大容量向けのフォーマット形式です。FAT32が最大容量32GBなのに対して、exFATだと16EBまでサポートできるとのこと。
見たことのない単位ですが、EBとは「エクサバイト」と呼び、GB「ギガバイト」の10億倍の容量だそうなので、最大サポート容量が約5億倍になった計算になるんですかね。
また、FAT32では1つのファイルの最大容量が4GBなのに対して、exFATは制限がないそうでうす。

ただ、OSによりサポートしていないものがあります。Windowsでいうと、exFATをサポートしているのはWindows 7、Vista Service Pack 1以上、XP Service Pack 2以上で、それ以外の環境ではUSBを挿しても認識してくれません。

つまりは、クライアント先のPCがWindows XP SP1以下だったため、ファイルを読み書きできなかったのです。
IE6の問題と一緒で、いつ古い環境を切り離すかというタイミングの問題がありますが、先走ると痛い目を見るという事ですかね。
そういうわけで、しばらくはFAT32に再フォーマットして使いたいと思います。

そもそも、16GBのメモリなので、exFATでフォーマットする必要もなく、FAT32で十分だったんですね。

PHPで動的に連想配列を作りたかったのですが、うまくいきません。

具体的には、以下にダンプに示すような配列をプログラムで作る想定です。

Array
(
    [key1] => data1
    [key2] => data2
    [key3] => data3
    [key4] => data4
)

これをPHPで静的に定義するためには、以下のようにすればよいです。

$array = array(
	'key1' => 'data1',
	'key2' => 'data2',
	'key3' => 'data3',
	'key4' => 'data4'
)

ただ、プログラム上、どうしても動的に配列を操作したい場合があり、その方法を考えていたのです。
例えば、上に要素を追加したい場合、array_push関数を使うとこうなるでしょうか。

array_push($array, 'key5' => 'data5');

PHPの文法に反しているので、当然ですがエラーになってしまいます。

CakePHPのモデルには、DBを更新する際に値をチェックするvalidate機能があります。
今回、それを活用しようとプログラミングしてみたのですが、なかなか問題が多かったので、とりあえずメモとして残しておきます。
CakePHPのバージョンは1.3.6です。

プライマリキーの重複チェックを試す

Sampleモデルについて、validate機能でプライマリキーの重複チェックをする場合には、以下のようにモデルに記述するだけです。CakePHPはこの簡易さがありがたい。

class Sample extends AppModel {
	var $name = 'Sample';
	var $validate = array(
		'id' => array(
			array(
				'rule' => 'isUnique',
				'message' => '「ID」が重複しています',
			),
		),
	);

マニュアルにもあるように、この記述で問題ないはずですが、なぜかチェックは機能せず、エラーパターンでもスルーして正常処理を続行してしまいます。
原因は不明ですが、どうしても出来ないので、ひとまずこの方法はあきらめます。

CakePHP1.3でページ毎にkeywordsとdescriptionを設定する方法を考えてみました。

CakePHPでサイトを構築した場合、通常、メタ情報を含めたヘッダ部分はレイアウト機能で共通化します。その中でも、keywordsやdescriptionといったページ毎に動的に切り替えたい部分があります。今回は、そのしくみについていろいろと試してみました。

Htmlヘルパーのmeta関数を用いる

Htmlヘルパーではmeta情報を出力するために関数が用意されています。例えば、keywordsタグを出力したい場合、ビューで以下のように設定します。

<?php echo $html->meta('keywords', 'キーワード1,キーワード2,キーワード3') ?>

その出力結果は以下の通りです。

<meta name="keywords" content="キーワード1,キーワード2,キーワード3" />

しかし、このままでは1つ問題があります。それは、ビューでmeta関数をコールした箇所に出力されてしまうということです。
「$script_for_layout」では設定したcssやjavascriptをメタタグ内に出力してくれますが、meta関数はそれとは異なるようです。したがって、ビュー内のmeta関数を置く場所や、レイアウトとビューの構成を工夫しなければ、正しい位置にkeywordsを設定することはできません。
あまりスマートな感じがしませんね。

CakePHP1.3、MySQL5の環境下で、DBにアクセスして情報を取得したのですが、どうしても日本語が文字化けしてしまいます。

$result = $this->find('all', array(
	'conditions' => array(
		'Sample.id' => $id
	),
));

例えば、このようにしてデータを取得しているのですが、2バイト文字だけどうしても化けます。ちなみにMySQLは文字コードUTF8の設定でテーブルに情報を保持しています。

原因は単純にデータベース設定でエンコードをUTF8に指定していないだけでした。

CakePHPでMySQLを利用する場合には、明示的にエンコードを指定する必要があるようです。
具体的には以下のように「app/config/database.php」に「encoding」を設定することで、問題を文字化けを回避できます。

Monthly Archives

Search