Ich versuche, eine Funktion zu entwickeln, mit der bestimmte Zeichenfolgen gut bereinigt werden können, damit sie sicher in der URL verwendet werden können (wie ein Post-Slug) und auch sicher als Dateinamen verwendet werden können. Wenn zum Beispiel jemand eine Datei hochlädt, möchte ich sicherstellen, dass alle gefährlichen Zeichen aus dem Namen entfernt werden.
Bisher habe ich die folgende Funktion entwickelt, die dieses Problem hoffentlich löst und auch fremde UTF-8-Daten zulässt.
/**
* 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');
}
Hat jemand knifflige Beispieldaten, die ich dagegen ausführen kann - oder kennt er einen besseren Weg, um unsere Apps vor schlechten Namen zu schützen?
$ is-filename erlaubt einige zusätzliche Zeichen wie temporäre VIM-Dateien
Update: Das Sternzeichen wurde entfernt, da mir keine gültige Verwendung einfiel
quelle
Antworten:
Einige Beobachtungen zu Ihrer Lösung:
Schnecke erstellen
Sie sollten wahrscheinlich keine Zeichen mit Akzent usw. in Ihren Post-Slug aufnehmen, da diese technisch gesehen prozentual codiert sein sollten (gemäß den URL-Codierungsregeln), damit Sie hässlich aussehende URLs haben.
Wenn ich Sie wäre, würde ich nach dem Kleinbuchstaben alle 'Sonderzeichen' in ihre Entsprechungen (z. B. é -> e) konvertieren und Nicht-[az] -Zeichen durch '-' ersetzen, was sich auf Läufe eines einzelnen '-' beschränkt. wie du es getan hast. Hier können Sie Sonderzeichen konvertieren: https://web.archive.org/web/20130208144021/http://neo22s.com/slug
Desinfektion im Allgemeinen
OWASP verfügt über eine PHP-Implementierung seiner Enterprise Security-API, die unter anderem Methoden zum sicheren Codieren und Decodieren von Ein- und Ausgaben in Ihrer Anwendung enthält.
Die Encoder-Schnittstelle bietet:
https://github.com/OWASP/PHP-ESAPI https://www.owasp.org/index.php/Category:OWASP_Enterprise_Security_API
quelle
สังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่.txt
und dann eine UTF-8-HTML-Datei mit einem Link dazu erstellt. Erstaunlicherweise hat es funktioniert - sogar unter Fenstern! Allerdings hatte ich dann PHPfile_put_contents('สังเวช พระปกเกศกองบู๊กู้ขึ้นใหม่.txt')
und es konnte kein Basar-Dateiname aus dieser Zeichenfolge erstellt werden. Dann habe ich versucht, es mit zu erstellenfopen()
und habe den gleichen durcheinandergebrachten Dateinamen erhalten. Offensichtlich ist PHP (zumindest unter Windows) nicht in der Lage, UTF-8-Dateinamen zu erstellen. bugs.php.net/bug.php?id=46990&thanks=6Ich habe diese größere Funktion im Chyrp- Code gefunden:
und dieser im WordPress- Code
Update September 2012
Alix Axel hat in diesem Bereich unglaubliche Arbeit geleistet. Sein Phunction-Framework enthält mehrere großartige Textfilter und Transformationen.
quelle
apply_filters
/[\s-]+/
mit-
denen ist besser als die erste Version (die nur ersetzt/\s+/
) , die mehrere Striche in Folge führen kannDies sollte Ihre Dateinamen sicher machen ...
und eine tiefere Lösung dafür ist:
Dies setzt voraus, dass Sie einen Punkt im Dateinamen möchten. Wenn Sie möchten, dass es in Kleinbuchstaben übertragen wird, verwenden Sie einfach
für die letzte Zeile.
quelle
'ľ' => 'l', 'Ľ' => 'L', 'č' => 'c', 'Č' => 'C', 'ť' => 't', 'Ť' => 'T', 'ň' => 'n', 'Ň' => 'N', 'ĺ' => 'l', 'Ĺ' => 'L', 'Ř' => 'R', 'ř' => 'r', 'ě' => 'e', 'Ě' => 'E', 'ů' => 'u', 'Ů' => 'U'
Versuche dies:
Basierend auf der ausgewählten Antwort in diesem Thread: URL-freundlicher Benutzername in PHP?
quelle
trim()
sollte auch seintrim($string, '-')
.preg_replace()
sollte alle gefährlichen Zeichen entfernen.Dies ist nicht gerade eine Antwort, da es (noch!) Keine Lösungen bietet, aber es ist zu groß, um auf einen Kommentar zu passen ...
Ich habe einige Tests (in Bezug auf Dateinamen) unter Windows 7 und Ubuntu 12.04 durchgeführt und dabei festgestellt, dass:
1. PHP kann keine Nicht-ASCII-Dateinamen verarbeiten
Obwohl sowohl Windows als auch Ubuntu Unicode-Dateinamen verarbeiten können (auch RTL-Dateinamen, wie es scheint), erfordert PHP 5.3 Hacks, um auch mit dem einfachen alten ISO-8859-1 fertig zu werden. Daher ist es aus Sicherheitsgründen besser, ASCII beizubehalten.
2. Die Länge des Dateinamens ist wichtig (speziell unter Windows)
Unter Ubuntu beträgt die maximale Länge eines Dateinamens (einschließlich Erweiterung) 255 (ohne Pfad):
Unter Windows 7 (NTFS) hängt die maximale Länge eines Dateinamens jedoch von seinem absoluten Pfad ab:
Wikipedia sagt, dass:
Nach meinem besten Wissen (und Testen) ist dies falsch.
Insgesamt (Schrägstriche zählen) haben alle diese Beispiele 259 Zeichen, wenn Sie das entfernen
C:\
, das 256 Zeichen ergibt (nicht 255?!). Die Verzeichnisse wurden mit dem Explorer erstellt, und Sie werden feststellen, dass er nicht den gesamten verfügbaren Speicherplatz für den Verzeichnisnamen verwendet. Der Grund dafür ist, die Erstellung von Dateien unter Verwendung der 8.3-Dateinamenskonvention zu ermöglichen . Das gleiche passiert für andere Partitionen.Dateien müssen natürlich nicht die Anforderungen für 8,3 Längen reservieren:
Sie können keine Unterverzeichnisse mehr erstellen, wenn der absolute Pfad des übergeordneten Verzeichnisses mehr als 242 Zeichen enthält
256 = 242 + 1 + \ + 8 + . + 3
. Mit Windows Explorer können Sie kein anderes Verzeichnis erstellen, wenn das übergeordnete Verzeichnis mehr als 233 Zeichen enthält (abhängig vom Gebietsschema des Systems)256 = 233 + 10 + \ + 8 + . + 3
. Das10
hier ist die Länge der ZeichenfolgeNew folder
.Das Windows-Dateisystem stellt ein unangenehmes Problem dar, wenn Sie die Interoperabilität zwischen Dateisystemen sicherstellen möchten.
3. Achten Sie auf reservierte Zeichen und Schlüsselwörter
Neben dem Entfernen von Nicht-ASCII-, nicht druckbaren und Steuerzeichen müssen Sie auch Folgendes neu platzieren (platzieren / verschieben):
Das Entfernen dieser Zeichen ist möglicherweise nicht die beste Idee, da der Dateiname möglicherweise etwas an Bedeutung verliert. Ich denke, dass zumindest mehrere Vorkommen dieser Zeichen durch einen einzigen Unterstrich (
_
) oder vielleicht etwas Repräsentativeres ersetzt werden sollten (dies ist nur eine Idee):"*?
->_
/\|
->-
:
->[ ]-[ ]
<
->(
>
->)
Es gibt auch spezielle Schlüsselwörter, die vermieden werden sollten (wie
NUL
), obwohl ich nicht sicher bin, wie ich das überwinden soll. Vielleicht wäre eine schwarze Liste mit einem zufälligen Fallback ein guter Ansatz, um sie zu lösen.4. Groß- und Kleinschreibung
Dies sollte selbstverständlich sein. Wenn Sie jedoch die Eindeutigkeit von Dateien unter verschiedenen Betriebssystemen sicherstellen möchten, sollten Sie die Dateinamen in einen normalisierten Fall umwandeln. Auf diese Weise
my_file.txt
undMy_File.txt
unter Linux werden untermy_file.txt
Windows nicht beide zur gleichen Datei.5. Stellen Sie sicher, dass es einzigartig ist
Wenn der Dateiname bereits vorhanden ist, sollte eine eindeutige Kennung an den Basisdateinamen angehängt werden .
Zu den allgemeinen eindeutigen Kennungen gehören der UNIX-Zeitstempel, eine Zusammenfassung des Dateiinhalts oder eine zufällige Zeichenfolge.
6. Versteckte Dateien
Nur weil es benannt werden kann, heißt das nicht, dass es ...
Punkte werden normalerweise in Dateinamen auf die weiße Liste gesetzt, aber unter Linux wird eine versteckte Datei durch einen führenden Punkt dargestellt.
7. Andere Überlegungen
Wenn Sie einige Zeichen des Dateinamens entfernen müssen, ist die Erweiterung normalerweise wichtiger als der Basisname der Datei. Wenn Sie eine beträchtliche maximale Anzahl von Zeichen für die Dateierweiterung (8-16) zulassen, sollten Sie die Zeichen vom Basisnamen entfernen. Es ist auch wichtig , dass in dem unwahrscheinlichen Fall zu beachten , von einer mehr als eine langen Verlängerung mit - wie
_.graphmlz.tag.gz
-_.graphmlz.tag
nur_
als Dateibasisnamen in diesem Fall in Betracht gezogen werden sollte.8. Ressourcen
Calibre geht ziemlich anständig mit dem Mangeln von Dateinamen um:
Wikipedia-Seite zum Mangeln von Dateinamen und zum verknüpften Kapitel von Using Samba .
Wenn Sie beispielsweise versuchen, eine Datei zu erstellen, die gegen eine der Regeln 1/2/3 verstößt, wird eine sehr nützliche Fehlermeldung angezeigt:
quelle
Ich habe immer gedacht, dass Kohana einen ziemlich guten Job gemacht hat .
Das Handy
UTF8::transliterate_to_ascii()
dreht Sachen wie ñ => n.Natürlich können Sie die anderen
UTF8::*
Dinge durch mb_ * -Funktionen ersetzen .quelle
In Bezug auf das Hochladen von Dateien ist es am sichersten, zu verhindern, dass der Benutzer den Dateinamen kontrolliert. Speichern Sie, wie bereits angedeutet, den kanonisierten Dateinamen in einer Datenbank zusammen mit einem zufällig ausgewählten und eindeutigen Namen, den Sie als tatsächlichen Dateinamen verwenden.
Mit OWASP ESAPI können diese Namen folgendermaßen generiert werden:
Sie können einen Zeitstempel an den $ safeFilename anhängen, um sicherzustellen, dass der zufällig generierte Dateiname eindeutig ist, ohne nach einer vorhandenen Datei zu suchen.
In Bezug auf die Kodierung der URL und erneut die Verwendung von ESAPI:
Diese Methode führt vor dem Codieren der Zeichenfolge eine Kanonisierung durch und verarbeitet alle Zeichencodierungen.
quelle
Ich empfehle * URLify für PHP (480+ Sterne auf Github) - "den PHP-Port von URLify.js aus dem Django-Projekt. Transliteriert Nicht-ASCII-Zeichen zur Verwendung in URLs".
Grundlegende Verwendung:
So generieren Sie Slugs für URLs:
So generieren Sie Slugs für Dateinamen:
* Keiner der anderen Vorschläge entsprach meinen Kriterien:
Als Bonus entfernt URLify auch bestimmte Wörter und entfernt alle nicht transliterierten Zeichen.
Hier ist ein Testfall, bei dem Tonnen von Fremdzeichen mithilfe von URLify ordnungsgemäß transliteriert werden: https://gist.github.com/motin/a65e6c1cc303e46900d10894bf2da87f
quelle
Ich habe mich aus einer anderen Quelle angepasst und ein paar zusätzliche hinzugefügt, vielleicht ein wenig übertrieben
quelle
und das ist Joomla 3.3.2 Version von
JFile::makeSafe($file)
quelle
Ich denke nicht, dass es sicher ist, eine Liste mit Zeichen zu haben, die entfernt werden müssen. Ich würde lieber folgendes verwenden:
Für Dateinamen: Verwenden Sie eine interne ID oder einen Hash des Dateiinhalts. Speichern Sie den Dokumentnamen in einer Datenbank. Auf diese Weise können Sie den ursprünglichen Dateinamen beibehalten und die Datei trotzdem finden.
Für URL-Parameter: Verwenden Sie diese Option
urlencode()
, um Sonderzeichen zu codieren.quelle
Je nachdem, wie Sie es verwenden, möchten Sie möglicherweise eine Längenbeschränkung hinzufügen, um sich vor Pufferüberläufen zu schützen.
quelle
Dies ist eine gute Möglichkeit, einen Upload-Dateinamen zu sichern:
quelle
.\x00..\x20
kann sich darauf reduzieren.\x00\x20
..\x00..\x20
entfernt Punkte und jedes Zeichen zwischen\x00
und\x20
, während.\x00\x20
nur diese 3 Bytes entfernen sollten.Hier ist die Implementierung von CodeIgniter.
Und die
remove_invisible_characters
Abhängigkeit.quelle
warum nicht einfach PHPs verwenden
urlencode
? Es ersetzt "gefährliche" Zeichen durch ihre hexadezimale Darstellung für URLs (dh%20
für ein Leerzeichen).quelle
Es gibt bereits mehrere Lösungen für diese Frage, aber ich habe den größten Teil des Codes hier gelesen und getestet und bin zu dieser Lösung gekommen, die eine Mischung aus dem ist, was ich hier gelernt habe:
Die Funktion
Die Funktion ist hier in einem Symfony2- Bundle gebündelt, kann jedoch extrahiert werden, um als einfaches PHP verwendet zu werden. Sie hängt nur von der
iconv
Funktion ab, die aktiviert werden muss:Filesystem.php :
Das Gerät testet
Interessant ist, dass ich PHPUnit-Tests erstellt habe, um zunächst Randfälle zu testen. So können Sie überprüfen, ob sie Ihren Anforderungen entsprechen: (Wenn Sie einen Fehler finden, können Sie einen Testfall hinzufügen.)
FilesystemTest.php :
Die Testergebnisse: (unter Ubuntu mit PHP 5.3.2 und MacOsX mit PHP 5.3.17 überprüft:
quelle
Ich habe Eintragstitel mit allen Arten von seltsamen lateinischen Zeichen sowie einige HTML-Tags, die ich in ein nützliches, durch Bindestriche getrenntes Dateinamenformat übersetzen musste. Ich habe die Antwort von @ SoLoGHoST mit ein paar Elementen aus der Antwort von @ Xeoncross kombiniert und ein wenig angepasst.
Ich musste das em-Strichzeichen (-) manuell zum Übersetzungsarray hinzufügen. Es mag andere geben, aber bisher sehen meine Dateinamen gut aus.
So:
Teil 1: Die "Žurburts" meines Vaters? - sie sind (nicht) die besten!
wird:
Teil-1-meine-Väter-zurburts-sie sind-nicht-die-besten
Ich füge einfach ".html" zur zurückgegebenen Zeichenfolge hinzu.
quelle
'ľ' => 'l', 'Ľ' => 'L', 'č' => 'c', 'Č' => 'C', 'ť' => 't', 'Ť' => 'T', 'ň' => 'n', 'Ň' => 'N', 'ĺ' => 'l', 'Ĺ' => 'L', 'Ř' => 'R', 'ř' => 'r', 'ě' => 'e', 'Ě' => 'E', 'ů' => 'u', 'Ů' => 'U'
$string = transliterator_transliterate('Any-Latin;Latin-ASCII;', $string);
Siehe meine Antwort unten oder lesen Sie den verlinkten Blog-Beitrag.Lösung 1: Sie können PHP-Erweiterungen auf dem Server installieren (Hosting)
Für die Transliteration von "fast jeder einzelnen Sprache auf dem Planeten Erde" in ASCII-Zeichen.
Installieren Sie zuerst die PHP Intl- Erweiterung. Dies ist der Befehl für Debian (Ubuntu):
sudo aptitude install php5-intl
Dies ist meine Dateinamenfunktion (erstelle test.php und füge dort folgenden Code ein):
Diese Linie ist der Kern:
Antwort basierend auf diesem Beitrag .
Lösung 2: Sie können keine PHP-Erweiterungen auf dem Server installieren (Hosting)
Das Transliterationsmodul für CMS Drupal leistet ziemlich gute Arbeit . Es unterstützt fast jede einzelne Sprache auf dem Planeten Erde. Ich schlage vor, das Plugin- Repository zu überprüfen, wenn Sie wirklich vollständige Lösungsbereinigungszeichenfolgen haben möchten.
quelle
Dieser Beitrag scheint unter allen, die ich gebunden habe, am besten zu funktionieren. http://gsynuh.com/php-string-filename-url-safe/205
quelle
Dies ist eine gute Funktion:
quelle
\\s+
bedeutet einen Backslash, gefolgt von einem oder mehreren Leerzeichen. Worum geht es? Dies verwendet auch Blacklisting anstelle von Whitelisting, wobei Dinge wieCMD
null oder ignoriert werdenBEL
./blog/2014-02/just-in-time
nicht erlaubt. Bitte verwenden Sie den oben getesteten Code oder denphunction
PHP-Framework-Code.preg_replace('~[^\-\pL\pN\s]+~u', '-', $string)
Dies ist der Code, der von Prestashop verwendet wird, um URLs zu bereinigen:
wird verwendet von
diakritische Mittel zu entfernen
quelle
Es gibt zwei gute Antworten, um Ihre Daten zu verschlechtern. Verwenden Sie dazu https://stackoverflow.com/a/3987966/971619 oder https://stackoverflow.com/a/7610586/971619
quelle
quelle