php scandir() - Invalid argument supplied for foreach() [file] - php

I have a server running PHP Version 5.4.16 and am trying to use scandir to list files within a directory. I am having a hard time figuring out what the issue is. I've tried both ../store/dir_to_scan and /root/store/dir_to_scan. I've also tried using both glob and scandir as you can see below both to no avail. If I remove the dir_to_scan directory it will list the directories inside of /root/store which is what I find most puzzling of all. I've also chmod'd the folders and files to 777 just to make sure it wasn't a permissions issue. I receive an error of "Array ( [type] => 2 [message] => Invalid argument supplied for foreach() [file] => /root/html/test.php [line] => 5 )" also upon running with correct directory setup.
Thanks for any help.
Directory Setup
/root/html //where php script is run
/root/store/dir_to_scan //files I need to list
PHP Script
<?
#$files = glob('../store/dir_to_scan/*', GLOB_BRACE);
$files = scandir("/root/store/dir_to_scan/");
foreach($files as $file) {
//do work here
if ($file === '.' || $file === '..') {
continue;
}
echo $file . "<br>";
}
print_r(error_get_last());
?>

this might be silly but try supplying a trailing slash at the end of:
/root/store/dir_to_scan ->
$files = scandir("/root/store/dir_to_scan/");

this should to solve your problem
$carpeta= "/root/store/dir_to_scan";
if(is_dir($carpeta)){
if($dir = opendir($carpeta)){
while(($file = readdir($dir)) !== false){
if($file != '.' && $file != '..' && $file != '.htaccess'){
echo $file; //or save file name in an array..
// $array_file[] = $file;
}
}
closedir($dir);
}
}

Related

delete_dir() from Codeigniter doesn't work

I get this error message when I try to delete a directory:
"Unable to delete the file" using PHP Codeigniter's delete_dir('/path/to/my/dir/'). No additional info provided.
There is no problem with the ftp conn (works with everything else), no problem with the file permission (delete_file() works jsut fine)..no problem with the code, the path is also valid. I'm all out of ideas and open for suggestions.
You can use unlink() to remove php directory.
function removedir($dir1) {
if (is_dir($dir1)) {
//scan
$files = scandir($dir1);
//loop through all the files
foreach ($files as $file) {
if ($file != "." && $file != "..") {
if (filetype($dir1."/".$file) == "dir1")
rrmdir($dir1."/".$file);
else
unlink($dir1."/".$file);
}
}
reset($files);
rmdir($dir);
}
}

readdir() in php not seeming to work

