Htaccess kullanarak tümünü index.php'ye yönlendirin


131

Basit bir PHP tabanlı MVC-ish çerçevesi yazıyorum. Bu çerçevenin herhangi bir dizine kurulabilmesini istiyorum.

PHP betiğim istek uri'sini alır ve onu segmentlere ayırır. Segment 1'i kontrolör ve segment 2'yi eylem yapar. Bunu yaptığımda her şey yolunda gidiyor:

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

Belirli modül denetleyicisine ve yöntemine gidecektir. Şimdi varsayılan bir denetleyicim var, ana klasörde bulunan ev denetleyicisi.

Şimdi bu klasöre doğrudan eriştiğimde http://www.example.com/mvc/home/ Bu klasör var olduğu için yasak 403 gösterecek, bunun yerine http://www.example.com adresine de dönmesi gerekiyor /mvc/index.php

Çerçeveyi farklı bir klasöre kurmuş olsaydım, klasör çerçevesinin http://www.example.com/framework/index.php adresine geri yönlendirilmesi gerektiğini varsayalım.

Her klasörü ve php dosyasını tekrar index.php'ye yönlendirmek istiyorum, geri kalan her şeyi olduğu gibi bırakıyorum.

Karşılaştığım ilk sorun, asla doğru klasöre, her zaman etki alanı kök klasörüne yönlendirmemesiydi.

Denediğim şey buydu:

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

Sorunuzu doğru anladığımdan emin olmak için: her isteği köke index.php yönlendirmek mi istiyorsunuz yoksa yapılan her isteği o belirli klasöre index.php mi yeniden yönlendirmek istiyorsunuz ?
Technoh

Htaccess dosyasının bulunduğu klasöre, çerçeve kök dizini. Örneğimde mvc dizinine geri dönün
David Ericsson

Yanıtlar:


259

Yeniden yazma kuralınız neredeyse sorunsuz görünüyor.

Öncelikle, .htaccessdosyanızın belge kökünüzde (ile aynı yerde index.php) olduğundan emin olun veya yalnızca içinde bulunduğu alt klasörü (ve içindeki tüm alt klasörleri - özyinelemeli olarak) etkiler.

Ardından, aşağıdaki gibi görünmesi için kuralınızda küçük bir değişiklik yapın:

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

Şu anda herhangi bir karakterin .hangisinin bir örneği olduğunu eşleştirdiğiniz anda , en azından .*herhangi bir karakterin herhangi bir sayıda örneğini eşleştirmeniz gerekir .

$_GET['path']Değişken yüzden, sahte dizin yapısını içerecek /mvc/module/testsonra belirlemek için index.php kullanabilirsiniz Örneğin, için Kontrolörü gerçekleştirmek istediğiniz ve eylemler.


Aşağıdaki gibi bir alt dizinde yüklü bütün mesele, isterseniz /mvc/veya /framework/bu hesaba katmalı hafifçe yeniden yazma kuralını değiştirmektir bunu yapmak için en az karmaşık bir yol.

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

Ve dosya, belge kök dizinindeyken index.phpo klasörde bulunduğunuzdan emin olun .htaccess.


Alternatif$_GET['path'] (Şubat '18 ve Ocak '19 güncellendi)

Yolu bir $_GETdeğişken olarak ayarlamak aslında gerekli değil (hatta şimdi bile yaygın) , birçok çerçeve $_SERVER['REQUEST_URI']aynı bilgileri almak için güvenecek - normalde hangi Denetleyicinin kullanılacağını belirlemek için - ancak ilke tamamen aynı.

