try、throw、catch・・・その2

2008/04/19 | PHPの基本

try{}catch(){}構文の研究中につき、理解できた範囲をメモ。
PHP5から使えるようになったJAVAライクなエラー処理だが、慣れない自分にとっては理解に苦しむ記述なので、自分でいろいろ試してみることにした。
こんなスクリプトを書いた。

class myException extends Exception
{
}

class myClass
{
  function __construct()
  {
    print(‘1′);
    print(‘2′);
    throw(new myException(‘error’));
    print(‘3′);
    print(‘4′);
  }
}

try{
  $obj=new myClass;
}catch(myException $e){
  exit();
}

まずExceptionというクラスを継承してmyExceptionという派生クラスを作った。別に特別な処理をしているわけではないけれど、いろいろ調べたかったので、まずは派生クラスを定義しておいた。
次に実際に例外を投げるクラスをつくった。このクラスのコンストラクタの中で、
throw(new myException(‘error’));
と単に例外を投げるように記述した(実際はif文とか使ってエラーが発生した場合に例外を投げることは言うまでもない)。
最後のところで実際にオブジェクトを生成する処理を書いてある。
これを自分なりに読んでいく。

throw(new myException(‘error’));
throw関数の引数は例外として生成したオブジェクトらしい。おそらくいろいろな例外をあらかじめ想定し、例外の種類に応じてそれぞれの例外派生クラスを引き当てるのだろう。この例外クラスの引数は文字列でないといけないっぽい。つまりエラーメッセージをセットするようなイメージだろうか。いちおうもうひとつ引数を取れるみたいで、そちらにはエラーコード(番号)をセットするような感じ。

エラーが発生(例外をthrow)すると、そのスクリプトは途中で中断され(上記で言えば関数内の処理が途中で中断され)、catch構文へ処理が遷移することになる。

catch(myException $e)
この構文の意味がなかなか理解できなかった。どうやらmyExceptionのところは事前に想定した例外のクラス名を割り当てる(のだと思う)。後ろの$eはというと、実はここは$abcでも$errorでも何でもよさそう。new myException(‘error’)で「作りっぱなし」かよ、と思えたオブジェクトはこの変数に代入されるようだ。
あとは$eを煮るなり焼くなりすればいい。

ちなみに、いくつもの例外を想定するわけだから、実際はこんな記述になるのだろうか。

try{
  $obj=new myClass;
}catch(my1Exception $e){
  exit();
}catch(my2Exception $e){
  exit();
}catch(my3Exception $e){
  exit();
}catch(Exception $e){
  exit();
}

いろんなエラーを想定しておいて、どれに合致するか試してみて、それにも合致しないエラーが出てしまったら最後のデフォルトの例外クラスでキャッチ。

理解できたようなできていないような・・・。まだしっくりこない。

classに関するメモ

2008/04/18 | PHPの基本

PHPのクラスに関するメモ。
クラスAとそれを継承したクラスBのコンストラクタに関して、時々どうだったっけ、と思うのでメモしておく。

class A
{
  function A(){print(‘A’);}
}

クラスBにコンストラクタがない場合
class B extends A
{
}
$obj=new B;
// Aと表示される(親クラスのコンストラクタが実行される)

クラスBにコンストラクタがある場合
class B extends A
{
  function B(){print(‘B’);}
}
$obj=new B;
// Bと表示される(親クラスのコンストラクタは実行されない)

コンストラクタはPHP5以降、__construct()とも書けたりもするのでこんがらがってしまうけど、__construct()のほうがわかりやすい。

だって、
class B extends A
{
}

って書いてるのだから、コンストラクタはB()か__construct()であって、A()がコンストラクタにはならないほうがいいように思う。だって複数回継承されたときの元のコンストラクタがなんだったかわからなくなるから。昔からの名残だからしょうがないんだろうけど・・・。
やはりPHP5ライクな記述を目指すべきだと思った(PHP4の環境が当面なくなりそうにないからしょうがないか)。

携帯でGoogle Mapsを使う

2008/04/17 | ケータイ

Google Maps APIはJacaScript/Ajaxを活用した技術だから、同然携帯では使用することができる(携帯ではJavaScriptが動かないという前提だが)。しかしGoogleはいつの間にか、やってくれていた。ついに携帯でも地図を表示させることができる。

Google Static Maps API

