utf-8 karakter & bela

4 Cevap php

Ben mesajı http://stackoverflow.com/questions/2565864/validating-utf-8-in-htaccess-rewrite-rule görmek ve ben harika olduğunu düşünüyorum, ama daha temel bir sorun ben ilk yaşıyorum:

Ben sorgu dizesi parametreleri, dizin, dosya adları ve kullanıcılara vb ekranlarda kullanılan utf-8 karakter işlemek için genişletmek için gerekli

Ben DefaultCharset utf-8 ve aynı zamanda benim php bu konularda benim Apache yapılandırılmış. Benim orijinal yazma kuralı normal A-Za-z hariç her şeyi süzülür ve çizgi ve tire. ve işe yaradı. Başka bir şey (ne istiyorum ki!) Size 404 verecek Şimdi, ancak o sorgu dizesinde gitmez maç gibi görünüyor, ancak her şeyi, ben ancak, istemiyorum şeyler de dahil olmak üzere, maçlar görünüyor sürece düzenli bir A-Za-z_-karakter dizesidir.

Kural sorgu dizeye eşleşti ne yakarım diyor çünkü ben, bu kafa karıştırıcı bulabilirsiniz:

Burada orijinal kural şudur:

RewriteRule ^/puzzle/([A-Za-z_-]+)$ /puzzle.php?g=$1 [NC]

ve burada revize kural şudur:

RewriteRule ^/puzzle/(\w+)$ /puzzle.php?g=$1 [NC]

Yerde ben \ w-Zetc olarak TÜM alfa karakter eşleşen okudum çünkü ben bir değişiklik yaptı. sadece aksan ve malzeme olmadan olanları eşleşir.

İşte olur: Ben kullanmak bu kuralların hangi önemli görünmüyor:

Uygulamada bu var:

echo $_GET['g'];

If I feed it a url like http://mydomain.com/puzzle/USA it echoes out "USA" and works fine.
If I feed it a url like http://mydomain.com/puzzle/México it echoes nothing for that and warns me that index g is not defined and of course doesn't get resources for Mexico.
if I feed it a url like http://mydomain.com/puzzle/fuzzle/buzzle/j.qle it does the same thing.
This last case should be a 404!

Ve ne olursa olsun ben kullanmak yukarıdaki kuralların hangi yapar. Ben bir yeniden yazma günlüğünü yapılandırılmış

   RewriteLogLevel 5
   RewriteLog /opt/local/apache2/logs/puzzles.httpd.rewrite

ama boş.

İşte (o 200 bir statü verir) düzenli erişim günlüğüne değil

[26/May/2010:11:21:42 -0700] "GET /puzzle/M%C3%A9xico HTTP/1.1" 200 342
[26/May/2010:11:21:54 -0700] "GET /puzzle/M/l.foo HTTP/1.1" 200 342