Bu basitleştirmek gelmez RewriteRuleoluşturmak gerekmez olarak hafifçe yolu parametresini (yani OP'ın orijinal RewriteRule olacak şimdi iş):

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

Ancak , bir alt dizine kurulumla ilgili kural hala geçerlidir, örn.

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



Bayraklar:

NC = Büyük / Küçük Harfe Hayır (büyük / küçük harfe duyarlı değildir, desende karakter olmadığından gerçekten gerekli değildir)

L = Son (bu Yeniden Yazmadan sonra yeniden yazmayı durdurur, bu nedenle yeniden yazma listenizdeki son şey olduğundan emin olun)

QSA= Sorgu Dizesi ?like=penguinsSonunda tutmak ve index.php'ye iletmek istediğiniz gibi bir şey olması durumunda ekleyin .


1
index.php olmalıdır? yol = $ 1
Jacek Pietal

1
@Prozi değil Bir alt dizinde konum ve eğer index.php o zaman / lider gerek, DOCROOT içindedir - ile Options +Indexesve index.php dahil DirectoryIndexsen olabilir kapalı terk index.php tamamen ve sadece kullanmak /?path=$1Bu zaman geçerlidir httpd-vhosts.conf <Directory>türü yönergesi yerine .htaccess aracılığıyla yeniden yazmalar yapmak .
CD001

Bunu kullanırsanız ve $ _GET ['yol'] 'a
güvenirseniz

3
Güzel mesaj! Kullanıcıyı belirterek It yetmeyecek üzerine yazabilirsiniz $_GET['path']onlar eklerseniz path=whateverURL'ye.
rybo111

1
@Liviuge - doğru, ama başlangıçta tüm yolu geçerek $_GETgerekli olacaktı (.*)... komik ama OP'nin 6 yıl önce kullandığı RewriteRule o zamanlar onlar için işe yaramadı - ancak MVC mimarisinin PHP ile gelişti ( Güncellenen Şubat 18 biti olarak) şimdi ... sanırım zamanlarının ilerisindeydiler :) /mvc/Elbette dizinin doğru yoluna ihtiyacı var .
CD001

28

Var olmayan her şeyi yeniden yönlendirmek index.phpiçin FallBackResourceyönergeyi de kullanabilirsiniz.

FallbackResource /index.php

Bu gibi çalışır ErrorDocumentEğer sunucu üzerinde forwords sessizce direktifi isteği var olmayan bir yol veya dosya istediğinde, index.php.

Her şeyi ( including existant files or folders) öğesine yeniden yönlendirmek istiyorsanız index.php, aşağıdaki gibi bir şey kullanabilirsiniz:

RewriteEngine on

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

Sonsuz döngü hatasını önlemek için hedef yolu ^((?!index\.php).+)$ hariç index.phptuttuğumuz dışında kalıbın herhangi bir uri ile eşleştiğine dikkat edin.


Ama şunu da kullanmak isteyebilirsiniz:DirectoryIndex index.php
Shao

1
Kök yolunun kendisini de yeniden yönlendirmek istiyorsanız, modelde *yerine kullanın +.
Mir-Ismaili

15

Bunun gibi bir şey kullanabilirsiniz:

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

Bu, her sorguyu kök dizinin index.php'sine yönlendirecektir. Görüntüler, javascript dosyaları veya stil sayfaları gibi var olan dosyalar için sorguları da yeniden yönlendireceğini unutmayın.


1
Bu çözüm neredeyse benim için çalıştı. "AH00124: İstek, 10 dahili yeniden yönlendirme sınırını aştı" mesajı almaya devam ettim. Daha önce "RewriteRule ^ index \ .php - [L]" ekledim ve mükemmel çalışıyor!
Fredster

11

Bu problem için tüm senaryolara uyan bir "numara" var, o kadar bariz bir çözüm ki, gerçekten işe yaradığına inanmak için denemeniz gerekecek ... :)

İşte burada...

<IfModule mod_rewrite.c>

   RewriteEngine On

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

</IfModule>

Temel olarak, MOD_REWRITE'tan her zaman bir dosya mevcut olduğunda VE her zaman istenen dosya bulunmadığındaindex.php URI isteğini iletmesini istiyorsunuz !

Nasıl çalıştığını anlamak için MOD-REWRITE kaynak kodunu araştırırken, tüm kontrollerinin her zaman doğrulamadan sonra referans alınan dosyanın var olup olmadığını fark ettim. Ancak o zaman RegExişlenir. URI'niz bir klasöre işaret etse bile, Apache , yapılandırma dosyasında listelenen dizin dosyalarını denetlemeyi zorunlu kılar .