I'm working on the following piece of code:
<?php
$dir=opendir("docs/recipes");
$files=array();
while (($file=readdir($dir)) !== false)
{
if ($file != "." and $file != ".." and $file != "index.php")
{
array_push($files, $file);
}
}
closedir($dir);
sort($files,SORT_STRING | SORT_FLAG_CASE);
print "<div class=\"blocktext\">";
foreach ($files as $file)
print "$file<br>";
print "</div>";
?>
I had this working on my raspberry pi web server, but I moved my server to arch linux, and it doesn't seem to be working. When I load the page, it spins but then the list of files is empty.
I have checked that httpd is running with systemd and because my webpages load. I know php is working because my phpinfo test page works.
In the folder containing this file, I have a symbolic link called docs, and I know the path is correct. I have all the files in the destination readable. This file is executable.
Is there something else I am missing?
Not necessarily a solution, but some help with good practices and a way to find what is happening on your script
<?php
// initialize variables first
$dir = false;
$files = array();
// assign the handler
$dir = opendir( "docs/recipes" );
// work only if necessary
if ( $dir !== false ) {
while ( ( $file = readdir( $dir ) ) !== false ) {
if ($file != "." and $file != ".." and $file != "index.php") {
array_push($files, $file);
}
}
closedir( $dir );
sort( $files,SORT_STRING | SORT_FLAG_CASE );
print "<div class=\"blocktext\">";
foreach ( $files as $file ) {
print "$file<br>";
}
print "</div>";
} else {
// get informed that something is wrong, print anything that helps you
echo( 'problems opening' );
exit( __FILE__.' '.__LINE__ );
}
?>
from php.net/readdir comes a warning: This function may return Boolean FALSE, but may also return a non-Boolean value which evaluates to FALSE.
you have not specified which version of PHP you are using, nor if it's installed/compiled locally. it would help. my guess is that you don't have all errors turned on, and readdir is catching one of those corner cases.
try this:
$cycle = true;
while ( $cycle !== false ) {
$file = readdir( $dir );
print ( "GOT a FILe or a FALSE:". $file ."br>" );
// do your stuff here
$cycle = $file;
}
then in php.ini set the errors to E_ALL. if using PHP >= 5.4 (i guess you are, since you're on arch :) you can fire up the built-in server, so all errors/logs/messages go straight to STDERR. just do a command from the folder where your index.php is located:
$ php -S <local ip>:<some port>
open as usual in the browser (or a curl, or whatever). output goes to browser, errors go straight to console, no middle-man to cover up any message.
this should enable you to catch the real problem. and/or, you can wrap it all up in a try-catch and see if something pops up.

Unexplained GET errors

I have code that reads the images directory for a user (user 38 below) and returns an array of the file names, skipping the . and .. references.
// $dir = 38/images
$dirHandle = opendir($dir)$dirHandle = opendir($dir)
while (false !== ($fileName = readdir($dirHandle))) {
if ($fileName == "." || $fileName == "..")
continue;
-- Put file on array which gets returned to ajax load call at end --
}
This works fine but it seems to generate the access errors shown below:
Am I doing something fundamentally wrong?
Thanks
Unless you have an index.php file in your 38 and 38/images folders, you are issuing a get over a folder, over which you don't have permissions enough.
Check your script path, and your JS code in order to fix it.
I got to the bottom of this. It happens when a directory of images is being prefetched to the page:
while($fileName = readdir($dirHandle)) {
$filepath = $dir . $fileName;
echo ("<img class='galleryThumb' src='$filepath' >");
}
The trouble occurs when $fileName is "." or "..". The <img class='galleryThumb' src='$filepath' > echoed down with Ajax then has trouble evaluating a src attribute that's a directory rather than a file. I fixed it by adding a check for "." and ".." :
while($fileName = readdir($dirHandle)) {
if ($fileName == "." || $fileName == "..") {
continue;
}
$filepath = $dir . $fileName;
echo ("<img class='galleryThumb' src='$filepath' >");
}
Since you see 403 errors from network panel of javascript debugger, it is javascript, who is accesing these paths. The php code you posted has almost nothing to do with that.

Why does opendir not show folders with a single integer as the name

I have a script that opens a directory, checks if the folders matches an array, and then opens them.
In the directory there is a list of folders like "apache2-50", but when the script opens that folder, it only displays the .DS_Store file. Here is the output:
This-is-not-a-MacBook:backend code archangel$ php -f frolic.php "/Users/archangel/Desktop/Httpbench Files/results"
Test Found apache2 in directory /Users/archangel/Desktop/Httpbench Files/results/apache2-50
--/Users/archangel/Desktop/Httpbench Files/results/apache2-50/.DS_Store
But here is the directory listing:
This-is-not-a-MacBook:apache2-50 archangel$ ls
0 1 2
Now what I am trying to figure out why my php script is not showing those folders. When I change the folder "0" to "3" it works:
This-is-not-a-MacBook:apache2-50 archangel$ ls
1 2 3
This-is-not-a-MacBook:backend code archangel$ php -f frolic.php "/Users/archangel/Desktop/Httpbench Files/results"
Test Found apache2 in directory /Users/archangel/Desktop/Httpbench Files/results/apache2-50
--/Users/archangel/Desktop/Httpbench Files/results/apache2-50/.DS_Store
--/Users/archangel/Desktop/Httpbench Files/results/apache2-50/1
--/Users/archangel/Desktop/Httpbench Files/results/apache2-50/2
--/Users/archangel/Desktop/Httpbench Files/results/apache2-50/3
Here is the code that I am running:
#!/bin/php
//...
$dir = opendir($argv[1]);
//Opened the directory;
while($file = readdir($dir)){
//Loops through all the files/directories in our directory;
if($file!="." && $file != ".."){
$f = explode("-", $file);
if(in_array($f[0], $servers) and in_array($f[1], $tests)) {
echo "Test Found $f[0] in directory $argv[1]/$f[0]-$f[1]\n";
$sdir = opendir("$argv[1]/$f[0]-$f[1]");
while($sfile = readdir($sdir)){
if($sfile!="." && $sfile != ".."){
echo "--$argv[1]/$f[0]-$f[1]/$sfile\n";
}
}
}
}
}
Could this be something wong with my script, or a bug in php(PHP 5.3.3)?
Thanks
This is a (very nasty) side effect of the string "0" evaluating to false in PHP. When that happens, your while loop
while($file = readdir($dir))
will break.
This should work, because it breaks only when readdir() actually returns false:
while(($file = readdir($dir)) !== false)
(obviously, change both loops accordingly, not just the outer one.)
Why are you using opendir at all? I think glob would be a little easier to use:
$files = glob("$argv[1]/*-*/*");
foreach($files as $file) {
$parts = explode("/", $file);
// get the directory part
$f = explode("-", $parts[count($parts) - 2]);
if(in_array($f[0], $servers) and in_array($f[1], $tests)) {
echo "Test Found $f[0] in directory $argv[1]/$f[0]-$f[1]\n";
echo "--$argv[1]/$f[0]-$f[1]/$sfile\n";
}
}
Replace
while($sfile = readdir($sdir)){
with
while(($sfile = readdir($sdir)) !== 0){
Otherwise when filename is 0, $sfile is "0" which is translated to false. By using !== or === you are forcing a type check between the variables so that "0" does not equal 0.

PHP: Using scandir(), folders are treated as files

Using PHP 5.3.3 (stable) on Linux CentOS 5.5.
Here's my folder structure:
www/myFolder/
www/myFolder/testFolder/
www/myFolder/testFile.txt
Using scandir() against the "myFolder" folder I get the following results:
.
..
testFolder
testFile.txt
I'm trying to filter out the folders from the results and only return files:
$scan = scandir('myFolder');
foreach($scan as $file)
{
if (!is_dir($file))
{
echo $file.'\n';
}
}
The expected results are:
testFile.txt
However I'm actually seeing:
testFile.txt
testFolder
Can anyone tell me what's going wrong here please?
You need to change directory or append it to your test. is_dir returns false when the file doesn't exist.
$scan = scandir('myFolder');
foreach($scan as $file)
{
if (!is_dir("myFolder/$file"))
{
echo $file.'\n';
}
}
That should do the right thing
Doesn't is_dir() take a file as a parameter?
$scan = scandir('myFolder');
foreach($scan as $file)
{
if (!is_dir($file))
{
echo $file.'\n';
}
}
Already told you the answer here: http://bugs.php.net/bug.php?id=52471
If you were displaying errors, you'd see why this isn't working:
Warning: Wrong parameter count for is_dir() in testFile.php on line 16
Now try passing $file to is_dir()
$scan = scandir('myFolder');
foreach($scan as $file)
{
if (!is_dir($file))
{
echo $file.'\n';
}
}
If anyone who comes here is interested in saving the output to an array, here's a fast way of doing that (modified to be more efficient):
$dirPath = 'dashboard';
$dir = scandir($dirPath);
foreach($dir as $index => &$item)
{
if(is_dir($dirPath. '/' . $item))
{
unset($dir[$index]);
}
}
$dir = array_values($dir);

Categories