I'm trying to get a webpage to show images but it doesn't seem to be working.
here's the code:
<?php
$files = glob("images/*.*");
for ($i=1; $i<count($files); $i++)
{
$num = $files[$i];
echo '<img src="'.$num.'" alt="random image">'." ";
}
?>
If the code should work, where do i put it?
If not, is there a better way to do this?
You'd need to put this code in a directory that contains a directory named "images". The directory named "images" also needs to have files in a *.* name format. There are definitely better ways to do what you're trying to do. Such would be using a database that contains all the images that you want to display.
If that doesn't suit what you want to do, you'd have to be much more descriptive. I have no idea what you want to do and all I'm getting from the code you showed us is to render every file in a directory called "images" as an image.
However, if this point of this post was to simply ask "How do I execute PHP?", please do some searching and never bother us with a question like that.
Another thing #zerkms noticed was that your for .. loop starts at iteration 1 ($i = 1). This means that a result in the array will be skipped over.
for ($i = 0; $i < count($files); $i++) {
This code snippet iterates over the files in the directory images/ and echos their filenames wrapped in <img> tags. Wouldn't you put it where you want the images?
This would go into a PHP file (images.php for example) in the parent directory of the images folder you are listing the images from. You can also simplify your loop (and correct it, since array indexes should start at 0, not 1) by using the following syntax:
<?php
foreach (glob("images/*.*") as $file){
echo '<img src="'.$file.'" alt="random image"> ';
}
?>
/**
* Lists images in any folder as long as it's inside your $_SERVER["DOCUMENT_ROOT"].
* If it's outside, it's not accessible.
* Returns false and warning or array() like this:
*
* <code>
* array('/relative/image/path' => '/absolute/image/path');
* </code>
*
* #param string $Path
* #return array/bool
*/
function ListImageAnywhere($Path){
// $Path must be a string.
if(!is_string($Path) or !strlen($Path = trim($Path))){
trigger_error('$Path must be a non-empty trimmed string.', E_USER_WARNING);
return false;
}
// If $Path is file but not folder, get the dirname().
if(is_file($Path) and !is_dir($Path)){
$Path = dirname($Path);
}
// $Path must be a folder.
if(!is_dir($Path)){
trigger_error('$Path folder does not exist.', E_USER_WARNING);
return false;
}
// Get the Real path to make sure they are Parent and Child.
$Path = realpath($Path);
$DocumentRoot = realpath($_SERVER['DOCUMENT_ROOT']);
// $Path must be inside $DocumentRoot to make your images accessible.
if(strpos($Path, $DocumentRoot) !== 0){
trigger_error('$Path folder does not reside in $_SERVER["DOCUMENT_ROOT"].', E_USER_WARNING);
return false;
}
// Get the Relative URI of the $Path base like: /image
$RelativePath = substr($Path, strlen($DocumentRoot));
if(empty($RelativePath)){
// If empty $DocumentRoot === $Path so / will suffice
$RelativePath = DIRECTORY_SEPARATOR;
}
// Make sure path starts with / to avoid partial comparison of non-suffixed folder names
if($RelativePath{0} != DIRECTORY_SEPARATOR){
trigger_error('$Path folder does not reside in $_SERVER["DOCUMENT_ROOT"].', E_USER_WARNING);
return false;
}
// replace \ with / in relative URI (Windows)
$RelativePath = str_replace('\\', '/', $RelativePath);
// List files in folder
$Files = glob($Path . DIRECTORY_SEPARATOR . '*.*');
// Keep images (change as you wish)
$Files = preg_grep('~\\.(jpe?g|png|gif)$~i', $Files);
// Make sure these are files and not folders named like images
$Files = array_filter($Files, 'is_file');
// No images found?!
if(empty($Files)){
return array(); // Empty array() is still a success
}
// Prepare images container
$Images = array();
// Loop paths and build Relative URIs
foreach($Files as $File){
$Images[$RelativePath.'/'.basename($File)] = $File;
}
// Done :)
return $Images; // Easy-peasy, general solution!
}
// SAMPLE CODE COMES HERE
// If we have images...
if($Images = ListImageAnywhere(__FILE__)){ // <- works with __DIR__ or __FILE__
// ... loop them...
foreach($Images as $Relative => $Absolute){
// ... and print IMG tags.
echo '<img src="', $Relative, '" >', PHP_EOL;
}
}elseif($Images === false){
// Error
}else{
// No error but no images
}
Try this on for size. Comments are self explanatory.
Related
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 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/';
I would like to delete all files matching a particular extension in a specified directory and all subtree. I suppose I should be using using unlink but some help would be highly appreciated... Thank you!
you need a combination of this
Recursive File Search (PHP)
And the unlink / delete
You should be able to edit the example instead of echoing the file, to delete it
To delete specific extension files from sub directories, you can use the following function. Example:
<?php
function delete_recursively_($path,$match){
static $deleted = 0,
$dsize = 0;
$dirs = glob($path."*");
$files = glob($path.$match);
foreach($files as $file){
if(is_file($file)){
$deleted_size += filesize($file);
unlink($file);
$deleted++;
}
}
foreach($dirs as $dir){
if(is_dir($dir)){
$dir = basename($dir) . "/";
delete_recursively_($path.$dir,$match);
}
}
return "$deleted files deleted with a total size of $deleted_size bytes";
}
?>
e.g. To remove all text files you can use it as follows:
<?php echo delete_recursively_('/home/username/directory/', '.txt'); ?>
So I'm trying to make a simple script, it will have a list of predefined files, search for anything that's not on the list and delete it.
I have this for now
<?php
$directory = "/home/user/public_html";
$files = glob($directory . "*.*");
foreach($files as $file)
{
$sql = mysql_query("SELECT id FROM files WHERE FileName='$file'");
if(mysql_num_rows($sql) == 0)
unlink($directory . $file);
}
?>
However, I'd like to avoid the query so I can run the script more often (there's about 60-70 files, and I want to run this every 20 seconds or so?) so how would I embedd a file list into the php file and check against that instead of database?
Thanks!
You are missing a trailing / twice.. In glob() you are giving /home/user/public_html*.* as the argument, I think you mean /home/user/public_html/*.*.
This is why I bet nothing matches the files in your table..
This won't give an error either because the syntax is fine.
Then where you unlink() you do this again.. your argument home/user/public_htmltestfile.html should be home/user/public_html/testfile.html.
I like this syntax style: "{$directory}/{$file}" because it's short and more readable. If the / is missing, you see it immediately. You can also change it to $directory . "/" . $file, it you prefer it. The same goes for one line conditional statements.. So here it comes..
<?php
$directory = "/home/user/public_html";
$files = glob("{$directory}/*.*");
foreach($files as $file)
{
$sql = mysql_query("SELECT id FROM files WHERE FileName=\"{$file}\";");
if(mysql_num_rows($sql) == 0)
{
unlink("{$directory}/{$file}");
}
}
?>
EDIT: You requested recursion. Here it goes..
You need to make a function that you can run once with a path as it's argument. Then you can run that function from inside that function on subdirectories. Like this:
<?php
/*
ListDir list files under directories recursively
Arguments:
$dir = directory to be scanned
$recursive = in how many levels of recursion do you want to search? (0 for none), default: -1 (for "unlimited")
*/
function ListDir($dir, $recursive=-1)
{
// if recursive == -1 do "unlimited" but that's no good on a live server! so let's say 999 is enough..
$recursive = ($recursive == -1 ? 999 : $recursive);
// array to hold return value
$retval = array();
// remove trailing / if it is there and then add it, to make sure there is always just 1 /
$dir = rtrim($dir,"/") . "/*";
// read the directory contents and process each node
foreach(glob($dir) as $node)
{
// skip hidden files
if(substr($node,-1) == ".") continue;
// if $node is a dir and recursive is greater than 0 (meaning not at the last level or disabled)
if(is_dir($node) && $recursive > 0)
{
// substract 1 of recursive for ever recursion.
$recursive--;
// run this same function again on itself, merging the return values with the return array
$retval = array_merge($retval, ListDir($node, $recursive));
}
// if $node is a file, we add it to the array that will be returned from this function
elseif(is_file($node))
{
$retval[] = $node;
// NOTE: if you want you can do some action here in your case you can unlink($node) if it matches your requirements..
}
}
return $retval;
}
// Output the result
echo "<pre>";
print_r(ListDir("/path/to/dir/",1));
echo "</pre>";
?>
If the list is not dynamic, store it in an array:
$myFiles = array (
'some.ext',
'next.ext',
'more.ext'
);
$directory = "/home/user/public_html/";
$files = glob($directory . "*.*");
foreach($files as $file)
{
if (!in_array($file, $myFiles)) {
unlink($directory . $file);
}
}
$value can = a folder structure to the language file. Example: languages/english.php
$value can also = the files name. Example: english.php
So I need to get the current folder that $value is in and delete the folder ONLY if there are no other files/folders within that directory (after deleting the actual file as I am doing already, ofcourse).
foreach($module['languages'] as $lang => $langFile)
{
foreach ($langFile as $type => $value)
{
#unlink($module_path . '/' . $value);
// Now I need to delete the folder ONLY if there are no other directories inside the folder where it is currently at.
// And ONLY if there are NO OTHER files within that folder also.
}
}
How can I do this?? And wondering if this can be done without using a while loop, since a while loop within a foreach loop could take some time, and need this to be as quick as possible.
And just FYI, the $module_path should never be deleted. So if $value = english.php, it should never delete the $module_path. Ofcourse, there will always be another file in there, so checking for this is not necessary, but won't hurt either way.
Thanks guys :)
EDIT
Ok, now I'm using this code here and it is NOT working, it is not removing the folders or the files, and I don't get any errors either... so not sure what the problem is here:
foreach($module['languages'] as $lang => $langFile)
{
foreach ($langFile as $type => $value)
{
if (#unlink($module_path . '/' . $value))
#rmdir(dirname($module_path . '/' . $value));
}
}
NEVERMIND, this works a CHARM!!! Cheers Everyone!!
The easyest way is try to use rmdir. This don't delete folder if it is not empty
rmdir($module_path);
also you can check is folder empty by
if(count(glob($module_path.'*'))<3)//delete
2 for . and ..
UPD: as I reviewed maybe you should replace $module_path by dirname($module_path.'.'.$value);
Since the directory you care about might be part of the $value, you need to use dirname to figure out what the parent directory is, you can't just assume that it's $module_path.
$file_path = $module_path . '/' . $value;
if (#unlink($file_path)) {
#rmdir(dirname($file_path));
}
if (is_file($value)) {
unlink($value);
} else if (is_dir($value)) {
if (count(scandir($value)) == 2) }
unlink($value)
}
}
http://php.net/manual/en/function.is-dir.php
http://www.php.net/manual/en/function.scandir.php
The code below will take a path, check if it is a file (i.e. not a directory). If it is a file, it will extract the directory name, then delete the file, then iterate over the dir and count the files in it, if the files are zero it'll delete the dir.
Code is as an example and should work, however privileges and environment setup may result in it not working.
<?php
if(!is_dir ( string $filename )){ //if it is a file
$fileDir = dirname ( $filename );
if ($handle = opendir($fileDir)) {
echo "Directory handle: $handle\n";
echo "Files:\n";
$numFiles=0;
//delete the file
unlink($myFile);
//Loop the dir and count the file in it
while (false !== ($file = readdir($handle))) {
$numFiles = $numFiles + 1;
}
if($numFiles == 0) {
//delete the dir
rmdir($fileDir);
}
closedir($handle);
}
}
?>