Disinfezione delle stringhe per renderle sicure per URL e nome file?


136

Sto provando a trovare una funzione che faccia un buon lavoro di sanificazione di determinate stringhe in modo che siano sicure da usare nell'URL (come un post slug) e anche sicure da usare come nomi di file. Ad esempio, quando qualcuno carica un file, voglio assicurarmi di rimuovere tutti i caratteri pericolosi dal nome.

Finora ho escogitato la seguente funzione che spero risolva questo problema e consenta anche dati UTF-8 stranieri.

/**
 * 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');
}

Qualcuno ha dei dati di esempio complicati che posso eseguire contro questo - o conosce un modo migliore per proteggere le nostre app da nomi cattivi?

$ is-filename consente alcuni caratteri aggiuntivi come i file temp vim

aggiornamento: rimosso il personaggio stella poiché non riuscivo a pensare a un uso valido


Faresti meglio a rimuovere tutto tranne [\ w.-]
elias

3
È possibile trovare utile il Normalizer e i relativi commenti.
Matt Gibson,

Risposte:


57

Alcune osservazioni sulla tua soluzione:

  1. 'u' alla fine del tuo pattern significa che il pattern , e non il testo che sta abbinando, sarà interpretato come UTF-8 (presumo tu abbia assunto quest'ultimo?).
  2. \ w corrisponde al carattere di sottolineatura. Lo includi specificamente per i file che portano a supporre che non li desideri negli URL, ma nel codice che hai gli URL sarà permesso di includere un carattere di sottolineatura.
  3. L'inclusione di "UTF-8 straniero" sembra essere dipendente dalla locale. Non è chiaro se si tratti della locale del server o del client. Dai documenti PHP:

Un carattere "parola" è qualsiasi lettera o cifra o il carattere di sottolineatura, ovvero qualsiasi carattere che può far parte di una "parola" Perl. La definizione di lettere e cifre è controllata dalle tabelle dei caratteri di PCRE e può variare se si verifica una corrispondenza specifica della locale. Ad esempio, nella locale "fr" (francese), per le lettere accentate vengono utilizzati alcuni codici di caratteri maggiori di 128 e questi sono abbinati da \ w.

Creare la lumaca

Probabilmente non dovresti includere caratteri accentati ecc. Nel tuo post slug poiché, tecnicamente, dovrebbero essere codificati in percentuale (secondo le regole di codifica URL) in modo da avere URL dall'aspetto brutto.

Quindi, se fossi in te, dopo aver messo le lettere minuscole, convertivo tutti i caratteri "speciali" nel loro equivalente (ad es. É -> e) e sostituivo i caratteri non [az] con "-", limitando le esecuzioni di un singolo "-" come hai fatto. C'è un'implementazione di conversione di caratteri speciali qui: https://web.archive.org/web/20130208144021/http://neo22s.com/slug

Sanificazione in generale

OWASP ha un'implementazione PHP della sua API di sicurezza aziendale che include tra l'altro metodi per codificare e decodificare in modo sicuro input e output nell'applicazione.

L'interfaccia Encoder fornisce:

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


Hai ragione sul mio presupposto del modificatore "u" - Ho pensato che fosse per il testo. Ho anche dimenticato il modificatore \ w incluso il carattere di sottolineatura. Normalmente convertirei tutti i caratteri accentati in ASCII, ma voglio che funzioni anche per altre lingue. Supponevo che ci sarebbe stato un modo sicuro di UTF-8 che qualsiasi carattere di una lingua potesse essere usato in una lumaca URL o in un nome file in modo che anche i titoli arabi funzionassero. Dopotutto, Linux supporta i nomi di file UTF-8 e i browser dovrebbero codificare i collegamenti HTML secondo necessità. Grazie mille per il tuo contributo qui.
Xeoncross,

A pensarci bene, in realtà hai ragione, ma non è solo un problema con il browser che codifica correttamente i collegamenti. Il modo più semplice per avvicinarti a ciò che desideri è mappare i caratteri non ASCII al loro equivalente ASCII più vicino e quindi codificare l'URL del tuo link nel corpo HTML. Il modo più difficile è garantire una codifica UTF-8 coerente (o UTF-16, penso per alcuni dialetti cinesi) dal tuo archivio dati, attraverso il tuo server web, il livello applicazione (PHP), il contenuto della pagina, il browser web e non urlencode i tuoi URL ( ma rimuovi comunque caratteri "indesiderabili"). Questo ti darà bei link e URL non codificati.
Alan Donnelly,

Buon Consiglio. Proverò a creare un ambiente UTF-8 puro. Quindi, prendendo diverse stringhe da linguaggi non ASCII, rimuoverò caratteri pericolosi (./ ;: etc ...) e creerò file e quindi collegamenti HTML a quei file per vedere se posso fare clic su di essi e vedere se tutto questo lavori. In caso contrario, probabilmente dovrò tornare a (raw)? Urlencode () per consentire UTF-8. Pubblicherò i risultati qui.
Xeoncross,

3
Ho creato un file chiamato สังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่.txte quindi creato un file HTML UTF-8 con un collegamento ad esso. Incredibilmente ha funzionato, anche su Windows! Tuttavia, ho avuto PHP file_put_contents('สังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่.txt')e non è riuscito a creare un nome file bazar da quella stringa. Poi ho provato a crearlo con fopen()lo stesso nome di file incasinato. Quindi apparentemente PHP (almeno su Windows) non è in grado di creare nomi di file UTF-8. bugs.php.net/bug.php?id=46990&thanks=6
Xeoncross

1
Premetto questa risposta perché mi ha fatto pensare di più e ho anche incluso un link utile a un progetto di cui non ho mai sentito parlare che vale la pena esaminare. Pubblicherò una volta che troverò una risposta però.
Xeoncross,

87

Ho trovato questa funzione più grande nel codice Chyrp :

/**
 * 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;
}

e questo nel codice wordpress

/**
 * 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);
}

Aggiornamento settembre 2012

Alix Axel ha svolto un lavoro incredibile in questo settore. Il suo framework di phunction include diversi grandi filtri di testo e trasformazioni.


23
Il codice WordPress non è portatile in quanto utilizzaapply_filters
Kevin Mark,

1
Nota che la versione di wordpress sostituisce /[\s-]+/con la -quale è migliore della prima versione (che sostituisce solo /\s+/) che può causare più trattini di fila
Yotam Omer,

Solo per riferimento wordpress apply_filters è disponibile qui e sanitize_file_name qui .
Eric,

che dire di più spazi? Sostituisci
Jeffrey the Giraffe

8
La variabile $ anal mi sembra molto spaventosa con l'opzione force.
Viljun,

30

Questo dovrebbe rendere i tuoi nomi di file sicuri ...

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

e una soluzione più profonda a questo è:

// 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);

Ciò presuppone che si desideri un punto nel nome file. se vuoi che sia trasferito in minuscolo, basta usare

$clean_name = strtolower($clean_name);

per l'ultima riga.


1
'ľ' => 'l', 'Ľ' => 'L', 'č' => 'c', 'Č' => 'C', 'ť' => 't', 'Ť' => 'T', 'ň' => 'n', 'Ň' => 'N', 'ĺ' => 'l', 'Ĺ' => 'L', 'Ř' => 'R', 'ř' => 'r', 'ě' => 'e', 'Ě' => 'E', 'ů' => 'u', 'Ů' => 'U'
Mancano

22

Prova questo:

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

Sulla base della risposta selezionata in questa discussione: URL Friendly Username in PHP?


Molto bello - non l'ho mai visto fatto senza una tabella di traduzione (come usa WordPress). Tuttavia, non penso che questa funzione sia sufficiente così com'è poiché traduce solo caratteri speciali ma non rimuove i caratteri pericolosi. Forse può essere aggiunto a quello sopra ...
Xeoncross

4
Ha! Quell'entità che codifica l'hack è dolce! Anche se a prima vista non è affatto chiaro come questo metodo faccia quello che fa. C'è un problema però. "Frédéric & Éric" non si trasformeranno in "Frederic amp Eric"?
Alan Donnelly,

@AlanDonnelly: In effetti, ho aggiornato la funzione nella mia risposta originale (controlla il link), trim()dovrebbe anche essere trim($string, '-').
Alix Axel,

@Xeoncross: l'ultimo preg_replace()dovrebbe rimuovere tutti i caratteri pericolosi.
Alix Axel,

@AlixAxel, non sei proprio ovunque. Stavo solo leggendo l'SDK di PHP AWS e avevano un po 'del tuo codice per gli UUID. Il fantastico codice di phunction è semplicemente difficile da battere.
Xeoncross,

13

Questa non è esattamente una risposta in quanto non fornisce soluzioni (ancora!), Ma è troppo grande per adattarsi a un commento ...


Ho fatto alcuni test (riguardanti i nomi dei file) su Windows 7 e Ubuntu 12.04 e quello che ho scoperto è che:

1. PHP non è in grado di gestire nomi di file non ASCII

Sebbene sia Windows che Ubuntu siano in grado di gestire i nomi di file Unicode (anche quelli RTL come sembrano) PHP 5.3 richiede che gli hack possano gestire anche il semplice vecchio ISO-8859-1, quindi è meglio tenerlo ASCII solo per sicurezza.

2. La lunghezza dei nomi dei file è importante (specialmente su Windows)

Su Ubuntu, la lunghezza massima che può avere un nome file (inclusa l'estensione) è 255 (escluso il percorso):

/var/www/uploads/123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345/

Tuttavia, su Windows 7 (NTFS) la lunghezza massima che può avere un nome file dipende dal suo percorso assoluto:

(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 afferma che:

NTFS consente a ciascun componente del percorso (directory o nome file) di contenere 255 caratteri.

Per quanto ne so (e test), questo è sbagliato.

In totale (contando le barre) tutti questi esempi hanno 259 caratteri, se si rimuove quello C:\che dà 256 caratteri (non 255 ?!). Le directory sono state create utilizzando Explorer e noterai che si impedisce di utilizzare tutto lo spazio disponibile per il nome della directory. La ragione di ciò è consentire la creazione di file usando la convenzione di denominazione dei file 8.3 . La stessa cosa accade per altre partizioni.

Ovviamente i file non devono riservare i requisiti di lunghezza 8.3:

(255 chars) E:\12345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901234567890123456789012345678901.txt

Non è possibile creare più sottodirectory se il percorso assoluto della directory padre ha più di 242 caratteri, perché 256 = 242 + 1 + \ + 8 + . + 3. Utilizzando Esplora risorse di Windows, non è possibile creare un'altra directory se la directory padre ha più di 233 caratteri (a seconda della locale del sistema), perché 256 = 233 + 10 + \ + 8 + . + 3; il 10qui è la lunghezza della stringa New folder.

Il file system di Windows pone un brutto problema se si desidera assicurare l'interoperabilità tra i file system.

3. Attenzione ai caratteri riservati e alle parole chiave

Oltre a rimuovere i caratteri non ASCII, non stampabili e di controllo , devi anche ri (posizionare / spostare):

"*/:<>?\|

