« 2005年10月 | トップページ | 2005年12月 »

・[2005年11月21日]XML Libraryを使ってみよう
・[2005年11月13日]PHPのShift_JIS文字化け対策1
・[2005年11月08日]Google Mapsを使ってみよう2
・[2005年11月04日]Google Mapsを使ってみよう1
・[2005年11月03日]Excelファイルの書き出し2

2005年11月21日

XML Libraryを使ってみよう

XMLをPHP上で簡単に操作する方法を「PHP XML Library」を使って紹介します。
PHPとXMLを連携する際に、PHPの標準関数を使用したりPEARを使ったり色々な方法がありますが、今回紹介するのはXMLを多次元配列にセットしたり、またはその逆(配列をXMLに変換すること)が出来ます。

Keith Devens .com

まず、Keith Devens .comから「PHP XML Library, version 1.2b」をダウンロードします。
次にダウンロードしたプログラムをrequire_once関数やinclude_once関数で読み込ませます。

require_once('xml.php');

これで準備はOKです。
次に読み込ませるXMLを準備しましょう。
今回は、簡単な例として以下のようにシンプルなXMLを準備しました。
<?xml version="1.0" encoding="utf-8"?>
<DOCUMENT>
  <members id="1">
    <name>テスト 太郎</name>
    <age>30</age>
  </members>
  <members id="2">
    <name>テスト 花子</name>
    <age>25</age>
  </members>
</DOCUMENT>

このXMLを「test.xml」を言う名前で保存しておきます。
fread関数を用いて、xmlを変数に全て格納します。
$fp = fopen("test.xml", "r");
$xml = fread($fp, filesize("test.xml"));
fclose($fp);

require_onceで読み込ませたファイルの中に定義されているXML_unserialize関数を使用して変数に格納します。
$data = XML_unserialize($xml);

$data配列の中にXMLの内容が格納されています。
var_dump関数などを使用して表示してみましょう。
今までのソースをまとめると以下の通りです。
require_once('xml.php');

$fp = fopen("test.xml", "r");
$xml = fread($fp, filesize("test.xml"));
fclose($fp);

$data = XML_unserialize($xml);
var_dump($data);


XMLを配列に変換するサンプルはこちらから。(ソースを表示すると見やすいと思います)

今度は、変数に格納したXMLを復元してみましょう。
先程、生成した変数をXMLに変換するにはXML_serialize関数を使用します。

echo XML_serialize($data);

XMLとして出力されます。
出力したサンプルはこちらから。

今まで紹介したように、XMLを簡単に使用したい場合など重宝します^^;
ただ、今までの経験上からですが配列にセットした場合、予想した値が格納されなかったりバグの原因になりやすく、また発見しにくいので複雑な処理には向いてないと思います。
それでも結構便利ですが、、、^^;

・関連記事
XML_Serializerを使ってみようを見る
XML LibraryのPEAR版みたいなものです。

| | コメント (3) | トラックバック (0)

2005年11月13日

PHPのShift_JIS文字化け対策1

PHPで開発の経験を積んでいくと必ずと言っていいほど文字化けに悩まされます。
PHPに限ったことじゃないけど、文字化け対策は私達WEB業界の永遠のテーマかなって思ってます^^;
私は文字コードを統一したり、文字コードの変換などある程度ルールを決めてうまく回避してます。
WEBシステム開発において、「Shift_JIS」はかなりの曲者で、私もかなり苦戦してきました。
一番問題になったのが「\」マークが自動でついてくることで、例えばフォームの文字列に「表示」を入力してフォームを送信するとフォームの値が「表\示」となって返ってきます。
この業界で仕事を始めた頃は「Shift_JIS」を使用しないで「EUC-JP」等で統一することでうまく回避してきたのですが、どうしても「Shift_JIS」で開発しなきゃいけない場合もあります。
例えば、携帯サイトを作る場合は古い機種も対象にいれるので「Shift_JIS」での開発が必要になります。
最近の機種だと「Shift_JIS」以外も可能みたいですが、古い機種は「Shift_JIS」しか表示出来ません。
さて、前置きが長くなりましたが「\」マークが自動でついた時にどのような対策案があるのかご紹介します。

Shift_JIS文字化け問題のお話をする前に「"」や「\」等の特殊文字について説明します。

「\」マークはこの業界ではエスケープ文字と言います。
PHPで文字列を変数に格納する際に以下のような記述をします。

$str = "変数に文字列を格納";

「"」を文字列として使用したい場合に「"」の前に「\」を入れることで「"」を文字列として判断してくれます。
$str = "「\"」を変数に格納";