Bu basit keşfe dayanarak , dosya varlığı kontrolüne iki kez dokunduğumuz ve her iki sonucu da olasılıkların% 100'ünü kapsayacak şekilde aynı uç noktaya yönlendirdiğimiz sürece, tüm olası aramalar için basit bir dosya doğrulamasının yeterli olacağı aşikardı .

ÖNEMLİ: İçinde " / " olmadığına dikkat edin index.php. Varsayılan olarak MOD_REWRITE , yönlendirme için "temel klasör" olarak ayarlandığı klasörü kullanacaktır. İşin güzelliği, sitenin "kök klasörü" olması gerekmemesi ve bu çözümün localhost/uyguladığınız herhangi bir alt klasör için çalışmasına izin vermesidir.

Nihayetinde, daha önce test ettiğim bazı diğer çözümler (iyi çalışıyor gibi görünen çözümler), PHP'nin bir dosyayı serseri olan göreceli yolu üzerinden "gerektirme" yeteneğini kırdı. Dikkatli ol.

Bazı insanlar bunun uygunsuz bir çözüm olduğunu söyleyebilir. Aslında olabilir, ancak testlere kadar, birkaç senaryoda, birkaç sunucuda, birkaç farklı Apache sürümünde, vb., Bu çözüm tüm durumlarda% 100 çalıştı!


Teşekkürler, bu, bir FallbackResource index.phphattın bir Mac (OS X 10.11) üzerinde çalıştığı ancak Centos 7.5 altında çalışmadığı sorunumu çözdü . Ancak: bu RewriteRule, örneğin CSS dosyalarının konumunu da yeniden yazar. Yalnızca PHP dosyalarını yeniden yönlendirmem gerektiğinden, kuralı olarak değiştirdim RewriteRule ^(.*)php$ index.php [L,QSA]. YMMV.
Laryx Decidua

1
Yardım etmesine sevindim. Haklısın, TÜM dosyaları hedefliyor çünkü soru şuydu: " htaccess kullanarak hepsini index.php'ye yönlendir ". Yalnızca PHP dosyalarını yeniden yönlendirmenin daha zarif yolları da vardır, örneğin RewriteRule ^(.*)\.php$ index.php [L,NE,QSA](çalışmak için hiçbir koşul gerektirmez). Ancak günümüzde, daha ucuz bir kural kullanıyorum: RewriteRule ^.+$ index.php [L,NE,QSA]Koşullarla RewriteCond %{REQUEST_FILENAME} !-fve RewriteCond %{REQUEST_FILENAME} !-dhatta RewriteCond $1 !^(index\.php|assets|robots\.txt|favicon\.ico)gerçekten spesifik olmak için birleştirilebilen .
Julio Marchi

5

Aptalca cevap ama neden yönlendirmediğini anlayamıyorsanız, aşağıdakilerin web klasörü için etkin olup olmadığını kontrol edin.

AllowOverride All

Bu, çalışması gereken htaccess'i çalıştırmanızı sağlayacaktır! (alternatifler var ama üzerinde olmamak sorunlara neden olacak https://httpd.apache.org/docs/2.4/mod/core.html#allowoverride )


0

Bağlantı etiketinizi değiştirmeyi unutmayın.

Misal:

.htacces file
RewriteEngine On

RewriteRule ^about/$ /about.php

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

<a> etiketini değiştirmeyi her zaman unutmayın.
Collins Benson

2
Etiketinizi değiştirme işlemini yaptıktan sonra ev ne anlama geliyor?
Enrico Maria De Angelis

0

Yine de, dizin varsa (çekirdek çerçeve klasörleri ve dosyaları için) tüm istekleri çerçeve dizin işleyicisine nasıl yeniden yönlendireceğinizi merak ediyorsanız, bazı hata / başarı girişimleri sadece .htaccess dosyasındaki RewriteCond'u değiştirmem gerektiğini fark ettikten sonra. dosya

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

Yukarıdaki koşul "dosyalar bulunamadı" ve "dizinler bulunamadı" durumlarını belirtir, tamam, ya "bulunamadı" (! -d) satırını kaldırır ve aşağıdaki gibi bir şeyle biterse:

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

Benim için bir cazibe gibi çalıştı

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.