Rimuovere questi caratteri potrebbe non essere la migliore idea perché il nome del file potrebbe perdere parte del suo significato. Penso che, almeno, le ricorrenze multiple di questi personaggi dovrebbero essere sostituite da un singolo trattino basso ( _), o forse qualcosa di più rappresentativo (questa è solo un'idea):

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

Ci sono anche parole chiave speciali che dovrebbero essere evitate (come NUL), anche se non sono sicuro di come risolverlo. Forse una lista nera con un fallback di nome casuale sarebbe un buon approccio per risolverlo.

4. Sensibilità ai casi

Ciò dovrebbe essere ovvio, ma se si desidera garantire l'unicità dei file tra diversi sistemi operativi, è necessario trasformare i nomi dei file in un caso normalizzato, in questo modo my_file.txte My_File.txtsu Linux non diventeranno entrambi lo stesso my_file.txtfile su Windows.

5. Assicurati che sia unico

Se il nome del file esiste già, è necessario aggiungere un identificatore univoco al nome del file di base.

Gli identificatori univoci comuni includono il timestamp UNIX, un digest del contenuto del file o una stringa casuale.

6. File nascosti

Solo perché può essere nominato non significa che dovrebbe ...

I punti sono di solito elencati in bianco nei nomi dei file, ma in Linux un file nascosto è rappresentato da un punto iniziale.

7. Altre considerazioni

Se devi eliminare alcuni caratteri del nome del file, l'estensione è generalmente più importante del nome di base del file. Consentendo un numero massimo considerevole di caratteri per l'estensione del file (8-16), è necessario rimuovere i caratteri dal nome di base. E 'anche importante notare che nel caso improbabile di avere un'estensione più di un tempo - come ad esempio _.graphmlz.tag.gz- _.graphmlz.tagsolo _dovrebbe essere considerato come il nome di base del file, in questo caso.

8. Risorse

Calibre gestisce il nome del file in modo abbastanza decadente:

Pagina di Wikipedia sulla manipolazione dei nomi dei file e capitolo collegato da Uso di Samba .


Se, ad esempio, provi a creare un file che viola una delle regole 1/2/3, otterrai un errore molto utile:

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

11

Ho sempre pensato che Kohana avesse fatto un ottimo lavoro .

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);
}

