I have a snippet of code here that grabs the last modified file from a directory. However, I want it to exclude any file that has the word "placeholder" written on it. How do I modify this so that it does exclude those files, especially since the file that has "placeholder" written on its page is usually the last modified file?
Here is the code that I have:
<?php
$dir = "path goes here";
$pattern = '\.(php)$'; // check only file with these ext.
$newstamp = 0;
$newname = "";
if ($handle = opendir($dir)) {
while (false !== ($fname = readdir($handle))) {
// Eliminate current directory, parent directory
if (ereg('^\.{1,2}$',$fname)) continue;
// Eliminate other pages not in pattern
if (! ereg($pattern,$fname)) continue;
$timedat = filemtime("$dir/$fname");
if ($timedat > $newstamp) {
$newstamp = $timedat;
$newname = $fname;
}
}
}
closedir ($handle);
$name = basename($newname,".php");
echo "<b><span class='latestch'>Latest Chapter:</span></b> $name";
?>
To skip over files which contain the string "placeholder":
if(strpos(file_get_contents($fname), 'placeholder') !== false) continue;
You could save a lot of code:
array_multisort(
array_map('filemtime',
$files = preg_grep('/placeholder/',
glob("$dir/*.php"), PREG_GREP_INVERT)),
SORT_ASC, $files);
$name = basename(end($files), '.php');
Related
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;
?>
I'm using bootstrap tables and rows to count how much files are in a folder, but the destination is pointing to a different server the code below does not work.
As i'm using localhost (xampp) trying to do this don't know if its possible.
<?php
// integer starts at 0 before counting
$i = 0;
$dir = 'uploads/'; <!--\\189.207.00.122\folder1\folder2\folder3\test-->
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";
?>
Here is a handy little function you might want to try out. Just pass the path to the Directory as the first argument to it and you'd get your result.
NOTE: This Function is RECURSIVE, which means: it will traverse all sub-directories... to disable this behaviour, simply comment out or delete the following lines towards the end of the Funciton:
<?php
}else if(is_dir($temp_file_or_dir) && !preg_match('/^\..*/', $val) ){
getFilesInFolder($temp_file_or_dir);
}
THE CODE:
<?php
$folder = dirname(__FILE__).'/uploads'; // ASSUMES YOUR uploads DIRECTORY
// IS IN THE SAME DIRECTORY AS index.php
// (/htdocs/php/pages)
// OR
$folder = dirname(__FILE__).'/../uploads'; // ASSUMES YOUR uploads DIRECTORY
// IS ONE DIRECTORY ABOVE
// THE CURRENT DIRECTORY (/htdocs/php)
// THIS IS MOST LIKELY RIGHT
// OR
$folder = dirname(__FILE__).'/../../uploads';// ASSUMES YOUR uploads DIRECTORY
// IS TWO DIRECTORIES ABOVE
// THE CURRENT DIRECTORY (/htdocs)
// MAKE SURE THE FOLDER IN QUESTION HAS THE RIGHT PERMISSIONS
// OR RATHER CHANGE PERMISSIONS ON THE FOLDER TO BE ABLE TO WORK WITH IT
chmod($folder, 0777);
var_dump(getFilesInFolder($folder));
// IF YOU PASS false AS THE THE 2ND ARGUMENT TO THIS FUNCTION
// YOU'D GET AN ARRAY OF ALL FILES IN THE $path2Folder DIRECTORY
// AS WELL AS IN SUB-DIRECTORIES WITHIN IT...
function getFilesInFolder($path2Folder, $countOnly=true){
$files_in_dir = scandir($path2Folder);
$returnable = array();
foreach($files_in_dir as $key=>$val){
$temp_file_or_dir = $path2Folder . DIRECTORY_SEPARATOR . $val;
if(is_file($temp_file_or_dir) && !preg_match("#^\..*#", $temp_file_or_dir)){
$arrRX = array('#\.{2,4}$#', '#\.#');
$arrReplace = array("", "_");
$returnVal = preg_replace($arrRX, $arrReplace, $val);
$returnable[$returnVal] = $temp_file_or_dir;
}else if(is_dir($temp_file_or_dir) && !preg_match('/^\..*/', $val) ){
getFilesInFolder($temp_file_or_dir);
}
}
return ($countOnly) ? count($returnable) : $returnable;
}
Use $_SERVER['DOCUMENT_ROOT'] to get your root directory.
$dir = $_SERVER['DOCUMENT_ROOT'].'/uploads/';
This is a part two to my previous question that got answered Php Browsing Multiple Directories
Now that I got the script reading the directories perfectly, Is it possible to load the results of the file listings into a new page like races.php to "pretty it up"
Here is how it's listing the files Example of Files being listed from server
I would really like to have that be displayed inside of the site instead of jumping out into a apache server listing so its more user friendly.
EDIT
I think what I'm trying to do in theory that is once the script scans the dir it puts it into an array called $files I then foreach loop it for all of the folders but where I get stuck now is how do I pass that $file into a new page ? and make it show the contents inside the folder :)
Thanks again and sorry super newbie here trying to learn!
Script File to generate list and click to files inside of each:
<?php
$files = array();
$dir = opendir('races/ob/');
// $dir = opendir('races/ob/');
while(false != ($file = readdir($dir))) {
if(($file != ".") and ($file != "..") and ($file != "index.php")) {
$files[] = $file; // put in array.
}
}
natsort($files); // sort.
// print.
foreach($files as $file) {
echo("<span class='txt-spacing'><a href='races/ob/$file'>$file</a> <br />\n</>");
}
?>
The simple function can do all for you
scandir(<path>);
It will give you list of all files in the directory.
I figured out my problem with some help from a friend. I hope others can use this to help out the community.
1) First thing is to list A directory of files on the index.php
2) Once the user clicks the generated folder, go into races.php and display the the results of the files listed inside the folder clicked.
Here is how it's done by passing a parameter in the URL
index.php
<?php
$files = array();
$dir = opendir('races/ob/');
// $dir = opendir('races/ob/');
while(false != ($file = readdir($dir))) {
if(($file != ".") and ($file != "..") and ($file != "index.php")) {
$files[] = $file; // put in array.
}
}
natsort($files); // sort.
// print.
foreach($files as $file) {
$url = "races/ob/$file";
$path = urlencode($url);
echo("<span class='txt-spacing'>
<a href='races.php?race=$path'>$file</a> <br />\n</>");
}
?>
races.php
<?php
$path = $_GET['race'];
// right here, you need the path prefix
$path = '/public_html' . urldecode($path); //SERVER PATH
// above here you need it
$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path), RecursiveIteratorIterator::SELF_FIRST);
$fileData = array();
foreach($objects as $name => $object){
$fileinfo = pathinfo($name);
if (!is_dir($name) && isset($fileinfo['extension'])) {
$file = $fileinfo['basename'];
$fileData[] = $file;
}
}
?>
<?php foreach($fileData as $file): ?>
<a target = '_blank' href="http://crpu.ca<?php echo urldecode($_GET['race']) . '/' . $file; ?>"><?php echo "$file<br>"; ?></a>
<?php endforeach; ?>
I need to find a file in a directory that matches a certain condition. For example, I know the file name starts with '123-', and ends with .txt, but I have no idea what is in between the two.
I've started the code to get the files in a directory and the preg_match, but am stuck. How can this be updated to find the file I need?
$id = 123;
// create a handler for the directory
$handler = opendir(DOCUMENTS_DIRECTORY);
// open directory and walk through the filenames
while ($file = readdir($handler)) {
// if file isn't this directory or its parent, add it to the results
if ($file !== "." && $file !== "..") {
preg_match("/^".preg_quote($id, '/')."\\-(.+)\\.txt$/" , $file, $name);
// $name = the file I want
}
}
// tidy up: close the handler
closedir($handler);
I wrote up a little script here for ya, Cofey. Try this out for size.
I changed the directory for my own test, so be sure to set it back to your constant.
Directory Contents:
123-banana.txt
123-extra-bananas.tpl.php
123-wow_this_is_cool.txt
no-bananas.yml
Code:
<pre>
<?php
$id = 123;
$handler = opendir(__DIR__ . '\test');
while ($file = readdir($handler))
{
if ($file !== "." && $file !== "..")
{
preg_match("/^({$id}-.*.txt)/i" , $file, $name);
echo isset($name[0]) ? $name[0] . "\n\n" : '';
}
}
closedir($handler);
?>
</pre>
Result:
123-banana.txt
123-wow_this_is_cool.txt
preg_match saves its results to $name as an array, so we need to access by it's key of 0. I do so after first checking to make sure we got a match with isset().
You must test if the match was successful.
Your code inside the loop should be this:
if ($file !== "." && $file !== "..") {
if (preg_match("/^".preg_quote($id, '/')."\\-(.+)\\.txt$/" , $file, $name)) {
// $name[0] is the file name you want.
echo $name[0];
}
}
I have a python script I wrote that I need to port to php. It recursively searches a given directory and builds a string based on regex searches. The first function I am trying to port is below. It takes a regex and a base dir, recursively searches all files in that dir for the regex, and builds a list of the string matches.
def grep(regex, base_dir):
matches = list()
for path, dirs, files in os.walk(base_dir):
for filename in files:
fullpath = os.path.join(path, filename)
with open(fullpath, 'r') as f:
content = f.read()
matches = matches + re.findall(regex, content)
return matches
I never use PHP except for basic GET param manipulation. I grabbed some directory walking code from the web, and am struggling to make it work like the python function above due to my utter lack of the php API.
function findFiles($dir = '.', $pattern = '/./'){
$prefix = $dir . '/';
$dir = dir($dir);
while (false !== ($file = $dir->read())){
if ($file === '.' || $file === '..') continue;
$file = $prefix . $file;
if (is_dir($file)) findFiles($file, $pattern);
if (preg_match($pattern, $file)){
echo $file . "\n";
}
}
}
Here is my solution:
<?php
class FileGrep {
private $dirs; // Scanned directories list
private $files; // Found files list
private $matches; // Matches list
function __construct() {
$this->dirs = array();
$this->files = array();
$this->matches = array();
}
function findFiles($path, $recursive = TRUE) {
$this->dirs[] = realpath($path);
foreach (scandir($path) as $file) {
if (($file != '.') && ($file != '..')) {
$fullname = realpath("{$path}/{$file}");
if (is_dir($fullname) && !is_link($fullname) && $recursive) {
if (!in_array($fullname, $this->dirs)) {
$this->findFiles($fullname, $recursive);
}
} else if (is_file($fullname)){
$this->files[] = $fullname;
}
}
}
return($this->files);
}
function searchFiles($pattern) {
$this->matches = array();
foreach ($this->files as $file) {
if ($contents = file_get_contents($file)) {
if (preg_match($pattern, $contents, $matches) > 0) {
//echo $file."\n";
$this->matches = array_merge($this->matches, $matches);
}
}
}
return($this->matches);
}
}
// Usage example:
$fg = new FileGrep();
$files = $fg->findFiles('.'); // List all the files in current directory and its subdirectories
$matches = $fg->searchFiles('/open/'); // Search for the "open" string in all those files
?>
<html>
<body>
<pre><?php print_r($matches) ?></pre>
</body>
</html>
Be aware that:
It reads each file to search for the pattern, so it may require a lot of memory (check the "memory_limit" configuration in your PHP.INI file).
It does'nt work with unicode files. If you are working with unicode files you should use the "mb_ereg_match" function rather than the "preg_match" function.
It does'nt follow symbolic links
In conclusion, even if it's not the most efficient solution at all, it should work.