グリグリと地図を動かすことはできないけど、一枚の画像として画像を呼び出すことができるようになっている。HTML中にimgタグを使ってRESTで呼び出せばいい。RESTの形式はこんな感じ。

http://maps.google.com/staticmap?
center=[中心の緯度],[中心の経度]
&zoom=[倍率(ズームレベル)]
&size=[出力する画像の横ピクセル]x[出力する画像の縦ピクセル]
&maptype=[mobile / roadmap]
&markers=[マーカー緯度],[マーカー経度],[色][マーカーのアルファベット]
&key=[APIキー(Google Mapsと共通)]

住所からダイレクトに地図を表示することはできないけれど、緯度経度をなんとか用意できれば大丈夫。さっそく使うことにしよう。

JavaScriptと<a>タグで

2008/04/16 | JavaScript/Ajax

<a>タグを設定して、当該リンクのクリック時にJavaScriptで各種の処理をしたい場合の記述方法のメモ。

例えば以下のように書くことがある。
<a href="javascript:(JavaScriptの関数);">リンク</a>
<a href="#" onClick="(JavaScriptの関数)">リンク</a>

いずれの場合も期待通りに動いてくれれば問題ないけど、期待した動作+余計な動作(2つ目の記述をした場合にページの一番上に移動してしまう)があった場合などは以下のような記述をしてみるといい。
<a href="javascript:void((JavaScriptの関数));">リンク</a>
<a href="javascript:void(0);" onClick="(JavaScriptの関数)">リンク</a>

void(0)
何もしない、ということらしい。「希望通りに動けばいい」というセンスだから詳しく調べはしないけれど・・・便利だね。

文字列のエスケープ

2008/04/12 | PHPの基本

例えば掲示板プログラムを作った場合、入力された文字はそのままデータベースやテキストファイルで保存して、出力するときに<や>などを変換して表示するのはよくあることだ。これには通常htmlspecialchars関数を使用する。しかしこの関数、実は奥深い。
まずhtmlspecialcharsとよく似た働きをする関数にhtmlentitiesという関数がある。両者の違いは何かというと、実際に引数で与えられた文字列を変換する際に、変換する文字列の種類(というか変換する文字数)が違うのだ。基本的にhtmlspecialcharsでは「>」「<」「"」「&」だけなのだが(HTMLで使用する際に支障が出そうな文字列だけを変換)、htmlentitiesでは、&と;で囲んだ文字に変換できるものはすべて変換するのだ。htmlspecialcharsで変換されないものは、実は結構たくさんある。両者の違いは以下の2行のスクリプトを実行すればわかるだろう(普通のウェブ開発で使用することはまずないので、一回くらいは試してみてもいい)。

print_r(get_html_translation_table(HTML_ENTITIES));
print_r(get_html_translation_table(HTML_SPECIALCHARS));

つまり変換で使用する一覧を、それぞれの関数の場合で表示させることができるのだ。本来変換可能な文字列というのは、割とたくさんあることがわかるだろう。

さてhtmlspecialcharsで通常変換する文字列が「>」「<」「"」「&」と言ったが、何か気にならないだろうか。気になった人は鋭い。「'」だ。HTMLで属性の値を囲むときは通常「"」を使うが「'」も使うことが可能だ。であれば「'」も変換できたほうがいいはずだ。

実はこの「'」は、デフォルトでは変換されないのだが、htmlspecialchars関数に第二引数を与えることによって変換することができる。ちなみに第二引数でとりうる値は以下の3つだ。

ENT_COMPAT 「'」は変換せず「"」は変換(デフォルト)
ENT_quotS 「'」も「"」は変換
ENT_NOquot 「'」も「"」も変換せず

シングルクォーテーション、ダブルクォーテーションにはいろいろあるわけだ。ちなみにhtmlentitiesでも上記と同様第二引数で指定することができる。基本的に両者は同じなのだが、日本語環境でほとんどhtmlentitiesが使われないのは、例えば半角カナが割り当てられた領域も変換をかけようという処理が入ってしまうためにもろもろ不具合がでる、というところによるのだろう。

htmlspecialcharsのような一般的な関数でも、実は奥が深かったりする。前からうすうす理解はしていたのだが、しっかり調べるとなるほど納得。やはりおくが深いのだ。


守谷市(まちの情報ポータル) 無料アンケートレンタルjpForm.net