[php] PHP로 URL 재 작성

다음과 같은 URL이 있습니다.

url.com/picture.php?id=51

해당 URL을 다음으로 변환하는 방법은 무엇입니까?

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

워드 프레스도 마찬가지라고 생각합니다.

PHP에서 친숙한 URL을 만들려면 어떻게해야합니까?



답변

기본적으로이 두 가지 방법으로 수행 할 수 있습니다.

mod_rewrite를 사용한 .htaccess 경로

.htaccess루트 폴더에 있는 파일을 추가하고 다음과 같이 추가하십시오.

RewriteEngine on
RewriteRule ^/?Some-text-goes-here/([0-9]+)$ /picture.php?id=$1

이것은 아파치에게이 폴더에 대해 mod_rewrite를 활성화하도록 지시하고, 정규식과 일치하는 URL을 요청 받으면 최종 사용자가 보지 않고 원하는대로 내부적 으로 다시 씁니다 . 쉽고 유연하지 않으므로 더 많은 전력이 필요한 경우 :

PHP 경로

대신 .htaccess에 다음을 넣으십시오. (슬래시를 주목하십시오)

FallbackResource /index.php

이것은 index.php일반적으로 귀하의 사이트에서 찾을 수없는 모든 파일에 대해 실행하도록 지시합니다 . 거기에서 예를 들어 :

$path = ltrim($_SERVER['REQUEST_URI'], '/');    // Trim leading slash(es)
$elements = explode('/', $path);                // Split path on slashes
if(empty($elements[0])) {                       // No path elements means home
    ShowHomepage();
} else switch(array_shift($elements))             // Pop off first item and switch
{
    case 'Some-text-goes-here':
        ShowPicture($elements); // passes rest of parameters to internal function
        break;
    case 'more':
        ...
    default:
        header('HTTP/1.1 404 Not Found');
        Show404Error();
}

URL, 구성 및 데이터베이스 종속 URL 등을 구문 분석하는 데 훨씬 더 많은 유연성을 허용하기 때문에 이것이 큰 사이트와 CMS 시스템에서 수행하는 방식 .htaccess입니다.


답변

경로를 변경하려는 경우 picture.php다시 쓰기 규칙을 추가하면 .htaccess요구 사항을 충족시킬 수 있지만 WordPress에서와 같이 URL을 다시 작성하려면 PHP가 좋습니다. 여기에 간단한 예제가 있습니다.

폴더 구조

이 루트 폴더에 필요한 두 개의 파일이있다, .htaccess그리고 index.php,의 나머지 배치하는 것이 좋을 것 .php처럼, 별도의 폴더에있는 파일을 inc/.

root/
  inc/
  .htaccess
  index.php

.htaccess

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

이 파일에는 네 가지 지시문이 있습니다.

  1. RewriteEngine -재 작성 엔진 사용
  2. RewriteRuleinc/폴더의 모든 파일에 대한 액세스를 거부 하고 해당 폴더에 대한 호출을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 )
         */
    }
}

성공적인 일치는 정규 표현식에서 명명 된 하위 패턴을 사용하기 $params때문에 PHP가 $_GET배열을 채우는 것과 거의 동일하게 배열을 채 웁니다 . 그러나 동적 URL을 사용하는 $_GET경우 매개 변수를 확인하지 않고 배열이 채워집니다.

    / picture / some + text / 51

    정렬
    (
        [0] => / picture / 일부 텍스트 / 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' );


답변

이것은 거의 모든 것을 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 또는 무엇이든 라우팅하십시오.


답변

PHP는 당신이 찾고있는 것이 아닙니다, mod_rewrite를 확인하십시오


답변

이미 대답했지만 저자의 의도는 프론트 컨트롤러 유형 앱을 만드는 것이지만 문제가있는 문제에 대한 리터럴 규칙을 게시하고 있습니다. 누군가가 같은 문제를 겪고 있다면.

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

위의 url 작동합니다 picture.php/Some-text-goes-here/51. index.php를 리디렉션 앱으로 사용하지 않습니다.


답변