2007-10-03 (水)
■ JavaScript も CSS も使わずにブラウザを判別するハックが公開されていた
- hoshikuzu | star_dust の書斎 - 2007-09-25
- wafful.org - Web Security Blog - BrowserDetect
- TAKESAKO @ Yet another Cybozu Labs: 続イメージファイト - HTML 2.0 New Browser Detection
すげぇ、感動した!
■ 名前に縦棒記号を含む場合のリンクの記法
tDiary (and Hiki ?) で URL へのリンクを作る時、名前に | が含まれている場合は、
* [[hoshikuzu \| star_dust の書斎 - 2007-09-25|http://d.hatena.ne.jp/hoshikuzu/20070925#p1]]
みたくエスケープすればいいのか。 勘でやってみたらうまくいったんだけど、これ、ドキュメントに載っていないよね?
2007-10-05 (金)
■ IE5 以上 (含む Macintosh 版) で min-width を実現する CSS ハック
IE6 以下で min-width を実現する CSS ハックがよく紹介されていますが、 その多くは後方互換モード (Quirks Mode) 用で、 標準準拠モード (Standards Mode) では機能しません。 標準準拠モードで使える方法が欲しかったので、探し出してきました。
ここにいくつかの例が載っていますが、 そのうちの4番、5番は、次のような特徴を持つかなり万能な方法です。
- 標準準拠モードにも対応
- IE 5.0 や Macintosh 版 Internet Explorer にも対応
- float は使わずに実現
下手にここで解説するよりも、上のリンク先を実際に見て欲しいのですが、 基本的な部分だけ書き出しておくと、こんな HTML と CSS で実現されています。
<div class="width"> <div class="minwidth"> <div class="container"> </div> </div> </div>
.width {
min-width: 300px;
background: #fff;
}
* html .minwidth {
border-left: 300px solid #fff;
}
* html .container {
margin-left: -300px;
position: relative;
}
/*\*/
* html .minwidth,
* html .container,
* html .content {
height: 1px;
}
/*/
.width {
display: inline-block;
}
/**/
つまり、
- 背景色と同じ色のボーダーで幅を確保
- ネガティブマージンを使ってその上に載せる
- Windows 版 IE では hasLayout = true にセット
という仕組みですね。 <div> タグを2重、3重に使わなければならないのが嫌ですが、 JavaScript を無効にしていても使える方法なので、 覚えておいて損はないと思います。
2007-10-06 (土)
■ CSS で Sticky footer を実現する2つの方法の比較
フッターの下の余白をなくす Sticky footer のサンプルをこの前作ったが、 その後調べていて、別系統のやり方があることに気が付いた。
2番の方法では、
div#footer {
position: absolute;
bottom: 0;
}
のようにして、フッターを最下部に配置している。 こちらの方法の方が HTML の構造もきれいで単純明快だと思うが、 実は意外な落とし穴があることに気が付いた。 それは IE7 のズーム機能を使うと、フッターの下に余白が空いてしまうというもの。
一方、この前使った1番の方法は、 空の div 要素を使うなど HTML の構造的には汚いが、 ズーム機能を使っても、フッターは最下部に張り付いたままになっている。 (ただしフッターに position:relative; を指定すると、なぜか同様に余白ができる。)
はてなブックマークのコメントなんかを見ると、 2番の方法の方が優れているように書かれているが、 見た目を重視するなら1番の方法を使う方がいいかな。
2007-10-08 (月)
■ PukiWiki 用プラグイン ajaxtree.inc.php Ver.1.1 を公開
Ajax を用いたエクスプローラ風ツリーメニューのプラグインをバージョンアップした。 前バージョン からの変更点は以下の通り。
- Ajax での読み込みに失敗した場合もマーカーが変化していたのを修正
- encodeURIComponent が使えない古いブラウザ用の対策コードを追加
- span 要素に対する :hover 疑似クラスの指定が機能していなかったのを修正
- CSS を Validator に通る書式に書き換え
ダウンロードは以下のページからどうぞ。
いろいろテストしてみて、ほとんどのブラウザで動くことが確認できたので、 ここの Wiki ページのメニューも、 treeview.inc.php プラグインを使っていたのを、 ajaxtree.inc.php プラグインを使うように変更しておいた。
2007-10-11 (木)
■ ネガティブマージンを用いたカラム落ちしない2カラムレイアウト
まずはこちらのサンプルをご覧下さい。 ブラウザの幅や高さをどんなに変えても、レイアウトが保たれていると思います。 IE6 以下の古いブラウザでも平気です。
これは、以前ブログで書いた次の2つを組み合わせ、さらに修正を加えたものです。 ですので、仕組みについては、それぞれの記事を参照して下さい。
HTML の構造と CSS がかなり複雑になってしまいましたが、 例えば min-width を擬似的に実現するのを JavaScript でやるようにすれば、 もう少しすっきりさせることもできると思います。
欲しい人がいるかどうか分かりませんが、上のサンプルで使っている HTML と CSS も置いておきます。 自由に改変して使って下さい。
2007-10-14 (日)
■ VML を利用して IE で border-radius が使えるようにする
元ネタはこれ。
IE の機能不足を、IE の独自機能で補う、というアプローチが実に素敵だが、 残念なことに後方互換モードでしか使えないという制限がある。 でもきっとなにか方法があるはずだと思ったので、いろいろ調べつつ、 標準準拠モードや IE7 でも問題なく使えるように手を加えてみた。
標準準拠モードで使えない
これは Microsoft のサポート技術情報に対処法が載っていた。
つまり、<v:roundrect> タグに style="display: inline-block;" を追加で設定すれば良いらしい。 なお、<v:fill> タグの方にも style="display: inline-block;" を追加すると妙な余白ができてしまうので、 よく分からないが、こちらはそのままにしておけば良いようだ。
IE7 で -moz-border-radius の指定が無視される
IE7 で見るとボーダーの半径がおかしい。 調べてみると -moz-border-radius の値を取得する部分でおかしなことになっていた。
- alert(this.currentStyle['moz-border-radius']); とした場合、
IE6 以下: 20px IE7: undefined
- alert(this.currentStyle['-moz-border-radius']); とした場合、
IE6 以下: undefined IE7: 20px
なんなんだ、これは。 裏付けとなる資料が見つけられなかったが、 behavior で currentStyle を使う場合、IE6 以下と IE7 では使い方が違うようだ。 ということで、
--- border-radius.htc.orig
+++ border-radius.htc
@@ -5,4 +5,5 @@
this.className = this.className.concat(' ', classID);
var arcSize = Math.min(parseInt(this.currentStyle['moz-border-radius'] ||
+ this.currentStyle['-moz-border-radius'] ||
this.currentStyle['border-radius']) /
Math.min(this.offsetWidth, this.offsetHeight), 1);
のように修正して対処。
<html> タグに xmlns:v="urn:schemas-microsoft-com:vml" の指定が必要
VML 用の namespace が自動で設定されるように、以下のようなコードを追加してみた。
if (!document.namespaces.v) {
document.namespaces.add("v", "urn:schemas-microsoft-com:vml");
}
ただし検索してみると、 このコードがウィルスだと誤検出される場合があるらしいので、 素直に <html> タグに namespace の指定を書く方がいいのかも。
2007-10-17 (水)
■ Internet Explorer で SVG を表示する方法のまとめ
SVG というのはベクターグラフィックスを扱うデータ形式のことで、 Firefox, Opera, Safari といった多くのブラウザが SVG に対応している。 一方、Internet Explorer は標準では SVG に対応しておらず、 Adobe SVG Viewer というプラグインをインストールしないと表示できない。 しかし、Adobe SVG Viewer は 2009/01/01 でサポートを打ち切る らしいので、 他にどういう方法があるのかを調べてみた。
- Internet Explorer 用 SVG プラグイン
- Adobe SVG Viewer
- Corel SVG Viewer
- SVG Map Toolkit (ベータ版。速いらしい)
- Renesis Player (日本語不可)
- XAML (Silverlight) を用いて SVG をエミュレート
試してみての感想は、Adobe SVG Viewer がいろんな意味で標準。 SVG Map Toolkit は一部表示されないことがあったりするが期待できそう。 VML でエミュレートする方法はまだまだ発展途上という感じ。
SVG は良い技術だからいろいろ使いたいのに、 IE が非対応なせいで導入しづらかったりする。 ほんと、なんとかして欲しい。
(2008/04/09 追記)
このページが検索の上位に出てくるようなので追記。 上で発展途上と書きましたが、最近、SIE の再現度がかなり良くなってきました。 ブックマークレット版の Sieb もあるので、
- SVG を使った Web ページを構築したい人
- Web ページに貼られた SVG ファイルを Internet Explorer で表示したい人
のいずれにもオススメです。
2007-10-18 (木)
■ 無料で使えるグラフ用 PHP ライブラリのまとめ
ライセンス、PHP のバージョン、出力形式、日本語が表示できるかどうか、 を調べたのでまとめておきます。
- PEAR::Image_Graph
- LGPL
- PHP4, PHP5
- PNG, JPEG, PDF, SVG
- 日本語OK (若干の設定が必要)
- Artichow
- public domain
- PHP4, PHP5
- PNG, GIF, JPEG, Flash
- 日本語OK
- eZ Components - Graph
- New BSD license
- PHP5
- PNG, JPEG, Flash, SVG
- 日本語OK
- Libchart
- GPL v3
- (PHP4), PHP5
- PNG
- 日本語はダメ? (参考: http://www.moongift.jp/2007/08/libchart/ )
他に phpGraphEd, PHPLOT なんてのもありましたが、 上に挙げたライブラリの方が高機能なので、選択肢からは外していいでしょう。
2007-10-20 (土)
■ Artichow を使ってグラフを描いてみる
先日、PHP でグラフを描くためのライブラリについて調べた が、
- ライセンスが public domain
- 3D っぽいグラフが描ける
- グラフの見た目がなんだか綺麗
という理由で、Artichow が結構良さそうだと思ったので試してみた。
アーカイブをダウンロードしてきて展開。ディレクトリ名は Artichow にリネームしておく。
$ tar xvfz Artichow-1.1.0-php5.tar.gz $ mv Artichow-php5 Artichow
どうもアクセラレータの APC と相性が悪い(?)みたいなので、APC を切っておく。 Artichow ディレクトリに以下の .htaccess ファイルを作成。
php_flag apc.cache_by_default off
examples ディレクトリにあるファイルにどれでもいいからアクセス。 こんなグラフが表示される。
うん、いい感じだ。
2007-10-21 (日)
■ Artichow で日本語やキャッシュを使うための設定方法
昨日 に引き続き、 もう少し Artichow を使ってみた。
日本語を表示できるようにする
fonts/Tuffy.ttf というフォントがデフォルトで使われるようになっているので、 それを好みの日本語 TrueType フォント (IPA フォントなど) で上書きコピーしてしまうのが楽。 あとは、グラフを描くスクリプト中で、
$title = '日本語のテスト'; $graph->title->set($title);
のようにすれば良い。文字化けする場合は、
$title = '日本語のテスト'; $title = mb_convert_encoding($title, 'UTF-8', 'auto');
のように文字コードを変換する。
もう少し丁寧にやりたい場合は、 日本語 TrueType フォント (ipagp.ttf など) を fonts ディレクトリにコピーして、 Artichow.cfg.php を以下のように変更。
$fonts = array( + 'ipagp', 'Tuffy', 'TuffyBold', 'TuffyBoldItalic', 'TuffyItalic' );
文字を表示する時には、
$graph->title->setFont(new ipagp(14));
のように毎回フォントを指定するようにする。
キャッシュを有効にする方法
まず、cache ディレクトリを書き込み可にする。
$ chmod 777 cache
さらに、Graph オブジェクトを作成する際に、 引数としてユニークな id と有効期限も指定するようにする。
- $graph = new Graph(400, 400); + $graph = new Graph(400, 400, 'uniqueName', time() + 3600);
この例の場合、1時間の間は、この作成された画像がキャッシュとして使われるようになる。 PHP 5.1 以降の場合は、
date_default_timezone_set('Asia/Tokyo');
のようにタイムゾーンの設定も必要かも。
2007-10-24 (水)
■ APC が誤ったファイルのキャッシュを返す件
先日、Artichow が APC と相性が悪いみたい、と書いたが、 実は APC の opcode cache を有効にしていると、 サンプル一覧で同じ画像ばかり現れる、という怪現象が起こっていた。
Artichow がなんか変わったことでもしているんだろう、と思っていたが、 気になって PEAR::Image_Graph のサンプル一覧を試してみたら、同じ現象が起こったので、 これは相性うんぬんではなく、APC のバグなんじゃないかという気がしてきた。
調べてみると、類似の現象が、結構昔から報告されている。
- PECL :: Bug #11357 :: Wrong script executed (sapi_get_stat returns 0 inode)
- PECL :: Bug #9969 :: APC returns wrong file
- PECL :: Bug #9482 :: cache hit mismatch
これらのバグはまだ解決されていないようだが、一応、これらのページを参考に、
- 最新の APC 3.0.15 にアップデートしてみる
- apc.stat のオプションを変えてみる
- apc.stat_ctime のオプションを変えてみる
などをやってみたが全く効果無し。
そこでさらに検索してみると、ごく最近ブログに書かれたこんな記事を発見。 APC の開発者がチャットで言っていたことらしい。
remove the sapi_get_stat() call and see if it works out fine that means. If you use apache2 and a sapi handler for php5 just comment line #759 in apc_cache.c
つまり、こういうパッチをあてたらどうかということ。
--- apc_cache.c.orig
+++ apc_cache.c
@@ -757,5 +757,7 @@
if(!strcmp(SG(request_info).path_translated, filename)) {
+#if 0
tmp_buf = sapi_get_stat(TSRMLS_C); /* Apache has already done this stat() for us */
+#endif
}
if(tmp_buf) {
試しにこのパッチをあててビルドし直してみたら…、 直った! ちゃんとそれぞれ別の画像が表示されるようになった!
パッチ箇所の前後のコードを見ると、 Apache が保持している stat の情報を利用するのをとりあえずやめる、 というパッチのようなので、少なくとも悪影響が出ることはなさそうだ。 正式にバグフィックスされるまでは、これで様子を見てみよう。
2007-10-25 (木)
■ PECL::APC をさらに高速化するための設定
PECL の APC (Alternative PHP Cache) のチューニングに関する情報をいくつか見つけたのでメモ。
.::t3rmin4t0r::. : include_once: "Mostly Harmless"
APC 3.0.12 以降の apc.include_once_override オプションについて、 その効果や仕組みが分かりやすく書かれていた。 php.ini あたりで、
apc.include_once_override=1
のように設定するとこのオプションが有効になり、 include_once() や require_once() が高速化される。
PHP Works 2007: apc@facebook
APC 全般について非常に詳しく書かれている資料。 これによると、APC には数種類のロック方式が用意されているが、 その中で pthread mutex Locks という方式が速くてオススメらしい。 このロック方式を使うには、ビルド時に、
./configure --enable-apc --enable-apc-pthreadmutex
のようにすれば良い。
2007-10-28 (日)
■ Artichow の円グラフのバグ修正パッチ
Artichow のバグを発見したので修正してみた。
値がゼロの要素の扱い
値がゼロの要素が1つでもあると、円グラフがうまく塗りつぶされない。 下手すると、グラフ全体が1色で塗りつぶされたりする。 結局、円グラフを描画する時は、値がゼロの要素を除外するようにした。 以下、修正パッチ。
--- Artichow-php5.orig/Pie.class.php
+++ Artichow-php5/Pie.class.php
@@ -333,6 +333,17 @@
foreach($this->values as $key => $value) {
+ $color = $this->colors[$key % count($this->colors)];
+ $parts[$key] = new awPiePart($color);
+
+ // Add part to the legend
+ $legend = array_key_exists($key, $this->legendValues) ? $this->legendValues[$key] : $key;
+ $this->legend->add($parts[$key], $legend, awLegend::BACKGROUND);
+
+ if ($value == 0) {
+ continue;
+ }
+
$angle = ($value / $sum * 360);
if($key === $count - 1) {
@@ -372,13 +383,6 @@
$position, ($position + $angle), $explode
);
- $color = $this->colors[$key % count($this->colors)];
- $parts[$key] = new awPiePart($color);
-
- // Add part to the legend
- $legend = array_key_exists($key, $this->legendValues) ? $this->legendValues[$key] : $key;
- $this->legend->add($parts[$key], $legend, awLegend::BACKGROUND);
-
$position += $angle;
}
@@ -512,6 +516,10 @@
break;
}
+ if ($value == 0) {
+ continue;
+ }
+
if(is_null($this->minimum) === FALSE and $value < $this->minimum) {
continue;
}
ラベルの有効数字
円グラフで $plot->setLabelPrecision(1); のように指定しても、 最後の桁がちょうどゼロだと、7.0% でなく 7% のように表示される。 この挙動が気に入らないので直す。
--- Artichow-php5.orig/Pie.class.php
+++ Artichow-php5/Pie.class.php
@@ -100,7 +100,7 @@
*
* @var int
*/
- protected $precision;
+ protected $precision = 0;
/**
* Labels number
@@ -498,6 +498,9 @@
$pc = array();
foreach($this->values as $key => $value) {
$pc[$key] = round($value / $sum * 100, $this->precision);
+ if ($this->precision > 0) {
+ $pc[$key] = sprintf('%.' . $this->precision . 'f', $pc[$key]);
+ }
}
if($this->label->count() === 0) { // Check that there is no user defined values
$this->label->set($pc);
2007-10-31 (水)
■ Zend_Feed を使って Atom フィードを作成してみる
Atom フィードの作成をしようと思い、 Feedcreator の使い方を調べていたところ、 ふと Zend Framework に Zend_Feed というコンポーネントがあることを思い出した。 あれ? でも、あれはフィードを読み込むのに使うライブラリじゃなかったかな?
でも念のため、と思って調べてみると…、なんだ、フィードを出力する機能もあるじゃん。
ということで、これらのページを参考にして Atom フィードの出力機能を実装できたが、 Zend Framework 以外から使う時のために、少し手直しして、 Zend_Feed を単独のライブラリとして使うサンプルも書いてみた。 手抜きだが、こんな感じのコードで Atom 1.0 のフィードを出力できる。
<?php
date_default_timezone_set('Asia/Tokyo');
$zendLibDir = '/path/to/ZendFramework-1.0.2/library';
set_include_path($zendLibDir . PATH_SEPARATOR . get_include_path());
/*
ここでデータベースやファイルからデータを読み込んでおく
$entries = ...
*/
$array = array(
'title' => 'れぶろぐ', // required
'link' => 'http://www.revulo.com/blog/', // required
'lastUpdate' => strtotime($entries[0]->timestamp),
'charset' => 'utf-8', // required
'description' => 'PHP や JavaScript 関連で調べたことをぐだぐだと',
'author' => 'revulo',
'email' => 'xxx@revulo.com',
'copyright' => 'revulo.com. All rights reserved.',
'generator' => 'Zend_Feed',
'language' => 'ja',
'entries' => array(),
);
foreach ($entries as $entry) {
$array['entries'][] = array(
'title' => $entry->title, // required
'link' => $entry->permalink, // required
'description' => mb_substr($entry->text, 0, 100), // required
'content' => $entry->text,
'lastUpdate' => strtotime($entry->timestamp),
);
}
require_once 'Zend/Feed.php';
$feed = Zend_Feed::importArray($array, 'atom');
$feed->send();
対応フォーマットが RSS 2.0 と Atom 1.0 だけなのがイマイチだが、 このように手軽にフィードの読み書きができる。
