nieuwste file in folder

Status
Niet open voor verdere reacties.

whitetigerck

Gebruiker
Lid geworden
8 aug 2008
Berichten
196
hallo,

Ik probeer om de nieuwste file in een folder op te halen, alleen dat is een folder waar meerdere folders inzitten, die moet hij ook meenemen en dat lukt mij niet echt.

Ik heb nu deze code gevonden, die werkt voor 1 map, maar als ik hem een map terug zet dus alleen de map upload, dan geeft hij geen resultaat:(

PHP:
 $dir = "upload/folderA";
$pattern = '\.(docx|doc|pdf|pgn)$';

$newstamp = 0;
$newname = "";
$dc = opendir($dir);
while ($fn = readdir($dc)) {
  # Eliminate current directory, parent directory
  if (ereg('^\.{1,2}$',$fn)) continue;
  # Eliminate other pages not in pattern
  if (! ereg($pattern,$fn)) continue;
  $timedat = filemtime("$dir/$fn");
  if ($timedat > $newstamp) {
    $newstamp = $timedat;
    $newname = $fn;
	$timedattt = date("l, j F Y",$newstamp);
  }
}
# $timedat is the time for the latest file
# $newname is the name of the latest file
echo "<a href=\"upload/folderA/$newname\">$newname</a>  date: $timedattt";

hopelijk weet iemand van jullie een goede manier hoe het moet:)
 
Wat je kunt doen is een recursieve functie gebruiken:

PHP:
function scan($dir){
    $dc = opendir($dir);
    while ($fn = readdir($dc)) {
        if($fn!="." && $fn!=".."){ //alleen nieuwe mappen gebruiken
            if(is_dir($fn)){
                scan($fn); //submappen scannen
            }
            else{
                //hier het hele truukje uithalen dat je al hebt (timestamp vergelijken)
            }
        }
    }
}
scan("upload/folderA");

De hoofdmap word dus gescand, waarna met submappen hetzelfde gebeurd.
HTH ;)
 
dank voor de snelle reactie:)

helaas werkt hij niet voor mij, ik heb mijn functie in de jouwe gezet, maar ik krijg geen resultaat. Dit is wat ik heb:

PHP:
function scan($dir){
    $dc = opendir($dir);
    while ($fn = readdir($dc)) {
        if($fn!="." && $fn!=".."){ //alleen nieuwe mappen gebruiken
            if(is_dir($fn)){
                scan($fn); //submappen scannen
            }
            else{
				$pattern = '\.(docx|doc|pdf|pgn)$';

                $newstamp = 0;
				$newname = "";
				$dc = opendir($dir);
				while ($fn = readdir($dc)) {
				  # Eliminate current directory, parent directory
				  if (ereg('^\.{1,2}$',$fn)) continue;
				  # Eliminate other pages not in pattern
				  if (! ereg($pattern,$fn)) continue;
				  $timedat = filemtime("$dir/$fn");
				  if ($timedat > $newstamp) {
					$newstamp = $timedat;
					$newname = $fn;
					$timedattt = date("l, j F Y",$newstamp);
				  }
				}

            }
        }
    }
}
scan("upload");
# $timedat is the time for the latest file
# $newname is the name of the latest file
echo "<a href=\"upload/folderA/$newname\">$newname</a>  date: $timedattt";
 
Errr, ik denk niet dat het zo handig is om je volledige script tussen 'mijn' functie te plaatsen...

Zoals je kunt zien leest de Scan functie de map al in, dus dat hoef je niet nog een keer te doen. Je hoeft alleen nog maar de timestamp van $fn te vergelijken met de vorige timestamp, en de filename met de hoogste timestamp-waarde op te slaan in een variable.

PHP:
$timedat = filemtime("$dir/$fn");
  if ($timedat > $newstamp) {
    $newstamp = $timedat;
    $newname = $fn;
    $timedattt = date("l, j F Y",$newstamp);
  }

om maar meteen alles voor te kauwen :)
 
Het is alweer een tijdje geleden dat ik met php heb geknutseld;)

ik had ook eerst alleen die code gepakt die je daarnet gaf, maar ik kreeg daarbij ook geen resultaat, dus vandaar.

ik heb nu heel simpel dit:

PHP:
function scan($dir){
    $dc = opendir($dir);
    while ($fn = readdir($dc)) {
        if($fn!="." && $fn!=".."){ //alleen nieuwe mappen gebruiken
            if(is_dir($fn)){
                scan($fn); //submappen scannen
            }
            else{
					 $timedat = filemtime("$dir/$fn");
				  if ($timedat > $newstamp) {
					$newstamp = $timedat;
					$newname = $fn;
					$timedattt = date("l, j F Y",$newstamp);
											}
            }
        }
    }
}
scan(upload);

echo "a $newname";
echo "<br> b $newstamp";

