【雑談】どうして Hello, World なの?

何かしらのプログラミング言語を勉強したことのある人なら、文字列を表示させるもっともシンプルな構文のテスト文言として “Hello, World” というのを目にしたことがあると思うんですが、どうして “Hello, World” なんでしょう?

ずっと前から疑問に思っていたんですが、まわりの人に聞いても、分からない、とか、特に意味はないんじゃない?、とか、たまたまじゃない?、というような感じなんですよね。

どうしてか、というのははっきりしないけど、いつから使われているのかという起源ならはっきりとしています。テスト文言として “Hello, World” を使う習慣はブライアン・カーニハンとデニス・リッチーによる著書「プログラミング言語C」(1978年)からです。

だったらカーニハンかリッチーに聞けば分かりそうな感じだけど、本人たちがそんなことにあまり言及していなかったみたいですね。たくさんの人が疑問に思ってネットでも質問しています。

でも、どこかしらになにか書かれているだろうと思って、IT系のブログや記事を散々読み漁っていたら、アメリカのITニュース配信サイト「SLATE」で、こんなの見つけました。
Why the first code a programmer writes is “Hello, World.”
NewYork Times にも寄稿しているクライブ・トンプソン氏の記事です。

抜粋です。
「Kernighan had recently seen “some cartoon of a chick coming out of an egg, and it says Hello, World,” as he told me when I called him up to ask about it. It tickled his fancy, so he used that. 」

和訳(変だったらごめんなさい)
「(どうして Hello, World なのか)質問したところ、カーニハンは、最近、こう言っていました。”卵からヒヨコが出てくる漫画があるんだけど、それが Hello, World なんだよ。” それに空想が刺激されて、彼はそれを使うことにしたのです。」

2019年10月16日の記事だったので、最近、このようにおっしゃったのでしょうか。

プログラミングの世界の入り口に立つ者が、これから広がる世界に対して「Hello, World」と1行目を書き込む、広大な世界へ歩き出したばかりのひよっこですものね。
AI だろうが、ロボットのプログラミングだろうが、この一行から始まっているんですよ。

なぜ別の言葉じゃなく、よりによって Hello, World なのか、ようやく納得できて、長年の疑問が解けてうれしくなりました。
明日から自慢げに言いふらしてしまいそうです。(自分の周りにどれぐらいこれを知りたい人がいるのかが疑問ですけど・・・ 笑)

【WordPress】本文中に PHP を利用する方法

WordPress の投稿ページにしろ、固定ページにしろ、直接 PHP を書き込むことは出来ません。不便ですよねーーー。WordPress そのものを作っているプログラミング言語が PHP であるので、PHP をコンテンツに直接書き込むとセキュリティを落とすため、書き込みができなくなっているそうです。

WordPress の本文中に PHP を利用する場合は、ショートコードを作成して利用します。
(プラグインもあるようなのですが、セキュリティ上問題があるようですね。)

ショートコードとは

別個に作ったプロブラムファイルを、本文の中に埋め込むための仕組みです。
WordPress 側ですでに用意されているショートコードもたくさんありますね。
Available shortcodes
これを自分で作るのですが、既存のコードと同じ名前にならないようにしなくてはいけません。
functions.php において、コードとプログラムを関係づけます。

ショートコード作成・利用の流れ

① 組み込みたい内容の PHP ファイルを作成。
② functions.php で、① で作成した PHP ファイルを読み込むための関数を記述。その関数を呼び出すショートコードを作成。
③ WordPress 投稿・固定ページに、②で作成したショートコードを記述。

* functions.php に、投稿・固定ページに書き込みたい PHP のコマンドを、直接記述することもできます。短ければそれでもいいのでしょうが、複数ある、長い、となることを想定して、別の PHP ファイルを作成する前提としました。

それぞれのファイルの関係はこのようになります。

① 組み込みたい内容の PHP ファイルを作成

おなじみ “Hello, World!” という文字列を表示させるプログラムです。
これを投稿ページに埋め込みます。

ex.php

<?php 
echo 'Hello, World!';
?>

このファイルは、子テーマにアップロードします。(子テーマがなければ、テーマの中ですが、子テーマは用意しておいた方がいいです。)

② functions.php で、PHP ファイルを読み込むための関数を記述 + ショートコードを作成

子テーマの中の functions.php に記述します。(子テーマがなければテーマの中の)

functions.php

<?php

// 投稿ページのショートコードで指定された PHP ファイルを読み込む関数
function sc_php($atts = array()) {
  shortcode_atts(array(   /* shortcode_atts でショートコードの属性名を指定 */
    'file' => 'default'   /* 属性名とデフォルトの値 */
  ), $atts);   /* 属性を格納する変数 */
  ob_start();   /* バッファリング */
  include(STYLESHEETPATH . "/$atts[file].php");  /* CSSのあるパス = 子テーマのパスを指定 */
  return ob_get_clean();  /* バッファの内容取得、出力バッファを削除 */
}

// ショートコード作成(sc というショートコードは、sc_php()という関数を呼び出すという意味)
add_shortcode('sc', 'sc_php');
?>

