I'm very basic when it comes to PHP.
With my website, I have a directory called "uploads"
Within "uploads" I have 3 folders "Example1" "Example2" and "Example3"
Within each of the folders, they contain images.
I need to know how to use php to create a navigation for every sub directory.
So that if I add a new folder "Example4" it will give a navigation like:
Select what section you're looking for:
Example1 | Example2 | Example3
and if I later add new folders add them to the navigation.
EX:
Example1 | Example2 | Example3 | Example4 | Example5
Then once they click the link to go into the folder, have a code that displays all the images in that folder.
So far I have:
<?php
$files = glob("uploads/*.*");
for ($i=0; $i<count($files); $i++)
{
$num = $files[$i];
echo '<img src="/'.$num.'">'."<p>";
}
?>
but it will only display the images in the upload directory, not the images in Example1 and so on.
How on earth would I go about doing this? I'm doing it for a school project and have two weeks to complete it, but I am so lost. I only have knowledge with CSS, HTML, and the only PHP I know is php includes, so any help would be appreciated.
Since it seems that you are familiar with globs a bit, here is an example using the "glob" function. You can see a basic working example of what you are looking for here:
http://newwebinnovations.com/glob-images/
Here is how I have the example set up:
There are two PHP files, one is index.php and the other is list-images.php.
There is also a folder for images two subfolders that have images inside of them.
index.php is the file that finds the folders in the images folder and places them in a list with links list-images.php which will display the images inside of the folder:
$path = 'images';
$folders = glob($path.'/*');
echo '<ul>';
foreach ($folders as $folder) {
echo '<li>'.$folder.'</li>';
}
echo '</ul>';
The links created above have a dynamic variable created that will pass in the link to the list-images.php page.
Here is the list-images.php code:
if (isset($_GET['folder'])) {
$folder = $_GET['folder'];
}
$singleImages = array();
foreach (glob($folder . '/*.{jpg,jpeg,png,gif}', GLOB_BRACE) as $image) {
$imageElements = array();
$imageElements['source'] = $image;
$singleImages[$image] = $imageElements;
}
echo '<ul>';
foreach ($singleImages as $image) {
echo '<li><img src="'.$image['source'].'" width="400" height="auto"></li>';
}
echo '</ul>';
The links created here will link you to the individual images.
To get files of every specific folder ,pass it throw a get variable that contains folder's name,an then scan this folder an show images ,url should be like this :
listImages.php?folderName=example1
To have menu like what you want :
<?php
$path = 'uploads/' ;
$results = scandir($path);
for ($i=0;$i<count($results);$i++ ) {
$result=$results[$i];
if ($result === '.' or $result === '..') continue;
if (is_dir($path . '/' . $result)) {
echo "<a href='imgs.php?folderName=$result'>$result</a> ";
}
if($i!=count($results)-1) echo '|'; //to avoid showing | in the last element
}
?>
And here is PHP page listImages that scan images of a specific folder :
<?php
if (isset($_GET['folderName'])) $folder=$_GET['folderName'];
$path = 'uploads/'.$folder.'/' ;
$images = glob($path . '*.{jpg,jpeg,png,gif}', GLOB_BRACE);
foreach ($images as $image) {
echo "<img src='$image' />";
}
?>
First of all, do read more PHP manual, for directory related: opendir, for files related: fopen
The following code is basically re-arranging the example code provided in opendir. What it does:
A scan_directory function to simply check if directory path is valid and is a directory, then proceed to do a recursive call if there's a child directory else just print out the file name.
The first if/else condition is just to ensure the base directory is valid.
I'll added ul and li to make it slightly more presentable.
$base_dir = 'upload';
if (is_dir($base_dir))
scan_directory($base_dir);
else
echo 'Invalid base directory. Please check your setting.';
// recursive function to check all dir
function scan_directory($path) {
if (is_dir($path)) {
if ($dir_handle = opendir($path)) {
echo '<ul>';
while (($file = readdir($dir_handle)) !== false) {
if ($file != '.' && $file != '..') {
if (is_dir($path . '/' . $file)) {
echo '<li>';
echo $file;
scan_directory($path . '/' . $file);
echo '</li>';
}
else
echo "<li>{$file}</li>";
}
}
echo '</ul>';
}
}
}
create image as subdirectory name with image name and save it in database
example:
subdirectory name: example2
image name: image.jpg
store image name in db as "example2/image.jpg"
Related
I have a directory with subfolders containing images. I need to display all these on one page, and also their folder name, so something like this:
echo Subfolder name
echo image, image, image
echo Subfolder2 name
echo image2, image2 , image2
etc
I've tried using
$images = glob($directory . "*.jpg");
but the problem is I have to exactly define the subfolder name in $directory, like "path/folder/subfolder/";
Is there any option like some "wildcard" that would check all subfolders and echo foreach subfolder name and its content?
Also, opendir and scandir can't be applied here due to server restrictions I can't control.
Glob normally have a recursive wildcard, written like /**/, but PHP Glob function doesn't support it. So the only way is to write your own function. Here's a simple one that support recursive wildcard:
<?php
function recursiveGlob($pattern)
{
$subPatterns = explode('/**/', $pattern);
// Get sub dirs
$dirs = glob(array_shift($subPatterns) . '/*', GLOB_ONLYDIR);
// Get files in the current dir
$files = glob($pattern);
foreach ($dirs as $dir) {
$subDirList = recursiveGlob($dir . '/**/' . implode('/**/', $subPatterns));
$files = array_merge($files, $subDirList);
}
return $files;
}
Use it like that $files = recursiveGlob("mainDir/**/*.jpg");
is there any way for RecursiveDirectoryIterator to echo files in subfolders separately based on folder and not all together?
Here is my example. I have a folder (event), which has multiple subfolders (logo, people, bands). But subfolder names vary for certain events, so I can't simply set to look inside these three, I need a "wildcard" option.
When I use RecursiveDirectoryIterator to echo out all images from these folders, it works, but I would like to separate these based on subfolder, so it echoes out folder name and all images from within below and then repeats for the next folder and so on.
Right now I use this:
<?php
$directory = "path/to/mainfolder/";
foreach (new RecursiveIteratorIterator(new
RecursiveDirectoryIterator($directory,RecursiveDirectoryIterator::SKIP_DOTS)) as $filename)
{
echo '<img src="'.$filename.'">';
}
?>
So, how do I make this echo like:
Logo
image, image, image
People
image, image, image
...
Thanks in advance for any useful tips and ideas.
for me, code is more readable when you put objects into variables with descriptive names then pass those on when instantiating other classes. I've used the RegexIterator() over the RecursiveFilterIterator() to filter just image file extensions (didn't want to get into extending the RecursiveFilterIterator() class for example). The rest of the code is simple iterating, extracting strings and page breaking.
NOTE: there is no error handling, best to add a try/catch to manage exceptions
<?php
$directory = 'path/to/mainfolder/';
$objRecursiveDirectoryIterator = new RecursiveDirectoryIterator($directory, RecursiveDirectoryIterator::SKIP_DOTS);
$objRecursiveIteratorIterator = new RecursiveIteratorIterator($objRecursiveDirectoryIterator);
// use RegexIterator() to grab only image file extensions
$objRegexIterator = new RegexIterator($objRecursiveIteratorIterator, "~^.+\.(bmp|gif|jpg|jpeg|img)$~i", RecursiveRegexIterator::GET_MATCH);
$lastPath = '';
// iterate through all the results
foreach ($objRegexIterator as $arrMatches) {
$filename = $arrMatches[0];
$pos = strrpos($filename, DIRECTORY_SEPARATOR); // find position of last DIRECTORY_SEPARATOR
$path = substr($filename, 0, $pos); // path is everything before
$file = substr($filename, $pos + 1); // file is everything after
$myDir = substr($path, strrpos($path, DIRECTORY_SEPARATOR) + 1); // directory the file sits in
if ($lastPath !== $path) { // is the path the same as the last
// display page break and header
if ($lastPath !== '') {
echo "<br />\n";
echo "<br />\n";
}
echo $myDir ."<br />\n";
$lastPath = $path;
}
echo $file . " ";
}
I'm trying to make an image gallery that scans a main directory and creates a separate album for each subdirectory.
My structure is similar to this:
-Gallery
--Subdir 1
---Image 1
---Image 2
--Subdir 2
---Image 1
---Image 2
The idea is that each album is going to be made of a div with a class of web-gallery. Then there will be a header for the album title made from the subdirectories name. After that a list is generated of each image. This is going to be a one page gallery. If possible I would like to have a variable that sets how many albums are listed that way if I have 30 subdirectories my page doesn't get too crowded.
So far I've written this but it doesn't work. I'm not getting any errors or logs though it just doesn't work.
$dirs = glob('img/gallery_temp/*', GLOB_ONLYDIR);
foreach($dirs as $val) {
echo '<div class="web-gallery">';
echo "<h3><span>»</span> ".basename($val). "</h3>";
echo '<ul class="web-gallery-list">';
$files = glob($val.'*.{jpg,png,gif}', GLOB_BRACE);
foreach($files as $file) {
echo "<li><a href='".$file."'><img src='" . $file . "' alt='description'></a></li> \r\n";
}
echo "</ul>";
echo "</div>";
}
Simply add a / before *.{jpg,png,gif} like this:
$files = glob($val.'/*.{jpg,png,gif}', GLOB_BRACE);
This is because $val doesn't have a final / for the directory.
You might consider using "readdir" instead of glob. Glob is to find pathnames matching a pattern, see here: http://php.net/manual/en/function.glob.php and is known to be a bit problematic.
Readdir, if your directory is entirely images might be easier to use: http://php.net/manual/en/function.readdir.php
Couple this with is_dir() http://php.net/manual/en/function.is-dir.php to resolve your directories vs files. Here is a snippet
<?php
if ($handle = opendir('/galleries')) {
while (false !== ($entry = readdir($handle))) {
// this is a subdirectory
if (is_dir($entry)) {
}
// this is a file
else {
echo $entry;
}
}
closedir($handle);
}
?>
If you make it a recursive function you could actually have it traverse a number of subdirectories creating galleries within galleries.
I also found this fantastic little snippet that is very elegant on another stack question: Get Images In Directory and Subdirectory With Glob
$rdi = new RecursiveDirectoryIterator("uploads/prevImgs/");
$it = new RecursiveIteratorIterator($rdi);
foreach($it as $oneThing)
if (is_file($oneThing))
echo '<img src="'.$oneThing.'" /><br />';
Using SPL Library (PHP >= 5)
Better solution in your case
is to use SPL library (the most cross-platform)
$directory = new RecursiveDirectoryIterator("./img/gallery_temp", FilesystemIterator::SKIP_DOTS);
// Flatten the recursive iterator, folders come before their files
$it = new RecursiveIteratorIterator($directory, RecursiveIteratorIterator::SELF_FIRST);
foreach($it as $fileinfo)
{
if($fileinfo->isDir())
{
// prevPath used to separate each directory listing and closing the bracket UL list
$prevPath = $it->getSubPath().DIRECTORY_SEPARATOR.$fileinfo->getFilename();
echo sprintf
(
"<div class='web-gallery'>
<h3><span>></span> %s</h3>
<ul>".PHP_EOL,
$fileinfo->getFilename()
);
}
if($fileinfo->isFile())
{
echo sprintf("<li><a href=''><img src='%s/%s' alt='description'></a></li>".PHP_EOL, $it->getSubPath(), $fileinfo->getFilename());
if($prevPath != $it->getSubPath())
echo("</ul>");
}
}
Note:
For more informations : SPL Documentation
DIRECTORY_SEPARATOR is a cross-platform constant, will use the
correct directory separator of the OS where are executed the code
FilesystemIterator::SKIP_DOTS, avoid to fetch the '.' and '..' dir
link level.
you can limit the depth of scanning with $it->setMaxDepth(5);
I have an uploader that make me upload files to the server.
I would like that when I upload an image, this image is automatically visible in a page of the site. Eg, if I have a site of a music band, if I upload from an administrator password protected page the poster of the next concert, and automatically in the page "events" I can see that poster.
In the same way if I upload (from another uploader) the text for that concert, this text appears in the event page in a "description of the concert" div.
Is it possible?
thank you!
If you need to do that, then using the database and store the uploaded items in its coloumn is the better way..
But to answer your question
You can do something like this.
Step 1 :
Read all the files in your directory
$dir = 'up/';
$files = scandir($dir);
Step 2 :
Do a foreach and print it in your file (If you need to display an image it can be possible and you can have links over there )
$i = 1;
foreach ($files as $key)
{
echo $i.' - '.$key.'<hr>';
echo "<a href='up/".$key."'><img src ='up/".$key."'>".$key."</a>";
$i++;
}
So you can have something like this..
<?php
$dir = 'up/';
$files = scandir($dir);
echo '<h1>List of Uploaded Files</h1> <br><hr>';
$i = 1;
foreach ($files as $key)
{
echo $i.' - '.$key.'<hr>';
echo "<a href='up/".$key."'><img src ='up/".$key."'>".$key."</a>";
$i++;
}
echo 'End of Files';
?>
Note :
I am using the directory name as up you can have it any name of your own.
If you have this file as list.php then it should have a sub folder named as up and you should have files inside it.. You can have image or text file as you need.
Update :
If you just want to list the files, then you just need to echo it
<?php
$dir = 'up/';
$files = scandir($dir);
echo '<h1>List of Uploaded Files</h1> <br><hr>';
$i = 1;
foreach ($files as $key)
{
echo $i.' - '.$key.'<hr>';
$i++;
}
echo 'End of Files';
?>
Here's the eval link
Update 2 :
As the OP needs to have an anchor tag and wants to remove the directory level Here's the updated code
<?php
$dir = 'up/';
$files = scandir($dir);
echo '<h1>List of Uploaded Files</h1> <br><hr>';
$i = 1;
foreach ($files as $key)
{
if ($i>3)
{
$j = $i-3;
echo $j."<a href='up/".$key."'>".$key."</a><hr>";
}
$i++;
}
echo 'End of Files';
?>
Here's the Eval
Need help for a php script / page for generating links to folders.
Have a homepage with photos that I upload using Lightroom – each album in a separate folder.
The structure is:
mysite.com
|--images
|--folder1
|--folder2
|--folder3
.
.
So I would like to end up with a dynamic index.php file that generates links to all the subfolders of “images” instead of the static index.html file I got in the root of mysite.com:
<html>
<body>
folder1
folder2
folder3
.
.
</body>
</html>
Thanx in advance
<?php
$files = scandir();
$dirs = array(); // contains all your images folder
foreach ($files as $file) {
if (is_dir($file)) {
$dirs[] = $file;
}
}
?>
use dirs array for dynamically generating links
Maybe something like this:
$dir = "mysite.com/images/";
$dh = opendir($dir);
while ($f = readdir($dh)) {
$fullpath = $dir."/".$f;
if ($f{0} == "." || !is_dir($fullpath)) continue;
echo "$f\n";
}
closedir($dh);
When I need everything (i.e., something/*), I prefer readdir() over glob() because of speed and less memory consumption (reading a directory file by file, instead of getting the whole thing in an array).
If I'm not mistaken, glob() does omit .*files and has no need for the $fullpath variable, so if you're after speed, you might want to do some testing.
Try something like this:
$contents = glob('mysite.com/images/*');
foreach ($contents as content) {
$path = explode('/', $content);
$folder = array_pop($path);
echo '' . $folder . '';
}
Or also this:
if ($handle = opendir('mysite.com/images/') {
while (false !== ($content = readdir($handle))) {
echo echo '' . $content . '';
}
closedir($handle);
}