maar dat werkt ook niet:(
ik roep die scan functie toch goed aan?
 
Misschien is het handiger als je van te voren verteld hoe ver je ervaring hebt met PHP, want ik krijg niet echt de indruk dat je het principe hier begrijpt.

Daarnaast is "het werkt niet" wel erg vaag. Geef in het vervolg aan wat er mis gaat, wat eventuele foutmeldingen weergeven enzovoorts.

Hoe dan ook, je moet $newstamp en $newname nog even defineren aan het begin van het script (of na de functie-definiering):

PHP:
$newstamp = 0;
$newname = "";

Ook moet scan(upload) gewoon scan("upload") zijn (de eerste map waarin gezocht word, als een string, tussen aanhalingstekens).

Het totale script:

PHP:
function scan($dir){
    $dc = opendir($dir);
    while ($fn = readdir($dc)) {
        if($fn!="." && $fn!=".."){ //alleen nieuwe mappen gebruiken
            if(is_dir($fn)){
                scan($fn); //submappen scannen
            }
            else{
                $timedat = filemtime("$dir/$fn");
                if($timedat > $newstamp) {
                    $newstamp = $timedat;
                    $newname = $fn;
                }
            }
        }
    }
    closedir($dc); //ook wel belangrijk! zeker als je meerdere mappen gaat openen
}

$newstamp = 0;
$newname = "";

scan("upload");
$timedattt = date("l, j F Y",$newstamp); //de timestamp in het goede formaat opmaken (dit hoeft maar 1 keer gedaan te worden, dus dat zet je niet in de loop)
 
echo "<a href=\"upload/folderA/$newname\">$newname</a>  date: $timedattt";
 
Ik kan wel weg met php, ik weet de basis en op sommige gebieden zelfs iets meer. Alleen dat is wel een half jaar geleden, en die kennis verdwijnt best snel:confused:

Ik was wel wat vaag daarnet, daar heb je wel gelijk in. Het probleem is dat de variabelen $newname en $newstamp, niks bevatten. Ik krijg ook als datum 1-1-70, dat betekend ook dat hij leeg is.

De link naar de file die klopt ook, de map bestaat in de map met het document en er staat ook nog een map met dezelfde naam in de root van mijn server. Maar de variabelen zijn toch nog steeds leeg
 
"Log" eens wat weg zou ik zeggen. Echo de $fn variable elke keer dat de while loop weer begint, zodat je kunt zien of hij langs alle bestanden komt etc:

PHP:
function scan($dir){
    $dc = opendir($dir);
    while ($fn = readdir($dc)) {
        echo "<br><b>".$fn."</b> ";
        if($fn!="." && $fn!=".."){ //alleen nieuwe mappen gebruiken
            if(is_dir($fn)){
                echo "(map)";
                scan($fn); //submappen scannen
            }
            else{
                $timedat = filemtime("$dir/$fn");
                echo "(bestand - timestamp: ".$timedat.")";
                if($timedat > $newstamp) {
                    $newstamp = $timedat;
                    $newname = $fn;
                    echo " <b>NIEUWER</b>";
                }
            }
        }
    }
    closedir($dc); //ook wel belangrijk! zeker als je meerdere mappen gaat openen
}
 
$newstamp = 0;
$newname = "";
 
echo "Start<br>";

scan("upload");

echo "Klaar<br>";

$timedattt = date("l, j F Y",$newstamp); //de timestamp in het goede formaat opmaken (dit hoeft maar 1 keer gedaan te worden, dus dat zet je niet in de loop)
 
echo "<a href=\"upload/folderA/$newname\">$newname</a>  date: $timedattt";
 
Ik denk dat ik al weet wat hij fout doet dankzij dat loggen;)

Hij herkent alleen de eerste submap als een map, de submappen herkent hij alleen als een file.
En als een map met dezelfde naam een level lager staat, dan leest hij deze ipv van een level hoger, dus bij deze structuur:

Beginmap
map A​

Upload
map A​
map C​
map B​

Deze code werkt nog wel steeds als er geen submappen zijn, dus de kern werkt wel:)
 
Hmm, wat ik denk is dat het pad niet goed is opgegeven binnen de functie, foutje van mij.

Probeer scan($fn); eens te vervangen door scan($dir."/".$fn); (zo wordt dus het volledige pad gebruikt) ;)

