mod_rewrite sayesinde sayfalarımızın adreslerini istediğimiz formda gösterebiliyoruz (İlgili makale için:http://mfyz.com/htaccess-yardimiyla-tum-trafigi-te......n-yonetmek). Kullanımı çok yaygınlaşsa da bu kullanımın bazı ufak problemleri beraberinde getirdiği göz önünde bulundurulmalı.

Bu yazıda iki çok açık problemden ve basit çözümlerinden bahsedeceğim.

İlk problemlerden birisi sayfanızda kullandığınız tüm medya veya eklentilerin yollarını domain seviyesinden belirtmek durumunda olmanızdır. Eğer htmlinizi yazarken sayfanızdaki görselleri, stilleri, scriptleri bu şekilde tanımlamadıysanız tüm sayfalarınızdaki yolları güncellemeniz gerekiyor.

Basit bir örnekle, ana dizinde duran bir index.php veya html dosyanızın olduğunuz varsayalım ve images, css ve js olarak 3 medya dizininiz olsun. html'inizi kodlarken yolları su şekilde belirtmeniz dogal:
<html>
	<head>
		<title>Blah blah</title>
		<link rel="stylesheet" href="css/style.css" />
		<script src="js/myscript.js"></script>
	</head>
	<body>
		<div>
			<h1>Test page</h1>
			
			<img src="images/cat.jpg" alt="Cat" />
		</div>
	</body>
</html>
Eğer bu uygulmanızda bu sayfayı sunan kodu domain.com/about/license gibi, birden fazla derinlikte bir url ile sunduğunuz zaman, tarayıcınız o sayfa kodunun /about/ dizininde çalıştığını varsayarak medya dosyalarınızı /about/js/, /about/images/ gibi dizinlerde arayacaktır.

Çözümü ise basit. İki seçeneğiniz var bu noktada. Her medya yolunu belirtirkenhttp://domain/images/cat.jpg şeklinde tam yolu belirtebilirsiniz veya dosya/dizin yollarını belirtirken "/" işareti ile başlayarak domain seviyesinden itibaren işaret edeceksiniz yollarınızı yani yukarıdaki html kodunda her yol tanımlamasını "/" işareti ile başlayarak (ekleyerek) düzeltebilirsiniz.

Başında bir protokol ile belirtilmemiş her url domain üstündeki bir yolu ifade eder. "/" işareti ile başlayan yollar ise domain seviyesini işaret eder. Yani sadece "/" şeklinde tanımlanmış bir link aslında domain ana dizinini işaret eder. Ama bizim amacımız domain seviyesinden itibaren bir dizini işaretlemek, dolayısıyla /images/icons/plus.png gibi bir yol sızı nerede olursanız olur her zamanhttp://domain.com/images/icons/plus.png'yi işaret ederek istediğiniz dosyaya ulaştıracaktır.

Cookie Problemi

Bir diğer problem ise çerez (cookie) problemidir. Çerezlerin tarayıcıda kaydedildiğini hatırlamakta fayda var. Sunucu tarafında dahi çerez kaydetmek isteseniz o çerez aslında o isteğin cevabında gelen headerlar'da olacak ve tarayıcı istek cevabındaki değerlere göre çerezleri kaydedecek, silecek veya güncelleyecektir. Yani tarayıcının çerezleri yönettiğini bilmeniz gerekiyor, ayrıca çerezlerin dizin bağımlı olduklarını da belirtmek gerek. Yani bir çerezi /A/B/C dizininde iken ayarlarsanız bu çerez sadece C dizini ve alt dizinlerinden erişilebilir olacaktır. C dizinindeyken aryıca ana dizin, A ve B dizininde kaydedilmiş çerezlere de erişebilirsiniz. Tarayıcı, alt dizinlerdeki bir çereze erişimi bir üst dizinden veya paraleldeki bir dizinden vermez.

Bu durumda url'lerinizi klasör şeklinde ayarladıktan sonra uygulamanızda nerelerde çerez kaydediyor, siliyor veya güncelliyor olduğunuzu hatırlamanız ve güncellemeniz gerekiyor. Bu güncellemeyi hem javascript'deki cookie kullanımınız için hem de sunucu tarafındaki çerez kullanımınız için güncellemeniz gerekiyor. Sunucu tarafında bütün dillerde çok bilinen bir problem olduğu için yazdığınız sunucu taraflı dile ilişkin çerez methodlarını inceleyin. Ben kısaca php'de nasıl yapacağınızı anlatacağım.

Önce javascript ile çerez işlemlerinizi güncellemek için, normalde kullandığınız:
document.cookie = "";
koduna ek olarak "path=/" eklemeniz gerekecektir (tabi ki ; ayracını kullanarak diğer çerez cümlenize ekleyebilirsiniz.

Bu size karışık gelmiş olabilir çünkü javascript ile çerez yönetimini herhangi bir kütüphane kullanmadan yapmanın yolu bu. Ancak muhtemelen jquery veya en azından çerezlerinizi okumak, silmek veya kaydetmek için bir kütüpahne kullanıyor iseniz kullandığınız kütüpahenin "path" yani çerez dizinini belirtebileceğiniz bir yöntemi vardır, bu yöntemi uygulayarak tüm çerezlerinizi ana dizininizde ayarlamalısınız, böylece çerezleriniz her yerden erişilebilir hale geleceklerdir.

PHP'de bu problemi çözmek için tüm "setcookie" fonksiyonunun (name, value, expire) standart kullanımına 4. parametre olarak "/" yani dizin parametresi eklemeniz yeterli olacaktır. Bu noktadan sonra kaydettiğiniz tüm çerezler ana dizine kaydedilecek, böylece her yerden erişilebilir hale geleceklerdir.


Bu konu, daha teknik noktalarda başka problemleri de beraberinde getiriyor fakat url'lerinizi klasör şeklinde ayarladıktan sonra ilk karşılaşacağınız iki büyük problemden ve çözümünden kısaca bahsetmiş oldum.


Hazırlayan: Mehmet Fatih YILDIZ
Yine URL şemaları üstüne bir yazı hazırladım. Bu sefer htaccess'den çok dinamik bir url şeması hazırlamayı da anlattım. Bu yazı ile:

- apple.com/ipod/nike
- sahibinden.com/kiralik

veya kullanıcı sayfaları:

- twitter.com/mfyz
- twitter.com/mfyz/followers

Şeklindeki url şemaları oluşturmak için gerekli mantığın anlamış olacaksınız.

http://mfyz.com/dokuman/131/htaccess-yardimiyla-tu......n-yonetmek
URL şemaları, SEO amacıyla önem taşımakta. Bunun yanı sıra, her geliştirici ürettiği uygulamanın URL şemasının anlaşılır ve güzel görünmesinı ister. Eğer bir framework kullanıyorsanız muhtemelen bunu yönetebileceğiniz bir yer, yardımcı vs vardır. Fakat kendi kodunuzu yazıyorsanız htaccess ile mod_rewrite yardımıyla her url şema tipine göre bir rewrite kuralı yazmanız gerekecektir.

Basit bir proje örneği vereceğim, diyelim ki basit bir ürün katalogu hazırlıyorsunuz, katalog anasayfasında son ürünler ve kategoriler listeleniyor. Her her ürün de bir kategoride listeleniyor. Yani kategori sayfaları ve ürün detay sayfalarınız var. Basit bir php projesi ile bu uygulamayı 3 parçaya ayırdınız, anasayfa, kategori ve ürün detay. Her parçanın kendine ait kodu var. Normalde bu parçaları birer php dosyası olarak hazırladığınızı düşünürsek her parçayı birbirine
  • anasayfa.php
  • kategori.php?kategori_id=21
  • urun_detay.php?urun_id=2320
gibi linklerle bağlıyorsunuz.

URL şemasını su şekilde kurgulamak istediğinizi düşünelim:
  • /
  • /kategori/21
  • /urun/2320

Bunun için klasik yöntemlere göre htaccess dosyanıza her link şeması için bir kural yazıp gerekli yönlendirmeyi yapmanız gerekir. Fakat her kural için düzenli ifade (regex) yazmak hem yorucu olabilir hem de her yeni url şeması için yeni regex hazırlamanız ve htaccess dosyanızı güncellemek durumunda kalırsınız. Eğer url şemalarınız belirli bir mantığa göre hazırlıyorsanız -ki MVC frameworkleri genelde buna benzer kurallara sahiptir- bu kuralı algoritmaya çevirmeniz çok kolay.

Mesela Codeigniter kullanarak hazırladığınız aynı yapı için, anasayfa, kategori ve ürün detayı için ayrı controller ve ayrı view'lar yazmak durumunda olacaksınız. Gerçekten de olması gereken bu zaten. Ama controller'ı yazarken size bazı kurallar koyar Codeigniter. Verdiğiniz sınıf adı ve method'a URL üstünden doğrudan ulaşabilirsiniz eğer methodunuz public bir method ise. Atıyorum ürün detay controller'ının adını Urun koydunuz ve method adını da detay koydunuz. Bu methodu tetiklemek (ulasmak) için kullanacağınız url: /Urun/Detay/ekstra/parametreler şeklinde olabilir. Methodunuz içinde ekstra parametreleri yakalayabilirsiniz.

Kendiniz yazarak hazırlayacağınız kod ıle url şeması böyle ikili bir kurala sahip olmak zorunda değil. Tekil bir tanımlayıcı yeterli olacaktır, ama daha karışık bir mekanizma kurarak siz de çoğul (ikili veya üçlü) bir adresleme mekanizması oluşturabilirsiniz. Tekil bir adresleme için kurallı bir mekanizma olarak şöyle bir algoritmanız olabilir:
/Urun/3452/yazci-uyumlu-versiyon şeklindeki bir url'i, ilk parça controller adı, geri kalanlar da hem opsiyonel hem de controller tarafından yakalanıp işlenecek olan veri olarak düşünürseniz, ilk parçada gelen adda controller'a sahip olup olmadığınızı kontrol edebilirsiniz. Bunun için bütün controller'larınızı "Controllers" gibi bir dizinde toplu tutmanızda fayda var. Çok ilkel bir mekanizmayla controller'larınızın sınıf değil, düz php dosyaları olduklarını varsayıyorum ve böyle bir url çağırıldığında tek bir dosyadan gerekli controller'i tespit edip include ederek calıştırdığınızı düşünelim.

Peki bu url'ler nasıl tek merkezden geçecek?

Şimdi size önce anlatmam gereken kısma geldik, bütün trafiği tek dosyaya yönlendirmek. İşte bunun için htaccess'a oldukça genel bir kod koyuyoruz:
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php?path=$1 [L,QSA]
Yukarıdaki kod sitenize gelen tüm istekleri index.php dosyasına yönlendirir. Örnek olarak:
http://example.com/
http://example.com/kategori/123
http://example.com/urun/8765
gibi istekleri index.php?path=/kategori/123 şeklinde tek parametre olarak index.php dosyasına iletilecektir. Ama yukaridaki kod teknik olarak eğer url'de geçerli bir dizin adresi veya dosya adresi yoksa istekleri index.php'ye yönlendirecektir. Yani "kategori" adında bir dizininiz varsa istek index.php'ye gitmez. Bunda da bir detay daha var. Eğer "kategori" adında bir dizininiz var ve url /kategori/sdjfhsdkfjshd ise bu URL'de aranan dosya orada olmadığı için istek yine index.php dosyasına aktarılır.

Burada ilk problemin çözümü için, controller adlarınız projenizin kök dizininde varolmayan bir klasör adı olmalıdır. İkinci problem ise, siz kullanmıyor olsanız bile herhangi bir dizin içinde bulunamayan istek index.php dosyasına yönlenecek ve siz bunu kontrol etmek zorunda kalırsınız. Olmayan dosyalara yapılan istekler web'in doğasında olan bir şeydir. En basit örneği, sitenizi tarayan botlar (google bot etc...) sitenize robots.txt, favicon.ico, sitemap.xml veya crossdomain.xml gibi sorgular yapacaktır. Olmadığı için 404 hatası almaları gerekir yaptıkları şeyi doğru yapmak için. Bunun yanı sıra siz de bu gereksiz istekleri işlemenize gerek kalmazsınız.

Bunun için, yani ikinci problemi çözmek için, projenizin asset dizinlerini (stiller, js, resimler, imges, files etc...) bu url ayrıştırma mekanizmasından ayırmak isteyebilirsiniz. Aşağıdaki satırları yukaridaki kodun üstüne yerleştirmeniz yeterli.
RewriteCond %{REQUEST_URI}  !^/resimler.* [NC]
RewriteCond %{REQUEST_URI}  !^/proje.* [NC]
Böylece bu dizinler ve altındaki isteklere dokunulmayacaktır. Ama yine de kök dizindeki her spesifik isteği ya htaccess'da ya da index.php dosyanızda işlemeniz gerekmektedir.

index.php istekleri nasıl ayrıştıracak?

Artık sitenize gelen tüm istekler index.php'nin elinin altında. "path" parametresini "/" karakterine göre parçalayarak ilk parçayı controller adı olarak rezerve edebilirsiniz. Dizinin geri kalan elemanlarını global bir dizide tutarak controller'larinizin içinde yakalayabilirsiniz. Unutmayın hala $_GET dizisiyle soru işareti ve sonrasında kullanacağınız GET parametrelerini yakalayabilirsiniz. Yani /urun/67845?ref=facebook_campaign gibi bir url hala doğru şekilde calışacaktır.

Çok ilkel bir yapıda controller adını "Controllers" dizininde öyle bir dosya olup olmadığını kontrol ederek ve eğer dosya varsa o an include ederek basit bir yapı kurabilirsiniz.

Size biraz daha farklı bir yapı sunacağım şimdi


mfyz.com'un kodu çok eski sürümlerde Türkçe idi, sonrasında ilkel bir modüler yapıya evrimleşti, sonrasında dil değiştirdi, sonrasında ilkel bir MVC modeline evrimleşti, ve şu an oldukça gelişmiş bir MVC modeline sahip. Kod 95% İngilizce, çünkü hala Türkçe yazılmış ve refactor edilmeyi bekleyen eski kodlar duruyor hala derinlerde :-) Neyse, bu örneği çoklu dile sahip bir projede çalışma ihtimali için veriyorum. Kod, controller'lar ve method adlarınız hep ingilizce (veya başka bir dilde) olmak zorunda olabilir veya ölyle olmasını isteyebilirsiniz. Böyle bir durumda Türkçe bir domain altında yoresel-organik-sabun.com/product/detail/1231231 gibi bir url şemasından çok yoresel-organik-sabun.com/urun/1231231 gibi bir URL tercih edersiniz değil mi? Şimdi bunun için kuralsal bir yaklaşımdan çok bir yol haritasının yolu gösterdiği bir mekanizmayı anlatacağım. Bu mekanizmanin bir diğer avantajı da aynı controller ve method'lara birden fazla farklı url şemaları oluşturabilmenizdir. Yani örneğin bir iletişim formuna sahipsiniz ve example.com/contact ve example.com/callus gibi iki url hatta aynı zamanda example.com/iletisim gibi farklı dildeki adresleri oluşturabilirsiniz. Sonra otomatik dil değişimi yapıp yapmamak sizin controller'da yaptığınız hünerli kodlara kalmış.

Bir yol haritası oluşturmak aslında bu url şemalarını htaccess'da her şema için ayrı ayrı kural yazmaya benziyor, ama çok daha dinamik olabilir ve düzenli ifade yerine basit dizilerde tutulabilir. İlkel bir yol haritası dizisi yazacağım yukaridaki örnek proje için.
$router = array(
  'kategori' => array('controller'=>'kategori', 'method'=>'index'),
  'ürün' => array('controller'=>'ürün', 'method'=>'detail'),
  'urundetay' => array('controller'=>'ürün', 'method'=>'detail'),
)
Gördüğünüz gibi ürün için iki farklı adresleme kullanabilirsiniz. Daha dinamik bir yol haritasını veritabanınızda saklayabilir hatta otomatik güncelleyebilirsiniz. Bunun en güzel örneği kullanıcı adı ile adresleme yapabilmektir. Yani example.com/mfyz ve example.com/mfyz/links gibi kullanıcınıza domain.com/kullanici_adi gibi bir sayfa adresleyebilmenizdir. Gelen isteğinizi, sitenizin ana yol haritası kontrollerinizi yaptıktan sonra, eğer istekte bulunulan adres yol haritanızda bir yeri işaret etmiyorsa kullanıcı dizininizde aratarak adresin bir kullanıcı profili veya kullanıcı sayfasını işaret ettiğini yakalatabilirsiniz.


Hazirlayan: Mehmet Fatih YILDIZ
Herhalde milyon tane baslik acilmis ve bu soru cevaplanmistir fakat su an duzenleme yaparken daha dogru bir cozum buldum bu konuya ve sizinle paylasmak istedim.

Web sitenizin adresindeki www'dan kurtulmak icin htaccess'da mod_rewrite'i kullanabilirsiniz. Bircok farkli cozum var fakat icinde domain, hostname degisikligi yapmadan her yerde kullanabileceginiz ve bence en dogru cozum olarak su kodu kullanabilirsiniz:
RewriteEngine On
RewriteBase /
RewriteCond %{HTTP_HOST} ^www\.(.+) [NC]
RewriteRule ^.*$ http://%1%{REQUEST_URI} [R=301,L]
Not: otomatik link olustugu icin kod icindeki link ve ikona takilmayin, kodu kopyaladiginizda dogru kopyalanacaktir.

Popüler Etiketler

kurulum nasıl less css css3 wanda proje kampanya javascript js apple ipad iphone mobile itunes pharma hack php wordpress google seo oyun jquery framework plugin mysql sql optimizasyon analyse procedure twitter widget job regex firefox search optimization meta mail newsletter subscription api logo html5 html chart grafik web app open source icon ikon download banner calendar phpstorm jetbrains pgsql mssql ide editor mfyz design ubuntu workspace export tool macosx app social media sosyal medya facebook textarea signature imza assets ios app store store in-app purchase purchase verification integration storekit itunes connect server internet browsers table windows sitemap htaccess url form input wireless lisans mootools ajax xmlhttprequest portfolio doritos tytz konsol terminal laptop notebook istatistik ui ux icons link osx player service lifestream rss xml nedir language development style license blog date diff zaman tarih auth http support share bootstrap cache statistics graph radio button switch spam startups ruffles örnek kod generator login webkit connect box pear mdb2 db database code tebrik cms compile compiler linux on-the-fly ipucu dokuman apache gimp howto query injection svn subversion git version control deployment object parse prepare execute applications free mod_rewrite cookie ie internet explorer subdomain browser route router insanlar xhtml session developer www redirect crossdomain kontrol yapıları if while coding kitap digital iOS music select screen network ntfs fstab opengraph fql