次に「\」を文字列として使用したい場合は以下のように記述します。
$str = "「\\」を変数に格納する";

$strをechoやprint等で表示させると「「\」を変数に格納する」と表示されます。
以上のように「"」や「\」の特殊文字を文字列として使用する場合はエスケープする必要があります。

入力フォームを送信した際に、PHPでは「"」「'」「\」を自動でエスケープしてくれます。
Shift_JISで「\」をコードに変換すると「5C」です。
「表」は「95 5C」、「申」は「90 5C」、「ソ」は「83 5C」となります。
こうやって見ると「\」マークが自動でつくのにはパターンがあるのが分かります。
「5C」を「5C5C」と変換する為、
「表」→「表\」
「申」→「申\」
「ソ」→「ソ\」
となるわけです。

これらの文字化け対策として以下の2つの方法があります。
1.自動エスケープ処理をやめる
2.自動エスケープ処理をした後にアンエスケープする

1の対策案について、PHPの設定ファイル(php.ini)を変更するか、または「.htaccess」でPHPの設定ファイルを強制的に変更します。
PHPの設定ファイルの中に、「magic_quotes_gpc」というのがあります。
これを「On」にすると、「"」「'」「\」等を自動でエスケープしてくれます。
これを「Off」にすることで「\」が自動でつかなくなります。
「.htaccess」での対応方法は「.htaccess」の中に

php_value magic_quotes_gpc Off

と記述します。
「"」や「'」や「\」等をエスケープしなくなるので、セキュリティホールになる可能性があります。
「Off」にした際は、イタズラ防止のプログラムを忘れずに作りましょう。特にMySQL等のデータベースを使用するときには要注意です。

2の対策案について、プログラム上でアンエスケープします。
PHPの「stripslashes」関数を使用します。「html」という名前のフォームが送られてきた場合は以下のように処理します。

$html = stripslashes($_POST['html']);

この対策案については、レンタルサーバーなどで設定ファイルの変更権限がなく「.htaccess」権限もない場合に使えます。

これらをちょっと応用させて、「magic_quotes_gpc」がOnかOffかを判断させてアンエスケープ処理を行なってみます。
追記)magic_quotes_gpcが「On」の場合、ini_get('magic_quotes_gpc')は「1」になります。

if(ini_get('magic_quotes_gpc') == "1") {
  $html = stripslashes($_POST['html']);
}
else {
  $html = $_POST['html'];
}

「ini_get」関数はPHPの設定を取り出す関数です。
上記の例では、「ini_get('magic_quotes_gpc')」が「1」の場合はアンエスケープさせてそれ以外の場合は、エスケープさせないようにしています。

今回は、Shift_JISの自動エンコードの問題についてお話させていただきました。
実務で使う際には、上記の方法だけでは不足だと思います。「"」「'」「\」だけをエスケープさせる処理は必要になると思います。
文字コード対策で何かのやくにたってくれたら幸いですm(_ _)m

PHPのShift_JIS文字化け対策2」を見る

| | コメント (0) | トラックバック (0)

2005年11月08日

Google Mapsを使ってみよう2

今回は前回に引き続きGoogle Maps APIの使い方を説明します。
前回では単に指定した場所の地図を表示するだけでしたが、今回は指定した位置にマークを入れたり、指定した2つの場所の間に線を引いたりしてみます。

Google ローカル
Google Maps API(英語)
Google Mapドキュメント(英語)

基本的な記述方法は以前と同じ物を使用します。宣言文等に関しては前回の「Google Mapsを使ってみよう1」のページをご覧下さい。

まずは、Google Mapsの中にマークを挿入してます。
書き方は簡単です。以下の2行を追加するだけです。

var marker = new GMarker(new GPoint(経度, 緯度));
map.addOverlay(marker);

Gmarkerクラスは、Google Mapsの1つのポイントにアイコンを表示させる為に使用するクラスです。
上記の例では、new GMarker(地図の位置) コンストラクタを呼び出してmarker変数に格納しています。
GMarker(point, icon)
point:GPointオブジェクト
icon:Iconオブジェクト(指定なし:デフォルトGoogle Maps Icon)

Markerの位置が決まったら、GMapクラスのaddOverlayメソッドを使って、GMarkerをGoogle Mapsに挿入します。
addOverlayメソッドは、Google Mapsにマークや線などを追加することが出来ます。
addOverlay(overlay)
overlay:GMarkerオブジェクトやGPolylineオブジェクト等

GMarkerクラスのの説明で、Iconとありましたがマークに自作のIconを使用することが出来ます。
自作のアイコンを使用したい場合は、下記のようにGIconオブジェクトを作成します。

