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!
Related
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);
}
}
?>
lets say I have a folder on a webhost that is called sebis_files and this folder contains some files, maybe pictures, docs...
I want to return the contents of this folder on a separate page, something like:
$row = get dir host/sebis_files*//everything
for ( $row !== 0){ //for every valid file
echo $row . "<br/>"; //return name of file
}
You can use opendir and readdir. Here's a breakdown:
We use __DIR__ to make the path relative to the directory of the current script, just to be safe:
$dir = __DIR__ . '/sebis_files';
Next we open the directory to read it's entries.
We call readdir, which will return a 'resource' object, or false if $dir is not a readable directory:
if ($dh = opendir($dir))
{
The directory is successfully opened.
We now call readdir on that directory. We use the return value of opendir, the mysterious 'resource' object, that will let PHP know what directory we are reading.
Every time we call readdir it will give us the next entry in the directory. When there are no more entries, readdir will return false:
while ( ($entry = readdir($dh)) !== false)
{
We have read a directory $entry: the name of a file or sub-directory inside $dir. So, it's not a full pathname. Let's print it's name, along with whether it is a directory or a file. We will use is_file and is_dir, but we will need to pass the full pathname (hence "$dir/$entry"):
if ( is_dir( "$dir/$entry" ) )
echo "Directory: $entry<br/>";
else if ( is_file( "$dir/entry" ) )
echo "File: $entry<br/>";
}
we are done with the directory, let's close it to free the resource:
closedir($dh);
}
But what if $dir cannot be opened for reading? Let's print a warning:
else
echo "<div class='warning'>cannot open directory!</div>";
you need is to see this
<?php
$dir = "/tmp";
$dh = opendir($dir);
while (false !== ($filename = readdir($dh))) {
$files[] = $filename;
}
sort($files);
print_r($files);
rsort($files);
print_r($files);
?>
You can do it using the glob function :
$dir = "/your/dir/";
if(file_exists($dir))
{
foreach (glob("$dir*") as $file)
{
if(is_file($file))
{
echo basename($file) . "<br />";
}
}
}
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
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);
}
}
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.