Having some issues regarding the scandir() function in PHP.
When trying to echo a list of files in the current directory, it echoes . and .. as directories. I've attempted to filter these out like so:
<?php
$dir = "pages";
if ($d = scandir($dir)) {
foreach ($d as $value) {
echo("<script>console.log(\"$value\")</script>");
if ($value !== '.' || $value !== '..') {
echo("<p>$value</p>");
} else {
echo("");
}
}
}
I feel like it's something obvious that I'm missing.
Has anyone got any ideas?
-R
As per documentation, scandir() returns an array of files and directories from the target directory. So you could use array_diff, which in the end would return an array containing all the entries from the first array that are not present in the second array:
array_diff(scandir($directory), ['..', '.']);
Or if you're too lazy for that, you could actually array_shift the first two elements:
$dir = "pages";
if($d = scandir($dir)) {
array_shift($d);
array_shift($d);
...
}
I like doing this:
$dir = "pages";
if($d = scandir($dir)) {
foreach($d as $file){
if(substr($file,0,1) == '.') continue;
echo "$file\n";
}
}
This way it skips all $file starting with . such as .htaccess etc.
But I have a lot of stuff like this in my projects:
.
..
.buildpath
.git
.gitignore
.htaccess
.project
.settings
I would use is_file(). It will also avoid directories.
$dir = "pages";
if ($d = scandir($dir)) {
foreach ($d as $value) {
echo("<script>console.log(\"$value\")</script>");
if (is_file($value)) {
echo("<p>$value</p>");
} else {
echo("");
}
}
}
Just continue your loop when your find . or ..
Simply add this in first line of foreach block:
if($value == '.' || $value == '..') continue;
# your rest of codes
OR
if(in_array($value, array(".",".."))) continue;
# your rest of codes
in your code:
if ($value !== '.' || $value !== '..') {
when $value equals "." then it certainly doesn't equal ".." at the same time, so one side of the "||" will be true for ".", the other for ".." and the overall result will be true.
you need either:
if ($value !== '.' && $value !== '..') {
or
if ($value == '.' || $value == '..') continue;
Related
I have php funcation that scan dir and save content list into text.It works well but now i want to add filter funcation that restrict given extentoin to prevent to save into text.
function dirscan($dir,$file){
$folder = scandir($dir);
natsort($folder);
foreach ($folder as $value)
{
{
if ($value != '.' && $value != '..')
$val=$value."\r\n";
}
$fh = fopen($file,'a');
fwrite($fh,$val);
}
}
function dirscan($dir,$file,$ext){
$folder = scandir($dir);
natsort($folder);
foreach ($folder as $value)
{
{
if ($value != '.' && $value != '..'&& pathinfo($value, PATHINFO_EXTENSION) !== $ext)
$val=$value."\r\n";
}
$fh = fopen($file,'a');
fwrite($fh,$val);
}
}
$file_temp='list.txt';
unlink($file_temp);
credit for hint :Lawrence Cherone
I am using this code in order to get a list files from directory:
$dir = '/restosnapp_cms/images/';
if ($dp = opendir($_SERVER['DOCUMENT_ROOT'] . $dir)) {
$files = array();
while (($file = readdir($dp)) !== false) {
if (!is_dir($dir . $file)) {
$files[] = $file;
}
}
closedir($dp);
} else {
exit('Directory not opened.');
}
I want to get rid of the values '.' and '..'.
Is it possible to do this? Thank you. :)
Just check for them first:
while ($file = readdir($p)) {
if ($file == '.' || $file == '..') {
continue;
}
// rest of your code
}
DirectoryIterator is much more fun than *dir functions:
$dir = new DirectoryIterator($_SERVER['DOCUMENT_ROOT'] . $dir);
foreach($dir as $file) {
if (!$file->isDir() && !$file->isDot()) {
$files[] = $file->getPathname();
}
}
But the bottomline is regardless of which way you do it, you need to use a conditional.
I am writing a simple fishing game in PHP. I have a snippet of code that's printing all of the image files in my /img directory, but it's also outputting .DS_Store. I want to exclude that file, maybe using glob(), but I don't know how. I've googled this for hours with no luck.
$files = scandir('img');
if ($files !== false) {
foreach($files as $f) {
if ($f == '..' || $f == '.') continue;
echo '<li class="fish_pic"><img src="img/'.$f.'" alt="'.$f.'" title="" class="fish"></li>'."\n";
}
}
How can I exclude .DS_Store?
Just add an if rule.
if ($f == '..' || $f == '.' || $f == '.DS_Store') continue;
Alternatively, you could use an array and in_array() method.
$filesToSkip = array('.', '..', '.DS_Store', 'other_file_to_skip');
$files = scandir('img');
if ($files !== false) {
foreach($files as $f) {
if (in_array($f, $filesToSkip)) continue;
echo '<li class="fish_pic"><img src="img/'.$f.'" alt="'.$f.'" title="" class="fish"> </li>'."\n";
}
}
$files = scandir('img');
if ($files !== false) {
foreach($files as $f) {
if ($f == '..' || $f == '.' || substr($f, -strlen(".DS_Store")) === ".DS_Store") continue;
echo '<li class="fish_pic"><img src="img/'.$f.'" alt="'.$f.'" title="" class="fish"></li>'."\n";
}
}
hi I'm writing a script to loop through the current directory and list all sub directories
all is working fine but i can't get it to exclude folders starting with an _
<?php
$dir = __dir__;
// Open a known directory, and proceed to read its contents
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
echo("<ul>");
while (($file = readdir($dh)) !== false) {
if ($file == '.' || $file == '..' || $file == '^[_]*$' ) continue;
if (is_dir($file)) {
echo "<li> <a href='$file'>$file</a></li>";
}
}
closedir($dh);
}
}
?>
you can use substr[docs] like :
|| substr($file, 0, 1) === '_'
No need for a regex, use $file[0] == '_' or substr($file, 0, 1) == '_'
If you do want a regex, you need to use preg_match() to check: preg_match('/^_/', $file)
Or, if you would like to use regexp, you should use regex functions, like preg_match: preg_match('/^_/', $file); but as said by ThiefMaster, in this case a $file[0] == '_' suffices.
A more elegant solution is to use SPL. The GlobIterator can help you out. Each item is an instance of SplFileInfo.
<?php
$dir = __DIR__ . '/[^_]*';
$iterator = new GlobIterator($dir, FilesystemIterator::SKIP_DOTS);
if (0 < $iterator->count()) {
echo "<ul>\n";
foreach ($iterator as $item) {
if ($item->isDir()) {
echo sprintf("<li>%s</li>\n", $item);
}
}
echo "</ul>\n";
}
i wonder how i can transform exactly the following piece of code to scandir instead of readdir?
$path = 'files';
//shuffle files
$count = 0;
if ($handle = opendir($path)) {
$retval = array();
while (false !== ($file = readdir($handle))) {
$ext = pathinfo($file, PATHINFO_EXTENSION);
if ($file != '.' && $file != '..' && $file != '.DS_Store' &&
$file != 'Thumbs.db') {
$retval[$count] = $file;
$count = $count + 1;
} else {
//no proper file
}
}
closedir($handle);
}
shuffle($retval);
scandir returns, quoting :
Returns an array of filenames on
success, or FALSE on failure.
Which means you'll get the full list of files in a directory -- and can then filter those, using either a custom-made loop with foreach, or some filtering function like array_filter.
Not tested, but I suppose something like this should to the trick :
$path = 'files';
if (($retval = scandir($path)) !== false) {
$retval = array_filter($retval, 'filter_files');
shuffle($retval);
}
function filter_files($file) {
return ($file != '.' && $file != '..' && $file != '.DS_Store' && $file != 'Thumbs.db');
}
Basically, here :
First, you get the list of files, using scandir
Then, you filter out the ones you dn't want, using array_filter and a custom filtering function
Note : this custom filtering function could have been written using an anonymous function, with PHP >= 5.3
And, finally, you shuffle the resulting array.
Not sure why you want to do that, here's a much more concise solution though:
$path = 'files';
$files = array();
foreach (new DirectoryIterator($path) as $fileInfo) {
if($fileInfo->isDot() || $fileInfo->getFilename() == 'Thumbs.db') continue;
$files[] = $fileInfo->getFilename();
}
shuffle($files);
To get started with such problems always consult the PHP manual and read the comments, it's always very helpful. It states that scandir returns an array, so you can walk through it with foreach.
In order to be able to delete some entries of the array, here's an example with for:
$exclude = array( ".", "..", ".DS_Store", "Thumbs.db" );
if( ($dir = scandir($path)) !== false ) {
for( $i=0; $i<count($dir); $i++ ) {
if( in_array($dir[$i], $exclude) )
unset( $dir[$i] );
}
}
$retval = array_values( $dir );
Also have a look at the SPL iterators PHP provides, especially RecursiveDirectoryIterator and DirectoryIterator.
Here's a little function to scan a directory without getting the annoying files.
function cleanscandir ($dir) {
$list = [];
$junk = array('.', '..', 'Thumbs.db', '.DS_Store');
if (($rawList = scandir($dir)) !== false) {
foreach (array_diff($rawList, $junk) as $value) {
$list[] = $value;
}
return $list;
}
return false;
}
Outputs an array or false just like scandir does