タグ「.htaccess」が付けられているもの

使用しているレンタルサーバーのバージョンが上がったせいか、今まで正常に動いていたPHPのスクリプトでエラーが出始めた。

エラーの内容

なにやらデフォルトのタイムゾーンを設定しろ的なdate_default_timezone_set()に関するエラー。

Warning: date(): It is not safe to rely on the system's timezone settings. You are *required* to use the date.timezone setting or the date_default_timezone_set() function. In case you used any of those methods and you are still getting this warning, you most likely misspelled the timezone identifier. We selected the timezone 'UTC' for now, but please set date.timezone to select your timezone. in /public_html/hoshiya.biz/lib/***.php on line 123

対処法方法

タイムゾーンの設定はphp.iniか.htaccessでするか、スクリプト内に宣言するかなどできます。

php.iniの場合

[Date]セクション内を編集

;date.timezone =
     ↓↓↓
date.timezone = Asia/Tokyo

※スクリプト全てに対して適用されます

.htaccessの場合

以下を追加

php_value date.timezone Asia/Tokyo

※.htaccess制御範囲内のスクリプト全てに対して適用されます

スクリプト内で宣言する場合

date_default_timezone_set('Asia/Tokyo');

※記述を追加したスクリプトのみに対して適用されます

YSlowのUse cookie-free domain対策用として.htaccessに静的コンテンツのCookieを削除する方法を見つけたのでメモ。

<FilesMatch "\.(css|js|jpg|jpeg|png|gif)$">
RequestHeader unset Cookie
Header unset Cookie
Header unset Set-Cookie
</FilesMatch>

結局、静的コンテンツ用にサブドメインを用意してみましたが、CDNのCloudFlareを使っていると、この設定をしてもサブドメイン経由で表示する画像などにCloudFlareのクッキーが加えられ、完全なクッキーレスにはできないようです。

mod_rewriteで日本語を含むURLからのアクセスをリダイレクトしようと.htaccessに以下を記述しました。結局は以下の書き方で正しかったのですが、404エラーや500エラーが出て動きませんでした。いろいろなサイトを参考に試行錯誤するものの時間ばかり消費して心が折れそうになりました。

http://hoshiya.biz/ブログ/にアクセスがあったら、http://hoshiya.biz/blog/にリダイレクトする

Redirect permanent /ブログ/ http://hoshiya.biz/blog/
または
RewriteRule ^ブログ/$ /blog/ [R,L]

 

上記で正しく動くはずが動かなかったのは.htaccessをUTF-8の「BOMあり」で保存していたのが原因でした。BOMがどういうものかわかりませんが、「UTF-8(BOMあり)」で保存すると、例えURL内の文字や.htaccessの文字がちゃんとURLエンコードされていても転送元にエンコード文字や日本語があるとエラーになるようです。

UTF-8とUTF-8Nの違いによるワナ」を参考に「BOMなし」のUTF-8(UTF-8N)で保存したら、ちゃんとリダイレクトできました。メモ帳でできるかどうかわかりませんが、私の場合、テキストエディターのEmEditorで「BOMなし」保存しました。

 

ちなみに転送元の「ブログ」はUTF-8でダイレクト(URLエンコードなし)で書かないと動かないようです。

逆に、転送先に日本語が含まれている場合は、URLエンコードしていないとダメです。

http://hoshiya.biz/blog/にアクセスがあったら、http://hoshiya.biz/ブログ/にリダイレクトする

RewriteRule ^blog/$ /¥%e3¥%83¥%96¥%e3¥%83¥%ad¥%e3¥%82¥%b0/ [NE,R,L]

また、URLエンコードされた文字列の「%」の前に「\」を付けてエスケーブさせておくのと、「NE」を行末に入れておかないとURLエンコードの文字列のまま出力されたり、「%」なしの文字列が表示されたりします。

mod_rewriteで日本語を含むURLからのアクセスをリダイレクトしようと.htaccessに以下を記述しました。結局は以下の書き方で正しかったのですが、404エラーや500エラーが出て動きませんでした。いろいろなサイトを参考に試行錯誤するものの時間ばかり消費して心が折れそうになりました。