Ne (* # @! Karakter ama, benim programa nokta veya diğer non-alfa çizgi, ve bir kez orada, doğru onları deşifre edecek değil bu $% # $ @ almak için ne yapabilirim?? Karakter sınıfları POSIX misiniz daha iyi çalışır? Yapılandırmak için gereken başka bir şey var mı?

4 Cevap

On...

RewriteRule ^/puzzle/(\w+)$ /puzzle.php?g=$1 [NC]

Yanılıyorsam biri bana doğru, ama bu demek değil alt dizinleri soran istekleri sadece bu kural bypass olsun?

Ayrıca, bu çözmek için tembel bir yol '%' karakteri de grup etmektir. Bildiğim kadarıyla, sizinle çalışmak için izin konum herhangi bir url yolu üzerinde url kodlama olduğunu. Aslında, bkz: http://www.blooberry.com/indexdot/html/topics/urlencoding.htm

Bunu yapmak için daha gelişmiş ve daha iyi yollar vardır eminim, ama bu acil sorunu çözmek gerekir.

Bu destroyer cevap bir tepki ama çok uzun var.

Ben göstermek için bunu çözmek için yeterli kolaydır çünkü URL Unicode kodlama ile aşağı değilim. Yani belki bu temel sorun. Sonunda Ben sadece bunu yapmak için php url_encode kullanacağız, ancak ben sadece şeyleri test etmek için bir online birini deneyin düşündüm: Ben http://www.opinionatedgeek.com/dotnet/tools/urlencode/Encode.aspx gitti ve Meksika kodlamak için çalıştı ve M% c3% çıktı a9xico. Ben size gösterilen ve denedim siteye gitti ve farklı E9xico M% çıktı! Hangisi?? Ben php işlevi aslında bana verecek ne olursa olsun kabul etmek olurdu sanırım. Ama o hem ben basamak yanı sıra% kabul etmek anlamına içinde bir 9 vardır. TÜM Ben dahil etmek olurdu ki?

Ben bunu atlayarak ne demek eğer hakiki alt dizinleri soran istekleri NOT Bu kuralı maç olacağını umut ediyorum, ben doğrusu aslında alt dizinleri de statik sayfaları işlemek istiyorum. Gerçekten ben yaptım hangi düşünce / dışlamak istiyorum nedeni budur. Ama / iç içe alt dizinleri dahil olmak üzere puzzle.php dosyaya gittikten sonra bir şey eşleşen gibi görünüyor.

Here is what I tried, but no joy: I used this rule: RewriteRule ^/puzzle/([A-Za-z0-9_%-]+)$ /puzzle.php?g=$1 [NC] as you see I added the % and 0-9 to the group. Do I need to escape the % or something? I read that only \ needs escaping inside square brackets. I hope that's what you mean. Would these be the only additional character you would get by encoding any possible unicode string? then I passed the 2 different url encoded version of Mexico in. For M%E9xico I am now getting 404 and this message: The requested URL /puzzle/México was not found on this server. For M%c3%a9xico I am now getting this message on the 404: The requested URL /puzzle/México was not found on this server. And for non existent subdirectories it is now giving 404 as it should. So now it is just the rewrite rule not working. That's progress. Also the rewrite log started getting stuff in it: Here is some. I will google for how to read these logs:

kidd108d-mac3:logs tpdick$ cat puzzles.httpd.rewrite 
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (2) init rewrite engine with requested uri /puzzle/M?xico
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (3) applying pattern '^/puzzle/([A-Za-z0-9_%-]+)$' to uri '/puzzle/M?xico'
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (1) pass through /puzzle/M?xico
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (3) [perdir /Users/tpdick/Sites/puzzles/] add path info postfix: /Users/tpdick/Sites/puzzles/puzzle.php -> /Users/tpdick/Sites/puzzles/puzzle.php/M?xico
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (3) [perdir /Users/tpdick/Sites/puzzles/] strip per-dir prefix: /Users/tpdick/Sites/puzzles/puzzle.php/M?xico -> puzzle.php/M?xico
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (3) [perdir /Users/tpdick/Sites/puzzles/] applying pattern '^(.*)/GeoP-Test/puzzle/(.*)$' to uri 'puzzle.php/M?xico'
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (1) [perdir /Users/tpdick/Sites/puzzles/] pass through /Users/tpdick/Sites/puzzles/puzzle.php
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (3) [perdir /Users/tpdick/Sites/puzzles/] add path info postfix: /Users/tpdick/Sites/puzzles/puzzle.php -> /Users/tpdick/Sites/puzzles/puzzle.php/M?xico
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (3) [perdir /Users/tpdick/Sites/puzzles/] strip per-dir prefix: /Users/tpdick::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (2) init rewrite engine with requested uri /puzzle/México
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (3) applying pattern '^/puzzle/([A-Za-z0-9_%-]+)$' to uri '/puzzle/México'
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (1) pass through /puzzle/México
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (3) [perdir /Users/tpdick/Sites/puzzles/] add path info postfix: /Users/tpdick/Sites/puzzles/puzzle.php -> /Users/tpdick/Sites/puzzles/puzzle.php/México
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (3) [perdir /Users/tpdick/Sites/puzzles/] strip per-dir prefix: /Users/tpdick/Sites/puzzles/puzzle.php/México -> puzzle.php/México
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (3) [perdir /Users/tpdick/Sites/puzzles/] applying pattern '^(.*)/GeoP-Test/puzzle/(.*)$' to uri 'puzzle.php/México'
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#910858/subreq] (1) [perdir /Users/tpdick/Sites/puzzles/] pass through /Users/tpdick/Sites/puzzles/puzzle.php
::1 - - [26/May/2010:15:54:37 --0700] [puzzles.net/sid#886b00][rid#904858/initial] (3) [perdir /Users/tpdick/Sites/puzzles/] add path info postfix: /Users/tpdick/Sites/puzzles/puzzle.php -> /Users/tpdick/Sites/puzzles/puzzle.php/México

Şimdi ne olacak?

Ben MultiViews etkinleştirmek önermek ve mod_rewrite unuturdum. Ilgili Directory / VirtualHost bölümünde apache konfigürasyonunda ekleyin:

Options +MultiViews
#should already be set to this, but it doesn't hurt:
AcceptPathInfo Default

Hayır, her zaman olduğu gibi uzun istemcisi Accept başlığındaki muhabir mime türünü içerir gibi uzantıları atlayabilirsiniz.

Şimdi /puzzle/whatever /puzzle.php için harita ve $_SERVER['PATH_INFO'] ile dolacaktır için bir istek /whatever.


Eğer mod_rewrite ile yapmak istiyorsanız bu da mümkün. RewriteRule (% xx bölümlerini temsil ettikleri gerçek bayt dönüştürülür) çıkmamış olduğu için sınama dizesi. Sen (sonuncusu da HTTP yöntemi ve sürümünü içerir) %{REQUEST_URI} veya %{THE_REQUEST} kullanarak özgün dizgeyi alabilirsiniz.

Geleneksel olarak, web tarayıcıları URL'leri UTF-8 kodlaması kullanın. Bu "México" tarayıcılar ISO-8859-1 kullanılırsa beklenir ki, değil M%82xico, M%C2%82xico için urlencoded olacağı anlamına gelir. Ayrıca, [a-zA-Z] eşleşmez é. Ancak, bu çalışması gerekir:

RewriteCond %{REQUEST_URI} ^/puzzle/[^/]*$
RewriteRule ^/puzzle/(.*)$ /puzzle.php?q=$1 [B,L]

Eğer izin verilen karakter kümesi URI geri kalanı için daha küçük olduğu, bir sorgu dizesi kullanarak çünkü B geribaşvuru kaçmak gerekir.

Eğer farkında olmalıdır şey RewriteRule farkında unicode olmasıdır. Başka bir şey .* (potansiyel olarak) yanlış sonuçlar verebilir. Bir multi-byte karakter dizisinin bir parçası olabilir: / "karakter" (bayt okuma) çünkü bile [^/] çalışmayabilir. RewriteRule unicode farkında olsaydı, birlikte çözüm \w çalışmalıdır.

Alt dizinleri maç istemiyorum, ve RewriteRule ^/puzzle/[^/]* bir seçenek değildir bu yana, bu onay (kaçtı) %{REQUEST_URI} kullandığı bir RewriteCond ertelenir.

Bu çözüm dayanmaktadır: http://www.dracos.co.uk/code/apache-rewrite-problem/

Bu kuralları yeniden deneyin:

AddDefaultCharset UTF-8
RewriteEngine On
RewriteCond %{THE_REQUEST} /puzzle/([^?\ /]+)
RewriteRule ^puzzle/(.*)$ puzzle.php/%1 [L]

Nasıl sorgu param almak için:

<?php
// Get query param
$g = substr($_SERVER['PATH_INFO'], 1); 
echo "<p>g: $g</p>";

// Test if '/' is present in URL for 404's
$g2 = substr($_SERVER['REQUEST_URI'], 8); 
if (strpos($g2, '/') === false) {
    // do stuff
} else {
    // Send 404 header here
    echo "<p>404</p>";
}
?>

Bu çözüm ile php den 404 göndermek zorunda.