Dizeleri URL ve dosya adını güvenli hale getirmek için dezenfekte etmek mi?


136

URL (kullanmak bir post sümük gibi) ve aynı zamanda dosya adları olarak kullanmak güvenli böylece belirli dizeleri dezenfekte iyi bir iş yapan bir işlev ile gelmeye çalışıyorum. Örneğin, birisi bir dosya yüklediğinde, addan tüm tehlikeli karakterleri kaldırdığımdan emin olmak istiyorum.

Şimdiye kadar bu işlevi çözdüğünü ve yabancı UTF-8 verilerine de izin verdiğini umduğum şu fonksiyonla geldim.

/**
 * Convert a string to the file/URL safe "slug" form
 *
 * @param string $string the string to clean
 * @param bool $is_filename TRUE will allow additional filename characters
 * @return string
 */
function sanitize($string = '', $is_filename = FALSE)
{
 // Replace all weird characters with dashes
 $string = preg_replace('/[^\w\-'. ($is_filename ? '~_\.' : ''). ']+/u', '-', $string);

 // Only allow one dash separator at a time (and make string lowercase)
 return mb_strtolower(preg_replace('/--+/u', '-', $string), 'UTF-8');
}

Buna karşı çalıştırabileceğim herhangi bir zor örnek verisi olan veya uygulamalarımızı kötü adlardan korumanın daha iyi bir yolunu bilen var mı?

$ is-filename geçici vim dosyaları gibi bazı ek karakterlere izin verir

update: geçerli bir kullanım düşünemediğim için yıldız karakteri kaldırıldı


[\ W.-]
elias

3
Sen bulabilirsiniz Normalizeri ve kullanışlı üzerinde bir yorum.
Matt Gibson

Yanıtlar:


57

Çözümünüzle ilgili bazı gözlemler:

  1. Desenin sonundaki 'u', eşleştiği metnin değil , desenin UTF-8 olarak yorumlanacağı anlamına gelir (ikincisini varsaydığınızı varsayıyorum?).
  2. \ w alt çizgi karakteriyle eşleşir. URL'lerde istemediğiniz varsayımına yol açan dosyalar için özellikle dahil edersiniz, ancak kodda URL'lerinizin alt çizgi içermesine izin verilir.
  3. "Yabancı UTF-8" in dahil edilmesi yerel ayara bağımlı görünmektedir. Bunun sunucunun veya istemcinin yerel ayarı olup olmadığı açık değildir. PHP belgelerinden:

Bir "kelime" karakteri herhangi bir harf ya da rakam ya da alt çizgi karakteri, yani Perl kelimesinin bir parçası olabilecek herhangi bir karakterdir. Harflerin ve rakamların tanımı PCRE'nin karakter tabloları tarafından kontrol edilir ve bölgeye özgü eşleştirme gerçekleşiyorsa değişebilir. Örneğin, "fr" (Fransızca) yerel ayarında, aksanlı harfler için 128'den büyük bazı karakter kodları kullanılır ve bunlar \ w ile eşleştirilir.

Bilgi oluşturma

Muhtemelen post slug'ınıza aksanlı vb karakterler eklememelisiniz, çünkü teknik olarak, bunların kodlanmış yüzdesi (URL kodlama kurallarına göre) olmalıdır, böylece çirkin görünen URL'leriniz olur.

Yani, ben olsaydım, küçük harflerden sonra, herhangi bir 'özel' karakteri eşdeğerlerine (örneğin é -> e) dönüştürür ve [az] olmayan karakterleri '-' ile değiştiririm, tek bir '-' yaptığınız gibi. Burada özel karakterleri dönüştürmenin bir uygulaması var: https://web.archive.org/web/20130208144021/http://neo22s.com/slug

Genel olarak sanitasyon

OWASP, Enterprise Security API'sinin PHP uygulamasına sahiptir; diğer şeylerin yanı sıra, uygulamanızdaki giriş ve çıkışın güvenli kodlanması ve kodunun çözülmesi için yöntemler içerir.

Enkoder arayüzü şunları sağlar:

canonicalize (string $input, [bool $strict = true])
decodeFromBase64 (string $input)
decodeFromURL (string $input)
encodeForBase64 (string $input, [bool $wrap = false])
encodeForCSS (string $input)
encodeForHTML (string $input)
encodeForHTMLAttribute (string $input)
encodeForJavaScript (string $input)
encodeForOS (Codec $codec, string $input)
encodeForSQL (Codec $codec, string $input)
encodeForURL (string $input)
encodeForVBScript (string $input)
encodeForXML (string $input)
encodeForXMLAttribute (string $input)
encodeForXPath (string $input)

https://github.com/OWASP/PHP-ESAPI https://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API


Benim "u" değiştirici varsayım hakkında doğru - metin için olduğunu düşündüm. Ayrıca alt çizgi dahil \ w değiştirici unuttum. Normalde tüm aksanlı karakterleri ASCII'ye dönüştürürdüm - ancak bunun diğer diller için de çalışmasını istiyorum. Arapça başlıkların bile çalışabilmesi için bir dilin herhangi bir karakterinin bir URL bilgi dosyasında veya dosya adında kullanılabilmesinin bir tür UTF-8 güvenli yolu olacağını varsayıyordum. Sonuçta, linux UTF-8 dosya adlarını destekler ve tarayıcılar HTML bağlantılarını gerektiği gibi kodlamalıdır. Buraya katıldığınız için teşekkür ederiz.
Xeoncross

