PHP による JavaScript を書かない Ajax

![]()
佐久嶋 ひろみ (著)
九天社
ISBN: 4861671752
2007/05
3,150 円
HTML_AJAX/xajax,CakePHP/symfony の情報など
- サポートページ
http://sakushima.net/BOOK/AjaxFramework/

![]()
佐久嶋 ひろみ (著)
九天社
ISBN: 4861671752
2007/05
3,150 円
HTML_AJAX/xajax,CakePHP/symfony の情報など
- サポートページ
http://sakushima.net/BOOK/AjaxFramework/
以下のサイトにて,PHP の round() の挙動について解説されていました.
そこで,実際に 1 になるのかどうか試してみました.
- hnwの日記 - PHPの奇妙なround関数
http://d.hatena.ne.jp/hnw/20070515
結論から書くと,1 になる場合もならない場合もありました.こういうのが一番困ります.
分かったことは,バージョンによる差ではなくて,環境による差だろうということです.
round() を使う前にその環境で確認しておくことが重要ですね.
$ uname -mrs
Linux 2.4.9-e.9.18mlsmp i686
$ php -v
PHP 4.3.3 (cli) (built: Oct 9 2003 14:50:50)
Copyright (c) 1997-2003 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2003 Zend Technologies
$ php -r 'var_dump(round(0.49999999999));'
float(1)
$ uname -mrs
Linux 2.6.9-42.ELsmp i686
$ php -v
PHP 4.4.7 (cli) (built: May 28 2007 14:26:24)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2004 Zend Technologies
$ php -r 'var_dump(round(0.49999999999));'
float(1)
$ uname -mrs
Linux 2.6.17.13-smp i686
$ php -v
PHP 4.4.6 (cli) (built: May 2 2007 16:49:35)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2004 Zend Technologies
$ php -r 'var_dump(round(0.49999999999));'
float(1)
$ uname -mrs
Linux 2.4.9-e.9.18mlsmp i686
$ php -v
PHP 4.3.2 (cli) (built: May 10 2004 15:01:20)
Copyright (c) 1997-2003 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2003 Zend Technologies
$ php -r 'var_dump(round(0.49999999999));'
float(0)
$ uname -mrs
SunOS 5.10 i86pc
$ php -v
PHP 4.4.7 (cli) (built: May 13 2007 13:56:00)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2004 Zend Technologies
$ php -r 'var_dump(round(0.49999999999));'
float(0)
$ uname -mrs
SunOS 5.10 i86pc
$ php -v
PHP 5.2.2 (cli) (built: May 13 2007 14:15:44)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
$ php -r 'var_dump(round(0.49999999999));'
float(0)
$ uname -mrs
SunOS 5.10 sun4u
$ php -v
PHP 5.2.1 (cli) (built: Feb 28 2007 16:54:38)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
$ php -r 'var_dump(round(0.49999999999));'
float(0)
$ uname -mrs
Linux 2.6.17.13-smp i686
$ php -v
PHP 4.4.4 (cli) (built: Jan 8 2007 00:09:11)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2004 Zend Technologies
$ php -r 'var_dump(round(0.49999999999));'
float(0)
$ uname -mrs
Linux 2.4.32 i686
$ php -v
PHP 4.4.4 (cli) (built: Sep 9 2006 10:36:27)
Copyright (c) 1997-2006 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2004 Zend Technologies
$ php -r 'var_dump(round(0.49999999999));'
float(0)
$ uname -mrs
Linux 2.6.17.13-smp i686
$ php -v
PHP 5.2.2 (cli) (built: May 25 2007 00:09:33)
Copyright (c) 1997-2007 The PHP Group
Zend Engine v2.2.0, Copyright (c) 1998-2007 Zend Technologies
$ php -r 'var_dump(round(0.49999999999));'
float(0)
$ uname -mrs
SunOS 5.8 i86pc
$ php -v
PHP 4.3.4 (cli) (built: Nov 30 2005 06:29:37)
Copyright (c) 1997-2003 The PHP Group
Zend Engine v1.3.0, Copyright (c) 1998-2003 Zend Technologies
$ php -r 'var_dump(round(0.49999999999));'
float(0)
ファイルへの直リンクを防止する方法としては,例えば Referer ヘッダ参照する方法とかがあると思います.
Apache クックブック のレシピ 6.5 に載っているのもその方法ですが,Referer ヘッダを送信しないクライアントはどうするかという問題があります.
そこで,PHP の apache_setenv と virtual を利用する方法を紹介します.
- apache_setenv
Apache サブプロセスの環境変数を設定する
http://php.net/apache-setenv
- virtual
Apache サブリクエストを実行する
http://php.net/virtual
ダウンロードするファイルがあるディレクトリを /var/www/html/data とします.
このディレクトリに .htaccess を置いて,以下のように記述します.
Order Allow,Deny
Allow from env=ACCESS_ALLOW
この時点で,/var/www/html/data 以下のファイルにアクセスできなくなります.具体的には 403 Forbidden が返されます.
これは,ACCESS_ALLOW という環境変数があれば,アクセスできますよと指定しているためです.
次に以下のような PHP スクリプトを記述します.サンプルなのでファイル名は固定にしてあります.
これを /var/www/html/foo.php として配置し,ブラウザからアクセスしてみてください.
<?php
// コンテンツタイプ
header('Content-type: image/jpeg');
// Apache 環境変数を設定
apache_setenv('ACCESS_ALLOW', '1');
// Apache にサブリクエストを投げる
// このスクリプトからの相対パスを指定する必要がある
virtual('data/foo.jpg');
?>
この foo.php にアクセスすると,今度は data/foo.jpg が表示されると思います.
つまり,環境変数 ACCESS_ALLOW を指定してアクセスしているわけです.
この foo.php のファイル名を時間によって変えるなどすれば,まあ,直リンクを防止することができる……のかな?ちと強引ですが.
パフォーマンスとか調査していないのですが,このような方法もあるということで紹介しておきます.
参考までに,上記スクリプトを以下のように改造してあげると,filename で指定されたファイルをダウンロードすることができます.
<?php
define('DATA_DIR', 'data' . DIRECTORY_SEPARATOR);
if (!isset($_GET['filename']) || $_GET['filename'] == '') {
exit;
}
$filepath = DATA_DIR . basename($_GET['filename']);
if (!is_readable($filepath)) {
exit;
}
$info = getimagesize($filepath);
// コンテンツタイプ
header('Content-type: ' . $info['mime']);
// Apache 環境変数を設定
apache_setenv('ACCESS_ALLOW', '1');
// Apache にサブリクエストを投げる
virtual($filepath);
?>
そもそもですが,CakePHP は MySQL 4.0 以上が対象らしいです.
ただ,公式のドキュメントは見つかっていませんが……
それでも,MySQL 3.23 な環境で CakePHP を使って,なおかつ hasAndBelongsToMany も使いたい場合の対処法です.
MySQL 3.23 な環境では,hasAndBelongsToMany を使うとき,SQL のエラーが出ます.具体的には JOIN に失敗しています.
このとき CakePHP は以下のような SQL 文を発行します.
SELECT `Tag`.`id`, `Tag`.`tag`
FROM `tags` AS `Tag`
JOIN `posts_tags` ON `posts_tags`.`post_id` = '2'
AND `posts_tags`.`tag_id` = `Tag`.`id`
WHERE 1 = 1
MySQL のリファレンスにあるように,JOIN は MySQL 4.0.11 以降で対応なので,この JOIN を INNER JOIN にしてあげればいいわけです.
- ref.: MySQL AB :: MySQL 4.1 リファレンスマニュアル :: 6.4.1.1 JOIN 構文
http://dev.mysql.com/doc/refman/4.1/ja/join.html
注意:INNER JOIN 構文で join_condition を使用できるのは、MySQL 3.23.17 以降に限られます。同様に、JOIN と CROSS JOIN に関しても、MySQL 4.0.11 以降でのみ条件を指定できます。
ちょうど昨日 CakePHP の最新版 (1.1.14.4797) がリリースされたので,この最新版と,その前のバージョン (1.1.13.4450) での修正箇所を挙げておきます.
- 1.1.14.4797 の場合
cake/libs/model/datasources/dbo_source.php の 1051 行目を修正します.
--- cake_1.1.14.4797-orig/cake/libs/model/datasources/dbo_source.php 2007-04-06 04:21:05.000000000 +0900
+++ cake_1.1.14.4797/cake/libs/model/datasources/dbo_source.php 2007-04-06 08:46:09.015389000 +0900
@@ -1048,6 +1048,7 @@
'joins' => array(array(
'table' => $joinTbl,
'alias' => $joinAssoc,
+ 'type' => 'INNER',
'conditions' => array(
array("{$joinAlias}.{$assocData['foreignKey']}" => '{$__cakeID__$}'),
array("{$joinAlias}.{$assocData['associationForeignKey']}" => '{$__cakeIdentifier['."{$alias}.{$linkModel->primaryKey}".']__$}')
- 1.1.13.4450 の場合
cake/libs/model/datasources/dbo_source.php の 1043 行目を修正します.
--- cake_1.1.13.4450-orig/cake/libs/model/datasources/dbo_source.php 2007-02-03 11:55:49.000000000 +0900
+++ cake_1.1.13.4450/cake/libs/model/datasources/dbo_source.php 2007-04-06 09:13:16.018886000 +0900
@@ -1040,7 +1040,7 @@
}
$sql .= ' ' . join(', ', am($this->fields($linkModel, $alias, $assocData['fields']), $joinFields));
$sql .= ' FROM ' . $this->fullTableName($linkModel) . ' ' . $this->alias . $this->name($alias);
- $sql .= ' JOIN ' . $joinTbl;
+ $sql .= ' INNER JOIN ' . $joinTbl;
$joinAssoc = $joinTbl;
上記の修正はあくまで,hasAndBelongsToMany を使いたい場合で,そのほかの項目はあまりテストしていませんのでご注意を.
可能であれば,MySQL 4.0.x にアップデートするのが一番だと思います.
- グルーブテクノロジー株式会社 - Web サービス
http://groovetechnology.co.jp/webservice/
グルーブテクノロジーによる郵便番号検索 API を利用して,結果を取得するライブラリ Services_Groove_ZipSearch を作りました.
この API の特長は,JSON 形式,JSONP 形式,XML 形式,PHP の serialize() 形式という風に,任意の形式で出力を受け取れることです.
今回は,PEAR パッケージにしてみました.
- Services_Groove_ZipSearch-0.1.0
http://pocari.org/tools/php/Services_Groove_ZipSearch-0.1.1.tgz
インストールは,以下のようできます.
# pear install http://pocari.org/tools/php/Services_Groove_ZipSearch-0.1.1.tgz
- 使い方
<?php
require_once 'Services/Groove_ZipSearch.php';
$zip = new Services_Groove_ZipSearch;
$result = $zip->search(1000001);
if (PEAR::isError($result)) {
exit($result->getMessage());
}
print_r(unserialize($result));
?>
- 出力
Array
(
[address] => Array
(
[0] => Array
(
[zipcode] => 1000001
[prefecture] => 東京都
[city] => 千代田区
[town] => 千代田
[prefecture_yomi] => トウキョウト
[city_yomi] => チヨダク
[town_yomi] => チヨダ
)
)
[office] => Array
(
)
)
Groove_ZipSearch::search() に郵便番号検索 API のパラメータを渡すことができます.
パラメータの種類と順序は,郵便番号検索 API のリクエストパラメータと同じです.詳しくはソースを見てください.
また,郵便番号検索 API の出力形式 (format) のデフォルト値は json になっていますが,このライブラリでは PHP になっています.
すなわち,serialize() された形がデフォルトで戻ってきます.
- via: using API; RESTで使える郵便番号検索API
http://api.zuzara.com/archives/115
- 追記 (2007-12-18)
サンプルが間違っていたのを修正して、0.1.1 (alpha) をリリースしました。
サンプルの出力結果を追記しました。
FC2 がスパム情報を共有するソーシャルスパム対策なるサービスを始めたので,公開されている API を利用して結果を取得するライブラリ Services_FC2 をつくりました.
- FC2 ソーシャルスパム対策
http://seo.fc2.com/spam/
Services とついていますが,PEAR パッケージには全くなっていません.
バージョンも 0.0.1 となっていますが,今後バージョンアップされるかどうか不明です.
- Services_FC2
http://pocari.org/tools/php/Services_FC2-0.0.1.tgz
- サンプル
上記ライブラリを展開して,Services_FC2-0.0.1 を Services にリネームして,以下のサンプルでとりあえず使えます.
<?php
require_once 'Services/FC2.php';
$fc2 = Services_FC2::factory('SPAM');
// URL を指定してスパムサイトに登録してあるかどうか取得
// オプションを個別に設定する
$fc2->setURL('http://example.com');
$fc2->setCharset('EUC-JP');
$fc2->setData(1);
$result = $fc2->execute();
echo $result, "\n";
// スパムリストの取得
// オプションを一括で設定することもできる
$fc2->setOptions(array(
'm' => 'ul',
'chr' => 'EUC-JP',
));
$result = $fc2->execute();
echo $result, "\n";
?>
- API のヘルプ
http://seo.fc2.com/spam/spamapi.php?m=h
使ってみるとすぐ分かりますが,この API はまだ発展途上のようです.
o 結果がどのような形で返って来るのかよくわからない
XML でもなんでもないただの CSV っぽいもので返って来るのですが,戻り値が仕様に明記されていないのでよくわかりません.
o キャラクターコードを指定しても,エラーメッセージは Shift-JIS 固定っぽい
o オプションの data に 1 を指定して,スパム情報詳細を返すようにするとなぜか <br> のように HTML のタグが含まれて返って来る.
o 最新のデータが返されないっぽい (現在は 1 件だけしか返ってこない?)
PHP 3 と PHP 4 を共存させる場合に,configure オプションに --enable-versioning を指定します.
実はこれが思わぬ落とし穴になる場合があります.
それは,DSO で拡張モジュールが動的にロードできないというものです.
PHP 4.4.4 + Apache 1.3.37 on Solaris 10 x86 の環境なので,もしかしたら環境依存かもしれません.
コンパイル・インストールはうまくいきますが,Apache を再起動すると以下のようなエラーが出ます.
- SQLite の場合
PHP Warning: Unknown(): Unable to load dynamic library '/usr/local/lib/php/extensions/no-debug-non-zts-20020429/sqlite.so' - ld.so.1: httpd: fatal: relocation error: file /usr/local/lib/php/extensions/no-debug-non-zts-20020429/sqlite.so: symbol executor_globals: referenced symbol not found in Unknown on line 0
- Xdebug の場合
Failed loading /usr/local/lib/php/extensions/no-debug-non-zts-20020429/xdebug.so: ld.so.1: httpd: fatal: relocation error: file /usr/local/lib/php/extensions/no-debug-non-zts-20020429/xdebug.so: symbol zend_compile_file: referenced symbol not found
CLI 版では,全く問題なくロードできるので,原因が全然分かりませんでした.
これらのエラーが出る場合は,--enable-versioning を外して PHP 4 を再コンパイルするとうまくいくと思います.
もはや,PHP 3 を共存させることは皆無に等しいと思うので,--enable-versioning のことは忘れてしまったほうがよさそうです.
参考までに --enable-versioning をマニュアルを見てみると,
--enable-versioning
要求されるシンボルのみをエクスポートします。 詳細な情報は INSTALL を参照ください。
--enable-versioning
Solaris 2.x および Linux が提供するバージョン管理機能を 有効にします。PHP 3 限定です!
とあります.
- Configure オプション
http://www.php.net/manual/ja/configure.php
- ref.: Blog::koyhoge - [PHP] --enable-versioningを止めるの巻
http://d.hatena.ne.jp/koyhoge/20061213/1165999933
PHP のテンプレートエンジン Smarty を使って開発するときに,割り当てた変数が複雑になって困ることはありませんか?
その際,何らかの方法を使って割り当てた変数を確認するのですが,いくつか方法があります.
おそらく一番有名な方法ですが,$debugging に true を指定して,常にデバッギングコンソールを表示する方法です.
require_once 'Smarty.class.php';
$smarty = new Smarty;
$smarty->debugging = true;
これで,常にデバッギングコンソールが表示されます.
デバッギングコンソールは,window.open() を使った JavaScript によるポップアップウィンドウですが,以下のように _smarty_debug_output に html を割り当てることで,ドキュメント中に埋め込むことができます.
require_once 'Smarty.class.php';
$smarty = new Smarty;
$smarty->debugging = true;
$smarty->assign('_smarty_debug_output', 'html'); // 'html' を '' にするとポップアップ
- ref.: $debugging
http://smarty.php.net/manual/en/variable.debugging.php
$debugging_ctrl に 'URL' を指定して,URL に QUERY_STRING が含まれる場合にデバッギングコンソールを表示する方法です.
require_once 'Smarty.class.php';
$smarty = new Smarty;
$smarty->debugging_ctrl = 'URL'; // 解除は 'NONE'
このように設定して,
という URL の場合には,
このようにすれば,デバッギングコンソールが表示されます.
ちなみに,SMARTY_DEBUG=off の場合は,デバッギングコンソールは表示されません.
$debugging = true の場合は,この設定は無視されます.
- ref.: $debugging_ctrl
http://smarty.php.net/manual/en/variable.debugging.ctrl.php
デバッギングコンソールはテンプレート変数を使っても表示することができます.
{debug}
たったこれだけです.$debugging や $debugging_ctrl の設定にかかわらず表示されます.
ポップアップ式ではないデバッギングコンソールをドキュメントに埋め込むには以下のようにします.
{debug output='html'}
- ref.: {debug}
http://smarty.php.net/manual/en/language.function.debug.php
この方法はドキュメントに載っていないのですが,上記 3 つのデバッギングコンソールを表示する方法とは異なり,1 つの変数の内容を表示するものです.
$foo = array(
'a' => 'あ',
'b' => 'い',
'c'=> array(
'd' => 'う'
)
);
$smarty->assing('foo', $foo);
上記のように,配列が割り当てられた場合は,
{$foo|@debug_print_var} {* $foo は配列なので @ が必要 *}
このようにすることで,以下のように $foo の内容だけが出力されます.
Array (3)
a => あ
b => い
c => Array (1)
d => う
debug_print_var はプラグインとして含まれてますが,ドキュメントには載っていません.
しかし,デフォルトのデバッギングコンソール用のテンプレート debug.tpl で使われています.
debug_print_var はデフォルトでは 40 文字で表示が切られてしまいます.これはオプションで調節できます.
例えば 100 文字まで表示する場合は,以下のように指定してあげれば OK です.
{$foo|@debug_print_var:0:100}
100 の前のオプションの 0 は,配列やオブジェクトを表示する際のインデント幅です.
- おまけ
Smarty のテンプレート内で JavaScript を書く場合 { } がテンプレート変数として扱われるので {literal} で囲むのが面倒だとか,JavaScript の中にテンプレート変数を割り当てられないだとか耳にすることがあります.
この場合は,テンプレート変数の { } を変更すればいいです.
require_once 'Smarty.class.php';
$smarty = new Smarty;
$smarty->left_delimiter = '<{';
$smarty->right_delimiter = '}>';
上記の設定は XOOPS が使っているもので,テンプレート変数は以下のよう記述します.
<{$foo}>
これを使うと,以下のように JavaScript を場合に {literal} で囲む必要もありませんし,JavaScript の中にテンプレート変数を割り当てることもできます.
<script type="text/javascript">
function foo() {
var a = '<{$foo|escape:"javascript"}>';
};
</script>
- Smarty 入門 PHP5+テンプレート・エンジンでつくる MVC アプリケーション

![]()
山田 祥寛 (著)
翔泳社
ISBN: 4798108839
2005/3/15
2,940 円