var icon = new GIcon();
icon.image = "http://www.s-memo.net/sample/google_map/icon.gif";
icon.iconSize = new GSize(12, 38);
icon.iconAnchor = new GPoint(0, 38);

GMarkerの第2引数にGIconオブジェクトを指定します。
var marker = new GMarker(new GPoint(経度, 緯度), icon);

GIconクラスの各メソッドの説明は以下の通りです。
尚、サイズは全てピクセル指定です。
icon.image = "使用する画像のURL";
icon.iconSize = new GSize(画像の横幅, 画像の縦幅);
icon.iconAnchor = new GPoint(画像を表示する横位置, 画像を表示する縦位置);

iconAnchorは、画像の表示位置から何ピクセルずらすかを指定します。緯度や経度ではないので注意して下さい。
自作画像でマークを設置する場合、最低でも上記の3つを指定しないとエラーが発生しますので注意して下さい。
今までのソースをまとめると以下の通りです。
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <style type="text/css">
    v\:* {
      behavior:url(#default#VML);
    }
    </style>
    <script src="http://maps.google.com/maps?file=api&v=1&key=キー指定" type="text/javascript"></script>
  </head>
  <body>
    <div id="map" style="width: 600px; height: 400px"></div>
    <div id="message"></div>
    <script type="text/javascript">
    
    var map = new GMap(document.getElementById("map"));

    map.addControl(new GLargeMapControl());
    map.addControl(new GMapTypeControl());
    map.centerAndZoom(new GPoint(139.7028136253357,35.68785351531429), 3);

    var polyline = new GPolyline([new GPoint(139.7028136253357,35.68785351531429),new GPoint(139.70330715179443, 35.69170502716)],"#ff0000", 8, 1);
    map.addOverlay(polyline);

    </script>
    
  </body>
</html>


自作のマークをGoogle Mapsの中に挿入するサンプルはこちらから。

次に、Google Maps上に線を引いてみます。
書き方はこちらも簡単です。以下の2行を追加するだけで線を引けます。

var polyline = new GPolyline([new GPoint(経度, 緯度),new GPoint(経度, 緯度)],"#ff0000", 8, 1);
map.addOverlay(polyline);

GPolylineクラスを変数に格納した後に、GMapクラスのaddOverlayメソッドを使ってGoogle Mapsに配置しています。
GPolylineクラスはその名の通り、Google Maps上に線を引く際に使用するクラスです。
各引数の説明は以下の通りです。
GPolyline(points, color, weight, opacity)
points:GPointオブジェクト([]で囲むことで複数指定可)
color:線の色・RGBカラー(指定なし:青色)
weight:線の太さ・ピクセル指定(指定なし:3ぐらい?)
opacity:透明度・0から1の間で指定(指定なし:0.5)

位置の指定は[]で囲ってカンマ区切りにすることで複数の場所を指定出来ます。
透明度については、0に近いほど薄くなり、1に近い程濃くなっていきます。

今までのソースをまとめると以下の通りです。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <style type="text/css">
    v\:* {
      behavior:url(#default#VML);
    }
    </style>
    <script src="http://maps.google.com/maps?file=api&v=1&key=キー指定" type="text/javascript"></script>
  </head>
  <body>
    <div id="map" style="width: 600px; height: 400px"></div>
    <div id="message"></div>
    <script type="text/javascript">
    
    var map = new GMap(document.getElementById("map"));

    map.addControl(new GLargeMapControl());
    map.addControl(new GMapTypeControl());
    map.centerAndZoom(new GPoint(139.7028136253357,35.68785351531429), 3);

    var polyline = new GPolyline([new GPoint(139.7028136253357,35.68785351531429),new GPoint(139.70330715179443, 35.69170502716)],"#ff0000", 8, 1);
    map.addOverlay(polyline);

    </script>
    
  </body>
</html>


Google Mapsに線を引くサンプルはこちらから。


今回は、Google Mapsにマークを挿入する方法とアイコンを設置する方法、更にGoogle Mapsの中に線を引く方法をご紹介しました。
これをプログラムと連携することで色々なことが出来そうです。

| | コメント (0) | トラックバック (0)

2005年11月04日

Google Mapsを使ってみよう1

今回は、Google Maps APIを使って地図を作ってみます。
作ってみた感想ですが、基本的にHTMLとJavaScriptの知識があれば簡単に作れるので結構便利です。
ただ、結構精密に出来てて、ちょっと位置を間違えただけでブラウザが固まったりします。
また、表示にも結構時間かかります^^;
多少の問題はありそうですが、その分を差し引いてもこれだけの機能を無料で使えるので凄いです。

Google ローカル
Google Maps API(英語)
Google Mapドキュメント(英語)

Google ローカルを自分のサイトで使う為には、「Google アカウント」の作成と「Google Maps」からGoogle Maps API keyを取得する必要があります。

最初にGoogle アカウントを作成します。メールアドレスとパスワードを指定するだけで登録出来ます。
次に、Google Maps API keyを取得します。ここでは、Google Mapsを使用したいサイトのURLを入力するとGoogle アカウントのMyPageにGoogle Maps API Keyが表示されるので、そのkeyをどこかに記録しておきます。

これでGoogle Mapsを使う準備が出来ました。これからHTMLを作って行きます。
HTMLの文字コードを「UTF-8」にして、ヘッダー部分を以下のように記述します。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <style type="text/css">
    v\:* {
      behavior:url(#default#VML);
    }
    </style>
    <script src="http://maps.google.com/maps?file=api&v=1&key=キーを指定" type="text/javascript"></script>
  </head>

<script src="http://maps.google.com/maps?file=api&v=1&key=キーを指定" type="text/javascript"></script>の部分で、Google Maps API keyを指定しています。
スタイルシート等の他の部分は、Google Mapsを使う際のおまじないみたいに思っていて下さい。
ここをちゃんと記入しないと全く動かなくなったりします^^;

次にMapを配置する場所を決めて、<div>を指定します。

<div id="map" style="width: 600px; height: 400px"></div>

widthとheightはMapの横の長さと縦の長さを指定します。
idは「map」と記述してありますが、これは別の名前でも構いません。idについてはこの後、説明します。

</div>の下に、JavaScriptを記述します。
まず、はじめにGMapオブジェクトを呼び出します。

var map = new GMap(document.getElementById("map"));

document.getElementByIdの引数には、<div>のid属性と同じ名前を記述します。
GMapオブジェクトの説明は以下の通りです。
GMap(container, mapTypes, width, height);
container:Google Mapsを表示する場所を指定
mapTypes:マップのTypeを指定(MAP_TYPE、SATELLITE_TYPEなどがあります)
width:Google Mapsの横幅
height:Google Mapsの縦幅

第1引数以外は、指定しなくても大丈夫です。
横幅と縦幅も<div>に依存されます。

次にaddControlメソッドを使って、Google Mapsをセットアップします。

map.addControl(new GLargeMapControl());
map.addControl(new GMapTypeControl());

addControlメソッドを使うとGoogle Mapsに色々な機能を追加することが出来ます。
addControl(control);
control:Google Mapsの機能を追加する

controlの種類には、以下のようなものがあります。
new GLargeMapControl()は、Google Mapsの左側にズーム機能を実装します。
new GMapTypeControl()は、Google Mapsの右上に「マップ」「サテライト」「デュアル」の3つのボタンが追加されます。

次は、centerAndZoomメソッドを使って表示するGoogle Mapsの場所を指定します。

map.centerAndZoom(new GPoint(139.7028136253357,35.68785351531429), 3);

centerAndZoomメソッドの説明は以下の通りです。
centerAndZoom(latLng, zoomLevel);
latLng:Google Mapsの位置を指定します
zoomLevel:ズームレベル(0~17:数字が低いほどアップします)

Google Mapsの位置を指定する場合は、GPointオブジェクトを使います。
GPoint(x, y);
x:経度
y:緯度

GPointオブジェクトは、与えられた座標値で新しいポイントを作成します。

ここまで作るととりあえずGoogle Mapsが見れるようになります。
今までのソースは以下の通りです。

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xmlns:v="urn:schemas-microsoft-com:vml">
  <head>
    <meta http-equiv="content-type" content="text/html; charset=UTF-8"/>
    <style type="text/css">
    v\:* {
      behavior:url(#default#VML);
    }
    </style>
    <script src="http://maps.google.com/maps?file=api&v=1&key=キーを指定" type="text/javascript"></script>
  </head>
  <body>
    <div id="map" style="width: 600px; height: 400px"></div>
    <script type="text/javascript">
    
    var map = new GMap(document.getElementById("map"));

    map.addControl(new GLargeMapControl());
    map.addControl(new GMapTypeControl());
    map.centerAndZoom(new GPoint(139.7028136253357,35.68785351531429), 3);

    </script>
    
  </body>
</html>


Google Maps制作例は以下の通りです。
Google Mapsの制作例を見てみる

Google Mapsには、指定の位置にマークを入れたりGoogle Maps上に線を引いたりすることが出来ます。
これらの機能は「Google Mapsを使ってみよう2」で紹介します。

| | コメント (0) | トラックバック (0)

2005年11月03日

Excelファイルの書き出し2

前回に続いて、MicrosoftのExcelファイルをPHPのPEARを使って自動作成するスクリプトを紹介します。
前回は、各セルの中に文字列を挿入するだけの基本的なものでした。今回はセルに合わせて線を引いたり文字の大きさを変えたりしてみます。
尚、PEARとSpreadsheet_Excel_Writerのインストール等と本家PEARサイトをご参照下さい。

PEAR本家サイト

前回の「Excelファイルの書き出し1」のページへ。

PEARのSpreadsheet_Excel_Writerを呼び出して、オブジェクトを変数に格納しファイル名を指定、更にExcelシート名を指定します。

$excel = new Spreadsheet_Excel_Writer();
$excel->send("test.xls");
$sheet = $excel->addWorksheet("myTest");

ここまでは前回を全く同じです。
シートの準備まで終わったら次のように配列(ハッシュ)を作ります。
尚、変数名は何でも構いません。
$propertiesTitle["Size"] = 12;
$propertiesTitle["Bold"] = 700;
$propertiesTitle["Border"] = 1;

配列(ハッシュ)の作成が終わったら次のように$excelオブジェクトからaddFormatメソッドを呼び出し、引数に先程作成した配列(ハッシュ)を指定します。
返ってきたオブジェクト(フォーマット)を変数に格納します。
$formatTitle = $excel->addFormat($propertiesTitle);

object addFormat([array $properties=array()])
$properties:フォーマットを格納してる配列(ハッシュ)
return:フォーマットオブジェクト

第1引数の配列(ハッシュ)には、「Bold(文字の太さ)」「Size(文字の大きさ)」「Border(枠線の太さ)」など色々な種類があります。興味のある方は本家PEARサイトで調べてみてください。
上記の要領でフォーマットを必要な分制作します。

次に前回と同じようにwriteメソッドを使ってセルの中に文字列を挿入します。

$sheet->write(0, 0, mb_convert_encoding("メンバー名", "SJIS", "auto"), $formatTitle);

前回と少し違う部分があります。前回は第3引数までの指定だったのに今回は第4引数を指定してます。
第4引数にフォーマットをセットすることで、初めて文字サイズを変更したり文字の太さを調整することが出来ます。
今まで紹介してきたスクリプトのサンプルは以下の通りです。
/***
* Excel用データダウンロードテスト2
*/
require_once("Spreadsheet/Excel/Writer.php");

$excel = new Spreadsheet_Excel_Writer();
$excel->send("test.xls");

$sheet = $excel->addWorksheet("myTest");

$propertiesTitle["Size"] = 12;
$propertiesTitle["Bold"] = 700;
$propertiesTitle["Border"] = 1;
$formatTitle = $excel->addFormat($propertiesTitle);

$propertiesData["Border"] = 1;
$formatData = $excel->addFormat($propertiesData);

$sheet->write(0, 0, mb_convert_encoding("メンバー名", "SJIS", "auto"), $formatTitle);
$sheet->write(0, 1, mb_convert_encoding("職業", "SJIS", "auto"), $formatTitle);
$sheet->write(1, 0, mb_convert_encoding("ピヨヒコ", "SJIS", "auto"), $formatData);
$sheet->write(1, 1, mb_convert_encoding("WEBプログラマー", "SJIS", "auto"), $formatData);
$sheet->write(2, 0, mb_convert_encoding("テスト太郎", "SJIS", "auto"), $formatData);
$sheet->write(2, 1, mb_convert_encoding("WEBデザイナー", "SJIS", "auto"), $formatData);

$excel->close();


上記のスクリプトの実行結果は以下の通りです。
Excelファイルをダウンロードする

addFormatメソッドについて
上記以外に以下のようなやり方もあるみたいです。

$formatTitle = $excel->addFormat();
$formatTitle->setBorder(1);
$formatTitle->setBold();
$formatTitle->setSize(12);

addFormatメソッドから返ってきた値を変数に格納して、その後に文字サイズを変更するやり方です。
ただ、私が実験してみたところなぜかうまく動きませんでした。。。
後は、配列で指定するやり方も駄目だったのですが文字の色や背景色も変えられませんでした^^;
うーん、、、何処間違えてるんだろ。。。?それともまだ安定してないのかなぁ。。。
その辺も調査してみます。分かり次第またエントリーします^^

もし情報がありましたらご連絡をお待ちしておりますm(_ _)m

| | コメント (0) | トラックバック (0)