WEB/システム/IT技術ブログ

CakePHPで「404 NOT FOUND」や「500 Internal Server Error」など、例外処理で画面を作る方法です。

CakePHPでは、特に何もしなくてもフレームワークの方でメッセージを出してくれます。しかし、開発側で意図的にエラーの種類を分けたり、画面を作成したい場合があります。
フレームワークを無視して独自でPHPで実装するのもありですが、CakePHPにそのしくみが用意されているのを見つけたので、利用してみます。

エラー用のビューを設置する

CakePHPではエラーが発生した際に参照するビューディレクトリがあります。

/app/views/erros/

例えば、404エラーの場合は「error404.ctp」というビューを設置しておけば、404エラーが発生した際に自動的にこのビューが出力されます。

FirefoxやGoogle Chromeでは問題ないのに、Internet Explorerからだと画像をアップロードできないという問題が発生しました。
結果から言うと、原因はMicrosoftの独自仕様である「image/pjpeg」でした。

例えば、フォームで画像をアップロードする際、JPG画像に限定させたいという場合があります。
アップロードされたファイル名の拡張子から判断するのは危険なので、通常ではContent-Typeからファイルタイプを読み取ります。

以下はフォームのソース例です。

<form action="" method="post" enctype="multipart/form-data">
<input type="file" name="image" />
</form>

フォームからのリクエストをPHPで受け取り、JPGかどうか判定するのに以下のように処理を実装します。

以前に以下のような記事を書きました。
CakePHPでAuthコンポーネントを使ってみる
この時はCakePHP1.3.9で検証したのですが、ログイン処理がマニュアル通り動作しない問題がありました。

原因は不明です。少しコアな部分を調べましたが、分かりませんでした。
デフォルトの設定が原因なのか、単純にバグだったのか分かりませんが、今回、CakePHP1.3.12で試したところマニュアル通り機能したので、改めて書きます。

ユーザ管理テーブルを用意する

こちらは以前と同じ仕様です。「users」テーブルに「username」と「password」のカラムを持たせます。

CREATE TABLE users (
    id INTEGER(8) auto_increment PRIMARY KEY,
    username VARCHAR(50) NOT NULL,
    password VARCHAR(50) NOT NULL,
    date_create VARCHAR(19) NOT NULL,
    date_update TIMESTAMP NOT NULL
);

Google Maps APIを利用する際、以前はマップ上にマーカーを立てるのにそのポイントとなる経度、緯度が必要でした。
つまり、住所から直接ポイントを設定することは出来ず、住所などの情報から一度、経度、緯度を調べる必要があったのです。マーカーが増えると、その作業もめんどくさくなりますね。

今回、このようなマーカーを複数立てるマップコンテンツを作ることになり調べていたのですが、Google Maps APIよりテキストの住所から経緯を取得できるAPIが公開されていたので、早速使ってみました。
Google Geocoding API

まずはサービスを使用するにあたり、APIを読み込みます。

<script type="text/javascript" src="http://maps.google.com/maps/api/js?sensor=true">

次に以下のようにしてGeocodingのインスタンスを生成します。

var geo = new google.maps.Geocoder();

APIにリクエストを投げる際には関数geocodeを使用します。関数geocodeの第一引数にはリクエストパラメータ、第二引数にはコールバック関数を設定します。
今回は試しにパラメータに東京スカイツリーの住所「東京都墨田区押上1丁目」を設定してみます。

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へリダイレクトさせるのはよく使う方法ですが、改めて使い方を確認します。

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

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

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

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

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

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

HTMLフォームのsubmitボタンを連続でクリックしてしまうと、意図しないデータが多重に送信されてしまうという問題があります。

これを防止するために、JavaScriptで二重にクリックするのを抑止する方法があります。
シンプルなしくみだと、一度クリックされたらフラグをオンにしてボタンクリックを無効にしたり、押されたボタンにdisabledをセットして非活性にしてしまうなど、比較的簡単な処理で済みます。しかし、深いところまで突き詰めて完全に抑止しようとすると、めんどくさい設計と処理を実装が必要となります。さらに、コーディング規約やフレームワークのルールなどで制限されている環境だと、さらに難しい問題となってふりかかります。

例えば、今回私が実装した環境では以下のような前提がありました。

  • サブミットまでの処理で極力JSを使わない
  • フォームのボタンタイプは「type=”image”」
  • 複数のボタンが存在しサーバ処理を分岐している

フラグを用いた方法だと、複数個所にJSを埋め込む必要があったので、却下しました。また、disabledをセットする方法では押されたボタンの情報はPOSTされないので、サーバ側でどのボタンが押されたのか判断できなくなるため、却下しました。

HTML5には新しいタグがいくつか追加されています。それらの中には文書構造に意味を持つものもあり、今後のコーディングにおいては各々のタグの役割を理解することが重要になるかもしれません。
そこで、今回は、HTML5のアウトラインを意識して、このブログの文書構造を調整したいと思います。

HTML5アウトラインを可視化する

アウトラインを可視化するツールとしては、Google Chromeのプラグイン「HTML5 Outliner」があります。
HTML5 Outliner – chrome ウェブストア
その他には、Webツールもあります。
HTML 5 Outliner
2つで可視化した結果、構造に大きな差はありませんが、後者は画像のaltを見出しとして読み込んでくれる点など、若干の違いはあります。ただ、HTML5の定義が厳密でない現時点では、優劣をつけるのは難しいです。

以下は、このブログをHTML5 Outlinerで可視化した結果です。

どうやら、意味を持つ要素に対して見出しが設定されていない箇所が多いようです。

CSS3のプロパティ「text-shadow」を使ってフォントを装飾する方法です。

フォントにシャドウを付ける

以下のように設定することで、フォントに影を付けることができます。

text-shadow: 1px 2px 3px #ff0000;

それぞれの値は、
右方向に1pxずらして(マイナスだと左方向)、
下方向に2pxずらして(マイナスだと上方向)、
ぼかし具合を3px、
影の色は「#ff0000」にというように指定してあります。

text-shadowのサンプルです。

もちろん、text-shadowが使えるのはCSS3に対応しているブラウザに限りますが、私の環境では、Firefox5とGoogle Chrome 12で表示できていることを確認できています。残念ながらIEは対応していません。

CSS3のプロパティ「radius」を使ってborderの角丸を表現する方法です。

基本設定

以下のようにCSSで設定することで、borderで指定した枠線を角丸で表現することができます。

border: 3px solid blue;
border-radius: 10px;

1ピクセルで青の枠線の角を10pxの度合いで曲線で表現します。以下に実際の組み込み例を示します。
※もちろんIE8以下など対応していないブラウザでは閲覧できません。

border: 3px solid blue;
border-radius: 10px;

みさなまお使いのブラウザでは角が丸く表示されているでしょうか。

少し前まで、「border-radius」はCSS3の草案で、表現できるブラウザは存在していませんでしたが、Firefox5.0、Google Chrome 12では問題なく表示されているようです。
それまではGoogle ChromeとSafariでは「-webkit-border-radius」、Firefoxでは「-moz-border-radius」が用意されていましたが、近い将来「border-radius」に統一されるでしょう。

-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;

ちなみにIE8以下は対応していないので、見比べるとその効果を確認することができます。

Monthly Archives