php include file with newest date - php

I'm trying to make a sort of blog with php and I want to include the 5 newest files in an other directory by modification time.
I can inculde them all one by one each time I have made a new file, but it would be nice if I can just include the newest 5.
Because i don't want to put the modification date in the file name I really don't know how to do it.
Is there a way to do that?

$path = "/path/to/directory"; //the directory path
$latest5files = array(); //array for latest 5 files to be stored
$d = dir($path);
while ((false !== ($entry = $d->read())) || count($latest5files) < 5)
{
$filepath = "{$path}/{$entry}";
if ((is_file($filepath)))
{
$latest_filename[] = $entry;
}
}
Then include the whole files in the array
for ($i = 0; $i < count($latest5files); $i++)
{
include $latest5files[ $i ];
}

You can get list files with array for eg.
$a[1234567890] = 'file1.php';
arsort($a);
foreach(array_slice($input, 0, 5) as $fTime => $file):

http://php.net/manual/en/function.filemtime.php
http://php.net/manual/en/function.stat.php
You can check the file modification time with this functions.
Read the file sort it with that time.
More info on
Sorting files by creation/modification date in PHP

This would be a way to get last access info of all files in a directory
$p = "path";
$a = scandir($p);
foreach($a as $f){
$last_access = fileatime($p."/".$f);
}

Related

php - Get the last modified dir

A little stuck on this and hoping for some help. I'm trying to get the last modified dir from a path in a string. I know there is a function called "is_dir" and I've done some research but can't seem to get anything to work.
I don't have any code i'm sorry.
<?php
$path = '../../images/';
// echo out the last modified dir from inside the "images" folder
?>
For example: The path variable above has 5 sub folders inside the "images" dir currently right now. I want to echo out "sub5" - which is the last modified folder.
You can use scandir() instead of is_dir() function to do it.
Here is an example.
function GetFilesAndFolder($Directory) {
/*Which file want to be escaped, Just add to this array*/
$EscapedFiles = [
'.',
'..'
];
$FilesAndFolders = [];
/*Scan Files and Directory*/
$FilesAndDirectoryList = scandir($Directory);
foreach ($FilesAndDirectoryList as $SingleFile) {
if (in_array($SingleFile, $EscapedFiles)){
continue;
}
/*Store the Files with Modification Time to an Array*/
$FilesAndFolders[$SingleFile] = filemtime($Directory . '/' . $SingleFile);
}
/*Sort the result as your needs*/
arsort($FilesAndFolders);
$FilesAndFolders = array_keys($FilesAndFolders);
return ($FilesAndFolders) ? $FilesAndFolders : false;
}
$data = GetFilesAndFolder('../../images/');
var_dump($data);
From above example the last modified Files or Folders will show as Ascending order.
You can also separate your files and folder by checking is_dir() function and store the result in 2 different arrays like $FilesArray=[] and $FolderArray=[].
Details about filemtime() scandir() arsort()
Here's one way you can accomplish this:
<?php
// Get an array of all files in the current directory.
// Edit to use whatever location you need
$dir = scandir(__DIR__);
$newest_file = null;
$mdate = null;
// Loop over files in directory and if it is a subdirectory and
// its modified time is greater than $mdate, set that as the current
// file.
foreach ($dir as $file) {
// Skip current directory and parent directory
if ($file == '.' || $file == '..') {
continue;
}
if (is_dir(__DIR__.'/'.$file)) {
if (filemtime(__DIR__.'/'.$file) > $mdate) {
$newest_file = __DIR__.'/'.$file;
$mdate = filemtime(__DIR__.'/'.$file);
}
}
}
echo $newest_file;
This will work too just like the other answers. Thanks everyone for the help!
<?php
// get the last created/modified directory
$path = "images/";
$latest_ctime = 0;
$latest_dir = '';
$d = dir($path);
while (false !== ($entry = $d->read())) {
$filepath = "{$path}/{$entry}";
if(is_dir($filepath) && filectime($filepath) > $latest_ctime) {
$latest_ctime = filectime($filepath);
$latest_dir = $entry;
}
} //end loop
echo $latest_dir;
?>

How to count all folder ,file and files in sub folder in server using php?