何をやっているのか、一行一行コメントアウトしてみました。(ちょっと鬱陶しいかも 笑)

9行目の include(STYLESHEETPATH . “/$atts[file].php”);
ですが、STYLESHEETPATH は、CSS のあるディレクトリへのパスということです。
CSS は子テーマに入っているので、作成した PHP ファイルも、同じ子テーマに入っているという前提で記述しています。もし、子テーマでなく、別の場所に PHP ファイルがある場合は、そのパスを記述します。

③ WordPress 投稿・固定ページに、ショートコードを記述

PHP を埋め込みたい投稿または固定ページに、ショートコードを記述します。
ショートコードは、[ショートコード名 属性] という形になります。今回は、属性に呼び出したいファイル名を記述します。file という属性は、functions.php で規定しましたね。

[sc file='ex.php']

これでブラウザには、ex.php の中身、
Hello, World!
と表示されます。

【.htaccess】Options ディレクティブ / DirectoryIndex ディレクティブ

Options ディレクティブ

クライアントがディレクトリ名の最後に / を指定して、そのディレクトリの中に、index.html ファイルがなかった場合、このようにディレクトリの中のファイルの一覧が表示されます。

内容を見せたくない場合、好ましくありませんね。

Options ディレクティブでは、ディレクトリに対してどの機能が使用可能かを制御することができます。

ディレクトリ内の一覧を見せないようにする構文例です。

Options -Indexes

“Option” に続いて、機能の値を記述します。

  • 複数の機能を指定する場合は、半角スペースで区切って指定します。
  • + や – を機能の値の前に付けることでディレクトリ毎の設定を変更できます。上位のディレクトリの設定に対して、追加、削除、していくことになります。
  • ↓ Options ディレクティブに指定可能な値一覧
    説明
    All MultiViews を除いた全ての機能が有効化。(デフォルト)
    ExecCGI mod_cgi による CGI スクリプトの実行可能化。
    FollowSymLinks シンボリックリンクを有効化。
    Includes mod_include が提供する SSI を有効化。
    IncludesNOEXEC SSI ⇒ 有効化。#exec コマンド / #exec CGI ⇒ 無効化。
    Indexes DirectoryIndex ディレクティブ(↓ で詳細記述)で指定したファイル (例えば index.html) がなければ、ディレクトリ一覧を表示許可。
    MultiViews リソースが複数の表現 (例えば、日本語や英語など) で利用できる場合、適切な言語や MIMEタイプ(Content-Type) を優先的に要求するコンテンツネゴシエーションを許可。
    SymLinksIfOwnerMatch シンボリック先のファイルやディレクトリが、シンボリックリンクの所有者と同じ権限である場合、シンボリックリンクを許可。
    None すべてのオプションを無効。

上記の構文の例では、オプションの値を “-Indexes” と指定し、ディレクトリの一覧の表示を許可する機能を、削除しています。

ブラウザで一覧は表示されなくなり、代わりに、403 Forbidden(アクセス権限がないエラー)が表示されます。

DirectoryIndex ディレクティブ

↑ で、クライアントがディレクトリ名の最後に / を指定し、index.html ファイルがなかった場合、ディレクトリの中のファイルの一覧が表示されることについて触れましたが、DirectoryIndex ディレクティブでは、ディレクトリインデックスを、index.html 以外に設定することができます。複数のディレクトリインデックスを指定している場合は、最初に見つかったものを返します。

DirectoryIndex index.html index.php top.html

上記の例では、index.html がなければ index.php、index.php がなければ top.html を呼び出します。

さらに、index.html も index.php も top.html も見つからない場合、
Options Indexes で一覧表示が許可されている場合 ⇒ ディレクトリのファイル一覧表示
Options Indexes で一覧表示が許可されていない場合 ⇒ 403 Forbidden

【.htaccess】ErrorDocument ディレクティブ

問題やエラーが発生したとき、ブラウザでこのように表示されることがありますね。これは、Chrome の存在しないページのリクエストに応答する 404 ページです。
こうなってしまうと、ユーザは別のサイトへ移動してしまったりするので、ユーザをサイト内の有益なコンテンツへ導けるように、独自にエラー表示を設定する方がいいですよね。

ErrorDocument ディレクティブは、問題やエラーが発生したときの動作を指定できます。

ErrorDocument の基本構文

Redirect ディレクティブで、URL を自動転送する基本的な構文です。

ErrorDocument error-code document
  • ErrorDocument
  • エラードキュメントの表示方法の設定の宣言です。

  • error-code
  • エラーのステイタスコードを指定します。↓ 主なコードの一覧

    コード エラー内容 意味
    401 Unauthorized ユーザー認証が必要なページで認証に失敗
    403 Forbidden 権限がない(ディレクトリにアクセスしようとしたなど)
    404 Not Found 指定したファイルが存在しない
    500 Internal Server Error サーバがリクエスト実行できない(PHP などのバグ、.htaccess の設定ミス)
    501 Not Implemented リクエストを処理できる機能がサーバにない
    503 Service Unavailable サービス利用不可
  • document
  • 表示するテキストまたはファイルへのパスを指定します。

    ErrorDocument ディレクティブは、問題やエラーが発生したとき、指定できる動作は、4 つがあります。

    ① Apache 標準のエラーメッセージを表示(デフォルト。↑ の Chrome の画面のような表示)
    ② 自分で指定した任意のメッセージを表示
    ③ 内部サーバの別の URL-path にリダイレクト
    ④ 外部サーバの別の URL にリダイレクト

    以下、②~③まで、例を一つずつ見ていきます。
    (①はデフォルトなので、特に設定の必要はありません。)