Il pratico UTF8::transliterate_to_ascii()trasformerà cose come ñ => n.

Ovviamente, potresti sostituire le altre UTF8::*cose con le funzioni mb_ *.


5

In termini di upload di file, sarebbe più sicuro impedire all'utente di controllare il nome del file. Come è già stato accennato, archiviare il nome file canonizzato in un database insieme a un nome univoco scelto casualmente che verrà utilizzato come nome file effettivo.

Utilizzando OWASP ESAPI, questi nomi potrebbero essere generati in questo modo:

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

È possibile aggiungere un timestamp a $ safeFilename per garantire che il nome file generato casualmente sia univoco senza nemmeno verificare la presenza di un file esistente.

In termini di codifica per URL e di nuovo utilizzando ESAPI:

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

Questo metodo esegue la canonicalizzazione prima di codificare la stringa e gestirà tutte le codifiche dei caratteri.


Sicuramente, inoltre, allontanando il controllo del nome file dagli utenti si eviterà la possibilità di 2 upload con lo stesso nome.
CodeVirtuoso

5

Raccomando * URLify per PHP (480+ stelle su Github) - "la porta PHP di URLify.js dal progetto Django. Traslittera caratteri non ascii da usare negli URL".

Utilizzo di base:

Per generare lumache per gli URL:

