phpanfaenger: Verzeichnis erstellen und Umlaute entfernen

Hallo,

ich bin noch neu was die OOP bei PHP angeht.

Ich habe nun ein Script bzw. eine Klasse in der eine Funktion erstellt ist die nach dem Upload einer Datei in einem Userbereich ein Verzeichnis anhand der ObjektID anlegt, das geht auch ganz gut.

Problem ist, wenn die ObjektID Umlaute enthält, funktioniert der Aufruf der Dateien nicht mehr, daher würde ich die Funktion gerne so abändern, dass beim erstellen des Verzeichnisses Umlaute rausgeworfen werden.

Bislang sieht die Funktion wie folgt aus:

  
  
 public function createFolder() {  
  
        if (!is_dir($this->imageP)) {  
            if (!mkdir($this->imageP, 0777, true)) {  
                $this->lastError = 'Erstellung der Verzeichnisse schlug fehl...';  
                return false;  
            }  
        }  

So weit so gut. Wie kann ich nun den Inhalt von $this->imageP von Umlauten befreien bzw. diese umwandeln, das zum Beispiel ein Ü in der ObjectID in ue umgewandelt wird?

Vielen Dank schon mal!

Grüße

  1. So weit so gut. Wie kann ich nun den Inhalt von $this->imageP von Umlauten befreien bzw. diese umwandeln, das zum Beispiel ein Ü in der ObjectID in ue umgewandelt wird?

    Mit einer simplen Zeichenersetzung - str_replace() lässt sich auch mit arrays füttern.

    Aber mal so nebenbei: warumw illst du ein Ü in einem Dateinamen ersetzen? Was stört dich daran?

    1. Aber mal so nebenbei: warumw illst du ein Ü in einem Dateinamen ersetzen? Was stört dich daran?

      Weil wenn ein Verzeichnis mit Umlaut erstellt wird, können die Dateien von dort nicht ausgelesen werden, das Array für die Ausgabe bleibt leer, ich habe leider keine Ahnung warum.

      Funktioniert das so?

        
      public function createFolderSt() {  
              if (!is_dir($this->imagePath)) {  
      			$suchen = array("ä", "ö", "ü", "Ä", "Ö", "Ü");  
      			$ersetzen = array("ae", "oe", "ue", "Ae", "Oe", "Ue");  
      			$newpath = str_replace($vokale, $ersetzen, $this->imagePath);  
                  if (!mkdir(newpath 0777, true)) {  
                      $this->lastError = 'Erstellung der Verzeichnisse schlug fehl...';  
                      return false;  
                  }  
              }
      
      1. Weil wenn ein Verzeichnis mit Umlaut erstellt wird, können die Dateien von dort nicht ausgelesen werden, das Array für die Ausgabe bleibt leer, ich habe leider keine Ahnung warum.

        Funktioniert das so?

        Ja - prinzipiell, aber ich gehe davon aus, dass du die Tragweite deines Vorhabens nicht abschätzen kannst. Diese Transkription ist augenscheinlich ganz einfach, aber die möglichen Zeichen die bei dir Probleme machen könnten sind schier unendlich. Es sind nicht einfach 10, 20 oder 100 Zeichen die du hier ersetzen müsstest.

        Es ist also wesentlich zielführender dein eigentliches Problem zu lösen als hier zu versuchen einen Eisberg zu umschiffen, dessen wahre Größe unter dem Meersspiegel verborgen liegt.

        TYPO3 erledigt die Transkription für Pfade z.B. mit csConvObj in der Klasse t3lib_cs

        Ein kleiner Auszug der entsprechenden Tabellen findet sich unter t3lib/unidata/

        Ein weiterer Teil unter t3lib/csconvtbl/

        1. Hi,

          Ja - prinzipiell, aber ich gehe davon aus, dass du die Tragweite deines Vorhabens nicht abschätzen kannst. Diese Transkription ist augenscheinlich ganz einfach, aber die möglichen Zeichen die bei dir Probleme machen könnten sind schier unendlich. Es sind nicht einfach 10, 20 oder 100 Zeichen die du hier ersetzen müsstest.

          Es ist also wesentlich zielführender dein eigentliches Problem zu lösen als hier zu versuchen einen Eisberg zu umschiffen, dessen wahre Größe unter dem Meersspiegel verborgen liegt.

          was ist denn falsch an iconv mit '//TRANSLIT'?

          Bis die Tage,
          Matti

          1. was ist denn falsch an iconv mit '//TRANSLIT'?

            prinzipiell nichts - nur funktioniert der Spaß nicht, wenn man nicht grade ö zu oe ersetzen will :)

        2. Hello,

          Es ist also wesentlich zielführender dein eigentliches Problem zu lösen als hier zu versuchen einen Eisberg zu umschiffen, dessen wahre Größe unter dem Meersspiegel verborgen liegt.

          Ich finde es im Moment immer noch wesentlich treffender, das Problem nicht erst lösen zu wollen, wenn es schon da ist, sondern es gleich zu vermeiden bevor es auftritt und daher überhaupt keine Dateinamen zuzulassen, die Zeichen außerhalb des druckbaren Bereiches des ersten Septetts enthalten.

          Man erspart sich beim Hin und Her mit Dateien viel Kummer, wenn man nur derartig reduzierte Namen akzeptiert. Das nennt sich dann "WEB 2.0²" oder "Marketing". Lass immer die User die Arbeit machen und anständig dafür bezahlen :-P

          Liebe Grüße aus dem schönen Oberharz

          Tom vom Berg

          --
           ☻_
          /▌
          / \ Nur selber lernen macht schlau
          http://bergpost.annerschbarrich.de
          1. Okay, meine Lösung macht eh keinen Sinn, die Ordner werden zwar korrekt angelegt, aber da die ID mit Umlaut ist, fehlt natürlich der Bezug, also sinnfrei.

            Das Problem ist einfach eine Seite wo auf Bilder in Verzeichnissen zugegriffen wird, welche angelegt werden, sobald man eine Datei hochlädt, das geschieht wiederum indem man das Objekt bearbeitet, also die ObjectID nötig ist und diese muss Umlaute erlauben, man kann vom User nicht erwarten das er diese entfernt.

            Also ohne Umlaute werden Bilder angezeigt, mit Umlaute (in einem Beispiel ein ö in der ObjectID) keine Chance, ich habe das mit Printer mal ausgeben lassen, mit Umlaute bleibt das Array leer.

            Die Funktion sieht erstmal so aus:

              
            public function getRessources() {  
                    if (!($this->ressourceManager instanceof RessourceManager)) {  
                        $this->ressourceManager = new RessourceManager($this->verwalter_id, $this->id);  
                    }  
                    return $this;  
                }  
              
                public function getImages() {  
                    return $this->ressourceManager->getImages();  
                } 
            

            In der Funktion getRessources werden scheinbar die Daten geladen, wenn man das Objekt mit Printer ausgibt erhält man die Pfade.

            Die Funktion getImages ruft dann aber ein Array auf welches die Pfade der Bilder nacheinander ausgibt und dieses ist leer.

              
            public function getRessources($resPath, $res = self::IMAGES_FOLDER) {  
              
                    $resArr = array();  
                    if ($handle = opendir($resPath)) {  
            			  
            			    /* Das ist der korrekte Weg, ein Verzeichnis zu durchlaufen. */  
            			    while (false !== ($file = readdir($handle))) {  
            			    	  if ($file != "." && $file != "..") {  
            				        $ressource = new stdClass();  
            		            $ressource->fileName = $file;  
            		            //$ressource->createDate = date('d-m-Y H:i', $file->getMTime());  
            		            $ressource->webPath = sprintf('https://www.domain.de/uploads/%s/%s/%s/%s', $this->userID, $this->objectID, $res, $file);  
            		            array_push($resArr, $ressource);  
            	          }  
            			    }  
            			  
              
            					    closedir($handle);  
            					}  
              
              
                    return $resArr;  
                }  
                
            

            Ich frage mich nur warum, ob das wirklich an den Umlauten liegt und ob sich da irgendwas ändern lässt?

            1. Hello,

              [...] man kann vom User nicht erwarten das er diese entfernt.

              Man kann vom User alles verlangen, sofern er einen Nutzen in Anspruch nehmen will und (leicht) verstehen kann, was man von ihm will, damit er Zugang zum Nutzen erhält. Dies sollte von normal intelligenten Menschen aber trotzdem in maximal einem zusätzlichen Arbeitsschritt zu erledigen sein.

              Wer den Usern "Captchas" abverlangen kann, kann ihnen auch ganz leicht das Umschreiben eines Dateinamens abverlangen. Das jetzt nur als Rechtfertigung für meinen Vorschlag, nicht also als Unterstellung, dass Du sowas jemals tun würdest :-)

              Liebe Grüße aus dem schönen Oberharz

              Tom vom Berg

              --
               ☻_
              /▌
              / \ Nur selber lernen macht schlau
              http://bergpost.annerschbarrich.de
            2. Tach!

              Das Problem ist einfach eine Seite wo auf Bilder in Verzeichnissen zugegriffen wird, welche angelegt werden, sobald man eine Datei hochlädt, das geschieht wiederum indem man das Objekt bearbeitet, also die ObjectID nötig ist und diese muss Umlaute erlauben, man kann vom User nicht erwarten das er diese entfernt.

              Du erwartest aber vom User, dass er eine bestimmte Stringlänge nicht überschreitet und sich bei den anderen (Sonder-)Zeichen an solche hält, die in einem Dateinamen verwendet werden können. Wenn ich das richtig sehe, verwendest du sie auch ohne weitere Behandlung im URL-Kontext. Vielleicht hättest du ja das Thema gar nicht weiter beachtet, wenn du nicht mit Umlauten ein Problem bekommen hättest.

              Also ohne Umlaute werden Bilder angezeigt, mit Umlaute (in einem Beispiel ein ö in der ObjectID) keine Chance, ich habe das mit Printer mal ausgeben lassen, mit Umlaute bleibt das Array leer.

              Es verschwinden nicht einfach so Zeichen, Strings oder Array-Einträge. Nur äußerst selten wirst du auf einen Fehler innerhalb PHPs stoßen, der solche Auswirkungen hätte. Die Ursache liegt also in deinem Code, davon kannst du ausgehen. Verwende var_dump() für die Kontrollausgaben, und wenn du ein Problem mit Zeichenkodierung vermutest, kannst du urlencode() missbrauchen. Das lässt im Gegensatz zu einem bin2hex() lateinische Buchstaben ungeschoren und zeigt für alle anderen Zeichen die Bytewerte an.

              Die Funktion sieht erstmal so aus:

              Dein Code ist irgendwie nicht richtig nachvollziehbar. Da gibt es zweimal die Methode getRessources() und getImages() ruft ein weiteres getImages() auf. Du erwähnst nicht, welchen Klassen diese Funktionen zugehören und auch bei der Problembeschreibung lässt du diese Information weg. Ein Zusammenspiel, wie welche Daten wohin gelangen, ist nicht zu erkennen.

              Es ist verständlich, wenn du nicht den gesamten Code posten möchtest und das ist auch nicht erforderlich/erwünscht. Extrahiere das Problem in eine neue Datei, so dass es lauffähig und damit für Außenstehende nachvollziehbar ist, entferne aber alles unwichtige, so dass so wenig Code wie möglich übrigbleibt.

              $ressource->webPath = sprintf('https://www.domain.de/uploads/%s/%s/%s/%s', $this->userID, $this->objectID, $res, $file);

              Der Kontextwechsel muss auch bei URLs beachtet werden. Und für Beispiel-Domains muss man keine real existierenden Namen verwenden, es gibt extra dafür vorgesehene: http://de.wikipedia.org/wiki/Domain#Sonderf.C3.A4lle

              array_push($resArr, $ressource);

              Beachte die Hinweise zur Funktion array_push().

              dedlfix.

    2. Tach!

      Mit einer simplen Zeichenersetzung - str_replace() lässt sich auch mit arrays füttern.

      strtr() in der zweiten Variante finde ich besser. Da stehen sich Wert und Substitut direkt gegenüber und nicht auf zwei Arrays aufgetrennt.

      dedlfix.

  2. Hello,

    if (!mkdir($this->imageP, 0777, true)) {

    Ich möchte nebenbei mal loswerden, dass die Rechtemaske 0777 die Blödeste ist, die man benutzen kann :-P

    Eigentümer und Gruppenzugehörigkeit sollten vorher auf jeden Fall berücksichtigt werden und ob der Fileserviceadmin z.B. das GID-Flag gesetzt hat (bei unixoiden Systemen) ...

    Liebe Grüße aus dem schönen Oberharz

    Tom vom Berg

    --
     ☻_
    /▌
    / \ Nur selber lernen macht schlau
    http://bergpost.annerschbarrich.de