PHP Concatenation, String Length = 0 - php

I have the following code in my PHP file - initializes $uploaded_files variable and then calls getDirectory (also listed below).
Now if I do a vardump($uploaded_files) I see the contents of my variable, but for some reason when I call <?php echo $uploaded_files; ?> in my HTML file I get a message stating "No Files Found" - am I doing something incorrect?
Can someone assist? Thank you.
/** LIST UPLOADED FILES **/
$uploaded_files = "";
getDirectory( Settings::$uploadFolder );
// Check if the uploaded_files variable is empty
if(strlen($uploaded_files) == 0)
{
$uploaded_files = "<li><em>No files found</em></li>";
}
getDirectory Function:
function getDirectory( $path = '.', $level = 0 )
{
// Directories to ignore when listing output. Many hosts
// will deny PHP access to the cgi-bin.
$ignore = array( 'cgi-bin', '.', '..' );
// Open the directory to the handle $dh
$dh = #opendir( $path );
// Loop through the directory
while( false !== ( $file = readdir( $dh ) ) ){
// Check that this file is not to be ignored
if( !in_array( $file, $ignore ) ){
// Its a directory, so we need to keep reading down...
if( is_dir( "$path/$file" ) ){
// We are now inside a directory
// Re-call this same function but on a new directory.
// this is what makes function recursive.
getDirectory( "$path/$file", ($level+1) );
}
else {
// Just print out the filename
// echo "$file<br />";
$singleSlashPath = str_replace("uploads//", "uploads/", $path);
if ($path == "uploads/") {
$filename = "$path$file";
}
else $filename = "$singleSlashPath/$file";
$parts = explode("_", $file);
$size = formatBytes(filesize($filename));
$added = date("m/d/Y", $parts[0]);
$origName = $parts[1];
$filetype = getFileType(substr($file, strlen($file) - 4));
$uploaded_files .= "<li class=\"$filetype\">$origName $size - $added</li>\n";
// var_dump($uploaded_files);
}
}
}
// Close the directory handle
closedir( $dh );
}

You either need to add:
global $uploaded_files;
At the top of your getDirectory function, or
function getDirectory( &$uploaded_files, $path = '.', $level = 0 )
Pass it by reference.
You could also make $uploaded_files the return value of getDirectory.
More reading about globals and security: http://php.net/manual/en/security.globals.php

PHP knows nothing about scope.
When you declare a variable from within the body of a function it will not be available outside the scope of said function.
For example:
function add(){
$var = 'test';
}
var_dump($var); // undefined variable $var
This is exactly the problem you are having when trying to access the variable $uploaded_files.

Related

PHP: recursively remove brackets from filenames in directory and all sub directories

I'm having an issue getting rid of brackets in uploaded files in a system.
I'm able to remove the brackets in the files of a single directory but I'm struggling to get this working recursively in the sub directories of the same folder.
I'm using str_replace to find the brackets [ ] and replacing them with a blank character.
$dir = $_SERVER["DOCUMENT_ROOT"]."/uploads" ; // what directory to parse
if ( $handle = opendir ( $dir)) {
print "Directory Handle = $handles\n" ;
print "Files : \n" ;
while ( false !== ($file = readdir($handle))) {
if ( $file != "." && $file != ".." ) {
$isdir = is_dir ( $file ) ;
if ( $isdir == "1" ) {} // if its a directory do nothing
else {
$file_array[] = "$file" ; // get all the file names and put them in an array
print "$file\n" ;
} // closes else
} // closes directory check
} // closes while
} // closes opendir
//Lets go through the array
$arr_count = count( $file_array ) ; // find out how many files we have found so we can initiliase the counter
for ( $counter=1; $counter<$arr_count; $counter++ ) {
print "Array = $file_array[$counter]\n" ; // tell me how many files there are
$illegals = array("[","]");
$new = str_replace ( $illegals, "", $file_array[$counter] ) ; // now create the new file name
$ren = rename ( "$dir/$file_array[$counter]" , "$dir/$new" ) ; // now do the actual file rename
print "$new\n" ; // print out the new file name
}
closedir ( $handle ) ;
echo $dir;
Ok so I took the code from the recursive renaming script and created my own sanitize script. Please let me know if I screwed anything up. Thanks for pointing me in the right direction NIC3500
$path = $_SERVER["DOCUMENT_ROOT"]."/uploads" ;
$illegals = array("[","]");
$di = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS),
RecursiveIteratorIterator::LEAVES_ONLY
);
foreach($di as $name => $fio) {
//$newname = $fio->getPath() . DIRECTORY_SEPARATOR . strtolower( $fio->getFilename() );
$newname = $fio->getPath() . DIRECTORY_SEPARATOR . str_replace ( $illegals, "", $fio->getFilename() );
//echo $newname, "\r\n";
rename($name, $newname);
}