<?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"

?>

Per generare lumache per i nomi di file:

<?php

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

?>

* Nessuno degli altri suggerimenti corrisponde ai miei criteri:

  • Dovrebbe essere installabile tramite compositore
  • Non dovrebbe dipendere da iconv poiché si comporta in modo diverso su sistemi diversi
  • Dovrebbe essere estensibile per consentire sostituzioni e sostituzioni di caratteri personalizzati
  • Popolare (ad esempio molte stelle su Github)
  • Ha dei test

Come bonus, URLify rimuove anche determinate parole e rimuove tutti i caratteri non traslitterati.

Ecco un caso di test con tonnellate di caratteri stranieri che vengono traslitterati correttamente usando URLify: https://gist.github.com/motin/a65e6c1cc303e46900d10894bf2da87f


1
Grazie - sembra ideale per i miei scopi.
David Goodwin,

5

Mi sono adattato da un'altra fonte e ho aggiunto un paio di extra, forse un po 'eccessivo

/**
 * 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

e questa è la versione Joomla 3.3.2 di 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

Non credo che avere un elenco di caratteri da rimuovere sia sicuro. Preferirei usare quanto segue:

Per i nomi di file: utilizzare un ID interno o un hash del contenuto del file. Salva il nome del documento in un database. In questo modo è possibile mantenere il nome file originale e trovare comunque il file.

Per i parametri url: utilizzare urlencode()per codificare eventuali caratteri speciali.


1
Sono d'accordo, la maggior parte dei metodi elencati qui rimuove i personaggi pericolosi noti - il mio metodo rimuove tutto ciò che non è un personaggio sicuro conosciuto . Poiché la maggior parte dei sistemi slug codifica post URL, suggerirei di continuare a seguire questo metodo collaudato piuttosto che utilizzare l' URLencode non sicuro documentato UTF-8 ().
Xeoncross,

3

A seconda di come lo userete, potreste voler aggiungere un limite di lunghezza per proteggere dagli overflow del buffer.


Sì, test per mb_strlen () è sempre una cosa importante!
Xeoncross,

3

Questo è un bel modo per proteggere un nome file di caricamento:

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

Non ne sono così sicuro, perché uno .\x00..\x20può essere ridotto a .\x00\x20.
Xeoncross,

@Xeoncross: penso che .\x00..\x20rimuova i punti e ogni carattere tra \x00e \x20, mentre .\x00\x20dovrebbe rimuovere solo quei 3 byte.
Alix Axel,

Questa risposta richiede ulteriori spiegazioni per poter essere utilizzata in modo sicuro. Non ci sono molte informazioni sulla sintassi esatta per charlist in rete.
Manuel Arwed Schmidt,

3

Ecco l'implementazione di CodeIgniter.

/**
 * 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));
}

E la remove_invisible_charactersdipendenza.

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

perché non usare semplicemente php urlencode? sostituisce i caratteri "pericolosi" con la loro rappresentazione esadecimale per gli URL (cioè %20per uno spazio)


2
Il carattere% non è raccomandato per i nomi di file e i caratteri con codifica esadecimale non sembrano così belli nell'URL. I browser possono supportare stringhe UTF-8 che sono molto più belle e più facili per le lingue non ascii.
Xeoncross,

potresti fare un urlencode e POI uno str_replace ('% 20', '-', url)?
Francesco,

2

Esistono già diverse soluzioni per questa domanda, ma ho letto e testato la maggior parte del codice qui e ho finito con questa soluzione che è un mix di ciò che ho imparato qui:

La funzione

La funzione è raggruppata qui in un bundle Symfony2 ma può essere estratta per essere utilizzata come semplice PHP , ha solo una dipendenza con la iconvfunzione che deve essere abilitata:

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

Le unità test

La cosa interessante è che ho creato i test PHPUnit, prima per testare casi limite e quindi puoi verificare se si adatta alle tue esigenze: (Se trovi un bug, sentiti libero di aggiungere un caso test)

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');
    }
}

I risultati del test: (controllato su Ubuntu con PHP 5.3.2 e MacOsX con PHP 5.3.17:

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
Ciò presuppone input basati principalmente in latino. Aggiungi altri caratteri UTF-8 da altre lingue per vedere dove avrai problemi.
Xeoncross,

@Xeoncross Sono d'accordo, come ha detto Christian, bisogna salvare un ID o hash E il nome file originale. Ma questa funzione fornisce un'alternativa in quanto è possibile specificare una stringa predefinita quando il processo di disinfezione non riesce. Ho aggiunto un test unitario per questo caso. Grazie per aver segnalato il bug.
Bobina

2

Ho titoli di ingresso con tutti i tipi di strani caratteri latini e alcuni tag HTML che dovevo tradurre in un utile formato di file delimitato da trattini. Ho combinato la risposta di @ SoLoGHoST con un paio di elementi della risposta di @ Xeoncross e personalizzato un po '.

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

Avevo bisogno di aggiungere manualmente il carattere em dash (-) all'array di traduzione. Potrebbero essercene altri, ma finora i nomi dei miei file sembrano buoni.

Così:

Parte 1: "Žurburts" di mio padre? - Sono (non) i migliori!

diventa:

part-1-my-papà-zurburts-theyre-not-the-best

Aggiungo semplicemente ".html" alla stringa restituita.


1
'ľ' => 'l', 'Ľ' => 'L', 'č' => 'c', 'Č' => 'C', 'ť' => 't', 'Ť' => 'T', 'ň' => 'n', 'Ň' => 'N', 'ĺ' => 'l', 'Ĺ' => 'L', 'Ř' => 'R', 'ř' => 'r', 'ě' => 'e', 'Ě' => 'E', 'ů' => 'u', 'Ů' => 'U'
Mancano

1
E senza dubbio molti altri. In realtà sto cercando di capire se esiste un set ISO che include combinazioni di caratteri. Come si fa a "scegliere" un set se il contenuto richiede caratteri da tutti loro? UTF-8 Sto assumendo ...
cbmtrx il

Ho scoperto come trascrivere qualsiasi stringa usando una riga di PHP : $string = transliterator_transliterate('Any-Latin;Latin-ASCII;', $string);vedi la mia risposta qui sotto o leggi il post sul blog collegato.
Jasom Dotnet,

1
No, hai letto male: SE puoi installare estensioni PHP sul tuo server (o hosting) :-) Ecco il post .
Jasom Dotnet,

1
Ah, capito. Grazie @JasomDotnet - Ho la mia soluzione attuale funzionante per ora, ma è un set di caratteri limitato, quindi vale la pena verificare l'estensione.
cbmtrx,

2

Soluzione n. 1: hai la possibilità di installare estensioni PHP sul server (hosting)

Per la traslitterazione di "quasi ogni singola lingua sul pianeta Terra" in caratteri ASCII.

  1. Installare prima l'estensione PHP Intl . Questo è il comando per Debian (Ubuntu):sudo aptitude install php5-intl

  2. Questa è la mia funzione fileName (crea test.php e incolla il seguente codice):

<!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>

Questa linea è fondamentale:

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

Risposta basata su questo post .

Soluzione n. 2: non è possibile installare estensioni PHP sul server (hosting)

inserisci qui la descrizione dell'immagine

Il lavoro abbastanza buono viene svolto nel modulo di traslitterazione per CMS Drupal. Supporta quasi ogni singola lingua sul pianeta Terra. Suggerisco di controllare il repository di plugin se si desidera avere soluzioni di disinfezione delle stringhe davvero complete.



1

Questa è una buona funzione:

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

Questo sembra male. \\s+indica una barra rovesciata seguita da uno o più spazi bianchi. Di cosa si tratta? Inoltre, questo utilizza la blacklist anziché la whitelisting ignorando cose come CMD, null o BEL.
Xeoncross,

Ancora male. Ora stringhe come /blog/2014-02/just-in-timenon sono consentite. Si prega di utilizzare il codice testato sopra o utilizzare il phunctioncodice framework PHP.
Xeoncross,

Giusto. Questa funzione è solo per la parte "just-in-time". Potrebbe essere utile per alcune persone.
joan16v,

1
Puoi cambiare il regexpreg_replace('~[^\-\pL\pN\s]+~u', '-', $string)
Xeoncross il

Eccezionale! Ho anche aggiunto: string = trim ($ string, "-");
joan16v,

0

Questo è il codice utilizzato da Prestashop per disinfettare gli URL:

replaceAccentedChars

è usato da

str2url

per rimuovere i segni diacritici

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);

} 
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.