http://hoshiya.biz/ブログ/にアクセスがあったら、http://hoshiya.biz/blog/にリダイレクトする

Redirect permanent /ブログ/ http://hoshiya.biz/blog/
または
RewriteRule ^ブログ/$ /blog/ [R,L]

 

上記で正しく動くはずが動かなかったのは.htaccessをUTF-8の「BOMあり」で保存していたのが原因でした。BOMがどういうものかわかりませんが、「UTF-8(BOMあり)」で保存すると、例えURL内の文字や.htaccessの文字がちゃんとURLエンコードされていても転送元にエンコード文字や日本語があるとエラーになるようです。

UTF-8とUTF-8Nの違いによるワナ」を参考に「BOMなし」のUTF-8(UTF-8N)で保存したら、ちゃんとリダイレクトできました。メモ帳でできるかどうかわかりませんが、私の場合、テキストエディターのEmEditorで「BOMなし」保存しました。

 

ちなみに転送元の「ブログ」はUTF-8でダイレクト(URLエンコードなし)で書かないと動かないようです。

逆に、転送先に日本語が含まれている場合は、URLエンコードしていないとダメです。

http://hoshiya.biz/blog/にアクセスがあったら、http://hoshiya.biz/ブログ/にリダイレクトする

RewriteRule ^blog/$ /¥%e3¥%83¥%96¥%e3¥%83¥%ad¥%e3¥%82¥%b0/ [NE,R,L]

また、URLエンコードされた文字列の「%」の前に「\」を付けてエスケーブさせておくのと、「NE」を行末に入れておかないとURLエンコードの文字列のまま出力されたり、「%」なしの文字列が表示されたりします。

WEBサーバーがApatchであればmod_writeでWordpressのURL書き換えが行えますが、IISの場合はmod_rewriteが使えません。でもIIS7以降は『URL Rewriteモジュール』というものをインストールすれば.htaccessのようなweb.configというファイルにリライトルールを記載することで実現ができるようです。

方法

  1. Microsoft Web Platform Installer』をダウンロード。
    http://www.microsoft.com/web/downloads/platform.aspx
  2. 『IIS Rewrite 2.0』を追加する
    『製品タブ』の中にあります。あとは画面に従ってインストールしてください。
    Microsoft Web Platform Installer
  3. サイトのルートディレクトリの『web.config』に以下を記載。
    ファイルが存在しなければ作成してください。
    <?xml version="1.0" encoding="UTF-8"?>
    <configuration>
    <system.webServer>
    <rewrite>
    <rules>
    <rule name="Main Rule" stopProcessing="true">
    <match url=".*" />
    <conditions logicalGrouping="MatchAll">
    <add input="{REQUEST_FILENAME}" matchType="IsFile" negate="true" />
    <add input="{REQUEST_FILENAME}" matchType="IsDirectory" negate="true" />
    </conditions>
    <action type="Rewrite" url="index.php/{R:0}" />
    </rule>
    </rules>
    </rewrite>
    </system.webServer>
    </configuration>

 

これで、以下のWordpressのリライトルール(.htaccess)と同じ動作になります。

# BEGIN WordPress
<IfModule mod_rewrite.c>
RewriteEngine On
RewriteBase /
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule . /index.php [L]
</IfModule>
# END WordPress

 

『URL Rewriteモジュール』をIIS8にインストールすると『インターネットインフォメーションサービス(IIS)マネージャー』のページに『URL書き換え』というアイコンが追加されています。ここから『web.config』の内容をGUIで追加することも可能です。

インターネットインフォメーションサービス(IIS)マネージャー

Apatchのmod_rewriteを使ってスマートホン用のサイトにリダイレクトさせる方法をメモ。

MovableTypeのプラグインを組み込んでスマホ用のブログページを作りました。

PC用のブログはルートディレクトリの「blog」にあり、スマートホン用のブログは「blog」の中の「i」にあります。

ディレクトリ

 

スマートホンからアクセスを転送するため、「blog」ディレクトリに以下の内容で.htaccessを作成しました。

