Disclaimer: I did not write this code myself a friend gave it to me.
<?php
$handle = opendir(dirname(realpath(__FILE__)).'/AlgemeneVergaderingen/');
while($file = readdir($handle)){
if($file !== '.' && $file !== '..'){
echo '<p>' .$file. '</p>';
}
}
?>
The point of this code is to loop inside a map and get all the files and echo them out IN THE ORDER that they are inside of the map.
The code does echo them but not in the correct order.
below 2 pictures to help visualize.
full code/file structure
the actual result
readdir() doesn't guarantee any order. You need to order it yourself.
For reference:
https://utcc.utoronto.ca/~cks/space/blog/unix/ReaddirOrder
Related
This is my code:
$ost=$_GET['id']; //get the ID from the URL
$path = "audio/soundtracks/$ost"; //use the ID to select a path
// Open the folder
$dir_handle = #opendir($path) or die("Unable to open $path");
// Loop through the files
while ($file = readdir($dir_handle)) {
if($file == "." || $file == ".." || $file == "index.php" )
continue;
echo "<a href='$path/$file'>$file</a><br />"; //return the name of the track
}
// Close
closedir($dir_handle);
It's purpose is to automatically list every sound track cointained in a directory, the name of which is given by the ID passed through the URL. Each track is named with the format "### - title.mp3", e.g. "101 - Overture.mp3".
It works fine, but the resulting list is sorted randomly for some reason. Is there any way to sort the tracks by title? Also, I'm pretty much a newbie with PHP, is there any security issue with the GET function? Thanks in advance.
EDIT: The GET is only used to specify the path, it's not supposed to interact with the database. Is this enough to prevent attacks?
$ost = $_GET['id'];
$bad = array("../","=","<", ">", "/","\"","`","~","'","$","%","#");
$ost = str_replace($bad, "", $ost);
$path = "audio/soundtracks/$ost";
Do some checks on GET parameter before using it. Like checking it is numeric, right lenght etc. And msyql_real_escape_String if used against db.
When looping directory, save files in array in php, with title as index. like this, then you can sort it as you please:
while ($file = readdir($dir_handle)) {
if($file == "." || $file == ".." || $file == "index.php" )
continue;
$array[$file] = "<a href='$path/$file'>$file</a><br />"; //return the name of the track
}
sort($array);
... after this, loop and print array separately.
It is a better coding practice to first loop to arrays, and then print separatly... in my eyes. It is more flexible.
Apart from checking length and using escape string security measures on the $_GET, you can also encode and decode the id into the URL and decode the before using it.
//before putting into URL
$id = $rows["id"];
$id = base64_encode($id);
<a href="yourUrl.php?id='$id'"
//in yourUrl.php
$id = $_GET['id'];
$id = base64_decode($id);
i have several millions files in a folder and there are several subfolders in that folder each subfolder consists of thousands of files . i am able to list all files of given folder using glob function but here in this case as its very high i am getting php fatal error . allowed memory size exhaused try to allocate more memory i know that can be done just by keeping one php.ini file in that subfolder but what i exactly want is listing all .txt extension size in descending order so the bigger file will be at the top and smaller file will be at the bottom but as i have said it is not possible to list millions of file so just like mysql can i list them in page wise or something like top 100 files will be listed in descending order when i click on next page it will show next 100-200 items but i dont want to use database if there is no other way how i can store all these details in database without causing heavy load on server.
<?php
foreach (glob("files/*") as $filename) {
echo "uploads/" . "$filename" . "\n</br>";
}
?>
use opendir insteed of glob();
Try something like this:
function printdirs($path) {
if ($handle = opendir($path)) {
while (false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != "..") {
if(is_dir($path.'/'.$entry))
printdirs($path.'/'.$entry);
else
echo $path . "/" . $entry . "\n</br>";
}
}
closedir($handle);
}}
printdirs('uploads');
I'm trying to think of a way to make this happen.
I'm using a jQuery slideshow to display images, and a simple php script to pull the images from a folder based on which gallery the user selects:
$handle = opendir(dirname(realpath(__FILE__)).'/../images/gallery/'.$gallery);
while($file = readdir($handle)){
if($file !== '.' && $file !== '..'){
$pictures .= '<img src="images/gallery/'.$gallery.'/'.$file.'" alt="" />';
}
}
I'm doing it this way since there are 6 different galleries, and the amount of photos in each gallery varies, from about 25 - 40 pictures. If I did the site staticly, or had a database running it'd be no problem, but I can't think of a PHP way of doing this.
Basically here is an example of what I'm hoping to do: I hard coded all the images and text
But on this page I can't think of a good way of doing it
You can add to each folder file like info.txt with descriptions. Check file_exists() on load and get data from the file.
If you want to set desc for each photo you can do smth like:
For files:
flower.jpg
cloud.jpg
girl.jpg
info.txt:
flower.jpg::This is flower
cloud.jpg::This is cloud
girl.jpg::This is girl
So you read info.txt, explode by rows and explode rows at last. At the result you're getting array with descriptions and filenames.
Probably not the best way to do it, but heres my work-around way I accomplished it:`
I renamed the images:
01-A Bird, 02-A Cat
$handle = opendir(dirname(realpath(__FILE__)).'/../images/gallery/'.$gallery);
while($file = readdir($handle)){
if($file !== '.' && $file !== '..'){
$alt = substr($file, 3, -4); //Removes the "##-" and the ".jpg"
$id = substr($file, 0, 2); // Removes EVERYTHING after the "##"
// The image
$pictures .= '<img src="images/gallery/'.$gallery.'/'.$file.'" alt="'.$alt.'" data-caption="#cap'.$id.'" />';
// The text
$span .= '<span class="caption" id="cap'.$id.'">'.$alt.'</span>';
}
}`
I'm fairly new to PHP and have been using PHP's readdir() to look into a folder full of images and render them out dynamically based on how many images there are in that folder. Everything works great, but one thing I've noticed is that the images are not displayed in the order that they appear on my local machine HD.
So my question to anyone who knows PHP is, is there way of using PHP to read the contents of a folder AND display them in order without having to rename the actual file names e.g. 01.jpg, 02.jpg etc etc?
Have a look at the glob() function, it returns files alphabetically sorted by default:
$files = glob('/some/path/*.*');
Bonus, you can filter just images, and leave out directories.
readdir likely just takes the file system order. Which is alphabetical on NTFS, but seemingly random on most Unix filesystems. The documentation even says as much: »The entries are returned in the order in which they are stored by the filesystem.«
So you'd have to store the list in an array and sort that based on how you would like them to be sorted.
The php manual says:
string readdir ([ resource $dir_handle ] )
Returns the name of the next entry in the directory. The entries are returned in the order in which they are stored by the filesystem.
Meaning they should appear the same way.
More information found in the manual.
Why not apply one of the sort-functions of PHP?
$files = readdir( $theFoldersPath );
sort( $files );
Here is what I came up with in answer (together with the help of the people who posted) to my own question.
<?php
$dir = "low res";
$returnstr = "";
// The first part puts all the images into an array, which I can then sort using natsort()
$images = array();
if ($handle = opendir($dir)) {
while ( false !== ($entry = readdir($handle))) {
if ($entry != "." && $entry != ".."){
$images[] = $entry;
}
}
closedir($handle);
}
natsort($images);
print_r($images);
$newArray = array_values($images);
// This bit then outputs all the images in the folder along with it's own name
foreach ($newArray as $key => $value) {
// echo "$key - <strong>$value</strong> <br />";
$returnstr .= '<div class="imgWrapper">';
$returnstr .= '<div class="imgFrame"><img src="'. $dir . '/' . $value . '"/></div>';
$returnstr .= '<div class="imgName">' . $value . '</div>';
$returnstr .= '</div>';
}
echo $returnstr;
?>
I have a double question. Part one: I've pulled a nice list of pdf files from a directory and have appended a file called download.php to the "href" link so the pdf files don't try to open as a web page (they do save/save as instead). Trouble is I need to order the pdf files/links by date created. I've tried lots of variations but nothing seems to work! Script below. I'd also like to get rid of the "." and ".." directory dots! Any ideas on how to achieve all of that. Individually, these problems have been solved before, but not with my appended download.php scenario :)
<?php
$dir="../uploads2"; // Directory where files are stored
if ($dir_list = opendir($dir))
{
while(($filename = readdir($dir_list)) !== false)
{
?>
<p><a href="http://www.duncton.org/download.php?file=login/uploads2/<?php echo $filename; ?>"><?php echo $filename;
?></a></p>
<?php
}
closedir($dir_list);
}
?>
While you can filter them out*, the . and .. handles always come first. So you could just cut them away. In particular if you use the simpler scandir() method:
foreach (array_slice(scandir($dir), 2) as $filename) {
One could also use glob("dir/*") which skips dotfiles implicitly. As it returns the full path sorting by ctime then becomes easier as well:
$files = glob("dir/*");
// make filename->ctime mapping
$files = array_combine($files, array_map("filectime", $files));
// sorts filename list
arsort($files);
$files = array_keys($files);