PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr

PHP-Scripte PHP-Tutorials PHP-Jobs und vieles mehr (https://www.php-resource.de/forum/)
-   PHP Developer Forum (https://www.php-resource.de/forum/php-developer-forum/)
-   -   Verzeichnis auslesen nach bestimmten Kriterien (https://www.php-resource.de/forum/php-developer-forum/101996-verzeichnis-auslesen-nach-bestimmten-kriterien.html)

Besth 04-08-2011 15:18

Verzeichnis auslesen nach bestimmten Kriterien
 
Hallo,
ich möchte gern ein Verzeichnis auslesen, dabei aber am Ende nur die Dateien bekommen, die einem bestimmten Kriterium entsprechen
Bisher habe ich folgendes:
PHP-Code:

if ($handle opendir("pfad")) {
  while (
false !== ($file readdir($handle))) {
// $pattern = "";
//    if ( preg_match($pattern, $file) )
    
echo $file."<br>";
  }
  
closedir($handle);


Nun scheitert es bei mir bei dem preg_match Pattern.
Die Dateien haben folgende Struktur:
jfBI8BJKD_page_0001.png
jfBI8BJKD_page_0002.png
jfBI8BJKD_page_0003.png
3kGsd78J_page_0001.png
3kGsd78J_page_0002.png
usw
Am ende möchte ich nur wissen wieviele "Seiten" (Bilder) jede Nummer hat.

Muss ich da überhaupt mit preg_match rangehen oder gibt es etwas performanteres? Das Verzeichnis kann später unter Umständen >100.000 Dateien beinhalten

AmicaNoctis 04-08-2011 15:29

Hallo,

ich würde da mit einem FilterIterator über einem DirectoryIterator herangehen und dann einen Gruppenwechsel machen.

Gruß,

Amica

wahsaga 04-08-2011 16:08

Zitat:

Zitat von Besth (Beitrag 655582)
Das Verzeichnis kann später unter Umständen >100.000 Dateien beinhalten

Dann kannst du Performance aber gleich auf den „ist mir nicht so wichtig“-Zettel notieren ...

Zitat:

jfBI8BJKD_page_0001.png
jfBI8BJKD_page_0002.png
jfBI8BJKD_page_0003.png
3kGsd78J_page_0001.png
3kGsd78J_page_0002.png
Da gehört m.E. anstelle des ersten Unterstriches ein Slash rein, wenn das halbwegs performant umgesetzt werden soll.

fireweasel 05-08-2011 13:42

Zitat:

Zitat von Besth (Beitrag 655582)
Hallo,
ich möchte gern ein Verzeichnis auslesen, dabei aber am Ende nur die Dateien bekommen, die einem bestimmten Kriterium entsprechen
Bisher habe ich folgendes:
PHP-Code:

if ($handle opendir("pfad")) {
  while (
false !== ($file readdir($handle))) {
// $pattern = "";
//    if ( preg_match($pattern, $file) )
    
echo $file."<br>";
  }
  
closedir($handle);


Nun scheitert es bei mir bei dem preg_match Pattern.

Und an welcher Stelle im Pattern, wenn man fragen darf?

Zitat:

Die Dateien haben folgende Struktur:
jfBI8BJKD_page_0001.png
jfBI8BJKD_page_0002.png
jfBI8BJKD_page_0003.png
3kGsd78J_page_0001.png
3kGsd78J_page_0002.png
usw
Ist die Unterscheidung von Groß- und Kleinschreibung wichtig oder nicht?

Gibts in dem Verzeichnis noch Dateien mit anderem Namensmustern? Dann wird das "Pattern" länger. Wenn nicht, reicht es, die Ziffern vor dem ".png" zu erfassen.

Ist die Zeichenanzahl aller Namen gleich? Dann reicht substr().

Zitat:

Am ende möchte ich nur wissen wieviele "Seiten" (Bilder) jede Nummer hat.
Ach so, also eine Art Fold-Funktion für ein Verzeichnis. ;)

Zitat:

Muss ich da überhaupt mit preg_match rangehen oder gibt es etwas performanteres? Das Verzeichnis kann später unter Umständen >100.000 Dateien beinhalten
Erstmal ist preg_match() per se nicht "unperformant". Woher kommen nur immer diese irrigen Annahmen?[0]

Ob du preg_match() oder eine ähnliche Mustersuchfunktion[1] benötigst, hängt (wie oben schon angedeutet) von den Namensmustern ab, die vorhanden sind und welche davon du "einfangen" möchtest.

Bei Verzeichnissen, die mehrere 100k Einträge haben, dürfte der Overhead von preg_match() nicht ins Gewicht fallen.

Dagegen habe ich bei Tests an Verzeichnissen mit ein paar tausen Einträgen unter Windows mit NTFS festgestellt, dass die gewöhnlichen Verzeichnisfunktionen (opendir(), readdir(), ...) oder das Dir-Objekt 50 bis 100 Prozent schneller sind als die SPL-Directory-Iteratoren. Frag mich aber bitte nicht, warum[2]. Ich war selbst überrascht, dass ein Haufen PHP-Script-Code einen Haufen C so deutlich schlägt ... :confused:

PHP-Code:

// Der Default-Wert von $pcre ist ein Vorschlag.
// Er lässt sich sicher noch optimieren.
// Aber erstmal funktioniert er.

function count_files(
    
$url/// string() directory path
    
$pcre '/\A(.+)[0-9]+\.png\z/'/// string(pcre) regex pattern
    
$xmpl_basename 'jfBI8BJKD_page_0001.png' /// for testing the regex
) {
    if (
        !
is_int(@preg_match($pcre$xmpl_basename$hits)) ||
        
count($hits) < // we use $hits[1] later
    
) {
        return 
null// invalid regex pattern
    
}
    if (!
is_resource($dir opendir($url))) {
        return 
null// could not open directory
    
}
    
$pwd getcwd(); // memoize current working dir
    
if (!chdir($url)) {
        return 
null// could not change current working dir
    
}
    
$accu = array (); /// assoc array
    
while (is_string($entry readdir())) {
        if (!
is_file($entry)) {
            continue; 
// skip non-files
        
}
        if (!
preg_match($pcre$entry$hits)) {
            continue; 
// skip non-matching filenames
        
}
        
$base $hits[1]; // if file-system is case-sensitive
        
if (!isset ($accu[$base])) {
            
$accu[$base] = 0;
        }
        
$accu[$base] += 1;
    }
    
closedir($dir);
    
chdir($pwd); // switch back to previous working dir
    
return $accu;



[0] Die gerne zitierte Aussage im PHP-Handbuch, dass preg_match() und Kollegen nicht für "einfache" String-Suche benutzt werden sollten, ist Unsinn. Die "Performance" hängt immer vom konkreten Anwendungsfall ab.

[1] PHP hat bspw. auch glob(), fnmatch() und einen "FilterIterator", der über Verzeichnisse operieren kann.

[2] Vermutlich bauen die den üblichen Opendir-readdir-closedir-Ablauf auch nur als C-Version mit den Funktionen der Zend-Engine nach und packen dann den Iterator-Krempel obendrauf.

P.S.: Man lernt eben nie aus: Ich wollte gerade einen vermeintlichen Fehler berichtigen, und readdir() durch readdir($dir) zu ersetzen, stellte aber fest, dass das Script auch ohne extra Argument funktioniert. Im Handbuch ist keine PHP-Versionsnummer erwähnt, ab der dieses Argument optional wurde. Was heißt: Das war höchstwahrscheinlich schon immer so ...


Alle Zeitangaben in WEZ +2. Es ist jetzt 19:12 Uhr.

Powered by vBulletin® Version 3.8.2 (Deutsch)
Copyright ©2000 - 2018, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0
[c] ebiz-consult GmbH & Co. KG