Alihkan semua ke index.php menggunakan htaccess


131

Saya sedang menulis kerangka kerja MVC-ish berbasis PHP sederhana. Saya ingin framework ini dapat diinstal di direktori mana pun.

Skrip PHP saya mengambil uri permintaan dan memecahnya menjadi beberapa segmen. Itu membuat segmen 1 sebagai pengontrol dan segmen 2 menjadi aksi. Ini akan baik-baik saja ketika saya melakukan ini:

http://www.example.com/mvc/module/test/

Ini akan menuju ke pengontrol modul dan metode tertentu. Sekarang saya memiliki pengontrol default, pengontrol rumah, yang ada di folder rumah.

Sekarang ketika saya mengakses folder ini secara langsung http://www.example.com/mvc/home/ Ini akan menampilkan 403 terlarang, karena folder ini memang ada, sebagai gantinya juga harus kembali ke http://www.example.com /mvc/index.php

Jika saya akan menginstal kerangka kerja di folder yang berbeda, katakanlah kerangka folder itu harus dialihkan kembali ke http://www.example.com/framework/index.php

Saya ingin mengarahkan setiap folder dan file php kembali ke index.php, membiarkan yang lainnya seperti itu.

Masalah pertama saya yang saya temui adalah tidak pernah dialihkan ke folder yang benar, selalu ke folder root domain.

Inilah yang saya coba:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-d
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule . index.php [L]

Hanya untuk memastikan saya memahami pertanyaan Anda dengan benar: Anda ingin mengarahkan setiap permintaan ke root index.php atau Anda ingin mengarahkan ulang setiap permintaan yang dibuat ke folder tertentu itu index.php ?
Technoh

Ke folder tempat file htaccess berada, direktori root framework. Dalam contoh saya, kembali ke direktori mvc
David Ericsson

Jawaban:


259

Aturan penulisan ulang Anda terlihat hampir oke.

Pertama-tama pastikan bahwa .htaccessfile Anda ada di root dokumen Anda (tempat yang sama dengan index.php) atau itu hanya akan mempengaruhi sub-folder di dalamnya (dan sub-folder di dalamnya - secara rekursif).

Selanjutnya buat sedikit perubahan pada aturan Anda sehingga terlihat seperti ini:

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ /index.php?path=$1 [NC,L,QSA]

Pada saat Anda hanya cocok pada .yang satu contoh dari karakter apapun, Anda memerlukan setidaknya .*untuk mencocokkan sejumlah contoh karakter apapun.

The $_GET['path']variabel akan berisi struktur direktori palsu, sehingga /mvc/module/testmisalnya, yang kemudian dapat digunakan dalam index.php untuk menentukan Pengendali dan tindakan Anda ingin melakukan.


Jika Anda ingin seluruh shebang dipasang di sub-direktori, seperti /mvc/atau /framework/cara paling tidak rumit untuk melakukannya adalah dengan mengubah sedikit aturan penulisan ulang untuk memperhitungkannya.

RewriteRule ^(.*)$ /mvc/index.php?path=$1 [NC,L,QSA]

Dan pastikan bahwa Anda index.phpada di folder itu sementara .htaccessfile ada di root dokumen.


Alternatif untuk$_GET['path'] (diperbarui Feb '18 dan Jan '19)

Sebenarnya tidak perlu (atau bahkan umum sekarang) untuk menyetel jalur sebagai $_GETvariabel, banyak kerangka kerja akan mengandalkan $_SERVER['REQUEST_URI']untuk mengambil informasi yang sama - biasanya untuk menentukan Pengontrol mana yang akan digunakan - tetapi prinsipnya persis sama.

Ini RewriteRulesedikit menyederhanakan karena Anda tidak perlu membuat parameter jalur (yang berarti orisinal OP sekarang RewriteRule akan berfungsi):

RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^.*$ /index.php [L,QSA]

Namun , aturan tentang menginstal di sub-direktori masih berlaku, mis

RewriteRule ^.*$ /mvc/index.php [L,QSA]



Bendera:

NC = Tidak Ada Kasus (tidak peka huruf besar kecil, tidak terlalu diperlukan karena tidak ada karakter dalam pola)

L = Terakhir (ini akan berhenti menulis ulang setelah Penulisan Ulang ini jadi pastikan itu adalah hal terakhir dalam daftar penulisan ulang Anda)

QSA= Query String Append, kalau-kalau Anda memiliki sesuatu seperti ?like=penguinsdi akhir yang ingin Anda simpan dan teruskan ke index.php.


1
seharusnya index.php? path = $ 1
Jacek Pietal

1
@Prozi tidak jika Anda berada di sub-direktori dan index.php ada di docroot, maka Anda perlu memimpin / - dengan Options +Indexesdan index.php disertakan di dalamnya DirectoryIndexAnda dapat meninggalkan index.php sama sekali dan hanya menggunakan /?path=$1Ini berlaku ketika menulis ulang melalui .htaccess daripada menggunakan <Directory>direktif jenis httpd-vhosts.conf .
CD001

Jika Anda menggunakannya dan mengandalkan $ _GET ['path'] Anda akan mendapat masalah jika pindah ke server nginx ...
barell

3
Pos yang bagus! Perlu diperhatikan bahwa pengguna dapat menimpa $_GET['path']jika mereka menambahkan path=whateverke URL.
rybo111

1
@Liviuge - benar, tetapi pada awalnya saya melewati seluruh jalur $_GETsehingga akan diperlukan (.*)... itu lucu tetapi RewriteRule yang digunakan OP 6 tahun yang lalu tidak berfungsi untuk mereka saat itu - tetapi dengan cara arsitektur MVC memiliki berevolusi dengan PHP (seperti yang saya masukkan di Update Feb 18 bit) sekarang akan ... menebak mereka lebih cepat dari waktu mereka :) Masih membutuhkan jalur yang benar ke /mvc/direktori tentunya.
CD001

28

Untuk mengarahkan semua yang tidak ada index.php, Anda juga bisa menggunakan FallBackResourcedirektif

FallbackResource /index.php

Ini berfungsi sama seperti ErrorDocument, ketika Anda meminta jalur atau file yang tidak ada di server, perintah diam-diam menguraikan permintaan untukindex.php .

Jika Anda ingin mengalihkan semuanya ( including existant files or folders) ke index.php, Anda dapat menggunakan sesuatu seperti berikut:

RewriteEngine on

RewriteRule ^((?!index\.php).+)$ /index.php [L]

Perhatikan bahwa pola ^((?!index\.php).+)$ cocok dengan uri mana pun kecuali index.phpkami telah mengecualikan jalur tujuan untuk mencegah kesalahan perulangan tak terbatas.


Tetapi Anda juga mungkin ingin menggunakan:DirectoryIndex index.php
Shao

1
Gunakan *sebagai ganti +pola jika Anda juga ingin mengalihkan jalur root itu sendiri.
Mir-Ismaili

15

Anda dapat menggunakan sesuatu seperti ini:

RewriteEngine on
RewriteRule ^.+$ /index.php [L]

Ini akan mengarahkan setiap kueri ke index.php direktori root. Perhatikan bahwa ini juga akan mengarahkan kueri untuk file yang ada, seperti gambar, file javascript atau lembar gaya.


1
Solusi ini hampir berhasil untuk saya. Saya terus mendapatkan "AH00124: Permintaan melebihi batas 10 pengalihan internal". Saya menambahkan "RewriteRule ^ index \ .php - [L]" sebelumnya dan berfungsi dengan sempurna!
Fredster

11

Ada satu "trik" untuk masalah ini yang cocok untuk semua skenario, solusi yang sangat jelas sehingga Anda harus mencobanya untuk meyakini bahwa ini benar-benar berfungsi ... :)

Ini dia...

<IfModule mod_rewrite.c>

   RewriteEngine On

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

</IfModule>

Pada dasarnya, Anda meminta MOD_REWRITE untuk meneruskan ke index.phppermintaan URI selalu ketika file ada DAN selalu ketika file yang diminta tidak ada !