#スマホサイトにリダイレクト
RewriteEngine On
RewriteBase /blog
RewriteCond %{REQUEST_URI} !^/blog/i/.*$
RewriteCond %{REQUEST_URI} !^(.JPG|.jpg|.GIF|.gif|.PNG|.png) [NC]
RewriteCond %{HTTP_USER_AGENT} ^(iPhone|iPod|Android|BlackBerry|Windows.Phone) [NC]
RewriteCond %{HTTP_USER_AGENT} !iPad [NC]
RewriteRule ^(.*)$ /blog/i/$1 [R=301,L]

 

もし、スマホ用のディクレトリではない「blog」で、画像でなく、iPadを除くスマートホンからアクセスがあった場合は「i」にリダイレクトするという内容。

「i」ディレクトリには画像がないため、ブログ内の画像のソースやリンクまでリダイレクトされると画像が表示されず困るので、画像はリダイレクトしないように5行目を加えています。

Apatchのmod_rewriteを使ってスマートホン用のサイトにリダイレクトさせる方法をメモ。

MovableTypeのプラグインを組み込んでスマホ用のブログページを作りました。

PC用のブログはルートディレクトリの「blog」にあり、スマートホン用のブログは「blog」の中の「i」にあります。

ディレクトリ

 

スマートホンからアクセスを転送するため、「blog」ディレクトリに以下の内容で.htaccessを作成しました。

#スマホサイトにリダイレクト
RewriteEngine On
RewriteBase /blog
RewriteCond %{REQUEST_URI} !^/blog/i/.*$
RewriteCond %{REQUEST_URI} !^(.JPG|.jpg|.GIF|.gif|.PNG|.png) [NC]
RewriteCond %{HTTP_USER_AGENT} ^(iPhone|iPod|Android|BlackBerry|Windows.Phone) [NC]
RewriteCond %{HTTP_USER_AGENT} !iPad [NC]
RewriteRule ^(.*)$ /blog/i/$1 [R=301,L]

 

もし、スマホ用のディクレトリではない「blog」で、画像でなく、iPadを除くスマートホンからアクセスがあった場合は「i」にリダイレクトするという内容。

「i」ディレクトリには画像がないため、ブログ内の画像のソースやリンクまでリダイレクトされると画像が表示されず困るので、画像はリダイレクトしないように5行目を加えています。

mod_rewriteサンプル

  • 投稿

.htaccessに記述するリライトルールのサンプル

mod_rewriteによるリダイレクトで、比較的よく使うリライトルールのサンプルをメモ。

 

URLのアンダーバーをハイフンに変更

/blog/2012/06/post_abc123.phpでアクセスがあったらpost-abc123.phpにリダイレクトします。

RewriteEngine on
RewriteRule ^([0-9]+)/([0-9]+)/post_(.+)\.php$ /$1/$2/post-$3.php [R,L]

 

ディレクトリの移動

古いディレクトリにアクセスがあったら新しいディレクトリにリダイレクトします。

RewriteEngine on
RewriteRule ^/old/(.*)$ /new/$1 [R=301,L]

 

動的なページを静的なページに見せる

/sample/2012/06.htmlにアクセスがあったら/sample/sample.php?a=2012&b=06lにリダイレクトします。

RewriteEngine on
RewriteRule ^/sample/([0-9A-Za-z]+)/([0-9A-Za-z)]+)\.html$ /sample/sample.php?a=$1&b=$2 [L]

 

特定のディレクトリにあるページの拡張子を書き換える

blogを含むURLの拡張子がhtmlの場合、phpに書き換えてアクセスする。

RewriteEngine on
RewriteCond %{REQUEST_URI} ^/blog.*$
RewriteRule ^(.*)\.html$ /$1.php [R,L]

 

その他参考ページ

".htaccess" に記述することにより、外部から要求されたリクエスト URL を書き換えてリダイレクトします。
ファイルの移転、ディレクトリ再編成、サイト移転、更にはアクセス拒否まで絶大な効果を発揮します。

具体的には、外部から要求されたリクエスト URL を Apache の "mod_rewrite" 拡張モジュール(URL書き換えエンジン)を使用し、 正規表現を使って書き換えます。 "Redirect" と異なり、リクエストの URL が実在しなくても転送が可能です。