Find all .php files in folder recursively

Using PHP, how can I find all .php files in a folder or its subfolders (of any depth)?
You can use RecursiveDirectoryIterator and RecursiveIteratorIterator:
$di = new RecursiveDirectoryIterator(__DIR__,RecursiveDirectoryIterator::SKIP_DOTS);
$it = new RecursiveIteratorIterator($di);
foreach($it as $file) {
if (pathinfo($file, PATHINFO_EXTENSION) == "php") {
echo $file, PHP_EOL;
}
}
just add something like:
function listFolderFiles($dir){
$ffs = scandir($dir);
$i = 0;
$list = array();
foreach ( $ffs as $ff ){
if ( $ff != '.' && $ff != '..' ){
if ( strlen($ff)>=5 ) {
if ( substr($ff, -4) == '.php' ) {
$list[] = $ff;
//echo dirname($ff) . $ff . "<br/>";
echo $dir.'/'.$ff.'<br/>';
}
}
if( is_dir($dir.'/'.$ff) )
listFolderFiles($dir.'/'.$ff);
}
}
return $list;
}
$files = array();
$files = listFolderFiles(dirname(__FILE__));
I modified the code a bit created by supajason
Because the code provided did not return a consistent result:
Mainly due to the nomenclature used.
I also added some functionality.
<?php
define('ROOT', str_replace('\\', '/', getcwd()).'/');
///########-------------------------------------------------------------
///########-------------------------------------------------------------
///######## FUNCTION TO LIST ALL FILES AND FOLDERS WITHIN A CERTAIN PATH
///########-------------------------------------------------------------
///########-------------------------------------------------------------
function list_folderfiles(
$dir, // *** TARGET DIRECTORY TO SCAN
$return_flat = true, // *** DEFAULT FLAT ARRAY TO BE RETURNED
$iteration = 0 // *** INTERNAL PARAM TO COUNT THE FUNCTIONS OWN ITERATIONS
){
///######## PREPARE ALL VARIABLES
$dir = rtrim($dir, '/'); // *** REMOVE TRAILING SLASH (* just for being pretty *)
$files_folders = scandir($dir); // *** SCAN FOR ALL FILES AND FOLDERS
$nested_folders = []; // *** THE NESTED FOLDERS BUILD ARRAY
static $total_files = []; // *** THE TOTAL FILES ARRAY
///######## MAKE SURE THAT THE STATIC $fileS ARE WILL BE CLEARED AFTER THE FIRST ITERATION, RESET AS EMPTY ARRAY
if($iteration === 0) $total_$files = [];
///######## RUN THROUGH ALL $fileS AND FOLDERS
foreach($files_folders as $file){
///######### IF THE CURRENT ``file`` IS A DIRECTORY UP
if($file === '.' || $file === '..') continue;
///######### IF IT CONCERNS A $file
if(is_dir($dir.'/'.$file)){
$iteration++; // *** RAISE THE ITERATION
$nested_folders[] = list_folderfiles($dir.'/'.$file, false, $iteration); // *** EXECUTE THE FUNCTION ITSELF
}
///######### IF IT CONCERNS A $file
else{
$total_files[] = $dir.'/'.$file; // *** ADD THE $file TO THE TOTAL $fileS ARRAY
$nested_folders[] = $file; // *** ADD THE $file TO THE NESTED FOLDERS ARRAY
}
}
///########==================================================
///######## IF A FLAT LIST SHOULD BE RETURNED
///########==================================================
if($return_flat) return $total_files;
///######## IF A NESTED LIST SHOULD BE RETURNED
else return $nested_folders;
///########==================================================
}
$files = list_folderfiles(ROOT, true); // *** FLAT ARRAY
///$files = list_folderfiles(ROOT, false); // *** NESTED ARRAY
echo print_r($files, true);
This is similar to another answer here, but removes SKIP_DOTS as it's not needed, and and works with strict_types:
<?php
$o_dir = new RecursiveDirectoryIterator('.');
$o_iter = new RecursiveIteratorIterator($o_dir);
foreach ($o_iter as $o_info) {
if ($o_info->getExtension() == 'php') {
echo $o_info->getPathname(), "\n";
}
}
https://php.net/splfileinfo.getextension