<document ⇒ 自分で指定した任意のメッセージを表示>

ErrorDocument 404 "Sorry... The file not found"

エラーコードの後に、メッセージをダブルクォート(”)で囲んで記述します。

<document ⇒ 内部サーバの別の URL-path にリダイレクト>

ErrorDocument 404 /error/404.html

“/” で始まるドキュメントルートからの相対パスを指定します。この例ですと、.htaccess ファイルの置かれたディレクトリ内、error というディレクトリの中にある 404.html へリダイレクトされます。

(401: 認証失敗、404: 未検出の場合、次で説明する「外部サーバーへのリダイレクト」ではなく、こちらの「内部サーバへのリダイレクト」を利用します。↓の理由参照)

<document ⇒ 外部サーバの別の URL にリダイレクト>

ErrorDocument 404 http://example.com/404.html

http などから始まる完全な URL を指定します。

注意しなくてはいけないのは、完全な URL を指定するリダイレクトにすると、例え内部サーバであっても、クライアントには、「エラーステイタスコード」ではなく、「リダイレクトステイタスコード」を通知します。
404 エラー(未検出)であるのに、有効なファイルかと、スクローラーなどのロボットは、混乱する可能性があります。
また、401 エラー(認証失敗)で外部 URL へリダイレクト指定する場合、クライアントは 401 のステータスコードを受け取らないため、パスワードをユーザに入力要求しなければならないことが分かりません。

そのため、401、404 エラーの場合は、相対パスを指定する「内部サーバへのリダイレクト」を記述します。

有益な 404 ページを作成

自分のサイトに合わせた 404 ページをカスタマイズすることで、クライアントに有益な情報を提供することができます。
有益な 404 ページを作るためのポイントは、Google のウェブマスターのページによると以下の通りです。

  • ユーザーに対して、探しているページが見つからないことを明確に伝えます。親しみやすく魅力的な言葉を使用します。
  • 404 ページを、サイトのその他の部分と同じデザイン(ナビゲーションを含む)にします。
  • 最も人気のある記事や投稿へのリンクの他、ホームページへのリンクを追加します。
  • 404 ページが Google や他の検索エンジンのインデックスに登録されないようにするため、存在しないページがリクエストされたときにウェブサーバーが実際の 404 HTTP ステータス コードを返すことを確認します。

.htaccess ファイルは、一番最後に空行が必要です。忘れずに・・・。

【.htaccess】mod_rewrite モジュール – その 5 RewriteRule のフラグ一覧

mod_rewrite モジュールを利用したリダイレクトについてまとめてきましたが、mod_rewrite は、そもそも URL の書き換えを行う機能なので、RewiteRule では、URL 書き換えを行うための様々なフラグがあります。

RewriteRule のフラグ一覧です。

フラグ syntax 説明
B 書き換え処理前に英数字以外の文字をエスケープ(パーセントエンコーディング)
C chain 条件に一致したら、後続の処理を適用。これは通常動作なので、条件が不一致の場合に後続の条件を適用しないために使用。
CO=NAME:VAL Cookie Cookie を設定。
DPI discardpath URI の PATH_INFO を破棄
E ENV 環境変数の値を設定。[E=変数名:値]で設定、 [E=!値] で値を削除。
F forbidden HTTP 403(閲覧禁止)エラーを返し、後続のルールを適用しない。
G gone HTTP 410(消滅)エラーを返し、後続のルールを適用しない。
H=Content-handler Handler 実行するアプリケーションのハンドラを強制的に指定。例)拡張子のないファイルはphp で実行。
RewriteRule !\. – [H=application/x-httpd-php]
L last URLの書き換え処理を終了します。以降のルールはスキップ。
N next 書き換え処理を先頭から再実行
NC nocase 条件を評価する時、英字の大文字小文字を区別しない。
NE noescape & や % をエスケープせず文字列として扱う。
PT passthrough URLの書き換え後、他のモジュール(Alias、Redirect、ScriptAliasなど)に制御を渡す。
QSA qsappend 書き換え前の URL と置換文字列に、それぞれクエリ文字列(URL の ? 以降の文字列)がある場合、置換文字列の末尾に & と書き換え前の URL に指定されたクエリ文字列を追加。本フラグを指定しない場合、クエリ文字列は置換文字列で上書き。
R[=code] Redirect 指定したURLにリダイレクト。レスポンスコードの範囲は 300 ~ 399 まで。
301: 恒久的な移動
302: 一時的な移動 (デフォルト)
303: 他のもので置き換えられた場合
304: 恒久的に削除された場合
temp(デフォルト値)、permanent、seeother のシンボル名も指定可
S=num skip 指定した数のルールをスキップ。[S=2] と指定すると、条件に一致した場合、以降のルールを 2 つスキップ。
T=MIME-type type ターゲットファイルを強制的に指定した MIME-type にする。

