Przepisywanie adresów URL za pomocą PHP
Mam URL, który wygląda tak:
url.com/picture.php?id=51
Jak mam przerobić ten adres URL na:
picture.php/Some-text-goes-here/51
Myślę, że WordPress robi to samo.
Jak zrobić przyjazne adresy URL w PHP?
5 answers
Możesz zasadniczo zrobić to na dwa sposoby:
The .htaccess route with mod_rewrite
Dodaj plik o nazwie .htaccess
w folderze głównym i dodaj coś takiego:
RewriteEngine on
RewriteRule ^/?Some-text-goes-here/([0-9]+)$ /picture.php?id=$1
To powie Apache, aby włączył mod_rewrite dla tego folderu, a jeśli zostanie zapytany o adres URL pasujący do wyrażenia regularnego, przepisuje go wewnętrznie do tego, co chcesz, bez tego, że użytkownik końcowy go zobaczy. Proste, ale nieelastyczne, więc jeśli potrzebujesz więcej mocy: {]}
Put the podążam za tobą .zamiast tego htaccess: (zwróć uwagę na ukośnik wiodący) Spowoduje to uruchomienie Tak robią duże witryny i systemy CMS, ponieważ pozwala to na znacznie większą elastyczność w analizowaniu adresów URL, adresów URL zależnych od konfiguracji i bazy danych itp. W przypadku sporadycznego użycia reguły przepisywania na twardo w Trasa PHP
FallbackResource /index.php
index.php
dla wszystkich plików, których normalnie nie może znaleźć w Twojej witrynie. Tam możesz na przykład: $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();
}
.htaccess
będą dobrze działać.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2018-02-19 12:22:35
Jeśli chcesz tylko zmienić trasę dla picture.php
to dodanie reguły przepisywania w .htaccess
będzie służyć twoim potrzebom, ale jeśli chcesz przepisać adres URL tak jak w WordPressie, PHP jest drogą. Oto prosty przykład na początek.
Struktura folderów
Są dwa pliki, które są potrzebne w folderze głównym, .htaccess
i index.php
, i dobrze byłoby umieścić resztę plików .php
w osobnym folderze, jak inc/
.
root/
inc/
.htaccess
index.php
.htaccess
RewriteEngine On
RewriteRule ^inc/.*$ index.php
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*)$ index.php [QSA,L]
Ten plik ma cztery dyrektywy:
-
RewriteEngine
- włącz silnik przepisywania -
RewriteRule
- deny access to all files ininc/
folder, redirect any call to that folder toindex.php
-
RewriteCond
- umożliwiają bezpośredni dostęp do wszystkich innych plików (takich jak obrazy, css lub skrypty ) -
RewriteRule
- przekieruj cokolwiek innego naindex.php
Indeks.php
Ponieważ wszystko jest teraz Przekierowano do indeksu.php, zostanie ustalone, czy adres url jest poprawny, wszystkie parametry są obecne i czy typ parametrów jest poprawny.
Aby przetestować url musimy mieć zestaw reguł, a najlepszym narzędziem do tego jest wyrażenie regularne. Używając wyrażeń regularnych zabijemy dwie muchy jednym ciosem. Url, aby przejść ten test musi mieć wszystkie wymagane parametry, które są testowane na dozwolonych znaków. Oto kilka przykładów zasad.
$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' => "/" // '/'
);
Następnie należy przygotować URI żądania.
$uri = rtrim( dirname($_SERVER["SCRIPT_NAME"]), '/' );
$uri = '/' . trim( str_replace( $uri, '', $_SERVER['REQUEST_URI'] ), '/' );
$uri = urldecode( $uri );
Teraz, gdy mamy URI żądania, ostatnim krokiem jest przetestowanie uri na zasadach wyrażeń regularnych.
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 )
*/
}
}
Pomyślne dopasowanie, ponieważ używamy nazwanych podpatternów w regex, wypełni tablicę $params
prawie tak samo jak PHP wypełnia tablicę $_GET
. Jednak przy użyciu dynamicznego adresu url tablica $_GET
jest wypełniana bez sprawdzania parametrów.
/picture/some+text/51 Array ( [0] => /picture/some text/51 [text] => some text [1] => some text [id] => 51 [2] => 51 ) picture.php?text=some+text&id=51 Array ( [text] => some text [id] => 51 )
Te kilka linijek kodu i podstawowa znajomość wyrażeń regularnych wystarczy, aby zacząć budować solidny system routingu.
Complete source
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' );
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-01-02 08:47:18
To jest an .plik htaccess, który przekazuje prawie wszystkie do indeksu.php
# 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
Następnie należy parse $_SERVER ["REQUEST_URI"] i route to picture.php lub cokolwiek
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-05 21:01:45
PHP nie jest tym, czego szukasz, sprawdź mod_rewrite
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-05 20:47:09
Chociaż już odpowiedział, a intencją autora jest stworzenie front controller type app, ale zamieszczam dosłowną regułę dla zadanego problemu. jeśli ktoś ma problem z tym samym.
RewriteEngine On
RewriteRule ^([^/]+)/([^/]+)/([\d]+)$ $1?id=$3 [L]
Powyżej powinno działać dla url picture.php/Some-text-goes-here/51
. bez użycia indeksu.php jako aplikacja przekierowująca.
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-04-27 06:44:23