【注意:サーバーの環境】
Apache1.2 以降で使用可能。 Apache の "httpd.conf" で、 "mod_rewrite" モジュールが利用可能になっている必要があります。 Apache httpd.conf の詳細設定 LoadModule

".htaccess" ファイルにおける Rewrite の記述方法

一般的な書式


RewriteEngine on

RewriteBase /



#ドメインの統一

RewriteCond %{HTTP_HOST} ^(example\.com)(:80)? [NC]

RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]



#ディレクトリの移転

RewriteRule ^old_dir(.*)$ /new_dir$1 [R=301,L]



#ファイルの移転

RewriteRule ^old_dir/index\.html$ /new_dir/index.html [R=301,L]



#クローラのアクセス禁止

RewriteCond %{HTTP_USER_AGENT} Badbot-1 [NC, OR]

RewriteCond %{HTTP_USER_AGENT} Badbot-2 [NC]

RewriteRule !^robots\.txt$ - [F]



RewriteEngine off


*注 書き換え対象に正規表現の特殊文字が含まれている場合は、 "\" (日本語環境では円マーク) でエスケープします。
*注 書き換え対象 "old_dir" が、 "/" から始まっていないことに注意してください。
*注 書き換え後 "/new_dir" が、 "/" から始まっていることに注意してください。

ファイルの移転

リクエストに対して、ファイルが移転したことを知らせます。


RewriteRule ^old_dir/index\.html$ /new_dir/index.html [R=301,L]

【解説】(行頭から)old_dir/index.html(行末まで)のアクセスを "/new_dir/index.html" にリダイレクトし、ここではファイルが永久に移転したことを通知しています。 書き換えが行われたら終了。

ディレクトリの移転

リクエストに対して、ディレクトリ全体が移転したことを知らせます。
"http://~" から記述することにより、外部ドメインへのリダイレクトも可能です。


# 内部移転

RewriteRule ^old_dir(.*)$ /new_dir$1 [R=301,L]

# 外部移転

RewriteRule ^old_dir(.*)$ http://www.example/new_dir$1 [R=301,L]

【解説】".*" =任意の1文字0回以上の繰り返し。 (.*) の値が、後方参照 $1 に入ります。

拡張子の変更

リクエストに対して、ファイルの拡張子を書き換えてリダイレクトします。


# 拡張子が ".html" のファイルを、全て ".phpl" に変更する

RewriteRule ^(.*)\.html$ /$1.php [R=301,L]



# 特定のディレクトリに対して、ファイルの拡張子を変更する

RewriteCond %{REQUEST_URI} ^/example/ [NC]

RewriteRule ^(.*)\.html$ /$1.php [R=301,L]



# 特定のディレクトリを除いて、ファイルの拡張子を変更する

RewriteCond %{REQUEST_URI} !^/example/ [NC]

RewriteRule ^(.*)\.html$ /$1.php [R=301,L]

【解説】特定のディレクトリに関しては、(行頭から)"/example/" の大小を問わない文字を含む(もしくは含まない)アクセスに対して、拡張子 ".html" を ".php" に書き換えてリダイレクトしています。 ここではファイルが永久に移転したことを通知しています。 書き換えが行われたら終了。

サーバ移転(サイトの引越し)

リクエスト全体を、新しいドメインへリダイレクトします。


RewriteRule ^(.*)$ http://www.new-example.com/$1 [R=301,L]

【解説】HTTPステータスコード "R=301(Moved Permanently)" を付加することにより、URLが永久に移動したことを検索サイトのクローラに通知します。 この処理で、旧サイトのページランクを自動的にほぼ引き継ぐことができます。
検索サイトへの反映は、クローラにもよりますが、1週間から1ヶ月ほどかかります。

ドメインの統一

サーバーは1つのドメイン、例えば "example.com" に対して、"www.example.com" でもリクエストを受け付けます。
host がサブドメインを使用している場合は、更に "example.host.com" と "www.example.host.com" でも閲覧可能になり、合計4つのサイトにアクセスが分散することになります。
これは、 SEO 対策上あまり好ましいことではありません。 ここでは、"Rewrite" を使って、"www.example.com" に統一する場合を記述します。

