Sandra: php ARRAY einlesen und bestimmte Begriffe behalten und andere ARRAY Teile löschen

Guten Tag,

vielleicht könnt ihr mir weiterhelfen. Ich habe ein Verzeichnis in dem viele Bilder liegen, hiervon möchte ich mir ein Zufallsbild anzeigen lassen. Allerding sollte im Dateinamen des Bilder auch noch das Wort Stadt stehen.

Im Verzeichnis BILDER liegen also:

  • stadt_mainz.jpg
  • dorf_sassen.jpg
  • stadt_hamburg.jpg

Ich lese das Verzeichnis mit php aus.

$meine-Bilder = scandir('bilder');

. . Hier ist mein Problem, wie kann ich alle Array Teile löschen die kein 'stadt' im Dateinamen haben . .

Dann gebe ich das Zufallsbild aus

echo array_rand($meine-Bilder,1));

so weit meine Theorie.

Aber ich komme mit dem durchsuchen das arrays nicht klar.

Sandra

  1. @@Sandra

    Hier ist mein Problem, wie kann ich alle Array Teile löschen die kein 'stadt' im Dateinamen haben

    array-filter()

    Jolan tru

    --
    Wenn der Faschismus wiederkehrt, wird er nicht sagen „Hallo, ich bin der Faschismus.“ Er wird sagen: „Ich suche in diesem Deutschen Bundestag keine anderen Mehrheiten als die in der demokratischen Mitte. Wenn es heute eine solche Mehrheit gegeben hat, bedauere ich das.“ (Friedrich Merz)
    1. Lieber Gunnar,

      array-filter()

      jetzt wollte ich wissen, wie Du das mit den zweierlei Farben gemacht hast. Das fand ich irgendwie cool. Jetzt, da ich Deinen Quelltext sehe, merke ich, dass Du nur den falschen Strich getippt hast, nämlich ein Minus-Zeichen anstelle eines Unterstrichs. -.- [array_filter()]

      Liebe Grüße

      Felix Riesterer

      1. @@Felix Riesterer

        Jetzt, da ich Deinen Quelltext sehe, merke ich, dass Du nur den falschen Strich getippt hast, nämlich ein Minus-Zeichen anstelle eines Unterstrichs.

        Nein, das würde ich nie tun. Ich hab einen Bindestrich getippt.

        Ganz ehrlich: Der Unterstrich hätte nie den Sprung von der Schreibmaschinentastatur[1] zur Computertastatur schaffen dürfen. Das Zeichen sollte es nicht geben. Vernünftige Programmiersprachen verwenden camelCase.

        Jolan tru

        --
        Wenn der Faschismus wiederkehrt, wird er nicht sagen „Hallo, ich bin der Faschismus.“ Er wird sagen: „Ich suche in diesem Deutschen Bundestag keine anderen Mehrheiten als die in der demokratischen Mitte. Wenn es heute eine solche Mehrheit gegeben hat, bedauere ich das.“ (Friedrich Merz)

        1. Dort tatsächlich für Unterstreichungen. ↩︎

        1. Lieber Gunnar,

          ein Minus-Zeichen anstelle eines Unterstrichs.

          Nein, das würde ich nie tun. Ich hab einen Bindestrich getippt.

          naja, in PHP ist der als Bestandteil eines Namens ebenso ungültig.

          Ganz ehrlich: Der Unterstrich hätte nie den Sprung von der Schreibmaschinentastatur zur Computertastatur schaffen dürfen. Das Zeichen sollte es nicht geben. Vernünftige Programmiersprachen verwenden camelCase.

          Seit wann sind denn Programmierer vernünftig? Wenn man schaut, wieviele Projekte mittlerweile einen code of conduct benötigen... Und der Unterstrich ist sehr gut dazu geeignet, Namen zu markieren, weil sie z.B. eine lokale Variable oder eine private Eigenschaft bezeichnen. Warum man in JavaScript das Hashtag-Zeichen für private Eigenschaften/Methoden eingeführt hat, anstatt den Unterstrich zu verwenden, weiß ich nicht. Es ist mir auch herzlich wurschd.

          Liebe Grüße

          Felix Riesterer

        2. Hallo Gunnar,

          array-filter()

          COBOL lässt grüßen? 😜

          Der Unterstrich hätte nie den Sprung von der Schreibmaschinentastatur zur Computertastatur schaffen dürfen.

          Aber klar doch. In den Zeiten der alten Kettendrucker wurde unterstrichen und fettgedruckt, indem man dem Drucker sagte: 0 Zeilen vorschieben und dann eine Reihe Unterstriche bzw. den gleichen Text nochmal druckte. Dafür gab's bei Ausgaben auf den Lineprinter in Spalte 1 extra das ASA Vorschubsteuerzeichen. Mein Gott, waren die Dinger laut. Aber dafür fix!

          Vernünftige Programmiersprachen verwenden camelCase.

          Und sind dazu auch case-insensitive.

          Rolf

          --
          sumpsi - posui - obstruxi
  2. Du baust einen zweiten Array.

    Du geht mit foreach alle gefundenden Dateinamen durch, testest mit preg_match ob er Dir gefällt und wenn das so ist hängst Du den aktuellen Dateiname an den Array an.

    <?php
    
    $allFiles= [];
    $myFiles = [];
    
    $allFiles = scandir( '/foo/bar/pics' );
    foreach ( $allFiles as $f ) {
    	if ( preg_match( '/^FirstChars/', $f ) ) {
    		$myFiles[] = $f;
    	}
    }
    print_r( $myFiles );
    ?>
    
    1. @@Raketenwilli

      Du baust einen zweiten Array.

      Ja.

      Du geht mit foreach alle gefundenden Dateinamen durch

      Nö, warum sollte man das tun, wenn es doch eine Funktion dafür gibt?

      Jolan tru

      --
      Wenn der Faschismus wiederkehrt, wird er nicht sagen „Hallo, ich bin der Faschismus.“ Er wird sagen: „Ich suche in diesem Deutschen Bundestag keine anderen Mehrheiten als die in der demokratischen Mitte. Wenn es heute eine solche Mehrheit gegeben hat, bedauere ich das.“ (Friedrich Merz)
      1. Nö, warum sollte man das tun, wenn es doch eine Funktion dafür gibt?

        Weil Sandra mit den Basics anfängt, nicht mit callbacks. Hatte schon wegen des Vorschlags preg_match() Bauchschmerzen.

        1. @@Raketenwilli

          Nö, warum sollte man das tun, wenn es doch eine Funktion dafür gibt?

          Weil Sandra mit den Basics anfängt, nicht mit callbacks. Hatte schon wegen des Vorschlags preg_match() Bauchschmerzen.

          Zurecht. Wenn die Dateinamen so sind wie im OP angegeben, dann braucht man keinen Regexp. Dann tut’s auch str_starts_with().

          Und callback anhand der verlinkten Beispiele nachzuvollziehen dürfte nicht schwieriger sein als foreach ( $allFiles as $f ) und $myFiles[] = $f;, was beides auch nicht gerade intuitiv verständlich ist.

          Und wenn du Wert auf lesbaren Code legst, verwende doch bitte sprechende Variablennamen, nicht $f.

          Jolan tru

          --
          Wenn der Faschismus wiederkehrt, wird er nicht sagen „Hallo, ich bin der Faschismus.“ Er wird sagen: „Ich suche in diesem Deutschen Bundestag keine anderen Mehrheiten als die in der demokratischen Mitte. Wenn es heute eine solche Mehrheit gegeben hat, bedauere ich das.“ (Friedrich Merz)
          1. Und wenn du Wert auf lesbaren Code legst, verwende doch bitte sprechende Variablennamen, nicht $f.

            Hehe. Ich hab die Antwort nicht geschrieben, um Dich zu ärgern. Die kam nur deswegen 34 Minuten später, weil nach dem Beginn des Tippens ein „Jöööööörg“ durch die Hütte schallte.

          2. Lieber Gunnar,

            Zurecht. Wenn die Dateinamen so sind wie im OP angegeben, dann braucht man keinen Regexp. Dann tut’s auch str_starts_with().

            warum nicht glob()?

            $meineBilder = glob('./bilder/stadt_*');
            foreach ($meineBilder as $pfad) {
              // $pfad zeigt auf eine Bilddatei mit 'stadt_' am Anfang
            }
            

            Liebe Grüße

            Felix Riesterer

            1. Hallo Felix Riesterer,

              die Frage lag mir auch auf den Fingern. Solange die Suche case-sensitive sein darf, ist glob() vermutlich brauchbar.

              Auf meinem Windoof-PC hat mich glob allerdings geärgert, ich hatte in einem Ordner gearbeitet auf dessen Pfad ein Symlink lag und er hat sich strikt geweigert, irgendwas auszugeben. Aber scandir hat die gleiche Macke. Sehr doof.

              Um case-insensitive zu suchen, ist scandir wohl notwendig. Aber zum Filtern nehme man doch bitte weder array_filter mit Callback-Akrobatik noch eine foreach-Schleife mit Array-Appendicitis.

              Wie Gunnar sagte:

              warum sollte man das tun, wenn es doch eine Funktion dafür gibt?

              Die Funktion der Wahl heißt hier preg_grep. Die durchflöht ein Array automatisch mit einer Regex. Und ist auch keine Erfindung von PHP 8, die gibt's seit PHP 4.

              $stadtbilder = preg_grep("/stadt.*\\.(jpg|png|gif)$/i", scandir($path));
              

              Die Regex /stadt.*\.(jpg|png|gif)$/i sollte alle Dateien heraussuchen, die stadt enthalten (in jeder Schreibung) und auf .jpg, .png oder .gif enden. Bei Bedarf kann die Extensionliste auch verlängert werden…

              Und ja, man könnte /^.*stadt.*\.(jpg|png|gif)$/i schreiben. Aber wozu vorne ankern, wenn man doch eh beliebig starten möchte.

              Falls aber dieser Satz von Gunnar zutrifft:

              Wenn die Dateinamen so sind wie im OP angegeben...

              dann kann man /^stadt.*\.(jpg|png|gif)$/i als Regex verwenden.

              Rolf

              --
              sumpsi - posui - obstruxi
              1. Lieber Rolf,

                Auf meinem Windoof-PC hat mich glob allerdings geärgert, ich hatte in einem Ordner gearbeitet auf dessen Pfad ein Symlink lag und er hat sich strikt geweigert, irgendwas auszugeben. Aber scandir hat die gleiche Macke. Sehr doof.

                das klingt nach einem Windows-Problem, nicht nach einem PHP-Problem. Es ist auch im OP nirgendwo ein Hinweis enthalten, dass ein Windows-OS mit Symlink-Strukturen unterstützt werden muss.

                Wenn die Dateinamen so sind wie im OP angegeben...

                dann kann man /^stadt.*\.(jpg|png|gif)$/i als Regex verwenden.

                Oder man nimmt eben doch glob(). Es gibt keinen Hinweis darauf, dass die Dateinamen in ihrer Groß-/Kleinschreibung uneinheitlich wären.

                Liebe Grüße

                Felix Riesterer

                1. Hallo Felix Riesterer,

                  Symlink

                  Windows-Problem

                  Nö. Es liegt an PHP, wenn es einen regulären Pfad mit Symlink mittendrin, in den ich per CD oder Windows Explorer oder XYZ-Commander ganz normal hinein kann, per glob nicht verwenden kann. NTFS Symlinks sind in Windows vielleicht seltener als in Linux, aber nichts ungewöhnliches

                  Es ist auch im OP nirgendwo ein Hinweis enthalten, dass ein Windows-OS mit Symlink-Strukturen unterstützt werden muss.

                  Das hat mit dem OP nichts zu tun. Das war ein ganz normaler Rant meinerseits.

                  Aber heute verrät mir Tante Google, dass es doch mein Fehler war!

                  Kaputt: MKLINK /D foo \some\where\else\foo

                  Geht: MKLINK /D foo D:\some\where\else\foo

                  Aua! Es war nur in PHP kaputt.


                  Es gibt keinen Hinweis darauf, dass die Dateinamen in ihrer Groß-/Kleinschreibung uneinheitlich wären

                  Ja und? Es gibt auch keinen Hinweis, dass die Namen grundsätzlich in Kleinschrift gesetzt sind. Ich habe in meinem Leben hinreichend oft grottige "Requirements by Example" erhalten, um zu wissen, dass Anforderungen fast immer unvollständig sind. Demnach ist es nützlich, das Thema "stadt" vs "Stadt" zumindest anzusprechen. Wenn Sandra das nicht braucht, auch gut.

                  Rolf

                  --
                  sumpsi - posui - obstruxi
                  1. Ja und? Es gibt auch keinen Hinweis, dass die Namen grundsätzlich in Kleinschrift gesetzt sind. Ich habe in meinem Leben hinreichend oft grottige "Requirements by Example" erhalten, um zu wissen, dass Anforderungen fast immer unvollständig sind. Demnach ist es nützlich, das Thema "stadt" vs "Stadt" zumindest anzusprechen. Wenn Sandra das nicht braucht, auch gut.

                    Recht hast Du. Sandra hat ja mit dem „$meine-Bilder = scandir('bilder');“ gezeigt, dass die Beschreibung sich nur an die zugrunde Tatsachen anlehnt.

                    Raketenwilli

                    Ehrenbürger von des Geindeverbandes aus Ober-, Unter-, Mittel- also Ganzgenauheim.

  3. Moin Sandra,

    Allerding sollte im Dateinamen des Bilder auch noch das Wort Stadt stehen.

    Im Verzeichnis BILDER liegen also:

    • stadt_mainz.jpg
    • dorf_sassen.jpg
    • stadt_hamburg.jpg

    Ich lese das Verzeichnis mit php aus.

    $meine-Bilder = scandir('bilder');

    wieso verwendest Du nicht glob?

    $staedte = glob('BILDER/stadt_*.jpg');
    

    Viele Grüße
    Robert