Recursion through a directory tree in PHP

I have a set of folders that has a depth of at least 4 or 5 levels. I'm looking to recurse through the directory tree as deep as it goes, and iterate over every file. I've gotten the code to go down into the first sets of subdirectories, but no deeper, and I'm not sure why. Any ideas?
$count = 0;
$dir = "/Applications/MAMP/htdocs/site.com";
function recurseDirs($main, $count){
$dir = "/Applications/MAMP/htdocs/site.com";
$dirHandle = opendir($main);
echo "here";
while($file = readdir($dirHandle)){
if(is_dir($file) && $file != '.' && $file != '..'){
echo "isdir";
recurseDirs($file);
}
else{
$count++;
echo "$count: filename: $file in $dir/$main \n<br />";
}
}
}
recurseDirs($dir, $count);
Check out the new RecursiveDirectoryIterator.
It's still far from perfect as you can't order the search results and other things, but to simply get a list of files, it's fine.
There are simple examples to get you started in the manual like this one:
<?php
$path = realpath('/etc');
$objects = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($path),
RecursiveIteratorIterator::SELF_FIRST);
foreach($objects as $name => $object){
echo "$name\n";
}
?>
There is an error in the call
recurseDirs($file);
and in
is_dir($file)
you have to give the full path:
recurseDirs($main . '/' .$file, $count);
and
is_dir($main . '/' .$file)
However, like other anwerers, I suggest to use RecursiveDirectoryIteretor.
The call to is_dir and recurseDirs is not fully correct. Also your counting didn't work correctly. This works for me:
$dir = "/usr/";
function recurseDirs($main, $count=0){
$dirHandle = opendir($main);
while($file = readdir($dirHandle)){
if(is_dir($main.$file."/") && $file != '.' && $file != '..'){
echo "Directory {$file}: <br />";
$count = recurseDirs($main.$file."/",$count); // Correct call and fixed counting
}
else{
$count++;
echo "$count: filename: $file in $main \n<br />";
}
}
return $count;
}
$number_of_files = recurseDirs($dir);
Notice the changed calls to the function above and the new return value of the function.
So yeah: Today I was being lazy and Googled for a cookie cutter solution to a recursive directory listing and came across this. As I ended up writing my own function (as to why I even spent the time to Google for this is beyond me - I always seem to feel the need to re-invent the wheel for no suitable reason) I felt inclined to share my take on this.
While there are opinions for and against the use of RecursiveDirectoryIterator, I'll simply post my take on a simple recursive directory function and avoid the politics of chiming in on RecursiveDirectoryIterator.
Here it is:
function recursiveDirectoryList( $root )
{
/*
* this next conditional isn't required for the code to function, but I
* did not want double directory separators in the resulting array values
* if a trailing directory separator was provided in the root path;
* this seemed an efficient manner to remedy said problem easily...
*/
if( substr( $root, -1 ) === DIRECTORY_SEPARATOR )
{
$root = substr( $root, 0, strlen( $root ) - 1 );
}
if( ! is_dir( $root ) ) return array();
$files = array();
$dir_handle = opendir( $root );
while( ( $entry = readdir( $dir_handle ) ) !== false )
{
if( $entry === '.' || $entry === '..' ) continue;
if( is_dir( $root . DIRECTORY_SEPARATOR . $entry ) )
{
$sub_files = recursiveDirectoryList(
$root .
DIRECTORY_SEPARATOR .
$entry .
DIRECTORY_SEPARATOR
);
$files = array_merge( $files, $sub_files );
}
else
{
$files[] = $root . DIRECTORY_SEPARATOR . $entry;
}
}
return (array) $files;
}
With this function, the answer as to obtaining a file count is simple:
$dirpath = '/your/directory/path/goes/here/';
$files = recursiveDirectoryList( $dirpath );
$number_of_files = sizeof( $files );
But, if you don't want the overhead of an array of the respective file paths - or simply don't need it - there is no need to pass a count to the recursive function as was recommended.
One could simple amend my original function to perform the counting as such:
function recursiveDirectoryListC( $root )
{
$count = 0;
if( ! is_dir( $root ) ) return (int) $count;
$dir_handle = opendir( $root );
while( ( $entry = readdir( $dir_handle ) ) !== false )
{
if( $entry === '.' || $entry === '..' ) continue;
if( is_dir( $root . DIRECTORY_SEPARATOR . $entry ) )
{
$count += recursiveDirectoryListC(
$root .
DIRECTORY_SEPARATOR .
$entry .
DIRECTORY_SEPARATOR
);
}
else
{
$count++;
}
}
return (int) $count;
}
In both of these functions the opendir() function should really be wrapped in a conditional in the event that the directory is not readable or another error occurs. Make sure to do so correctly:
if( ( $dir_handle = opendir( $dir ) ) !== false )
{
/* perform directory read logic */
}
else
{
/* do something on failure */
}
Hope this helps someone...

