[PHP] Directory scannen op bepaalde extensies

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
Ik heb onderstaande functie gemaakt om een directory te scannen op bepaalde documenten:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
function scan_dir($dir, $filter = false) {
  $handle = opendir($dir);

  while (false !== ($file = readdir($handle))) {
    if (!in_array($file, array('.', '..'))) {
      if ($filter) {
        for ($i = 0; $i < count($filter); $i++) {
          if (ereg($filter[$i], $file)) {
            $files[] = basename($file);
          }
        }
      }
      else if (is_file($dir.$file)) {
        $files[] = basename($file);
      }
    }
  }
  closedir($handle);
  return $files;
}

scan_dir(BASE_PATH .'/images', array('.jpg', '.gif'));

In het voorbeeld hierboven scan ik op plaatjes met extensie jpg en gif. Alleen staan er in die map ook thumbnails: ditiseenplaatje.thumb.jpg is de thumbnail van ditiseenplaatje.jpg. Met de huidige code krijg ik ook alle thumbnails terug in de $files[] array. maar dat wil ik niet. Ik wil de functie graag aanpassen dat $filter werkt op alles na de eerste punt, dus:
code:
1
2
3
4
plaatje.gif wordt toegevoegd aan $files
plaatje.jpg ook
plaatje.iets.jpg niet (want: "extensie" is iets.jpg en niet jpg)
plaatje.xls ook niet

Ik dacht dat mijn huidige code dat zou bewerkstelligen, maar dat blijkt dus van niet. Wie heeft er een oplossing?

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Werkt je losse array van filters überhaupt wel. Dus maak een array, laat er de regex-filter op los en komt er het juiste uit?

Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 14:53

MueR

Admin Tweakers Discord

is niet lief

Aantal keer het karakter '.' in de filename tellen.. wanneer het 1 is, met geldige extensie, toevoegen

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
MueR schreef op maandag 06 augustus 2007 @ 18:01:
Aantal keer het karakter '.' in de filename tellen.. wanneer het 1 is, met geldige extensie, toevoegen
Wat doe je dan met tar.gz of tar.bz2. Wat doe je met bestanden die meerdere punten bevatten door een timestamp?
"archive.tar.bz2" of "foto.20070509.jpg" zou er bij jou niet doorheen komen ;)

offtopic:
En ik zou sowieso eerder op mimetype filteren dan extensie, omdat die extensie eigenlijk niets zegt en eenvoudig te veranderen is. Verandert dan daarmee ook de content? Nee, en met mimetype filtering omzeil je zulke problemen.

Acties:
  • 0 Henk 'm!

  • Terranca
  • Registratie: April 2000
  • Laatst online: 18-09 18:25
Denk nu misschien te makkelijk, maar is substr($file, -1*(strlen($filter[$i]))) == $filter[$i] geen optie? :)

of preg_match("/^(.*)(.jpg)$/i", $file)

[ Voor 16% gewijzigd door Terranca op 06-08-2007 18:37 ]


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
- Een reguliere expressie is hier overkill (alles na de eerste punt kun je eenvoudig verkrijgen met een substr en een strpos)
- Op regel 6 dien je if(is_array($filter)) te gebruiken ipv if($filter)
- Op regel 7 kun je omwille van duidelijkheid beter een foreach gebruiken

Acties:
  • 0 Henk 'm!

  • MueR
  • Registratie: Januari 2004
  • Laatst online: 14:53

MueR

Admin Tweakers Discord

is niet lief

mithras schreef op maandag 06 augustus 2007 @ 18:10:
[...]
Wat doe je dan met tar.gz of tar.bz2. Wat doe je met bestanden die meerdere punten bevatten door een timestamp?
"archive.tar.bz2" of "foto.20070509.jpg" zou er bij jou niet doorheen komen ;)
Ik zeg ook niet dat het een goede oplossing is, maar de TS wil daar niet naar kijken.
offtopic:
En ik zou sowieso eerder op mimetype filteren dan extensie, omdat die extensie eigenlijk niets zegt en eenvoudig te veranderen is. Verandert dan daarmee ook de content? Nee, en met mimetype filtering omzeil je zulke problemen.
True, op mimetype is de beste optie. De TS kan dan ook altijd nog controleren of er '.thumb.' voorkomt in de filename.
GlowMouse schreef op maandag 06 augustus 2007 @ 19:16:
[...]

