PHP to create Links for files in a folder - php

I have a folder on my server that will receive monthly drops of newsletter files. These drops will occur automatically and I've been asked to write something in PHP to display the list of files as downloadable links while changing the display named based on the name of the file.
The folder I'm looking to is "/var/newsletters" and I'm including code on the index.php page at the root directory. The code I have so far is this:
<?php
$dir = "var/newsletters/";
// Open a directory, and read its contents
if (is_dir($dir)){
if ($dh = opendir($dir)){
while (($file = readdir($dh)) !== false){
echo "filename:" . $file . "<br>";
}
closedir($dh);
}
}
?>
This does display the list of files, but it's only the first step of the process. They are not linked and they are not renamed. These are monthly newsletter files and are named nmmyyyy.pdf (For example, September would be n092017.pdf). What I need to do is convert n092017.pdf to "September 2017" and then create the link, so something like n092017.pdf and n102017.pdf in the directory becomes
<ul>
<li>September 2017</li>
<li>October 2017</li>
</ul>
I've looked at a few links here:How to list files and folder in a dir (PHP)
and List all files in one directory PHP, but found that the code I showed above worked best. What I need help with is displaying the list as links and converting the names. Thank you!
EDIT:
I was able to get teh link to work with this code:
<?php
$dir = "var/newsletters/";
// Open a directory, and read its contents
if (is_dir($dir)){
if ($dh = opendir($dir)){
while (($file = readdir($dh)) !== false){
echo " <a href=var/newsletters/$file>Click here</a><br>";
closedir($dh);
}
}
?>
I'm now working on changing the file name and that is not displaying properly. I'm currently working with it as:
<?php
$dir = "var/newsletters/";
// Open a directory, and read its contents
if (is_dir($dir)){
if ($dh = opendir($dir)){
while (($file = readdir($dh)) !== false){
echo "<a href=var/newsletters/$file>
function getDateFromFileName($filename){
$dateObj = DateTime::createFromFormat('m-
Y',substr($filename,1,2).'-'.substr($filename,3,6));
return $dateObj->format('F Y');
}
</a><br>";
}
closedir($dh);
}
}
?>
EDIT 2
<?php
$dir = "var/newsletters/";
function getDateFromFileName($filename){
$dateObj = DateTime::createFromFormat('m-Y',substr($filename,1,2).'-'.substr($filename,3,6));
return $dateObj->format('F Y');
}
// Open a directory, and read its contents
if (is_dir($dir)){
if ($dh = opendir($dir)){
while (($file = readdir($dh)) !== false){
//echo $file . "<br>"; OR //echo "<a href=var/newsletters/$file>Click here</a><br>"; WORKING
$formatted_date = getDateFromFileName($file);
echo "<a href=var/newsletters/$file>{$formatted_date}</a><br>";
}
closedir($dh);
}
}
?>

You can add this function to help with getting the dates from the filenames
function getDateFromFileName($filename){
$dateObj = DateTime::createFromFormat('m-Y',substr($filename,1,2).'-'.substr($filename,3,6));
return $dateObj->format('F Y');
}
Calling getDateFromFileName("n102017.pdf") prints October 2017
EDIT:
To change the name in your scenario do
<?php
$dir = "var/newsletters/";
function getDateFromFileName($filename){
$dateObj = DateTime::createFromFormat('m-Y',substr($filename,1,2).'-'.substr($filename,3,6));
return $dateObj->format('F Y');
}
// Open a directory, and read its contents
if (is_dir($dir)){
if ($dh = opendir($dir)){
while (($file = readdir($dh)) !== false){
if($file == "." || $file ==".."){
continue;
}
$formatted_date = getDateFromFileName($file);
echo " <a href=var/newsletters/$file>{$formatted_date}</a><br>";
closedir($dh);
}
}
?>

Related

linking directories and files in php

Hello stackoverflow community;
I'm trying to display a few files in a directory using php and coming unstuck:
In my file ('salad') I have three recipe files ('recipe1.txt', recipe2.txt, 'recipe3.txt') and I want to display them so I'm writing the following:
$script = opendir('salad');
while(false !==($file = readdir($script))) {
if (is_file($file)) {
echo "<p>$file</p>";
}
}
Unfortunately this only echos to the screen .DS_store, what am i doing wrong?
You could use this:
<?php
$dir = "/tmp"; // put what suits you here
$dh = opendir($dir);
while (false !== ($filename = readdir($dh))) {
$files[] = $filename;
}
sort($files);
print_r($files);
rsort($files);
echo"$files";
?>
source:
http://php.net/manual/en/function.scandir.php

Read one file name "Only" and skip to next directory - PHP

I have the following code which reads all filnames from each directory, but I want it to read one filename "only" and skip to the next directory.
<?php
$dir = "/images/";
// Open a directory, and read its contents
if (is_dir($dir)){
if ($dh = opendir($dir)){
while (($file = readdir($dh)) !== false){
echo "filename:" . $file . "<br>";
}
closedir($dh);
}
}
?>
How can I read only one filename, then skip to the next directory to read "only" first filename and so on. Please let me know if you require any more information.
if it doesn't matter which file you read then just put a break; in your while loop or don't even go in a loop just take the $file = readdir($dh);
PS: In linux OS be aware of . and .. Also look up scabdir() function
You need to maintain counter here to do the same.
Do like this:
$dir = "/images/";
if (is_dir($dir)){
if ($dh = opendir($dir)){
while (($file = readdir($dh)) !== false){
echo "filename:" . $file . "<br>";
break;
}
closedir($dh);
}
}
Let me know for more help!

Require to display limited number of file names from directories -php

For the below code I have multiple directories and files. I can display one filename per directory(Which is good with the "BREAK").
<?php
$dir = "/images/";
$i=0;
// Open a directory, and read its contents
if (is_dir($dir)){
if ($dh = opendir($dir)){
while (($file = readdir($dh)) !== false){
echo "filename:" . $file . "<br>";
break;
//---- if ($i>=5) { break; }
}
closedir($dh);
}
}
?>
With
if ($i>=5) { break; } I can still display 5 filenames but it reads only one directory.
I want to display at least 5 file names from all directories, how can I do it?
Use the scandir function.
array scandir ( string $directory [, int $sorting_order = SCANDIR_SORT_ASCENDING [, resource $context ]] )
or
If you are using unix you could also do a system call and run the following command.
ls /$dir | head -5
$dir is the directory and -5 is the number filenames in the directory.
Since you said that you have multiple directory's, I rewrote your code a bit:
(Here I first loop through all directory's with array_map() then I get all files from each directory with glob(). After this I just limit the files per directory with array_slice() and at the end I simply print all file names)
<?php
$directorys = ["images/", "xy/"];
$limit = 3;
//get all files
$files = array_map(function($v){
return glob("$v*.*");
}, $directorys);
//limit files per directory
$files = array_map(function($v)use($limit){
return array_slice($v, 0, $limit);
}, $files);
foreach($files as $directory) {
echo "<b>Directory</b><br>";
foreach($directory as $file)
echo "$file<br>";
echo "<br><br>";
}
?>
You don't have to break it, you can just skip it. And in doing so, you have to use continue instead.
$dir = "/images/";
$i=0;
// Open a directory, and read its contents
if (is_dir($dir)){
if ($dh = opendir($dir)){
while (($file = readdir($dh)) !== false){
echo "filename:" . $file . "<br>";
if ($i>=5)
continue;
}
closedir($dh);
}
}
Here is also another scenario. Because you mentioned that you have many directories but you only show one main directory, I am guessing that the directories you've mentioned were inside the /images/ directory.
$dir = "images/";
$i=1;
// Open a directory, and read its contents
if (is_dir($dir)){
if ($dh = opendir($dir)){
while (($file = readdir($dh)) !== false){
$j=1;
if (is_dir($file)) {
if ($internalDir = opendir($file)) {
while (($internalFile = readdir($internalDir)) !== false) {
echo $file."->filename: ".$internalFile."<br>";
if ($j>=5)
continue;
$j++;
}
closedir(opendir($file));
}
} else {
echo "filename:" . $file . "<br>";
if ($i>=5)
continue;
$i++;
}
}
closedir($dh);
}
}
Read more about continue here: http://php.net/manual/en/control-structures.continue.php

Making download links out of all of the files in a particular folder

Right now there is an upload system on the site I am working on where users can upload some documents to a particular file. Later on I will need to make these documents downloadable. Is there an easy way to iterate through all the files in a particular directory and create download links for the files?
Something like:
foreach($file){
echo 'somefilename';
}
Many thanks in advance.
if($dh = opendir('path/to/directory')) {
while(($file = readdir($dh)) !== false) {
if($file == "." || $file == "..") { continue; }
echo '' . $file . '';
}
closedir($dh);
}
You should see opendir.
Example from that page adapted to question:
$dir = "/etc/php5/";
$path = "/webpath";
// Open a known directory, and proceed to read its contents
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
echo "$file";
}
closedir($dh);
}
}

Why does my zip code not work as expected?

See this question. I can't use that code:
function addFolderToZip($dir, $zipArchive, $zipdir = ''){
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
//Add the directory
$zipArchive->addEmptyDir($dir);
// Loop through all the files
while (($file = readdir($dh)) !== false) {
//If it's a folder, run the function again!
if(!is_file($dir . $file)){
// Skip parent and root directories
if( ($file !== ".") && ($file !== "..")){
addFolderToZip($dir . $file . "/", $zipArchive, $zipdir . $file . "/");
}
}else{
// Add the files
$zipArchive->addFile($dir . $file, $zipdir . $file);
}
}
}
Please write an example for me. The second problem is too complex.
When I use addfile function it will add and appear in the archive as a file and this great. Now when I use:
$z = new ZipArchive();
$z->open('test.zip')
for ($i=0; $i< $z->numFiles;$i++) {
$aZipDtls = $z->statIndex($i);
echo $aZipDtls['name'];
}
it now shows if I add a file in folder like that:
$zip->addFile('/path/to/index.txt', 'dir/newname.txt');
it show in the Winrar soft a dir then a file but in the code it shows it as one file.
Like that in winrar:
dir/
dir/newname.txt
In my PHP system, just only show one file without its dir, like that:
dir/newname.txt
This mean it's impossible to add a new file in a dir.
Difficult to know what you want, but here goes:
<?php
$zip = new ZipArchive();
$zip->open('test.zip');
$zip->addFile('/path/to/newname.txt','dir/newname1.txt');
$zip->addFile('/path/to/newname.txt','dir/newname2.txt');
$zip->addFile('/path/to/newname.txt','dir/dir/newname3.txt');
$zip->addFile('/path/to/newname.txt','dir/dir/dir/newname4.txt');
for ($i=0; $i< $zip->numFiles;++$i) {
$aZipDtls = $zip->statIndex($i);
echo $aZipDtls['name'],"\n";
}
$zip->close();
?>
Should cover all questions. That will unzip with exactly the structure you'd expect it to. The discrepancy is likely due to the way WinRar displays the archive structure.

Categories