web-dev-qa-db-ja.com

PHPを使用したURLの書き換え

次のようなURLがあります。

url.com/picture.php?id=51

そのURLを次のように変換します。

picture.php/Some-text-goes-here/51

私はWordPressが同じことをすると思います。

どうやってPHPでフレンドリーなURLを作るのですか?

128
Jazerix

picture.phpのルートを変更したいだけなら.htaccessに書き換えルールを追加するのがあなたのニーズを満たしますが、もしあなたがWordpressのようにURL書き換えをしたいのなら、PHPが方法です。これが最初の簡単な例です。

フォルダ構成

ルートフォルダには.htaccessindex.phpの2つのファイルが必要です。残りの.phpファイルはinc/のように別のフォルダに配置するのが良いでしょう。

root/
  inc/
  .htaccess
  index.php

。htaccess

RewriteEngine On
RewriteRule ^inc/.*$ index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]

このファイルには4つのディレクティブがあります。

  1. RewriteEngine - 書き換えエンジンを有効にする
  2. RewriteRule - inc/フォルダー内のすべてのファイルへのアクセスを拒否し、そのフォルダーへの呼び出しをindex.phpにリダイレクトする
  3. RewriteCond - 他のすべてのファイル(画像、CSS、スクリプトなど)への直接アクセスを許可します
  4. RewriteRule - 何か他のものをindex.phpにリダイレクトする

index.php

すべてがindex.phpにリダイレクトされるようになったため、URLが正しいか、すべてのパラメータがあるか、およびパラメータの種類が正しいかが判断されます。

URLをテストするには、一連の規則が必要です。そのための最適なツールは正規表現です。正規表現を使うことで、一撃で二匹のハエを殺すでしょう。このテストに合格するには、許可された文字でテストされるすべての必須パラメータが必要です。これがルールの例です。

$rules = array( 
    'picture'   => "/picture/(?'text'[^/]+)/(?'id'\d+)",    // '/picture/some-text/51'
    'album'     => "/album/(?'album'[\w\-]+)",              // '/album/album-slug'
    'category'  => "/category/(?'category'[\w\-]+)",        // '/category/category-slug'
    'page'      => "/page/(?'page'about|contact)",          // '/page/about', '/page/contact'
    'post'      => "/(?'post'[\w\-]+)",                     // '/post-slug'
    'home'      => "/"                                      // '/'
);

次にリクエストuriを準備します。

$uri = rtrim( dirname($_SERVER["SCRIPT_NAME"]), '/' );
$uri = '/' . trim( str_replace( $uri, '', $_SERVER['REQUEST_URI'] ), '/' );
$uri = urldecode( $uri );

Uriというリクエストが届いたので、最後のステップは正規表現ルールでuriをテストすることです。

foreach ( $rules as $action => $rule ) {
    if ( preg_match( '~^'.$rule.'$~i', $uri, $params ) ) {
        /* now you know the action and parameters so you can 
         * include appropriate template file ( or proceed in some other way )
         */
    }
}

正規表現では名前付きサブパターンを使用しているため、PHPが$params配列を埋めるのとほぼ同じように、$_GET配列を埋めることになります。ただし、動的URLを使用している場合は、パラメータをチェックせずに$_GET配列が設定されます。

 /picture/some+text/51

配列
(
 [0] =>/picture/some text/51 
 ] [text] =>いくつかのテキスト
 [1] =>いくつかのテキスト
 [id] => 51 
 [2] => 51 
)[ picture.php?text = some + text&id = 51 
 
配列
(
 [text] =>いくつかのテキスト[ [id] => 51 
)

これらの数行のコードと正規表現の基本的な知識は、しっかりしたルーティングシステムを構築するのに十分です。

完全な情報源

define( 'INCLUDE_DIR', dirname( __FILE__ ) . '/inc/' );

$rules = array( 
    'picture'   => "/picture/(?'text'[^/]+)/(?'id'\d+)",    // '/picture/some-text/51'
    'album'     => "/album/(?'album'[\w\-]+)",              // '/album/album-slug'
    'category'  => "/category/(?'category'[\w\-]+)",        // '/category/category-slug'
    'page'      => "/page/(?'page'about|contact)",          // '/page/about', '/page/contact'
    'post'      => "/(?'post'[\w\-]+)",                     // '/post-slug'
    'home'      => "/"                                      // '/'
);

$uri = rtrim( dirname($_SERVER["SCRIPT_NAME"]), '/' );
$uri = '/' . trim( str_replace( $uri, '', $_SERVER['REQUEST_URI'] ), '/' );
$uri = urldecode( $uri );

foreach ( $rules as $action => $rule ) {
    if ( preg_match( '~^'.$rule.'$~i', $uri, $params ) ) {
        /* now you know the action and parameters so you can 
         * include appropriate template file ( or proceed in some other way )
         */
        include( INCLUDE_DIR . $action . '.php' );

        // exit to avoid the 404 message 
        exit();
    }
}

// nothing is found so handle the 404 error
include( INCLUDE_DIR . '404.php' );
54
Danijel

これはほとんど全てindex.phpに転送する.htaccessファイルです。

# if a directory or a file exists, use it directly
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-l
RewriteCond %{REQUEST_URI} !-l
RewriteCond %{REQUEST_FILENAME} !\.(ico|css|png|jpg|gif|js)$ [NC]
# otherwise forward it to index.php
RewriteRule . index.php

それからあなた次第です$ _SERVER ["REQUEST_URI"]をパースしてpicture.phpまたは何でもにルーティングします

5
Luca Rocchi

PHPはあなたが探しているものではない、チェックアウト mod_rewrite

3
rauchmelder

すでに回答済みですが、作者の意図はフロントコントローラタイプのアプリを作成することですが、私は質問のために文字通りのルールを投稿しています。誰かが同じ問題を抱えている場合。

RewriteEngine On
RewriteRule ^([^/]+)/([^/]+)/([\d]+)$ $1?id=$3 [L]

上記はurl picture.php/Some-text-goes-here/51で動作するはずです。リダイレクトアプリとしてindex.phpを使用せずに。

1
Abhishek Gurjar