Saat menyelidiki kode sumber MOD-REWRITE untuk memahami cara kerjanya, saya menyadari bahwa semua pemeriksaannya selalu terjadi setelah verifikasi apakah file yang direferensikan ada atau tidak. Baru setelah RegExitu diproses. Meskipun URI Anda mengarah ke folder, Apache akan memberlakukan pemeriksaan untuk file indeks tercantum dalam file konfigurasinya.

Berdasarkan penemuan sederhana itu, ternyata validasi file sederhana akan cukup untuk semua kemungkinan panggilan , sejauh kita mengetuk dua kali pemeriksaan keberadaan file dan mengarahkan kedua hasil ke titik akhir yang sama, mencakup 100% kemungkinan.

PENTING: Perhatikan bahwa tidak ada " / " di index.php. Secara default, MOD_REWRITE akan menggunakan folder yang ditetapkan sebagai "folder dasar" untuk penerusan. Keindahannya adalah bahwa ini tidak perlu menjadi "folder root" dari situs, memungkinkan solusi ini bekerja untuk localhost/dan / atau subfolder yang Anda terapkan.

Pada akhirnya, beberapa solusi lain yang saya uji sebelumnya (yang tampaknya berfungsi dengan baik) mematahkan kemampuan PHP untuk "memerlukan" file melalui jalur relatifnya, yang sangat mengecewakan. Hati-hati.

Beberapa orang mungkin mengatakan ini adalah solusi yang tidak elegan. Mungkin sebenarnya, tetapi sejauh pengujian, dalam beberapa skenario, beberapa server, beberapa versi Apache yang berbeda, dll., Solusi ini bekerja 100% pada semua kasus!


Terima kasih, ini memperbaiki masalah saya di mana FallbackResource index.phpgaris berfungsi pada Mac (OS X 10.11) tetapi tidak di bawah Centos 7.5. Namun: ini RewriteRulejuga menulis ulang lokasi file CSS misalnya. Karena saya hanya perlu mengalihkan file PHP, saya mengubah aturan menjadi RewriteRule ^(.*)php$ index.php [L,QSA]. YMMV.
Laryx Decidua

1
Saya senang ini membantu. Anda benar, ini menargetkan SEMUA file karena pertanyaannya adalah: " Alihkan semua ke index.php menggunakan htaccess ". Ada cara lain yang lebih elegan untuk mengalihkan file PHP saja, seperti RewriteRule ^(.*)\.php$ index.php [L,NE,QSA](yang tidak memerlukan kondisi untuk berfungsi). Sekarang, bagaimanapun, saya menggunakan aturan yang lebih murah:, RewriteRule ^.+$ index.php [L,NE,QSA]yang dapat digabungkan dengan kondisi RewriteCond %{REQUEST_FILENAME} !-fdan RewriteCond %{REQUEST_FILENAME} !-d, atau bahkan dengan RewriteCond $1 !^(index\.php|assets|robots\.txt|favicon\.ico)benar-benar spesifik.
Julio Marchi


0

Setelah melakukan jangan lupa ganti anchor tag nya, home

Contoh:

.htacces file
RewriteEngine On

RewriteRule ^about/$ /about.php

PHP file:
<a href="about/"> about</a>

Ingatlah selalu untuk mengubah tag <a>.
Collins Benson

2
Apa yang dimaksud dengan Setelah melakukan jangan ubah tag Anda, beranda ?
Enrico Maria De Angelis

0

berjaga-jaga jika Anda masih bertanya-tanya bagaimana cara mengarahkan semua permintaan baik jika direktori ada (untuk folder dan file kerangka inti) ke penangan indeks kerangka kerja, setelah beberapa upaya kesalahan / sukses baru saja saya perhatikan saya hanya perlu mengubah RewriteCond di .htaccess mengajukan

RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d

kondisi di atas menyatakan "file tidak ditemukan" dan "direktori tidak ditemukan", ok, bagaimana jika hanya menghapus baris "tidak ditemukan" (! -d), dan diakhiri dengan sesuatu seperti di bawah ini:

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

Ini bekerja untuk saya seperti pesona

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.