Edited at

htaccessとPHPで日本語のURLに対応する方法

More than 1 year has passed since last update.

URLを日本語に対応させる方法を記述しました。

5分で理解できるように意識して書きました。

処理も簡潔に書いてあります。

このようなURLを作ることがこの記事の目的です。

https://qiita.com/きーたの記事


仕組み

1, URLの文字と同じファイルやディレクトリが無かったら全てarticle.phpに飛ばす。

2, article.phpで入力された文字を配列から検索。

3, 同じ文字があったら、記事表示、無かったら404を表示


使うファイル

・article.php

・.htaccess

この二つのファイルを作成してください。


.htaccess

.htaccessファイルに以下のように記述します。

<IfModule mod_rewrite.c>

RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ article.php?requestname=$1 [L]
</IfModule>


.htaccessの説明

書き換え機能をONにする

RewriteEngine On


!-fは、すでにファイルがあったら書き換えを実行しない。

(存在するファイルをそのまま表示する)

RewriteCond %{REQUEST_FILENAME} !-f


!-dは、すでにディレクトリがあったら書き換えを実行しない。

(存在するディレクトリをそのまま表示する)

RewriteCond %{REQUEST_FILENAME} !-d


文字があったらarticle.phpに飛ばす。

requestnameパラメータに、入力された値を代入。

RewriteRule ^(.)$ article.php?requestname=$1 [L]


下の正規表現を使用しています。

.とは任意の文字を表します。

*とは一つ前の文字の0回以上の繰り返しを表します。

()で、括弧内の文字をグループ化します。

^(.)$


article.php

article.phpの中にはこのように記述します!

入力された文字を配列から検索して、IDを取得しています!

<?php

//データベースを想定したテスト用配列
$databaseInfo = [
[
"id"=>1,
"file_name"=>"記事"
],
[
"id"=>2,
"file_name"=>"ぎっとはぶ"
],
[
"id"=>3,
"file_name"=>"きーた"
]
];

//requestnameの値を変数に格納
if(!empty($_GET["requestname"])){
$requestName = htmlspecialchars($_GET["requestname"]);
}else{
header("HTTP/1.0 404 Not Found");
exit(0);
}

//同じ文字がないか検索する
$urlExist = false;
$ArticleData = array();
foreach($databaseInfo as $val){
if($val["file_name"] == $requestName){
$urlExist = true;
$ArticleData = $val;
break;
}
}

//存在したら記事の内容を表示
//存在しなかったら404を表示
if($urlExist){
echo "データベースからIdが".$ArticleData["id"]."の記事を表示する";
}else{
header("HTTP/1.0 404 Not Found");
exit(0);
}



これで完了です。


DEMO

URLに「きーた」という日本語を入力して見ます!

スクリーンショット 2016-12-06 8.46.20.png

3というIDが取得できました!

実際のデータベースの情報もこれと同じように実装できます!


結論

・.htaccessで同じファイルに飛ばすことができる。

・.htaccessでファイルやディレクトがあったら書き換えを行わないという記述ができる。

・URLの文字をデータベースから検索して記事を表示する。

・header("HTTP/1.0 404 Not Found");でヘッダ情報を404にできる。

自分は昔はURLの日本語対応を実装できなかったが、改めて行ったら一瞬で実装できた。