How to count all folder ,file and files in sub folder in server using php ?
i want to count all files ,folder and files in sub folder in path /home1/example/public_html/
First i use this code
<?php
$directory = "/home1/example/public_html/";
$filecount = 0;
$files = glob($directory . "*");
if ($files){
$filecount = count($files);
}
echo "There were $filecount files";
?>
it's show There were 561 files
And then i use this code
<?php
$fi = new FilesystemIterator(__DIR__, FilesystemIterator::SKIP_DOTS);
printf("There were %d Files", iterator_count($fi));
?>
it's show There were 566 Files
And last i use this code
<?php
// integer starts at 0 before counting
$i = 0;
$dir = '/home1/example/public_html/';
if ($handle = opendir($dir)) {
while (($file = readdir($handle)) !== false){
if (!in_array($file, array('.', '..')) && !is_dir($dir.$file))
$i++;
}
}
// prints out how many were in the directory
echo "There were $i files";
?>`
it's show There were 500 Files
But result were difference.
I was test by create file in /home1/example/public_html/images/ But all result still show same like before i create file.
How can i do ?
Your second example will return a more precise answer than the first because glob ignores hidden files and FilesystemIterator does not.
The big difference in the third example is that in #1 and #2 you are iterating and then counting both files and directories, where as in #3 you are filtering directories in the count (by calling is_dir).
So #3 is probably correct (except for what I mention in the NOTE below), and I would suggest using a variant of #2 which will be much easier to read:
function recursive_file_count($dir)
{
$fi = new FilesystemIterator($dir, FilesystemIterator::SKIP_DOTS);
$c = 0;
foreach ($fi as $fileInfo)
{
if (!$fileInfo->isDir()) { ++$c; }
// can also test for $fileInfo->isLink() if needed
}
return $c;
}
NOTE: The count is also affected by filesystem permissions. So for example if this script is running in Apache under the httpd user, and the httpd doesn't have execute permission on a certain directory, it won't be able to enter that directory and count its files. There is no way to solve that without some sort of evil privilege escalation hacks.

How to get the newest file in a directory in php

So I have this app that processes CSV files. I have a line of code to load the file.
$myFile = "data/FrontlineSMS_Message_Export_20120721.csv"; //The name of the CSV file
$fh = fopen($myFile, 'r'); //Open the file
I would like to find a way in which I could look in the data directory and get the newest file (they all have date tags so they would be in order inside of data) and set the name equal to $myFile.
I really couldn't find and understand the documentation of php directories so any helpful resources would be appreciated as well. Thank you.
Here's an attempt using scandir, assuming the only files in the directory have timestamped filenames:
$files = scandir('data', SCANDIR_SORT_DESCENDING);
$newest_file = $files[0];
We first list all files in the directory in descending order, then, whichever one is first in that list has the "greatest" filename — and therefore the greatest timestamp value — and is therefore the newest.
Note that scandir was added in PHP 5, but its documentation page shows how to implement that behavior in PHP 4.
For a search with wildcard you can use:
<?php
$path = "/var/www/html/*";
$latest_ctime = 0;
$latest_filename = '';
$files = glob($path);
foreach($files as $file)
{
if (is_file($file) && filectime($file) > $latest_ctime)
{
$latest_ctime = filectime($file);
$latest_filename = $file;
}
}
return $latest_filename;
?>
My solution, improved solution from Max Hofmann:
$ret = [];
$dir = Yii::getAlias("#app") . "/web/uploads/problem-letters/{$this->id}"; // set directory in question
if(is_dir($dir)) {
$ret = array_diff(scandir($dir), array(".", "..")); // get all files in dir as array and remove . and .. from it
}
usort($ret, function ($a, $b) use ($dir) {
if(filectime($dir . "/" . $a) < filectime($dir . "/" . $b)) {
return -1;
} else if(filectime($dir . "/" . $a) == filectime($dir . "/" . $b)) {
return 0;
} else {
return 1;
}
}); // sort array by file creation time, older first
echo $ret[count($ret)-1]; // filename of last created file
Here's an example where I felt more confident in using my own validator rather than simply relying on a timestamp with scandir().
In this context, I want to check if my server has a more recent file version than the client's version. So I compare version numbers from the file names.
$clientAppVersion = "1.0.5";
$latestVersionFileName = "";
$directory = "../../download/updates/darwin/"
$arrayOfFiles = scandir($directory);
foreach ($arrayOfFiles as $file) {
if (is_file($directory . $file)) {
// Your custom code here... For example:
$serverFileVersion = getVersionNumberFromFileName($file);
if (isVersionNumberGreater($serverFileVersion, $clientAppVersion)) {
$latestVersionFileName = $file;
}
}
}
// function declarations in my php file (used in the forEach loop)
function getVersionNumberFromFileName($fileName) {
// extract the version number with regEx replacement
return preg_replace("/Finance D - Tenue de livres-darwin-(x64|arm64)-|\.zip/", "", $fileName);
}
function removeAllNonDigits($semanticVersionString) {
// use regex replacement to keep only numeric values in the semantic version string
return preg_replace("/\D+/", "", $semanticVersionString);
}
function isVersionNumberGreater($serverFileVersion, $clientFileVersion): bool {
// receives two semantic versions (1.0.4) and compares their numeric value (104)
// true when server version is greater than client version (105 > 104)
return removeAllNonDigits($serverFileVersion) > removeAllNonDigits($clientFileVersion);
}
Using this manual comparison instead of a timestamp I can achieve a more surgical result. I hope this can give you some useful ideas if you have a similar requirement.
(PS: I took time to post because I was not satisfied with the answers I found relating to the specific requirement I had. Please be kind I'm also not very used to StackOverflow - Thanks!)

How to use PHP readdir to read files in directories outside of the root level and link?

I am using a php include (side nav menu- where php script would be) that resides on the root level of my webserver.
I would like to use a php readdir or scandir to list the contents of a different folder on my server (/report_1) with links to those files excluding html, htm and xslt extensions. (or to just only include php extensions)
Currently I am using a readdir that only reads the contents of the current directory it resides in and returns links excluding certain file types.(see code below)
I would eventually like to have a php file in the include that lists and links to files outside the "include" root level. Any help would be very appreciated.
<?php
// These files will be ignored
$excludedFiles = array (
'excludeMe.file',
'excludeMeAs.well'
);
// These file extensions will be ignored
$excludedExtensions = array (
'html',
'htm',
'php'
);
// Make sure we ignore . and ..
$excludedFiles = array_merge($excludedFiles,array('.','..'));
// Convert to lower case so we are not case-sensitive
for ($i = 0; isset($excludedFiles[$i]); $i++) $excludedFiles[$i] =
strtolower(ltrim($excludedFiles[$i],'.'));
for ($i = 0; isset($excludedExtensions[$i]); $i++) $excludedExtensions[$i] =
strtolower($excludedExtensions[$i]);
// Loop through directory
$count = 0;
if ($handle = opendir('.')) {
while (false !== ($file = readdir($handle))) {
$extn = explode('.',$file);
$extn = array_pop($extn);
// Only echo links for files that don't match our rules
if (!in_array(strtolower($file),$excludedFiles) &&
!in_array(strtolower($extn),$excludedExtensions)) {
$count++;
print("".$file."<br />\n");
}
}
echo '<br /><br />Return';
closedir($handle);
}
?>
Make the directory loop a function.
Check if the current file is a directory using is_dir
If it is, re-run that directory through the same function.
Otherwise print the file name as you are doing.
You might want to consider using absolute paths in your links.
Hope this helps.

How to get ZipArchive to not overwrite certain files and folders

I would like to extract a zip folder to a location and to replace all files and folders except a few, how can I do this?
I currently do the following.
$backup = realpath('./backup/backup.zip');
$zip = new ZipArchive();
if ($zip->open("$backup", ZIPARCHIVE::OVERWRITE) !== TRUE) {
die ('Could not open archive');
}
$zip->extractTo('minus/');
$zip->close();
How can I put conditions in for what files and folders should NOT be replaced? It would be great if some sort of loop could be used.
Thanks all for any help
You could do something like this, I tested it and it works for me:
// make a list of all the files in the archive
$entries = array();
for ($idx = 0; $idx < $zip->numFiles; $idx++) {
$entries[] = $zip->getNameIndex($idx);
}
// remove $entries for the files you don't want to overwrite
// only extract the remaining $entries
$zip->extractTo('minus/', $entries);
This solution is based on the numFiles property and the getNameIndex method, and it works even when the archive is structured into subfolders (the entries will look like /folder/subfolder/file.ext).
Also, the extractTo method takes a second optional paramer that holds the list of files to be extracted.
If you just want to extract specific files from the archive (and you know what they are) then use the second parameter (entries).
$zip->extractTo('minus/', array('file1.ext', 'newfile2.xml'));
If you want to extract all the files that do not exist, then you can try one of the following:
$files = array();
for($i = 0; $i < $zip->numFiles; $i++) {
$filename = $zip->getNameIndex($i);
// if $filename not in destination / or whatever the logic is then
$files[] = $filename;
}
$zip->extractTo($path, $files);
$zip->close();
You can also use $zip->getStream( $filename ) to read a stream that you then write to the destination file.

Categories