JavaScriptを使わずにCSSをユーザに選ばせる

PHPSPOT開発日誌さんで、JavaScriptを用いずにユーザが好みのCSSを選べる仕組みが紹介されている。
http://phpspot.org/blog/archives/2006/08/javascriptcss.html

PHPでクッキーに設定を突っ込んで、表示側でクッキーの値に合わせてcssへのリンクを張っているようだ。単純な仕組みだ。

ところで、次の箇所は思わぬバグを引き起こしかねない。

$ref = (isset($_SERVER['HTTP_REFERER'])) ? $_SERVER['HTTP_REFERER'] : "/"; 
header("Location: $ref");  

RFC2616§14.36でRefererリクエストヘッダは次のように定義されている

Referer = "Referer" ":" ( absoluteURI | relativeURI )

一方、RFC2616§14.30でLocationレスポンスヘッダは次のように定義されている

Location = "Location" ":" absoluteURI

したがって、refererをそのままLocationレスポンスヘッダとして送信すると、Refererとして相対URIが送られた場合、RFCに違反することになる。すなわち、動作が保障されない。Refererリクエストヘッダが送られない場合も"/"という相対URIになってしまいますね。

また、次の箇所ではcookieの値とはいえ、外部から来た変数をそのまま出力している。これはセキュリティ上好ましくない。

<?php
$layout = (isset($_COOKIE["layout"])) ? $_COOKIE["layout"] : "main";
?>
<html>
<link rel="stylesheet" type="text/css" href="/css/<?php echo $layout; ?>.css">

ここは、次のように表示前にもチェックを入れるべきであろう。

<?php
$valids = array(
 "main", "blue", "red", "pink"
); 
$layout = (isset($_COOKIE["layout"]) && in_array($_COOKIE["layout"], $valids)) ? $_COOKIE["layout"] : "main";
?>

またHTMLの問題として、link要素はhead要素の中に入れなければいけない。

PHPの知識がなくても、次のサンプルを使えば簡単に誰でもCSSを切り替えることが出来ます。

のような記述をするのであれば、しっかりしたものを示すべきではないだろうか。