Je methode gaat de mist in wanneer er in zijn filter een 'tar.gz' voorkomt.
Dat zei mithras ook al, en ik zeg hier zojuist waarom ik dit vertelde.

[ Voor 32% gewijzigd door MueR op 06-08-2007 19:19 ]

Anyone who gets in between me and my morning coffee should be insecure.


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
MueR schreef op maandag 06 augustus 2007 @ 19:12:
[...]

Ik zeg ook niet dat het een goede oplossing is, maar de TS wil daar niet naar kijken.
Je methode gaat de mist in wanneer er in zijn filter een 'tar.gz' voorkomt.

Acties:
  • 0 Henk 'm!

  • brute51
  • Registratie: Augustus 2001
  • Laatst online: 07-08 23:35
Probeer is iets als:

$ext = substr($file, -4);
if (in_array($file, $ext) == true)
$files[] = basename($file);

dit dus ipv die ereg.

Ik heb echt een hele goeie PC.


Acties:
  • 0 Henk 'm!

Verwijderd

Topicstarter
mithras schreef op maandag 06 augustus 2007 @ 18:10:
[...]
Wat doe je dan met tar.gz of tar.bz2. Wat doe je met bestanden die meerdere punten bevatten door een timestamp?
"archive.tar.bz2" of "foto.20070509.jpg" zou er bij jou niet doorheen komen ;)

offtopic:
En ik zou sowieso eerder op mimetype filteren dan extensie, omdat die extensie eigenlijk niets zegt en eenvoudig te veranderen is. Verandert dan daarmee ook de content? Nee, en met mimetype filtering omzeil je zulke problemen.
De map die ik hier wil scannen is de images-map van mijn cms'je. Als mensen daar plaatjes in uploaden, controleer ik de mimetype en maak een thumbnail aan, welke functie true returned als er een thumb gemaakt kon worden. Ik weet dus (vrij) weet zeker dat er alleen plaatjes in staan. Op het moment dat ik plaatjes upload, worden alle punten (.) uit de naam gestript.

Ik probeer nu mijn generieke scan functie zo aan te passen, dat ik alleen bepaalde documenttypen kan oproepen. Ik heb nu de volgende functie:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
function scan_dir($dir, $filters = false) {
  $handle = opendir($dir);

  while (false !== ($file = readdir($handle))) {
    if (!in_array($file, array('.', '..'))) {
      if ($filters) {
        foreach ($filters as $filter) {
          if (substr($file, -1 * (strlen($filter))) == $filter) {
            $files[] = basename($file);
          }
        }
      }
      else if (is_file($dir . $file)) {
        $files[] = basename($file);
      }
    }
  }
  closedir($handle);
  return $files;
}

Maar als ik hierbij scan_dir(BASE_PATH .'/images', array('.jpg', '.gif')); aanroep, krijg ik nog steeds de plaatje.thumb.jpg's terug?

Nu ik erover nadenk is het misschien wel zo slim om 2 typen filters toe te laten: extensies die genegeerd moeten worden en extensies die gepakt moeten worden. Je kunt dan kiezen wat je gereturned wil hebben. Jullie mening over de bruikbaarheid hiervan graag :)

[ Voor 7% gewijzigd door Verwijderd op 06-08-2007 20:44 ]


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
Verwijderd schreef op maandag 06 augustus 2007 @ 20:42:
[...]
Maar als ik hierbij scan_dir(BASE_PATH .'/images', array('.jpg', '.gif')); aanroep, krijg ik nog steeds de plaatje.thumb.jpg's terug?
Dat klopt, het voorgestelde stukje code dat je zo hebt overgenomen werkt niet. Daarom is het ook niet verstandig zo stukjes code over te nemen zonder goed te kijken wat ze doen en waarom het zou doen wat je wilt.
Ik had eerder drie punten genoemd om dit beter aan te pakken, maar met twee lijk je nog niets te hebben gedaan.
Nu ik erover nadenk is het misschien wel zo slim om 2 typen filters toe te laten: extensies die genegeerd moeten worden en extensies die gepakt moeten worden. Je kunt dan kiezen wat je gereturned wil hebben. Jullie mening over de bruikbaarheid hiervan graag
Het zal werken voor je doel maar als normale files toch maar één punt bevatten, is het overbodig.