【.htaccess】mod_rewrite モジュール – その4 HTTP 環境変数一覧

RewriteCond ディレクティブで利用する主な HTTP 環境変数の一覧です。

ヘッダ環境変数

環境変数 意味・値
HTTP_HOST リクエスト先のホスト名 (DNS 名) 情報
例)http://hazu.jp/~ でのアクセスなら、”hazu.jp”
http://www.hazu.jp/~ のアクセスなら、”www.hazu.jp”
HTTP_REFERER 参照元の URL 情報(前にいたページのURL情報)
例)Google での検索からのアクセスなら、”https://www.google.com”
HTTP_ACCEPT ブラウザがサポートするメディア・MIMEタイプ情報
例)”text/html,application/xhtml+xml,application/xml;q=0.9″
HTTP_USER_AGENT クライアントのプラットフォーム、バージョン情報、ブラウザの情報
例)”Mozilla/5.0 (Windows NT 10.0; Win64; x64) Chrome/77.0.3865.90″

サーバ環境変数

環境変数 意味・値
SERVER_NAME Webサーバ名の情報
例)”hazu.jp”
SERVER_ADDR Web サーバの IP アドレス情報
例)”10.20.30.40:80″
SERVER_PORT Webサーバのポート番号の情報
例)一般的には、http ならポート番号 “80”、https ならポート番号 “443”

リクエスト環境変数

環境変数 意味・値
REMOTE_ADDR クライアントの IP アドレス情報
例)”10.20.30.40:80″
REMOTE_HOST クライアントのホスト名情報(必ず含まれているとは限らない)
例)”www.client123.hoge.com”
REMOTE_USER Basic 認証におけるユーザ認証時のユーザ ID 情報
SCRIPT_FILENAME 実行するスクリプトの絶対パス情報
例)example.php を実行する場合、その絶対パス “hazu.jp/home/example.php”
PATH_INFO ファイル名とクエリー文字列の間にあるパス情報
例)”example.php/foo/bar?id=123456″ にアクセスなら、”/foo/bar”
QUERY_STRING クエリー文字列である GET パラメータの情報
例)”example.php/foo/bar?id=123456″ にアクセスなら、”id=123456″

サーバー日付・時刻変数

環境変数 意味・値
TIME_YEAR サーバ時刻の年
例)”2019″ 西暦で表示
TIME_MON サーバ時刻の月
“01” ~ “12”
TIME_DAY サーバ時刻の日
“01” ~ “31”
TIME_HOUR サーバ時刻の時
“00” ~ “23”
TIME_MIN サーバ時刻の分
“00” ~ “59”
TIME_SEC サーバ時刻の秒
“00” ~ “59”
TIME_WDAY サーバ時刻の曜日
“0” (日曜) ~ “6” (土曜)
TIME サーバ時刻の年・月・日・時・分・秒
例)2019年10月11日、23:35:07なら、”20191011234507″

その他

環境変数 意味・値
THE_REQUEST リクエストの情報(クライアントのブラウザから送られてきた HTTP リクエスト行)
例)index.html に HTTP ver1.1 でリクエストの場合、”GET /index.html HTTP/1.1″
REQUEST_URI リクエストされたURI情報
例)http://hazu.jp/foo/bar.html にアクセスされた場合は “/foo/bar.html”
REQUEST_FILENAME リクエストされたファイルのサーバパス情報
例)”/home/blog/example.html”
HTTPS https (SSL) 判定
https 通信なら “on”、そうでなければ “off”

【.htaccess】mod_rewrite モジュール – その3 様々なリダイレクト利用例

mod_rewrite モジュールについて、これまでまとめたページはこちら
その1 mod_rewrite を利用したリダイレクトの基本
その2 RewiteCond ディレクティブ

mod_rewrite モジュールを利用することで、リダイレクトの様々な設定ができます。
以降の例は全て、「hazu.jp」というドメインへのアクセスがあった場合の例として記述します。

www ありなし設定

wwwあり URL を、wwwなし URL にリダイレクト、またその逆の処理を行います。
(例)「http://www.hazu.jp」⇔「http://hazu.jp」

<www なしに統一>

RewriteEngine On
RewriteCond %{HTTP_HOST} ^www\.hazu\.jp [NC]
RewriteRule ^(.*)$ http://hazu.jp/$1 [R=301,L]

1行目: “RewriteEngine On” => mod_rewrite モジュールを利用の有効化

2行目: “RewriteCond” => 書き換えの条件定義
環境変数 “HTTP_HOST” はリクエスト先のホスト名を返します。RewriteCond では、”%{HTTP_HOST}” という形で情報を読み込み、テスト文字列として扱います。
“^www\.hazu\.jp” は条件パターンです。正規表現が使われています。”^” は先頭にそれに続く文字列がある場合にマッチ。”.” がメタ文字であるため、それを普通の文字として扱うために、直前に “\” を記述しエスケープさせます。