サブドメインを使用していない場合

RewriteCond %{HTTP_HOST} ^(example\.com)(:80)? [NC]

RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]

サブドメインを使用している場合

RewriteCond %{HTTP_HOST} ^(example\.com)(:80)? [NC,OR]

RewriteCond %{HTTP_HOST} ^(example\.host\.com)(:80)? [NC,OR]

RewriteCond %{HTTP_HOST} ^(www\.example\.host\.com)(:80)? [NC]

RewriteRule ^(.*)$ http://www.example.com/$1 [R=301,L]

アクセス制限

サーバ変数を取得して、アクセス制限を掛けます。
アクセス制限は、サーバに思わぬ負荷をかけることがあります。 不必要なアクセス制限はできるだけ掛けないようにしてください。
*注 十分にアクセス情報を解析してから設定してください。 設定によっては正当な訪問者もアクセスできなくなる可能性があります。

  • [F] は、「Forbidden(アクセス禁止)」を意味します。
  • 特殊文字の前に "\"(日本語環境では円マーク)を付加する事に注意してください。
  • "REMOTE_HOST" は、サーバーによっては取得できない場合があります。
特定のホストからのアクセスを全て禁止する

RewriteCond %{REMOTE_HOST} ^example\.com$ [NC, OR]


RewriteCond %{REMOTE_ADDR} ^192\.168\.1\.

RewriteRule ^.* - [F]

【解説】"REMOTE_HOST" が取得できない場合は、 "REMOTE_ADDR" を使用してアクセス制限をかけます。

特定のブラウザからのアクセスを全て禁止する

RewriteCond %{HTTP_USER_AGENT} ^Mozilla/4\.0 \(compatible; MSIE 6\.0\)$ [NC]

RewriteRule ^.* - [F]

特定の Referer からのアクセスを全て禁止する

RewriteCond %{HTTP_REFERER} ^http://www\.example\.com/bad\.html$ [NC]

RewriteRule ^.* - [F]

特定の Referer 以外からのアクセスを全て禁止する(=特定の Referer からのみアクセスを全て許可する)

RewriteCond %{HTTP_REFERER} !^http://www\.example\.com/good\.html$ [NC]

RewriteRule ^.* - [F]

直リンクを全て禁止する

RewriteCond %{HTTP_REFERER} !example\.com [NC]

RewriteRule ^.* - [F]

【解説】Referer が "example.com" を含まないリクエストに対して、全てのアクセスを禁止します。

画像の直リンクを禁止する

RewriteCond %{HTTP_REFERER} !example\.com [NC]

RewriteRule \.(jpg|png|gif)$ - [F]

【解説】Referer が "example.com" を含まないリクエストに対して、拡張子が ".jpg" または ".png" または ".gif" へのアクセスを禁止します。

特定のホスト & 特定のブラウザからのアクセスを禁止する

RewriteCond %{REMOTE_ADDR} ^192\.168\.1\.

RewriteCond %{HTTP_USER_AGENT} ^Mozilla/4\.0 \(compatible; MSIE 6\.0\)$

RewriteRule ^.* - [F]

特定の検索ロボット(クローラ)に対して、 "robots.txt" 以外のアクセスを禁止する

クローラのアクセス禁止は、サーバの負荷を伴います。 そこで先に、ここに記述する全てのクローラを "robots.txt" で拒否しておきます。 それを無視した悪質クローラだけを、最終的にここでアクセス禁止にします。


RewriteCond %{HTTP_USER_AGENT} Badbot-1 [NC, OR]

RewriteCond %{HTTP_USER_AGENT} Badbot-2 [NC, OR]

RewriteCond %{HTTP_USER_AGENT} Badbot-3 [NC, OR]

RewriteCond %{HTTP_USER_AGENT} Badbot-n [NC]

RewriteRule !^robots\.txt$ - [F]

【解説】"HTTP_USER_AGENT" が、 "Badbot-1", から "Badbot-n" の文字(文字の大小を区別しない)を含むクローラに対して、 "robots.txt" 以外のアクセスを禁止します。
※悪質クローラに対する対策の詳細は: 検索ロボット対策 をご覧ください。