Acties:
  • 0 Henk 'm!

  • mithras
  • Registratie: Maart 2003
  • Niet online
Verwijderd schreef op maandag 06 augustus 2007 @ 20:42:
[...]

De map die ik hier wil scannen is de images-map van mijn cms'je. Als mensen daar plaatjes in uploaden, controleer ik de mimetype en maak een thumbnail aan, welke functie true returned als er een thumb gemaakt kon worden. Ik weet dus (vrij) weet zeker dat er alleen plaatjes in staan. Op het moment dat ik plaatjes upload, worden alle punten (.) uit de naam gestript.
Wat houd jou dan tegen om die thumbnails in een aparte map te zetten?
image.jpg
image2.jpg
thumb/image.jpg
thumb/image2.jpg
;)
Nu ik erover nadenk is het misschien wel zo slim om 2 typen filters toe te laten: extensies die genegeerd moeten worden en extensies die gepakt moeten worden. Je kunt dan kiezen wat je gereturned wil hebben. Jullie mening over de bruikbaarheid hiervan graag :)
Dat behoeft dan nog wat uitleg, want in dit script genereer je niets, je matcht alleen (of noem je het "genereren van een match"?).
GlowMouse schreef op maandag 06 augustus 2007 @ 21:23:
[...]

Negeren is wat anders dan genereren :>
Tralalala 8)7

[ Voor 7% gewijzigd door mithras op 06-08-2007 21:32 ]


Acties:
  • 0 Henk 'm!

  • GlowMouse
  • Registratie: November 2002
  • Niet online
mithras schreef op maandag 06 augustus 2007 @ 21:21:
Dat behoeft dan nog wat uitleg, want in dit script genereer je niets, je matcht alleen (of noem je het "genereren van een match"?).
Negeren is wat anders dan genereren :>

Acties:
  • 0 Henk 'm!

  • SchizoDuckie
  • Registratie: April 2001
  • Laatst online: 18-02 23:12

SchizoDuckie

Kwaak

PHP:
1
glob("*.jpg|gif");
:?

Stop uploading passwords to Github!


Acties:
  • 0 Henk 'm!

  • funkwurm
  • Registratie: December 2005
  • Laatst online: 22-02-2021
Verwijderd schreef op maandag 06 augustus 2007 @ 17:54:
In het voorbeeld hierboven scan ik op plaatjes met extensie jpg en gif. Alleen staan er in die map ook thumbnails: ditiseenplaatje.thumb.jpg is de thumbnail van ditiseenplaatje.jpg. Met de huidige code krijg ik ook alle thumbnails terug in de $files[] array. maar dat wil ik niet.
Ik concludeer dat het enige verschil tussen de bestanden die je wel wil en de bestanden die je niet wil de aanwezigheid van .thumb in de naamgeving is. De hersenspinsels die ik tot noch toe voorbij heb zien komen verwerken dit nergens...

Je moet dus of hardcoded op de aanwezigheid van ".thumb" moeten checken, of zoals je zelf aangeeft gebruik maken van het feit dat alle andere punten in de bestandsnaam verwijderd worden, dus dan zou dit volgens mij de truc moeten doen:
PHP:
1
2
3
4
5
[...]
$aFile=strtolower(explode('.', $file));
if (in_array($aFile[1], $filter)) {
[...]
scan_dir(BASE_PATH .'/images', array('jpg', 'jpeg', 'gif')); // note: punten hier weglaten in de array

Je weet immers zeker dat de bestanden die je wel wil maar 1 punt hebben, namelijk die van de extensie, bij de thumbnails zal de 2e index van de $aFile array het woord "thumb" bevatten, en de werkelijke extensie pas in de 3e index zitten.
offtopic:
Javascript zou zoiets als if (in_array(strtolower(explode('.', $file)[1]), $filter)) toelaten, maar volgens mij vindt php dat niet zo lief

[ Voor 2% gewijzigd door funkwurm op 07-08-2007 01:27 . Reden: typo's en zinsconstructies ]

Pagina: 1