要するに、「 “%{HTTP_HOST}” で得たホスト名 = “www.hazu.jp/~” 」かどうか、という条件を定義しています。

オプションの [NC] は、大文字小文字の区別をしないという指示をしています。

3行目:”RewriteRule” => 書き換えルールを指定
” ^(.*)$ ” => .htaccess ファイルの置かれたディレクトリの各ファイルが転送元であるという意味。
“^” は先頭にそれに続く文字列がある場合にマッチ、”(.*)” は0回以上の文字の繰り返し、” $ “は文字列の文末がマッチ。
” http://hazu.jp/$1 “=>同じファイル名で、www なしに書き換えを指示しています。
” $1 ” = ” (.*) ” を意味している後方参照です。
[R=301,L] => 301リダイレクト(恒久的な転送)後、終了。

このような流れです。

RewriteRule 条件 “^(.*)$” でファイル名取得

RewriteCond テスト文字列 “%{HTTP_HOST}” で、RewriteRule で得たファイル “^(.*)$” のホスト名を取得

RewriteCond 条件パターン “%{HTTP_HOST}” = “www.hazu.jp/~” であるかどうか検証

RewriteRule 置換文字列 RewriteCond での検証が true なら、”http://hazu.jp/~” に転送

<www ありに統一>
逆パターンです。

RewriteEngine On
RewriteCond %{HTTP_HOST} ^hazu\.jp [NC]
RewriteRule ^(.*)$ http://www.hazu.jp/$1 [R=301,L]

index.html ありなし設定

/index.html へアクセスがあった場合、/(ディレクトリ)へリダイレクトさせます。

RewriteEngine On
RewriteCond %{THE_REQUEST} ^.*/index\.html
RewriteRule ^(.*)/index\.html$ http://hazu.jp/$1 [R=301,L]

1行目: “RewriteEngine On” => mod_rewrite モジュールを利用の有効化

2行目: “RewriteCond” => 書き換えの条件定義
環境変数 “THE_REQUEST” は、ユーザのブラウザから送られる HTTP リクエスト行の情報です。”GET /index.html HTTP/1.1″ などというような内容なので、そこからどのファイルへのアクセスなのかということが分かります。
%{THE_REQUEST} でリクエスト行の情報を得て、次の条件パターン “^.*/index\.html” で、そこに”/index.html”という文字列が含まれるか検証します。

要するに、「 ユーザは “/index.html” の文字列の含まれるファイルにアクセス 」しようとしているかどうか、という条件を定義しています。

3行目:”RewriteRule” => 書き換えルールを指定
“^(.*)/index\.html$” ⇒ .htaccess ファイルの置かれたディレクトリの index.html ファイルが転送元という意味。
“^” は先頭にそれに続く文字列がある場合にマッチ、”(.*)” は0回以上の文字の繰り返し、” $ “は文字列の文末がマッチ。
” http://hazu.jp/$1 “=> 転送先はディレクトリ。
” $1 ” = ” (.*) ” を意味している後方参照です。
[R=301,L] => 301リダイレクト(恒久的な転送)後、終了。

https(SSL)へリダイレクト

http(非SSL)の URL へのアクセスを、https(SSL)の URL へリダイレクトさせます。
(当然ですが、前提として、サーバで SSL 利用可能となっている場合です。)

RewriteEngine On
RewriteCond %{HTTPS} off
RewriteRule ^(.*)$ https://hazu.jp/$1 [R=301,L]

1行目: “RewriteEngine On” => mod_rewrite モジュールを利用の有効化

2行目: “RewriteCond” => 書き換えの条件定義
環境変数 HTTPS は、https 通信なら on、http 通信なら off を返します。

なので、「“%{HTTPS}” = “off” 」かどうか、を検証しています。

3行目:”RewriteRule” => 書き換えルールを指定
” ^(.*)$ ” => .htaccess ファイルの置かれたディレクトリの各ファイルが転送元であるという意味。
“^” は先頭にそれに続く文字列がある場合にマッチ、”(.*)” は0回以上の文字の繰り返し、” $ “は文字列の文末がマッチ。
” https://hazu.jp/$1 “=> 同じファイル名で、https に書き換えを指示しています。
” $1 ” = ” (.*) ” を意味している後方参照です。
[R=301,L] => 301リダイレクト(恒久的な転送)後、終了。

特定のファイルやディレクトリを除外してリダイレクトさせたり、類似のファイル名をまとめたり、拡張子がないリクエストも表示させたり、時間や曜日によって表示させるページを振り分けたりなど、環境変数をうまく使って、様々な細かな設定ができます。

.htaccess では、コマンドの最後に空行を入れる必要があります。お忘れなく。

【.htaccess】mod_rewrite モジュール – その2 RewriteCond ディレクティブ

mod_rewrite モジュールを利用してリダイレクト方法の基本について、前回まとめました。