EDIT: Hetzelfde geld voor if(is_dir($dir."/"$fn)){ dat if(is_dir($dir."/"$fn)){ moet zijn (dan herkend hij de map ook als map, en gaat het script niet verder bij het gedeelte dat voor files is bedoeld).

Overigens moet je oppassen met het feit dat hier een recursieve functie wordt gebruikt. Op zich zijn recursieve functies geen probleem (er wordt vaak gesteld dat ze veel geheugen gebruiken, wat relatief ook wel klopt, maar anno 2009 heb je daar niet echt last van), maar deze functie sluit een map pas wanneer alle sub-mappen zijn doorzocht. Nu weet ik het echt niet zeker, maar ik kan me voorstellen dat dit een probleem kan zijn wanneer je met een groot aantal submappen gaat werken (wat in jouw geval waarschijnlijk niet zo is, maar ik vermeld het even), gezien enkele mogelijke limitaties van PHP.
 
Laatst bewerkt:
Hij scant nu de goede submappen, en hij geeft van elke submap de nieuwste file, dus dat werkt:thumb:

Alleen zou ik graag ook van die files de nieuwste file willen hebben ( dus maar 1 bestand als resultaat), dus misschien staat mijn deel van dat scriptje niet op de goede plek, of moet ik deze nog een keer een loop laten doen in het script? Dus dat ik dan die timestamps 2 keer vergelijk.

Alleen wat ik wel vreemd vind is dat alleen de variabelen binnen de functie gelden, buiten de functie zijn ze dus leeg. Ik kan ze wel binnen de functie echo'en, dus een probleem zal het niet echt zijn.

In de map upload zelf staan ook een paar php files, die wil ik niet echt graag als resultaat. Ik ben een paar scripts tegengekomen waar een array met uitzonderingen inzitten. Alleen waar zou ik deze in dit script moeten inbouwen?

Mijn functie scant op zijn hoogst maar 5 mappen, dus op dat probleem zal ik wel niet stuiten, toch bedankt voor de waarschuwing;)
 
Hmm, het script zou in principe al de timestamps moeten vergelijken, maar blijkbaar zijn het allemaal private variablen voor de functie. Ik moet eerlijk bekennen dat ik niet precies weet hoe het private/public verhaal werkt voor functies, dat zul je even moeten opzoeken.

In ieder geval zul je dan *iets* moeten veranderen aan

PHP:
if($timedat > $newstamp){
    $newstamp = $timedat;
    $newname = $fn;
}

Verder kun je inderdaad een aantal uitzonderingen maken. if($fn!="." && $fn!="..") controleert of de bestandsnaam niet "." of ".." is (een enkele punt is de huidige map, 2 punten is de bovenliggende map, en die wil je niet NOG een keer gaan doorzoeken, omdat je van "boven naar beneden" werkt). Een in_array functie toevoegen is voldoende:
if($fn!="." && $fn!=".." && !in_array($fn,$uitzonderingen)){ waarbij $uitzonderingen een array is met de bestandsnamen die niet gecontroleerd moeten worden.

EDIT: ik heb gevonden hoe je de globale variable kunt gebruiken. Gewoon bovenaan de functie global $newstamp; global $newname toevoegen schijnt voldoende te zijn:

PHP:
function scan($dir){
    global $newstamp;
    global $newname
    $dc = opendir($dir);
    while ($fn = readdir($dc)) {
<enzovoorts>
 
Laatst bewerkt:
Het werkt:)
Enorm bedankt:thumb:

Alleen wat nog niet werkt zijn de uitzonderingen, in principe moet nu alleen de .php pagina niet getoond worden. Of alleen de .doc, docx en pdf bestanden getoond, dat maakt mij niet zoveel uit, het komt op hetzelfde neer.

Ik krijg echter deze foutmelding:
Warning: in_array() [function.in-array]: Wrong datatype for second argument in /mnt/web5/20/32/51997132/htdocs/upload/show.php on line 18

en op lijn 18 staat dit:
PHP:
if($fn!="." && $fn!=".." && !in_array($fn,$uitzonderingen)){

ik heb $uitzonderingen gezet:
PHP:
$uitzonderingen = array("php");

Wat doe ik nu weer fout?:p
 
Hij zoekt letterlijk op "php", dus alleen een file die php heet, zonder extensie, zal genegeerd worden. Je moet de hele naam erin zetten.
 
waarbij $uitzonderingen een array is met de bestandsnamen die niet gecontroleerd moeten worden.

Ik nam aan dat je een aantal bestandsnamen had die niet gecontroleerd hoefden te worden. Als je gewoon alle bestanden met een .php extensie wilt filteren gebruik je:

PHP:
if($fn!="." && $fn!=".." && end(explode('.', $fn))!="php"){

(bestandsnaam wordt opgesplitst bij elke punt, het laatste deel word vergeleken met "php")

Zou het moeten doen. ;)
 
Geweldig het werkt helemaal goed:thumb:
enorm bedankt:)

Voor de mensen die hetzelfde probleem hebben, hier is de complete werkende code:

PHP:
function scan($dir){
    global $newstamp;
    global $newname;
    $dc = opendir($dir);
    while ($fn = readdir($dc)) {     
        if($fn!="." && $fn!=".." && end(explode('.', $fn))!="php"){  //alleen nieuwe mappen gebruiken
            if(is_dir($dir."/".$fn)){     
                scan($dir."/".$fn); //submappen scannen
            }
            else{
                $timedat = filemtime("$dir/$fn");
                if($timedat > $newstamp) {
                    $newstamp = $timedat;
                    $newname = $fn;
                }
            }
        }
    }
    closedir($dc); //ook wel belangrijk! zeker als je meerdere mappen gaat openen
}

scan("upload");

$timedattt = date("l, j F Y",$newstamp); //de timestamp in het goede formaat opmaken (dit hoeft maar 1 keer gedaan te worden, dus dat zet je niet in de loop)
 
echo "<br><br>$timedattt en $newname<br>";
 
Status
Niet open voor verdere reacties.
Steun Ons

Nieuwste berichten

Terug
Bovenaan Onderaan