PHP recursive directory path

i have this function to return the full directory tree:
function getDirectory( $path = '.', $level = 0 ){
$ignore = array( 'cgi-bin', '.', '..' );
// Directories to ignore when listing output. Many hosts
// will deny PHP access to the cgi-bin.
$dh = #opendir( $path );
// Open the directory to the handle $dh
while( false !== ( $file = readdir( $dh ) ) ){
// Loop through the directory
if( !in_array( $file, $ignore ) ){
// Check that this file is not to be ignored
$spaces = str_repeat( ' ', ( $level * 4 ) );
// Just to add spacing to the list, to better
// show the directory tree.
if( is_dir( "$path/$file" ) ){
// Its a directory, so we need to keep reading down...
echo "<strong>$spaces $file</strong><br />";
getDirectory( "$path/$file", ($level+1) );
// Re-call this same function but on a new directory.
// this is what makes function recursive.
} else {
echo "$spaces $file<br />";
// Just print out the filename
}
}
}
closedir( $dh );
// Close the directory handle
}
but what i want to do is to search for a file/folder and return it's path, how can i do that? do you have such a function or can you give me some tips on how to do this?
Try to use RecursiveIteratorIterator in combination with RecursiveDirectoryIterator
$path = realpath('/path/you/want/to/search/in');
$objects = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($path),
RecursiveIteratorIterator::SELF_FIRST);
foreach($objects as $name => $object){
if($object->getFilename() === 'work.txt') {
echo $object->getPathname();
}
}
Additional reading:
http://www.phpro.org/tutorials/Introduction-to-SPL.html
do you have such a function or can you give me some tips on how to do
this?
Yes I do.
I actually asked a similar question earlier this morning, but I figure it out. The problem I was having is that the file names . and .. are returned by readdir() and they cause problems when attempting to opendir() with them. When I filtered these out, my recursion worked perfectly. You might want to modify the format in which it outputs the directories that fit the search. Or modify it to output all files and directories. Find an image for "go.jpg" and try it out.
I can't find my post to notify that I found the solution.
define ('HOME', $_SERVER['DOCUMENT_ROOT']);
function searchalldirectories($directory, $seachterm, $maxrecursions, $maxopendir){
$dircontent= '';
$dirs= array();
if ($maxopendir > 0){
$maxopendir--;
$handle= opendir( HOME.'/'.$directory);
while (( $dirlisting= readdir($handle)) !== false){
$dn= ''; $fn= ' File';
if ( is_dir( HOME.'/'.$directory.'/'.$dirlisting) && $maxrecursions>0 && strpos( $dirlisting, '.')!==0){
$dirs[ count($dirs)]= $directory.'/'.$dirlisting;
$dn= '/'; $fn= 'Dir';
}
if ( stripos($dirlisting, $seachterm) !== false){
$dircontent.= '<input type="image" src="go.jpg" name="cmd" value="home:/'.$directory.'/'.$dirlisting.'"> '.$fn.':// <b>'.$directory.'/'.$dirlisting.$dn.'/</b><br>';
}
}
closedir( $handle);
for ( $i=0; $i<count( $dirs); $i++){
$dircontent.= searchalldirectories( $dirs[$i], $seachterm, ($maxrecursions-1), $maxopendir);
}
}
return $dircontent;
}