今回は、RewriteCond ディレクティブについてまとめます。これを利用することによって、RewriteRule の条件を更に定義することができます。
具体的によく利用されるものとしては、「wwwありなし設定」、「index.htmlありなし設定」、「https(SSL)へリダイレクト」などが行えます。

RewriteCondの基本構文

RewriteEngine On
RewriteCond テスト文字列  条件パターン  [フラグ]
RewriteRule 条件  置換文字列 [フラグ]

RewriteCond は、RewriteRule の前に、一つ以上設置できます。複数設置した場合は、フラグによって、OR 条件、AND 条件を指定できます。(省略すると AND になります。)

RewriteCond に利用できるフラグ(オプション)

フラグ 説明
[OR] 連続する RewriteCond のいずれかが true の場合に実行。省略時は、AND 条件として処理。
[NC] 条件を評価する時、大文字小文字を区別しない。

RewriteRule にも条件が記述されているわけですが、条件のマッチングから置換までの流れはこのようになります。

RewriteRule 条件

RewriteCond テスト文字列

RewriteCond 条件パターン

RewriteRule 置換文字列

RewriteRule の条件と置換の間に、RewriteCond の条件が入れ子になっているような順番となります。

RewriteCond の「テスト文字列」には「HTTP 環境変数」
RewriteCond の「条件パターン」には「演算子」が利用できます。
それぞれまとめます。

RewriteCond で利用できる HTTP 環境変数(テスト文字列)

HTTPリクエストヘッダの情報は “%{環境変数名}” と指定することで RewriteCond で利用できます。
例えば「HTTP_HOST」という環境変数は、リクエスト先のホスト名 (DNS 名) 情報を示し、” %{HTTP_HOST} ” とすると、http://www.hazu.jp/~” でアクセスがあった場合、” www.hazu.jp ” という DNS 名が返されます。

RewriteCond で利用できる主な環境変数の一覧です。

種類 環境変数名
ヘッダ環境変数 HTTP_HOST, HTTP_USER_AGENT, HTTP_REFERER, HTTP_ACCEPT
サーバー環境変数 SERVER_NAME, SERVER_ADDR, SERVER_PORT
リクエスト環境変数 EMOTE_ADDR, REMOTE_HOST, REMOTE_USER, SCRIPT_FILENAME, PATH_INFO, QUERY_STRING
日付・時刻変数 TIME_YEAR, TIME_MON, TIME_DAY, TIME_TIME_HOUR, TIME_MIN, TIME_SEC, TIME
その他 THE_REQUEST, REQUEST_URI, REQUEST_FILENAME, HTTPS

それぞれの環境変数の意味や、値の例をこちらにまとめました。
mod_rewrite モジュール – その4 HTTP 環境変数一覧

RewriteCond で利用できる演算子(条件パターン)

条件に一致するものを選び出すのに演算子、正規表現が利用できます。
RewriteCond 利用できる主な演算子の一覧です。

演算子 説明
! 否定
< テスト文字列より大きい場合は true
> テスト文字列より小さい場合は true
= テスト文字列と等しい場合は true
<= テスト文字列以上の場合は true
>= テスト文字列以下の場合は true
-d テスト文字列のディレクトリが存在する場合 true
-f テスト文字列のファイルが存在する場合 true
-s テスト文字列のファイルが存在し、サイズが0byteでない場合 true

RewriteCond における後方参照

後方参照については、前にこちらにまとめました。
後方参照

RewriteRule において、後方参照は、” $n “ と表記されますが、
RewriteCond においては、” %n “ と表されます。

二つを同時に利用できるように、別の表記となっているのだと思います。

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} ^(.*)/(.*)/index.html$
#                               ↑"%1" ↑"%2"
RewriteRule ^/blog/(.*)/(.*)$ /$1/%1/$2/%2
#                 ↑"$1" ↑"$2"   後方参照 ↑

.htaccess についてのあと、毎回言っていますが、最後に空行が必要です。お忘れなく。

【.htaccess】mod_rewrite モジュール – その1 リダイレクトの基本

mod_rewrite モジュールは、「URL の書き換え」を行うためのモジュールです。
mod_rewrite モジュールの機能を利用することで、Redirect ディレクティブと同じく、リダイレクトを行えます。mod_rewrite モジュールのリダイレクトでは、より細かな設定を行えます。

mod_rewrite モジュールを利用したリダイレクトの基本構文

mod_rewrite モジュールでリダイレクトを行うには、基本的には、RewriteEngine、RewriteBase、RewriteRule の3つのディレクティブを利用します。

RewriteEngine On
RewriteBase /
RewriteRule 転送元ファイル 転送先URL [R=301,L]