説明

ディレクティブ

ディレクティブと書式 初期値 説明
RewriteEngine on/off off 書き換えの可否を設定。
RewriteOptions inherit - inherit : 現在の設定値を親ディレクトリの設定値から強制的に継承する。
RewriteBase / / 書き換えのベースとなるパス(ベースが明白な場合は不要)。
RewriteCond テスト文字列 条件 パターン。 - 条件によるテスト文字列とパターンの比較。
RewriteRule パターン 置換対象。 - パターンを置換対象で置き換える。

オプション

[R] 強制的にリダイレクト (Redirect) する。
[R=301] : 永久的に移動。HTTP レスポンスの「301 : Moved Permanently」を返します。
[R=302] : 一時的な移動。HTTP レスポンスの「302 : Moved Temporarily」を返します、デフォルト。
[F] 強制的にアクセス禁止 (Forbidden) にする。
HTTP レスポンスの「403 : Forbidden」を返します。
[G] 強制的に消去済み (Gone) にする。
HTTP レスポンスの「410 : Gone」を返します。 もはや存在しないページを消去済みとしてマークします。
[L] 書き換えが行われたら終了 (Last) にする。
現在の書き換え後の URL が後続のルール によってそれ以上書き換えられることを防止します。
[NC] パターンについて、文字の大小を区別しない(No Case)。 つまり、"A-Z" と "a-z" は区別されません。
[OR] または。

正規表現

文字 説明
! 否定。
. 任意の1文字。
[ ] 括弧内のいずれかの文字。
[^ ] 括弧内のいずれかの文字以外。
| または。
? 直前の文字の0回または1回の繰り返し
* 直前の文字の0回以上の繰り返し。
+ 直前の文字の1回以上の繰り返し。
( ) 選択範囲の境界を明示する、もしくは後方参照を作成する。
^ 行頭。
$ 行末。
$n (0 <= n <= 9) 後方参照。 n番目の( )内の値が入ります。
%{ } サーバ変数の取得。
\ (日本語環境では円マーク)正規表現の特殊文字をエスケープする。

サーバ変数

変数名 説明
HTTP_USER_AGENT ブラウザの種類とバージョン。
HTTP_REFERER 参照元の URL 。
HTTP_COOKIE 設定されているクッキー情報。
HTTP_FORWARDED プロキシサーバ情報。
HTTP_HOST 接続要求しているホスト名。
HTTP_PROXY_CONNECTION 接続先プロキシサーバとの接続状態。
HTTP_ACCEPT ブラウザが認識可能なデータ形式。
DOCUMENT_ROOT サイトのルートディレクトリ。
SERVER_ADMIN サーバ管理者のメールアドレス情報。
SERVER_NAME サーバのホスト名、ドメイン名、またはIPアドレス情報。
SERVER_ADDR サーバのIPアドレス。
SERVER_PORT 送信に使われたサーバのポート番号。
SERVER_PROTOCOL 送信に使われたプロトコルの名前とレビジョン情報。
SERVER_SOFTWARE 起動したサーバソフトウエアの名前とバージョン情報。
REMOTE_ADDR リモートホストのIPアドレス情報。
REMOTE_HOST リモートホストのドメイン名。
REMOTE_USER ユーザの認証名。
REMOTE_IDENT リモートホストのユーザ名。
REQUEST_METHOD リクエストを送信した方法。
REQUEST_URI リクエストされたURI。
SCRIPT_FILENAME 現在実行しているスクリプト名。
PATH_INFO クライアントから送られるパス情報。
QUERY_STRING URL に付加して渡された "?" 以降の文字列。
AUTH_TYPE ユーザを認証するときに使用する認証方法。
TIME_YEAR サーバのシステム日付・年
TIME_MON サーバのシステム日付・月
TIME_DAY サーバのシステム日付・日
TIME_HOUR サーバのシステム日付・時
TIME_MIN サーバのシステム日付・分
TIME_SEC サーバのシステム日付・秒
TIME_WDAY サーバのシステム日付・曜日
TIME サーバのシステム日付・Unix タイムスタンプ。