dynamic formation of array with incremental depth in PHP

I want to use a function to recursively scan a folder, and assign the contents of each scan to an array.
It's simple enough to recurse through each successive index in the array using either next() or foreach - but how to dynamically add a layer of depth to the array (without hard coding it into the function) is giving me problems. Here's some pseudo:
function myScanner($start){
static $files = array();
$files = scandir($start);
//do some filtering here to omit unwanted types
$next = next($files);
//recurse scan
//PROBLEM: how to increment position in array to store results
//$next_position = $files[][][].... ad infinitum
//myScanner($start.DIRECTORY_SEPARATOR.$next);
}
any ideas?
Try something like this:
// $array is a pointer to your array
// $start is a directory to start the scan
function myScanner($start, &$array){
// opening $start directory handle
$handle = opendir($start);
// now we try to read the directory contents
while (false !== ($file = readdir($handle))) {
// filtering . and .. "folders"
if ($file != "." && $file != "..") {
// a variable to test if this file is a directory
$dirtest = $start . DIRECTORY_SEPARATOR . $file;
// check it
if (is_dir($dirtest)) {
// if it is the directory then run the function again
// DIRECTORY_SEPARATOR here to not mix files and directories with the same name
myScanner($dirtest, $array[$file . DIRECTORY_SEPARATOR]);
} else {
// else we just add this file to an array
$array[$file] = '';
}
}
}
// closing directory handle
closedir($handle);
}
// test it
$mytree = array();
myScanner('/var/www', $mytree);
print "<pre>";
print_r($mytree);
print "</pre>";
Try to use this function (and edit it for your demands):
function getDirTree($dir,$p=true) {
$d = dir($dir);$x=array();
while (false !== ($r = $d->read())) {
if($r!="."&&$r!=".."&&(($p==false&&is_dir($dir.$r))||$p==true)) {
$x[$r] = (is_dir($dir.$r)?array():(is_file($dir.$r)?true:false));
}
}
foreach ($x as $key => $value) {
if (is_dir($dir.$key."/")) {
$x[$key] = getDirTree($dir.$key."/",$p);
}
}
ksort($x);
return $x;
}
It returns sorted array of directories.

Categories