一つずつ見ていきましょう。

  • 1行目: RewriteEngine
  • mod_rewrite モジュールを有効化します。デフォルトでは “Off” になっているので、”On” にすることで利用を宣言します。

  • 2行目: RewriteBase
  • 転送先の URL の基準となるディレクトリを指定するのですが、

    ① 3行目の RewriteRule で指定する転送先の URL が相対パスの場合 ⇒ 転送元(.htaccess の置かれているディレクトリ)からみて、転送先の URL の基準となるディレクトリまでの相対パスを指定
    (省略した場合、RewriteRule ディレクティブの基準となる URL は .htaccess が置かれたディレクトリ、つまり ” RewriteBase / ” となります。)

    ② 3行目の RewriteRule で指定する転送先の URL が絶対パスの場合 ⇒ 不要

  • 3行目: RewriteRule
  • URL 書き換えのルールを指定します。

    転送元ファイル: .htaccess の置かれたディレクトリ内のファイル名となります。正規表現が使えます。

    転送先URL : 絶対パス、相対パス共に指定できますが、相対パスで指定する場合、2行目のRewriteBase で指定したディレクトリが基準となります。後方参照が利用できます。

    [R=301,L] : [ ] の中は、フラグ(RewriteRule ディレクティブの機能)を指定します。URL 書き換えに関する様々なフラグ(⇒ RewriteRule のフラグ一覧)がありますが、今回はリダイレクトを行うので、リダイレクトを指定するフラグ、” R (=リスポンスコード) ” と記述します。
    ” R=301 ” ⇒ 恒久的な移動の場合指定(”R= permanet ” と記述も可能)
    ” R=302 ” ⇒ 一時的な移動の場合指定(” R=temp ” と記述も可能)
    コードを指定しない場合、デフォルトの ” R=302 ” となります。

    複数のフラグを指定する場合は、” , ” で区切ります。” R=301 ” に続いて、URL の書き換えの終了を指示するフラグ、” L ” を記述し、後述のルールを実行させないようにします。

mod_rewrite モジュールを利用したリダイレクトの設定例

“blue.com” と、”green.com” という二つのドメインがあったとします。

以降、4つのパターンを考えてみます。

① 別サイトへ1ページのみの転送
blue.com/index.html ⇒ green.com/index.html

② サイト全体転送
blue.com ⇒ green.com (それぞれ対応するファイルへ転送)

③ サイト内一部のディレクトリを転送
blue.com/circle ⇒ green.com/square (それぞれ対応するファイルへ転送)

④ 同じサイト内で1ページ転送
blue.com/example01.html ⇒ blue.com/example02.html

すべて恒久的な移動とするので、RewriteRule のフラグは、[R=301,L] とします。

<① 別サイトへ1ページのみ転送>

RewriteEngine On
RewriteRule index\.html  http://green.com/index.html [R=301,L]

1行目: “RewriteEngine On” => mod_rewrite モジュールを利用の有効化

2行目: “RewriteRule” => 書き換えルールを指定
” index\.html ” => .htaccess ファイルの置かれた blue.com 内の index.html が転送元であるという意味
” http://green.com/index.html ” => 転送先 URL

* 転送先 URL が絶対パスで記述されているので、RewriteBase は省略
* RewriteRule ディレクティブは正規表現に対応するので、メタ文字を普通の文字として扱うには、直前に” \ “が必要です。” index.html ” は、” index\.html ” と記述。

<② サイト全体転送>

RewriteEngine On
RewriteRule (.*)$  http://green.com/$1 [R=301,L]

1行目: “RewriteEngine On” => mod_rewrite モジュールを利用の有効化

2行目: “RewriteRule” => 書き換えルールを指定
” (.*)$ ” => ” (.*) ” は0回以上の文字の繰り返し、” $ “は文字列の文末がマッチ(.htaccess ファイルの置かれた blue.com 内の それぞれのファイルが転送元であるという意味)
” http://green.com/$1 “=> 、” $1 ” = ” (.*) ” (green.com 内のそれぞれ対応する転送先 URLを意味)

* 転送先 URL が絶対パスで記述されているので、RewriteBase は省略

<③ サイト内一部のディレクトリを転送>

RewriteEngine On
RewriteRule ^circle/(.*)$  http://green.com/square/$1 [R=301,L]

1行目: “RewriteEngine On” => mod_rewrite モジュールを利用の有効化

2行目: “RewriteRule” => 書き換えルールを指定
” ^circle/(.*)$ ” => ” ^ ” は文字列先頭が一致、 ” (.*) ” は0回以上の文字の繰り返し、” $ “は文字列の文末がマッチ(.htaccess ファイルの置かれた blue.com 内、circle ディレクトリ内のそれぞれのファイルが転送元であるという意味)
” http://green.com/square/$1 “=> 、” $1 ” = ” (.*) ” (green.com 内、square ディレクトリ内のそれぞれ対応する転送先 URLを意味)

* 転送先 URL が絶対パスで記述されているので、RewriteBase は省略

<④ 同じサイト内で1ページ転送>

RewriteEngine On
RewriteBase /
RewriteRule example01\.html  example02.html [R=301,L]

1行目: “RewriteEngine On” => mod_rewrite モジュールを利用の有効化

2行目: “RewriteBase /” => 転送先の基準となる ディレクトリを指定。転送元(.htaccessの置かれたディレクトリ)と同じディレクトリ内という意味。

3行目:”RewriteRule” => 書き換えルールを指定
” example01\.html ” => .htaccess ファイルの置かれた blue.com 内の example01.html が転送元であるという意味
” example02.html ” => 2行目のRewriteBase で指定された基準となる伝送先ディレクトリ内 (blue.com) の example02.html が転送先 URL