İkinci düşüncede, aslında haklısınız, ancak bu sadece tarayıcıların bağlantıları doğru kodlamasıyla ilgili bir sorun değil. ASCII olmayan karakterleri en yakın ASCII eşdeğeriyle eşlemek ve ardından bağlantınızı HTML gövdesinde URL olarak kodlamaktır. Zor yol web sunucunuza, uygulama katmanı (PHP), sayfa içeriği, web tarayıcı aracılığıyla, veri deposundan (Ben bazı Çinli lehçeler için düşünmek veya UTF-16) tutarlı UTF-8 kodlaması sağlamak ve etmektir değil (Url'lerinize urlencode ama yine de 'istenmeyen' karakterleri soyun). Bu size güzel kodlanmamış bağlantılar ve URL'ler verecektir.
Alan Donnelly

İyi tavsiye. Saf bir UTF-8 ortamı yaratmaya çalışacağım. Sonra, ASCII olmayan dillerden birkaç dize alarak, tehlikeli karakterleri (./ ;: vb ...) kaldıracağım ve dosyaları oluşturacağım ve bunları tıklayıp tıklayamayacağımı görmek için tüm dosyalara HTML bağlantıları yapacağım İşler. Değilse, muhtemelen UTF-8'e izin vermek için (raw)? Urlencode () öğesine geri dönmem gerekecek. Sonuçları buraya göndereceğim.
Xeoncross

3
Adında bir dosya oluşturdum สังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่.txtve daha sonra bağlantı içeren bir UTF-8 HTML dosyası oluşturdum. Şaşırtıcı çalıştı - hatta pencerelerde! Ancak, daha sonra PHP vardı file_put_contents('สังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่.txt')ve bu dizeden bir çarşı dosya adı oluşturma başarısız oldu. Sonra ile oluşturmaya çalıştım fopen()ve aynı berbat dosya adını aldım. Görünüşe göre PHP (en azından pencerelerde) UTF-8 dosya adları oluşturamıyor. bugs.php.net/bug.php?id=46990&thanks=6
Xeoncross

1
Bu yanıtı verdim çünkü en çok düşünmemi sağladı ve daha önce hiç duymadığım bir projeye faydalı bir bağlantı da içeriyordu. Yine de bir cevap bulduğumda göndereceğim.
Xeoncross

87

Chyrp kodunda bu daha büyük işlevi buldum :

/**
 * Function: sanitize
 * Returns a sanitized string, typically for URLs.
 *
 * Parameters:
 *     $string - The string to sanitize.
 *     $force_lowercase - Force the string to lowercase?
 *     $anal - If set to *true*, will remove all non-alphanumeric characters.
 */
function sanitize($string, $force_lowercase = true, $anal = false) {
    $strip = array("~", "`", "!", "@", "#", "$", "%", "^", "&", "*", "(", ")", "_", "=", "+", "[", "{", "]",
                   "}", "\\", "|", ";", ":", "\"", "'", "‘", "’", "“", "”", "–", "—",
                   "—", "–", ",", "<", ".", ">", "/", "?");
    $clean = trim(str_replace($strip, "", strip_tags($string)));
    $clean = preg_replace('/\s+/', "-", $clean);
    $clean = ($anal) ? preg_replace("/[^a-zA-Z0-9]/", "", $clean) : $clean ;
    return ($force_lowercase) ?
        (function_exists('mb_strtolower')) ?
            mb_strtolower($clean, 'UTF-8') :
            strtolower($clean) :
        $clean;
}

ve bu wordpress kodunda

/**
 * Sanitizes a filename replacing whitespace with dashes
 *
 * Removes special characters that are illegal in filenames on certain
 * operating systems and special characters requiring special escaping
 * to manipulate at the command line. Replaces spaces and consecutive
 * dashes with a single dash. Trim period, dash and underscore from beginning
 * and end of filename.
 *
 * @since 2.1.0
 *
 * @param string $filename The filename to be sanitized
 * @return string The sanitized filename
 */
function sanitize_file_name( $filename ) {
    $filename_raw = $filename;
    $special_chars = array("?", "[", "]", "/", "\\", "=", "<", ">", ":", ";", ",", "'", "\"", "&", "$", "#", "*", "(", ")", "|", "~", "`", "!", "{", "}");
    $special_chars = apply_filters('sanitize_file_name_chars', $special_chars, $filename_raw);
    $filename = str_replace($special_chars, '', $filename);
    $filename = preg_replace('/[\s-]+/', '-', $filename);
    $filename = trim($filename, '.-_');
    return apply_filters('sanitize_file_name', $filename, $filename_raw);
}

Eylül 2012 Güncellemesi

Alix Axel bu alanda inanılmaz çalışmalar yaptı. Phunction çerçevesi birkaç harika metin filtresi ve dönüşüm içerir.


23
WordPress kodu kullandığı için taşınabilir değilapply_filters
Kevin Mark

1
Wordpress versiyon cümledeki o Not /[\s-]+/ile -hangi (sadece değiştirir ki ilk sürümü daha iyidir /\s+/üst üste birden tire neden olabilir)
Yotam Ömer

Sadece referans için wordpress Apply_filters burada ve sanitize_file_name burada bulunabilir .
Eric

birden fazla alan ne olacak? Yerine
Zürafa Jeffrey

8
$ Anal -değişken güç-seçeneği ile bana çok korkutucu geliyor.
viljun

30

Bu, dosya adlarınızı güvenli hale getirmelidir ...

$string = preg_replace(array('/\s/', '/\.[\.]+/', '/[^\w_\.\-]/'), array('_', '.', ''), $string);

ve buna daha derin bir çözüm:

// Remove special accented characters - ie. sí.
$clean_name = strtr($string, array('Š' => 'S','Ž' => 'Z','š' => 's','ž' => 'z','Ÿ' => 'Y','À' => 'A','Á' => 'A','Â' => 'A','Ã' => 'A','Ä' => 'A','Å' => 'A','Ç' => 'C','È' => 'E','É' => 'E','Ê' => 'E','Ë' => 'E','Ì' => 'I','Í' => 'I','Î' => 'I','Ï' => 'I','Ñ' => 'N','Ò' => 'O','Ó' => 'O','Ô' => 'O','Õ' => 'O','Ö' => 'O','Ø' => 'O','Ù' => 'U','Ú' => 'U','Û' => 'U','Ü' => 'U','Ý' => 'Y','à' => 'a','á' => 'a','â' => 'a','ã' => 'a','ä' => 'a','å' => 'a','ç' => 'c','è' => 'e','é' => 'e','ê' => 'e','ë' => 'e','ì' => 'i','í' => 'i','î' => 'i','ï' => 'i','ñ' => 'n','ò' => 'o','ó' => 'o','ô' => 'o','õ' => 'o','ö' => 'o','ø' => 'o','ù' => 'u','ú' => 'u','û' => 'u','ü' => 'u','ý' => 'y','ÿ' => 'y'));
$clean_name = strtr($clean_name, array('Þ' => 'TH', 'þ' => 'th', 'Ð' => 'DH', 'ð' => 'dh', 'ß' => 'ss', 'Œ' => 'OE', 'œ' => 'oe', 'Æ' => 'AE', 'æ' => 'ae', 'µ' => 'u'));

$clean_name = preg_replace(array('/\s/', '/\.[\.]+/', '/[^\w_\.\-]/'), array('_', '.', ''), $clean_name);

Bu, dosya adında bir nokta istediğinizi varsayar. küçük harfe aktarılmasını istiyorsanız,

$clean_name = strtolower($clean_name);

son satır için.


1
Bazı Çekçe ve Slovakça karakterler hala eksik:'ľ' => 'l', 'Ľ' => 'L', 'č' => 'c', 'Č' => 'C', 'ť' => 't', 'Ť' => 'T', 'ň' => 'n', 'Ň' => 'N', 'ĺ' => 'l', 'Ĺ' => 'L', 'Ř' => 'R', 'ř' => 'r', 'ě' => 'e', 'Ě' => 'E', 'ů' => 'u', 'Ů' => 'U'
Jasom Dotnet

22

Bunu dene:

function normal_chars($string)
{
    $string = htmlentities($string, ENT_QUOTES, 'UTF-8');
    $string = preg_replace('~&([a-z]{1,2})(acute|cedil|circ|grave|lig|orn|ring|slash|th|tilde|uml);~i', '$1', $string);
    $string = html_entity_decode($string, ENT_QUOTES, 'UTF-8');
    $string = preg_replace(array('~[^0-9a-z]~i', '~[ -]+~'), ' ', $string);

    return trim($string, ' -');
}

Examples:

echo normal_chars('Álix----_Ãxel!?!?'); // Alix Axel
echo normal_chars('áéíóúÁÉÍÓÚ'); // aeiouAEIOU
echo normal_chars('üÿÄËÏÖÜŸåÅ'); // uyAEIOUYaA

Bu başlıkta seçilen cevaba dayanarak: PHP'de URL Dostu Kullanıcı adı?


Çok güzel - Ben hiç bir çeviri tablosu (wordpress kullanır gibi) olmadan yapılan görmedim. Ancak, bu özelliğin yeterli olduğunu düşünmüyorum çünkü yalnızca özel karakterleri çeviriyor, ancak tehlikeli karakterleri kaldırmıyor. Belki yukarıdaki birine eklenebilir ...
Xeoncross

4
Ha! Kesmeyi kodlayan varlık tatlı! Her ne kadar ilk bakışta bu yöntemin ne yaptığını net değil. Yine de bir sorun var. "Frédéric & Éric" "Frederic amp Eric" e dönüşmeyecek mi?
Alan Donnelly

@AlanDonnelly: Gerçekten, orijinal cevabımdaki işlevi güncelledim (bağlantıyı kontrol edin), trim()ayrıca olmalı trim($string, '-').
Alix Axel

@Xeoncross: Sonuncusu preg_replace()tüm tehlikeli karakterleri kaldırmalıdır.
Alix Axel

@AlixAxel, hemen her yerde değilsiniz. Ben sadece PHP AWS SDK okuyordu ve onlar UUID için bazı kod vardı. Harika phunction kodu yenmek için sadece zor.
Xeoncross

13

Bu, henüz bir çözüm sunmadığı için tam olarak bir cevap değil, ancak bir yoruma sığmayacak kadar büyük ...


Windows 7 ve Ubuntu 12.04 üzerinde bazı testler yaptım (dosya adları ile ilgili) ve ne buldum:

1. PHP ASCII olmayan Dosya Adlarını İşleyemiyor

Hem Windows hem de Ubuntu, Unicode dosya adlarını (göründüğü gibi RTL olanları bile) işleyebilse de, PHP 5.3, eski ISO-8859-1 ile bile uğraşmak için kesmek gerektirir, bu nedenle ASCII'yi yalnızca güvenlik için tutmak daha iyidir.

2. Dosya Adının Uzunluğu Önemlidir (Özellikle Windows'ta)

Ubuntu'da, bir dosya adının sahip olabileceği maksimum uzunluk (uzantı dahil) 255'tir (yol hariç):

/var/www/uploads/123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345/

Ancak, Windows 7'de (NTFS) bir dosya adının sahip olabileceği maksimum uzunluk, mutlak yoluna bağlıdır:

(0 + 0 + 244 + 11 chars) C:\1234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234\1234567.txt
(0 + 3 + 240 + 11 chars) C:\123\123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890\1234567.txt
(3 + 3 + 236 + 11 chars) C:\123\456\12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456\1234567.txt

Wikipedia şunları söylüyor:

NTFS, her yol bileşeninin (dizin veya dosya adı) 255 karakter uzunluğunda olmasını sağlar.

Bildiğim kadarıyla (ve test), bu yanlış.

Toplamda (sayma eğik çizgileri) tüm bu örneklerde 259 karakter vardır, bu karakterleri ayırırsanız C:\256 karakter verir (255 ?! değil). Gezgin kullanılarak oluşturulan dizinler ve dizin adı için kullanılabilir tüm alanı kullanmaktan kendini kısıtladığını fark edeceksiniz. Bunun nedeni, 8.3 dosya adlandırma kuralını kullanarak dosyaların oluşturulmasına izin vermektir . Aynı şey diğer bölümler için de geçerlidir.

Dosyaların elbette 8.3 uzunluk gereksinimlerini karşılaması gerekmez:

(255 chars) E:\12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.txt

Üst dizinin mutlak yolu 242'den fazla karakter içeriyorsa, başka alt dizin oluşturamazsınız 256 = 242 + 1 + \ + 8 + . + 3. Üst dizinde 233'ten fazla karakter varsa (sistem yerel ayarına bağlı olarak) Windows Gezgini'ni kullanarak başka bir dizin oluşturamazsınız 256 = 233 + 10 + \ + 8 + . + 3; 10Burada dize uzunluğudur New folder.

Dosya sistemleri arasında çalışabilirlik sağlamak istiyorsanız Windows dosya sistemi kötü bir sorun oluşturur.

3. Ayrılmış Karakterlere ve Anahtar Kelimelere Dikkat Edin

ASCII olmayan, yazdırılamayan ve kontrol karakterlerini kaldırmanın yanı sıra, yeniden de (yerleştir / taşı) gerekir:

"*/:<>?\|

Bu karakterleri kaldırmak en iyi fikir olmayabilir çünkü dosya adı anlamının bir kısmını kaybedebilir. En azından, bu karakterlerin çoklu oluşumlarının tek bir alt çizgi ( _) veya belki de daha temsili bir şeyle değiştirilmesi gerektiğini düşünüyorum (bu sadece bir fikirdir):

  • "*? -> _
  • /\| -> -
  • : -> [ ]-[ ]
  • < -> (
  • > -> )

Ayrıca, bununNUL nasıl aşılacağından emin olmasam da, kaçınılması gereken (örneğin ) özel anahtar kelimeler vardır. Belki de rastgele bir isim geri dönüşüne sahip bir kara liste, bunu çözmek için iyi bir yaklaşım olacaktır.

4. Büyük / Küçük Harfe Duyarlılık

Bu söylemeden geçmelidir, ancak farklı işletim sistemlerinde dosya benzersizliğini sağlamak istiyorsanız, dosya adlarını normalleştirilmiş bir duruma dönüştürmelisiniz, bu şekilde my_file.txtve My_File.txtLinux'ta my_file.txtWindows'ta her ikisi de aynı dosya olmaz .

5. benzersiz olduğundan emin olun

Dosya adı zaten varsa, temel dosya adına benzersiz bir tanımlayıcı eklenmelidir .

Ortak benzersiz tanımlayıcılar arasında UNIX zaman damgası, dosya içeriğinin bir özeti veya rastgele bir dize bulunur.

6. Gizli Dosyalar

İsimlendirilebileceği anlamına gelmeli ...

Noktalar genellikle dosya adlarında beyaz olarak listelenir, ancak Linux'ta gizli bir dosya önde gelen bir nokta ile temsil edilir.

7. Diğer Hususlar

Dosya adının bazı karakterlerini çıkarmanız gerekiyorsa, uzantı genellikle dosyanın temel adından daha önemlidir. Dosya uzantısı (8-16) için önemli sayıda maksimum karaktere izin vermek , karakterleri temel addan ayırmalıdır. Gibi - O birden fazla uzatılmasını sahip olası olay olduğuna dikkat etmek de önemlidir _.graphmlz.tag.gz- _.graphmlz.tagsadece _bu durumda dosya taban adı olarak düşünülmelidir.

8. Kaynaklar

Calibre dosya adını oldukça düzgün bir şekilde yönetiyor:

Vikipedi sayfasında dosya adı mangling ve bağlantılı bölüm Samba kullanma .


Örneğin, 1/2/3 kurallarından herhangi birini ihlal eden bir dosya oluşturmaya çalışırsanız, çok yararlı bir hata alırsınız:

Warning: touch(): Unable to create file ... because No error in ... on line ...

11

Her zaman Kohana'nın oldukça iyi bir iş çıkardığını düşündüm .

public static function title($title, $separator = '-', $ascii_only = FALSE)
{
if ($ascii_only === TRUE)
{
// Transliterate non-ASCII characters
$title = UTF8::transliterate_to_ascii($title);

// Remove all characters that are not the separator, a-z, 0-9, or whitespace
$title = preg_replace('![^'.preg_quote($separator).'a-z0-9\s]+!', '', strtolower($title));
}
else
{
// Remove all characters that are not the separator, letters, numbers, or whitespace
$title = preg_replace('![^'.preg_quote($separator).'\pL\pN\s]+!u', '', UTF8::strtolower($title));
}

// Replace all separator characters and whitespace by a single separator
$title = preg_replace('!['.preg_quote($separator).'\s]+!u', $separator, $title);

// Trim separators from the beginning and end
return trim($title, $separator);
}

Kullanışlı UTF8::transliterate_to_ascii()ñ => n gibi şeyler dönecektir.

Tabii ki, diğer UTF8::*şeyleri mb_ * işlevleriyle değiştirebilirsiniz.


5

Dosya yüklemeleri açısından, kullanıcının dosya adını kontrol etmesini önlemek en güvenli yöntem olacaktır. Daha önce ima edildiği gibi, kurallı dosya adını gerçek dosya adı olarak kullanacağınız rastgele seçilen ve benzersiz bir adla birlikte bir veritabanında saklayın.

OWASP ESAPI kullanılarak, bu adlar şu şekilde oluşturulabilir:

$userFilename   = ESAPI::getEncoder()->canonicalize($input_string);
$safeFilename   = ESAPI::getRandomizer()->getRandomFilename();

Rastgele oluşturulan dosya adının var olan bir dosyayı denetlemeden bile benzersiz olmasını sağlamak için $ safeFilename öğesine bir zaman damgası ekleyebilirsiniz.

URL kodlaması açısından ve yine ESAPI kullanılarak:

$safeForURL     = ESAPI::getEncoder()->encodeForURL($input_string);

Bu yöntem, dizeyi kodlamadan önce standartlaştırma gerçekleştirir ve tüm karakter kodlamalarını işler.


Kesinlikle - ayrıca, dosya adı denetimini kullanıcılardan uzaklaştırmak, aynı ada sahip 2 yükleme olasılığını önleyecektir.
CodeVirtuoso

5

PHP için * URLify (Github'da 480+ yıldız) - "Django projesinden URLify.js'nin PHP portu. URL'lerde kullanılmak üzere ascii olmayan karakterleri translitte eder".

Temel kullanım:

URL'ler için salyangoz oluşturmak için:

<?php

echo URLify::filter (' J\'étudie le français ');
// "jetudie-le-francais"

echo URLify::filter ('Lo siento, no hablo español.');
// "lo-siento-no-hablo-espanol"

?>

Dosya adları için salyangoz oluşturmak için:

<?php

echo URLify::filter ('фото.jpg', 60, "", true);
// "foto.jpg"

?>

* Diğer önerilerin hiçbiri kriterlerimle eşleşmedi:

  • Besteci aracılığıyla kurulmalıdır
  • Farklı sistemlere farklı davrandığı için iconv'ye bağlı olmamalıdır
  • Geçersiz kılmalara ve özel karakter değiştirmelere izin vermek için genişletilebilir olmalıdır
  • Popüler (örneğin Github'daki birçok yıldız)
  • Testleri var

Bonus olarak, URLify da belirli kelimeleri kaldırır ve harf çevirisi yapılmayan tüm karakterleri kaldırır.

İşte URLify'ı kullanarak tonlarca yabancı karakterin doğru şekilde dönüştürüldüğü bir test örneği: https://gist.github.com/motin/a65e6c1cc303e46900d10894bf2da87f


1
Teşekkürler - bu benim amacım için ideal görünüyor.
David Goodwin

5

Başka bir kaynaktan adapte oldum ve birkaç ekstra daha ekledim, belki biraz aşırı

/**
 * Convert a string into a url safe address.
 *
 * @param string $unformatted
 * @return string
 */
public function formatURL($unformatted) {

    $url = strtolower(trim($unformatted));

    //replace accent characters, forien languages
    $search = array('À', 'Á', 'Â', 'Ã', 'Ä', 'Å', 'Æ', 'Ç', 'È', 'É', 'Ê', 'Ë', 'Ì', 'Í', 'Î', 'Ï', 'Ð', 'Ñ', 'Ò', 'Ó', 'Ô', 'Õ', 'Ö', 'Ø', 'Ù', 'Ú', 'Û', 'Ü', 'Ý', 'ß', 'à', 'á', 'â', 'ã', 'ä', 'å', 'æ', 'ç', 'è', 'é', 'ê', 'ë', 'ì', 'í', 'î', 'ï', 'ñ', 'ò', 'ó', 'ô', 'õ', 'ö', 'ø', 'ù', 'ú', 'û', 'ü', 'ý', 'ÿ', 'Ā', 'ā', 'Ă', 'ă', 'Ą', 'ą', 'Ć', 'ć', 'Ĉ', 'ĉ', 'Ċ', 'ċ', 'Č', 'č', 'Ď', 'ď', 'Đ', 'đ', 'Ē', 'ē', 'Ĕ', 'ĕ', 'Ė', 'ė', 'Ę', 'ę', 'Ě', 'ě', 'Ĝ', 'ĝ', 'Ğ', 'ğ', 'Ġ', 'ġ', 'Ģ', 'ģ', 'Ĥ', 'ĥ', 'Ħ', 'ħ', 'Ĩ', 'ĩ', 'Ī', 'ī', 'Ĭ', 'ĭ', 'Į', 'į', 'İ', 'ı', 'IJ', 'ij', 'Ĵ', 'ĵ', 'Ķ', 'ķ', 'Ĺ', 'ĺ', 'Ļ', 'ļ', 'Ľ', 'ľ', 'Ŀ', 'ŀ', 'Ł', 'ł', 'Ń', 'ń', 'Ņ', 'ņ', 'Ň', 'ň', 'ʼn', 'Ō', 'ō', 'Ŏ', 'ŏ', 'Ő', 'ő', 'Œ', 'œ', 'Ŕ', 'ŕ', 'Ŗ', 'ŗ', 'Ř', 'ř', 'Ś', 'ś', 'Ŝ', 'ŝ', 'Ş', 'ş', 'Š', 'š', 'Ţ', 'ţ', 'Ť', 'ť', 'Ŧ', 'ŧ', 'Ũ', 'ũ', 'Ū', 'ū', 'Ŭ', 'ŭ', 'Ů', 'ů', 'Ű', 'ű', 'Ų', 'ų', 'Ŵ', 'ŵ', 'Ŷ', 'ŷ', 'Ÿ', 'Ź', 'ź', 'Ż', 'ż', 'Ž', 'ž', 'ſ', 'ƒ', 'Ơ', 'ơ', 'Ư', 'ư', 'Ǎ', 'ǎ', 'Ǐ', 'ǐ', 'Ǒ', 'ǒ', 'Ǔ', 'ǔ', 'Ǖ', 'ǖ', 'Ǘ', 'ǘ', 'Ǚ', 'ǚ', 'Ǜ', 'ǜ', 'Ǻ', 'ǻ', 'Ǽ', 'ǽ', 'Ǿ', 'ǿ'); 
    $replace = array('A', 'A', 'A', 'A', 'A', 'A', 'AE', 'C', 'E', 'E', 'E', 'E', 'I', 'I', 'I', 'I', 'D', 'N', 'O', 'O', 'O', 'O', 'O', 'O', 'U', 'U', 'U', 'U', 'Y', 's', 'a', 'a', 'a', 'a', 'a', 'a', 'ae', 'c', 'e', 'e', 'e', 'e', 'i', 'i', 'i', 'i', 'n', 'o', 'o', 'o', 'o', 'o', 'o', 'u', 'u', 'u', 'u', 'y', 'y', 'A', 'a', 'A', 'a', 'A', 'a', 'C', 'c', 'C', 'c', 'C', 'c', 'C', 'c', 'D', 'd', 'D', 'd', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'E', 'e', 'G', 'g', 'G', 'g', 'G', 'g', 'G', 'g', 'H', 'h', 'H', 'h', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'I', 'i', 'IJ', 'ij', 'J', 'j', 'K', 'k', 'L', 'l', 'L', 'l', 'L', 'l', 'L', 'l', 'l', 'l', 'N', 'n', 'N', 'n', 'N', 'n', 'n', 'O', 'o', 'O', 'o', 'O', 'o', 'OE', 'oe', 'R', 'r', 'R', 'r', 'R', 'r', 'S', 's', 'S', 's', 'S', 's', 'S', 's', 'T', 't', 'T', 't', 'T', 't', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'W', 'w', 'Y', 'y', 'Y', 'Z', 'z', 'Z', 'z', 'Z', 'z', 's', 'f', 'O', 'o', 'U', 'u', 'A', 'a', 'I', 'i', 'O', 'o', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'U', 'u', 'A', 'a', 'AE', 'ae', 'O', 'o'); 
    $url = str_replace($search, $replace, $url);

    //replace common characters
    $search = array('&', '£', '$'); 
    $replace = array('and', 'pounds', 'dollars'); 
    $url= str_replace($search, $replace, $url);

    // remove - for spaces and union characters
    $find = array(' ', '&', '\r\n', '\n', '+', ',', '//');
    $url = str_replace($find, '-', $url);

    //delete and replace rest of special chars
    $find = array('/[^a-z0-9\-<>]/', '/[\-]+/', '/<[^>]*>/');
    $replace = array('', '-', '');
    $uri = preg_replace($find, $replace, $url);

    return $uri;
}

5

ve bu Joomla 3.3.2 sürümü JFile::makeSafe($file)

public static function makeSafe($file)
{
    // Remove any trailing dots, as those aren't ever valid file names.
    $file = rtrim($file, '.');

    $regex = array('#(\.){2,}#', '#[^A-Za-z0-9\.\_\- ]#', '#^\.#');

    return trim(preg_replace($regex, '', $file));
}

4

Kaldırılacak karakter listesinin güvenli olduğunu sanmıyorum. Aşağıdakileri kullanmayı tercih ederim:

Dosya adları için: Dosya içeriğinin dahili bir kimliğini veya karmasını kullanın. Belge adını bir veritabanına kaydedin. Bu şekilde orijinal dosya adını koruyabilir ve dosyayı yine de bulabilirsiniz.

URL parametreleri için: urlencode()Herhangi bir özel karakteri kodlamak için kullanın .


1
Kabul ediyorum, burada listelenen yöntemlerin çoğu bilinen tehlikeli karakterleri kaldırıyor - yöntemim bilinen güvenli bir karakter olmayan her şeyi kaldırıyor . Çoğu sistem slug posta URL'lerini kodladığından, belgelenmiş UTF-8 güvensiz urlencode () kullanmak yerine bu kanıtlanmış yöntemi izlemeye devam etmeyi öneririm .
Xeoncross

3

Nasıl kullanacağınıza bağlı olarak, arabellek taşmalarına karşı korumak için bir uzunluk sınırı eklemek isteyebilirsiniz.


Evet, mb_strlen () için test yapmak her zaman önemli bir şeydir!
Xeoncross

3

Bir yükleme dosya adını güvenli hale getirmenin güzel bir yolu:

$file_name = trim(basename(stripslashes($name)), ".\x00..\x20");

Bundan pek emin değilim, çünkü biri .\x00..\x20azaltılabilir .\x00\x20.
Xeoncross

@Xeoncross: Ben düşünüyorum .\x00..\x20kaldırır noktalar arasındaki her karakteri \x00ve \x20oysa .\x00\x20sadece bu 3 bayt kaldırmalısınız.
Alix Axel

Bu cevap güvenli bir şekilde kullanılması için daha fazla açıklama gerektirir. Net üzerinde charlist için tam sözdizimi hakkında fazla bilgi yok.
Manuel Arwed Schmidt

3

İşte CodeIgniter uygulaması.

/**
 * Sanitize Filename
 *
 * @param   string  $str        Input file name
 * @param   bool    $relative_path  Whether to preserve paths
 * @return  string
 */
public function sanitize_filename($str, $relative_path = FALSE)
{
    $bad = array(
        '../', '<!--', '-->', '<', '>',
        "'", '"', '&', '$', '#',
        '{', '}', '[', ']', '=',
        ';', '?', '%20', '%22',
        '%3c',      // <
        '%253c',    // <
        '%3e',      // >
        '%0e',      // >
        '%28',      // (
        '%29',      // )
        '%2528',    // (
        '%26',      // &
        '%24',      // $
        '%3f',      // ?
        '%3b',      // ;
        '%3d'       // =
    );

    if ( ! $relative_path)
    {
        $bad[] = './';
        $bad[] = '/';
    }

    $str = remove_invisible_characters($str, FALSE);
    return stripslashes(str_replace($bad, '', $str));
}

Ve remove_invisible_charactersbağımlılık.

function remove_invisible_characters($str, $url_encoded = TRUE)
{
    $non_displayables = array();

    // every control character except newline (dec 10),
    // carriage return (dec 13) and horizontal tab (dec 09)
    if ($url_encoded)
    {
        $non_displayables[] = '/%0[0-8bcef]/';  // url encoded 00-08, 11, 12, 14, 15
        $non_displayables[] = '/%1[0-9a-f]/';   // url encoded 16-31
    }

    $non_displayables[] = '/[\x00-\x08\x0B\x0C\x0E-\x1F\x7F]+/S';   // 00-08, 11, 12, 14-31, 127

    do
    {
        $str = preg_replace($non_displayables, '', $str, -1, $count);
    }
    while ($count);

    return $str;
}

2

neden sadece php kullanmak değil urlencode? "tehlikeli" karakterlerin yerine, URL'ler (örn %20. bir boşluk için) onaltılık gösterimleri


2
Dosya adları için% karakteri önerilmez ve onaltılık kodlanmış karakterler URL'de hoş görünmez. Tarayıcılar, ascii olmayan diller için çok daha hoş ve daha kolay olan UTF-8 dizelerini destekleyebilir.
Xeoncross

urlencode ve SONRA str_replace ('% 20', '-', url) yapabilir misiniz?
Francesco

2

Bu soru için halihazırda birkaç çözüm sağlandı, ancak burada kodun çoğunu okudum ve test ettim ve burada öğrendiklerimin bir karışımı olan bu çözümle sonuçlandım:

İşlev

İşlev burada bir Symfony2 paketinde ancak düz PHP olarak kullanılmak üzere çıkarılabilir , yalnızca iconvetkinleştirilmesi gereken işleve bağımlıdır :

Filesystem.php :

<?php

namespace COil\Bundle\COilCoreBundle\Component\HttpKernel\Util;

use Symfony\Component\HttpKernel\Util\Filesystem as BaseFilesystem;

/**
 * Extends the Symfony filesystem object.
 */
class Filesystem extends BaseFilesystem
{
    /**
     * Make a filename safe to use in any function. (Accents, spaces, special chars...)
     * The iconv function must be activated.
     *
     * @param string  $fileName       The filename to sanitize (with or without extension)
     * @param string  $defaultIfEmpty The default string returned for a non valid filename (only special chars or separators)
     * @param string  $separator      The default separator
     * @param boolean $lowerCase      Tells if the string must converted to lower case
     *
     * @author COil <https://github.com/COil>
     * @see    http://stackoverflow.com/questions/2668854/sanitizing-strings-to-make-them-url-and-filename-safe
     *
     * @return string
     */
    public function sanitizeFilename($fileName, $defaultIfEmpty = 'default', $separator = '_', $lowerCase = true)
    {
    // Gather file informations and store its extension
    $fileInfos = pathinfo($fileName);
    $fileExt   = array_key_exists('extension', $fileInfos) ? '.'. strtolower($fileInfos['extension']) : '';

    // Removes accents
    $fileName = @iconv('UTF-8', 'us-ascii//TRANSLIT', $fileInfos['filename']);

    // Removes all characters that are not separators, letters, numbers, dots or whitespaces
    $fileName = preg_replace("/[^ a-zA-Z". preg_quote($separator). "\d\.\s]/", '', $lowerCase ? strtolower($fileName) : $fileName);

    // Replaces all successive separators into a single one
    $fileName = preg_replace('!['. preg_quote($separator).'\s]+!u', $separator, $fileName);

    // Trim beginning and ending seperators
    $fileName = trim($fileName, $separator);

    // If empty use the default string
    if (empty($fileName)) {
        $fileName = $defaultIfEmpty;
    }

    return $fileName. $fileExt;
    }
}

Birim testleri

İlginç olan, önce uç durumları test etmek için PHPUnit testleri oluşturduğum ve böylece ihtiyaçlarınızı karşılayıp karşılamadığını kontrol edebilirsiniz: (Bir hata bulursanız, bir test durumu eklemekten çekinmeyin)

FilesystemTest.php :

<?php

namespace COil\Bundle\COilCoreBundle\Tests\Unit\Helper;

use COil\Bundle\COilCoreBundle\Component\HttpKernel\Util\Filesystem;

/**
 * Test the Filesystem custom class.
 */
class FilesystemTest extends \PHPUnit_Framework_TestCase
{
    /**
     * test sanitizeFilename()
     */
    public function testFilesystem()
    {
    $fs = new Filesystem();

    $this->assertEquals('logo_orange.gif', $fs->sanitizeFilename('--logö  _  __   ___   ora@@ñ--~gé--.gif'), '::sanitizeFilename() handles complex filename with specials chars');
    $this->assertEquals('coilstack', $fs->sanitizeFilename('cOiLsTaCk'), '::sanitizeFilename() converts all characters to lower case');
    $this->assertEquals('cOiLsTaCk', $fs->sanitizeFilename('cOiLsTaCk', 'default', '_', false), '::sanitizeFilename() lower case can be desactivated, passing false as the 4th argument');
    $this->assertEquals('coil_stack', $fs->sanitizeFilename('coil stack'), '::sanitizeFilename() convert a white space to a separator');
    $this->assertEquals('coil-stack', $fs->sanitizeFilename('coil stack', 'default', '-'), '::sanitizeFilename() can use a different separator as the 3rd argument');
    $this->assertEquals('coil_stack', $fs->sanitizeFilename('coil          stack'), '::sanitizeFilename() removes successive white spaces to a single separator');
    $this->assertEquals('coil_stack', $fs->sanitizeFilename('       coil stack'), '::sanitizeFilename() removes spaces at the beginning of the string');
    $this->assertEquals('coil_stack', $fs->sanitizeFilename('coil   stack         '), '::sanitizeFilename() removes spaces at the end of the string');
    $this->assertEquals('coilstack', $fs->sanitizeFilename('coil,,,,,,stack'), '::sanitizeFilename() removes non-ASCII characters');
    $this->assertEquals('coil_stack', $fs->sanitizeFilename('coil_stack  '), '::sanitizeFilename() keeps separators');
    $this->assertEquals('coil_stack', $fs->sanitizeFilename(' coil________stack'), '::sanitizeFilename() converts successive separators into a single one');
    $this->assertEquals('coil_stack.gif', $fs->sanitizeFilename('cOil Stack.GiF'), '::sanitizeFilename() lower case filename and extension');
    $this->assertEquals('copy_of_coil.stack.exe', $fs->sanitizeFilename('Copy of coil.stack.exe'), '::sanitizeFilename() keeps dots before the extension');
    $this->assertEquals('default.doc', $fs->sanitizeFilename('____________.doc'), '::sanitizeFilename() returns a default file name if filename only contains special chars');
    $this->assertEquals('default.docx', $fs->sanitizeFilename('     ___ -  --_     __%%%%__¨¨¨***____      .docx'), '::sanitizeFilename() returns a default file name if filename only contains special chars');
    $this->assertEquals('logo_edition_1314352521.jpg', $fs->sanitizeFilename('logo_edition_1314352521.jpg'), '::sanitizeFilename() returns the filename untouched if it does not need to be modified');
    $userId = rand(1, 10);
    $this->assertEquals('user_doc_'. $userId. '.doc', $fs->sanitizeFilename('亐亐亐亐亐.doc', 'user_doc_'. $userId), '::sanitizeFilename() returns the default string (the 2nd argument) if it can\'t be sanitized');
    }
}

Test sonuçları: ( PHP 5.3.2 ile Ubuntu ve PHP 5.3.17 ile MacOsX üzerinde kontrol edildi:

All tests pass:

phpunit -c app/ src/COil/Bundle/COilCoreBundle/Tests/Unit/Helper/FilesystemTest.php
PHPUnit 3.6.10 by Sebastian Bergmann.

Configuration read from /var/www/strangebuzz.com/app/phpunit.xml.dist

.

Time: 0 seconds, Memory: 5.75Mb

OK (1 test, 17 assertions)

1
Bu çoğunlukla Latin kökenli girdi olduğunu varsayar. Nerede sorun yaşayacağınızı görmek için diğer dillerden daha fazla UTF-8 karakteri ekleyin.
Xeoncross

@Xeoncross Katılıyorum, Christian dedi ki bir Id veya karma VE orijinal dosya adını kurtarmak gerekir. Ancak, sanitize etme işlemi başarısız olduğunda varsayılan bir dize belirtebileceğiniz için bu işlev bir alternatif sağlar. Bu vaka için bir birim testi ekledim. Hatayı bildirdiğiniz için teşekkür ederiz.
Bobin

2

Garip latin karakterleri her türlü giriş başlıkları ve yararlı bir çizgi sınırlı dosya adı biçimine çevirmek için gereken bazı HTML etiketleri var. @ SoLoGHoST'un cevabını @ Xeoncross'un cevabından birkaç öğe ile birleştirdim ve biraz özelleştirdim.

    function sanitize($string,$force_lowercase=true) {
    //Clean up titles for filenames
    $clean = strip_tags($string);
    $clean = strtr($clean, array('Š' => 'S','Ž' => 'Z','š' => 's','ž' => 'z','Ÿ' => 'Y','À' => 'A','Á' => 'A','Â' => 'A','Ã' => 'A','Ä' => 'A','Å' => 'A','Ç' => 'C','È' => 'E','É' => 'E','Ê' => 'E','Ë' => 'E','Ì' => 'I','Í' => 'I','Î' => 'I','Ï' => 'I','Ñ' => 'N','Ò' => 'O','Ó' => 'O','Ô' => 'O','Õ' => 'O','Ö' => 'O','Ø' => 'O','Ù' => 'U','Ú' => 'U','Û' => 'U','Ü' => 'U','Ý' => 'Y','à' => 'a','á' => 'a','â' => 'a','ã' => 'a','ä' => 'a','å' => 'a','ç' => 'c','è' => 'e','é' => 'e','ê' => 'e','ë' => 'e','ì' => 'i','í' => 'i','î' => 'i','ï' => 'i','ñ' => 'n','ò' => 'o','ó' => 'o','ô' => 'o','õ' => 'o','ö' => 'o','ø' => 'o','ù' => 'u','ú' => 'u','û' => 'u','ü' => 'u','ý' => 'y','ÿ' => 'y'));
    $clean = strtr($clean, array('Þ' => 'TH', 'þ' => 'th', 'Ð' => 'DH', 'ð' => 'dh', 'ß' => 'ss', 'Œ' => 'OE', 'œ' => 'oe', 'Æ' => 'AE', 'æ' => 'ae', 'µ' => 'u','—' => '-'));
    $clean = str_replace("--", "-", preg_replace("/[^a-z0-9-]/i", "", preg_replace(array('/\s/', '/[^\w-\.\-]/'), array('-', ''), $clean)));

    return ($force_lowercase) ?
        (function_exists('mb_strtolower')) ?
            mb_strtolower($clean, 'UTF-8') :
            strtolower($clean) :
        $clean;
}

Çeviri dizisine em çizgi karakterini (-) manuel olarak eklemem gerekiyordu. Başkaları olabilir ama şu ana kadar dosya adlarım iyi görünüyor.

Yani:

Bölüm 1: Babamın “bururburts”? - onlar en iyisi değil!

dönüşür:

Part-1-my-babalar-zurburts-onlar-not-the-best

Döndürülen dizeye sadece ".html" ekliyorum.


1
Bazı Çek ve Slovakça karakterleri hala eksik:'ľ' => 'l', 'Ľ' => 'L', 'č' => 'c', 'Č' => 'C', 'ť' => 't', 'Ť' => 'T', 'ň' => 'n', 'Ň' => 'N', 'ĺ' => 'l', 'Ĺ' => 'L', 'Ř' => 'R', 'ř' => 'r', 'ě' => 'e', 'Ě' => 'E', 'ů' => 'u', 'Ů' => 'U'
Jasom Dotnet

1
Ve şüphesiz çok daha fazlası. Aslında karakter kombinasyonları içeren bir ISO seti olup olmadığını anlamaya çalışıyorum. İçerik hepsinden karakter isterse bir seti nasıl "seçer"? UTF-8 varsayıyorum ...
cbmtrx 13:15

Ben PHP bir satır kullanarak herhangi bir dize transliterate nasıl öğrendim : $string = transliterator_transliterate('Any-Latin;Latin-ASCII;', $string);Aşağıdaki cevabımı görmek veya bağlantılı blog yazısı okuyun.
Jasom Dotnet

1
Hayır, yanlış okudunuz: Sunucunuza (veya barındırma) PHP uzantıları yükleyebiliyorsanız :-) İşte gönderi .
Jasom Dotnet

1
Ah, anladım. Teşekkürler @JasomDotnet - Şu an için geçerli çözümüm var, ancak sınırlı bir karakter kümesi, bu yüzden uzantı kontrol etmeye değer.
cbmtrx

2

1. Çözüm: PHP uzantılarını sunucuya (barındırma) yükleme olanağınız var

"Dünya gezegenindeki hemen hemen her dilin" ASCII karakterlerine çevirisi için.

  1. Önce PHP Intl uzantısını yükleyin . Bu Debian (Ubuntu) için komuttur:sudo aptitude install php5-intl

  2. Bu benim dosyaAdı işlevidir (test.php oluşturun ve aşağıdaki kodu yapıştırın):

<!doctype html>
<html lang="en">
<head>
<meta charset="utf-8">
<title>Test</title>
</head>
<body>
<?php

function pr($string) {
  print '<hr>';
  print '"' . fileName($string) . '"';
  print '<br>';
  print '"' . $string . '"';
}

function fileName($string) {
  // remove html tags
  $clean = strip_tags($string);
  // transliterate
  $clean = transliterator_transliterate('Any-Latin;Latin-ASCII;', $clean);
  // remove non-number and non-letter characters
  $clean = str_replace('--', '-', preg_replace('/[^a-z0-9-\_]/i', '', preg_replace(array(
    '/\s/', 
    '/[^\w-\.\-]/'
  ), array(
    '_', 
    ''
  ), $clean)));
  // replace '-' for '_'
  $clean = strtr($clean, array(
    '-' => '_'
  ));
  // remove double '__'
  $positionInString = stripos($clean, '__');
  while ($positionInString !== false) {
    $clean = str_replace('__', '_', $clean);
    $positionInString = stripos($clean, '__');
  }
  // remove '_' from the end and beginning of the string
  $clean = rtrim(ltrim($clean, '_'), '_');
  // lowercase the string
  return strtolower($clean);
}
pr('_replace(\'~&([a-z]{1,2})(ac134/56f4315981743 8765475[]lt7ňl2ú5äňú138yé73ťž7ýľute|');
pr(htmlspecialchars('<script>alert(\'hacked\')</script>'));
pr('Álix----_Ãxel!?!?');
pr('áéíóúÁÉÍÓÚ');
pr('üÿÄËÏÖÜ.ŸåÅ');
pr('nie4č a a§ôňäääaš');
pr('Мао Цзэдун');
pr('毛泽东');
pr('ماو تسي تونغ');
pr('مائو تسه‌تونگ');
pr('מאו דזה-דונג');
pr('მაო ძედუნი');
pr('Mao Trạch Đông');
pr('毛澤東');
pr('เหมา เจ๋อตง');
?>
</body>
</html>

Bu çizgi çekirdek:

  // transliterate
  $clean = transliterator_transliterate('Any-Latin;Latin-ASCII;', $clean);

Yanıt bazında bu yazı .

2. Çözüm: PHP uzantılarını sunucuya (barındırma) yükleme olanağınız yok

resim açıklamasını buraya girin

CMS Drupal için harf çevirisi modülünde oldukça iyi bir iş yapıldı . Dünya gezegenindeki hemen hemen her dili destekler. Gerçekten tam çözüm sanitize dizeleri istiyorsanız eklenti deposunu kontrol etmenizi öneririz .



1

Bu iyi bir işlev:

public function getFriendlyURL($string) {
    setlocale(LC_CTYPE, 'en_US.UTF8');
    $string = iconv('UTF-8', 'ASCII//TRANSLIT//IGNORE', $string);
    $string = preg_replace('~[^\-\pL\pN\s]+~u', '-', $string);
    $string = str_replace(' ', '-', $string);
    $string = trim($string, "-");
    $string = strtolower($string);
    return $string;
} 

Kötü görünüyor. \\s+ters eğik çizgi ve ardından bir veya daha fazla boşluk anlamına gelir. Bu ne hakkında? Ayrıca, bu CMD, null veya BEL.
Xeoncross

Hala kötü. Şimdi gibi dizelere /blog/2014-02/just-in-timeizin verilmiyor. Lütfen yukarıdaki test edilmiş kodu veya phunctionPHP çerçeve kodunu kullanın .
Xeoncross

Doğru. Bu işlev yalnızca "tam zamanında" kısım içindir. Bazı insanlar için yararlı olabilir.
joan16v

1
preg_replace('~[^\-\pL\pN\s]+~u', '-', $string)
Normal ifadeyi

Müthiş! Ayrıca ekledim: string = trim ($ string, "-");
joan16v

0

Prestashop tarafından URL'leri sterilize etmek için kullanılan kod budur:

replaceAccentedChars

tarafından kullanılır

str2url

aksanları gidermek

function replaceAccentedChars($str)
{
    $patterns = array(
        /* Lowercase */
        '/[\x{0105}\x{00E0}\x{00E1}\x{00E2}\x{00E3}\x{00E4}\x{00E5}]/u',
        '/[\x{00E7}\x{010D}\x{0107}]/u',
        '/[\x{010F}]/u',
        '/[\x{00E8}\x{00E9}\x{00EA}\x{00EB}\x{011B}\x{0119}]/u',
        '/[\x{00EC}\x{00ED}\x{00EE}\x{00EF}]/u',
        '/[\x{0142}\x{013E}\x{013A}]/u',
        '/[\x{00F1}\x{0148}]/u',
        '/[\x{00F2}\x{00F3}\x{00F4}\x{00F5}\x{00F6}\x{00F8}]/u',
        '/[\x{0159}\x{0155}]/u',
        '/[\x{015B}\x{0161}]/u',
        '/[\x{00DF}]/u',
        '/[\x{0165}]/u',
        '/[\x{00F9}\x{00FA}\x{00FB}\x{00FC}\x{016F}]/u',
        '/[\x{00FD}\x{00FF}]/u',
        '/[\x{017C}\x{017A}\x{017E}]/u',
        '/[\x{00E6}]/u',
        '/[\x{0153}]/u',

        /* Uppercase */
        '/[\x{0104}\x{00C0}\x{00C1}\x{00C2}\x{00C3}\x{00C4}\x{00C5}]/u',
        '/[\x{00C7}\x{010C}\x{0106}]/u',
        '/[\x{010E}]/u',
        '/[\x{00C8}\x{00C9}\x{00CA}\x{00CB}\x{011A}\x{0118}]/u',
        '/[\x{0141}\x{013D}\x{0139}]/u',
        '/[\x{00D1}\x{0147}]/u',
        '/[\x{00D3}]/u',
        '/[\x{0158}\x{0154}]/u',
        '/[\x{015A}\x{0160}]/u',
        '/[\x{0164}]/u',
        '/[\x{00D9}\x{00DA}\x{00DB}\x{00DC}\x{016E}]/u',
        '/[\x{017B}\x{0179}\x{017D}]/u',
        '/[\x{00C6}]/u',
        '/[\x{0152}]/u');

    $replacements = array(
            'a', 'c', 'd', 'e', 'i', 'l', 'n', 'o', 'r', 's', 'ss', 't', 'u', 'y', 'z', 'ae', 'oe',
            'A', 'C', 'D', 'E', 'L', 'N', 'O', 'R', 'S', 'T', 'U', 'Z', 'AE', 'OE'
        );

    return preg_replace($patterns, $replacements, $str);
}

function str2url($str)
{
    if (function_exists('mb_strtolower'))
        $str = mb_strtolower($str, 'utf-8');

    $str = trim($str);
    if (!function_exists('mb_strtolower'))
        $str = replaceAccentedChars($str);

    // Remove all non-whitelist chars.
    $str = preg_replace('/[^a-zA-Z0-9\s\'\:\/\[\]-\pL]/u', '', $str);
    $str = preg_replace('/[\s\'\:\/\[\]-]+/', ' ', $str);
    $str = str_replace(array(' ', '/'), '-', $str);

    // If it was not possible to lowercase the string with mb_strtolower, we do it after the transformations.
    // This way we lose fewer special chars.
    if (!function_exists('mb_strtolower'))
        $str = strtolower($str);

    return $str;
}


-4
// CLEAN ILLEGAL CHARACTERS
function clean_filename($source_file)
{
    $search[] = " ";
    $search[] = "&";
    $search[] = "$";
    $search[] = ",";
    $search[] = "!";
    $search[] = "@";
    $search[] = "#";
    $search[] = "^";
    $search[] = "(";
    $search[] = ")";
    $search[] = "+";
    $search[] = "=";
    $search[] = "[";
    $search[] = "]";

    $replace[] = "_";
    $replace[] = "and";
    $replace[] = "S";
    $replace[] = "_";
    $replace[] = "";
    $replace[] = "";
    $replace[] = "";
    $replace[] = "";
    $replace[] = "";
    $replace[] = "";
    $replace[] = "";
    $replace[] = "";
    $replace[] = "";
    $replace[] = "";

    return str_replace($search,$replace,$source_file);

} 
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.