ファイルの最終行には空行を入れる必要があります。ご注意ください!

【.htaccess】Redirect ディレクティブ

URLやドメインが変わって、旧 URL から新 URL への自動遷移に利用します。
リダイレクトは、Redirect ディレクティブ、mod_rewrite モジュールどちらでもできますが、2つの違いはこちらです。

Redirect ディレクティブ: 旧 URL から新 URL へシンプルなリダイレクトのみ。サーバのコア機能を利用するので、大概の場合利用できます。
mod_rewrite モジュール: リダイレクトの細かな設定が出来ます。サーバの拡張機能を利用するので、サーバによっては利用できないこともあります。(とは言っても、ほとんどは利用できると思いますが)

今回は、Redirect ディレクティブについてまとめます。

Redirect の基本構文

Redirect ディレクティブで、URL を自動転送する基本的な構文です。

Redirect [status] URL-path URL

左から一つずつ見ていきましょう。

  • Redirect
  • 旧 URL から新 URL へリダイレクトの宣言です。

  • [status]
  • 後述しますが、このオプションを指定することで、このリダイレクトが恒久的なものなのか、一時的なものなのか、など、HTTP ステイタスコードを返すことができます。指定がないと、デフォルトの “temp” となります。

  • URL-path
  • 転送元の URL パスを指定します。http: などで始まる絶対 URL ではなくて、/ で始まるルートパスです。.htaccess ファイルを置くディレクトリが、トップディレクトリとなります。

  • URL
  • 転送先の URL を指定します。http: などで始まる絶対 URL を指定します。

Redirect ディレクティブの status 引数一覧です。

説明
permanent 恒久的な移動の場合指定。HTTP ステータス:301
temp 一時的な移動の場合指定。HTTP ステータス:302
seeother 他のもので置き換えられた場合指定。HTTP ステータス:303
gone 恒久的に削除された場合指定。HTTP ステータス:410

Redirect 設定例

“blue.com” という旧ドメインから、”green.com” という新ドメインへ、サイトを恒久的に引越ししたとします。

恒久的な移動なので、[statas] は、”permanet” を指定します。
こうすることで、検索エンジンに、旧サイトの評価が、新サイトへと受け継がれるので、恒久的な引越しである場合、SEO 的にも重要です。

blue.com/ 以下のファイルは、それぞれ green.com/ 以下の対応するファイルへ転送されます。
blue.com/index.html ⇒ green.com/index.html
blue.com/example01.html ⇒ green.com/example01.html

しかしながら、blue.com/example02.html を転送しようとすると、green.com/ 以下には example02.html という対応するファイルがありません。この場合は、エラー(Error 404)となります。

このようなエラーに対応するために、ErrorDocument ディレクティブで、動作指定をするのですが、後日まとめます。

<サイト全体転送>
構文はこのようになります。

Redirect permanent / http://green.com/

左から一つずつ見ていきましょう。

“Redirect” => リダイレクトを行う宣言
“permanent” => 恒久的な移動
” / ” => 転送元の URL パス(.htaccess ファイルは、blue.com の直下に置かれているので、blue.com 以下のファイル全てに有効)
“http://green.com” => 転送先の絶対 URL

<一部のディレクトリ転送>
blue.com 以下の circle ディレクトリのみを、green.com 以下の square ディレクトリに転送したい場合の構文はこうなります。

Redirect permanent /circle/ http://green.com/square/

<特定のページ転送>
blue.com 以下の example01.html のみを、green.com 以下の example01.html に転送したい場合の構文はこうなります。

Redirect permanent /example01.html http://green.com/example01.html

RedirectMatch ディレクティブ

Redirect と同じ機能ですが、正規表現を用いて転送元の URL パスのマッチングを行います。

正規表現、後方参照についてはこちらを参照
正規表現の基本
後方参照

RedirectMatch [status] regex URL

左から一つずつ見ていきましょう。

  • RedirectMatch
  • 旧 URL から新 URL へ正規表現を使うリダイレクトの宣言です。

  • [status]
  • Redirect と同じ引数を指定できます。指定がない場合、デフォルトの “temp” となります。

  • regex
  • 転送元の URL パスを、正規表現を使って指定します。

  • URL
  • 転送先の URL を指定します。後方参照を利用できます。

上の図で、blue.com 以下の html ファイルのみ、green.com 以下の対応する html ファイルへ転送する場合の例です。

RedirectMatch permanent /(.+)(\.html)$ https://green.com/$1$2

左から一つずつ見ていきましょう。

“RedirectMatch” => 正規表現を使ったリダイレクトを行う宣言

“permanent” => 恒久的な移動

” /(.+)(\.html)$ ” => 正規表現を使った転送元の URL パス
(.+) = 1字以上の任意の文字列、(\.html) = “.html”、$ = 文字列の文末がマッチ

“http://green.com/$1$2” => 後方参照を使った転送先の絶対 URL
$1 = (.+)、$2 = (\.html)

最後になりましたが、ファイルの最終行には空行を入れる必要があります。
お忘れなく!