...

View Full Version : Resolved exclude files using arrays



sonny
10-24-2012, 06:35 AM
Hi I am trying to exclude more then one file and more then one extension
can someone show the proper way to implement arrays for $excludeExt
and $excludeFile vars below.



CreateRefFile($path,$level+1,$last+1,$files, $main_dir); // uses recursion
global $excludeFile, $excludeExt;
} else {
if ((strcmp($file, $excludeFile) == 0) || (substr($file, -4) === $excludeExt))
continue;


Thanks
Sonny

Fou-Lu
10-24-2012, 07:24 AM
global is not a good idea.
What is that else block in there for; it has no corresponding if? Arrays are easy to work with:


if (!in_array($fileExtension, array('txt', 'php', 'pl', '...'))
{
// good to go.
}

sonny
10-24-2012, 07:44 AM
global is not a good idea.
What is that else block in there for; it has no corresponding if? Arrays are easy to work with:


if (!in_array($fileExtension, array('txt', 'php', 'pl', '...'))
{
// good to go.
}


Hi
I really do not understand the full function, other then what I did
to exclude a single extension and a single file, problem is I need to
do more then one of each, here is the full function.



function CreateRefFile($dir,$level,$last,&$files, $main_dir) {
$dp = opendir($dir);

if ($dp !== FALSE) {
while (false!=($file=readdir($dp)) && $level == $last) {
if ($file!="." && $file!="..") {
$path = (substr($dir, -1) == '/') ? $dir.$file : $dir . "/" . $file;

if (is_dir($path)) {
if (ExcludeDirectory($path, $main_dir)) {
continue;
}

CreateRefFile($path,$level+1,$last+1,$files, $main_dir); // uses recursion
global $excludeExt, excludeFile;
} else {
if ((strcmp($file, $excludeFile) == 0) ||
(substr($file, -4) === $excludeExt)) // exclude this extension
continue;

$r = @stat($path);
$files[] = sprintf("%s,%d,%d,%d", $path, $r[7], $r[9],substr(sprintf('%o', @fileperms($path)), -3)); // reads the file into an array
}
}
}
closedir($dp);
}
}


Thanks
Sonny

Fou-Lu
10-24-2012, 04:31 PM
in_array is the key here. If you give it a collection, you need to search the collection to see if its in there.

I'd probably use a DirectoryIterator in combination with FilterIterators for this. Its a lot easier to compare items on an item by item basis than worry about any type of recursion required.


class FilterExtensionDisallow extends RecursiveFilterIterator
{
public function accept()
{
$bResult = true;
$aDisallow = array('php');
$cur = parent::current();
if (($cur instanceof SplFileInfo) && $cur->isFile())
{
if (in_array($cur->getExtension(), $aDisallow))
{
$bResult = false;
}
}
return $bResult;
}
}

class FilterStartingWithPeriod extends RecursiveFilterIterator
{
public function accept()
{
$bResult = true;
$cur = parent::current();
if ($cur instanceof SplFileInfo)
{
if (strpos($cur->getFilename(), '.') === 0)
{
$bResult = false;
}
}

return $bResult;
}
}

$directory = new RecursiveDirectoryIterator(__DIR__ . '/path');
$directory = new FilterStartingWithPeriod($directory);
$directory = new FilterExtensionDisallow($directory);
$directory = new RecursiveIteratorIterator($directory);

foreach ($directory AS $item)
{
printf("%s, %d, %d, %s" . PHP_EOL, realpath($item->getPathname()), $item->getSize(), $item->getMTime(), substr(sprintf('%o', $item->getPerms()), -4));
}


Filters are nice since you can stack'em.

sonny
10-24-2012, 11:00 PM
Hi I am just trying to use those two vars below with an array instead of a single variable
I am having trouble implementing that into the code below correctly.




$exclude_file = array('file1.php1','file2.php','test/file3.php'); //don't check these files
$exclude_ext = array('.php','html'); //don't check these extensions

if ((strcmp($file, $exclude_file) == 0) ||
(substr($file, -4) === $exclude_ext))

continue;


Thanks
Sonny

Fou-Lu
10-24-2012, 11:50 PM
You cannot use strcmp with an array. You use in_array which returns a boolean:


if (in_array($file, $exclude_file) || in_array(substr($file, -4), $exclude_ext))

Should do it.

sonny
10-25-2012, 12:11 AM
You cannot use strcmp with an array. You use in_array which returns a boolean:


if (in_array($file, $exclude_file) || in_array(substr($file, -4), $exclude_ext))

Should do it.

Thanks will try that, looks a lot smother then what I was thinking about
I was going to try and implement something like this in there somehow.



foreach ($excludeFile as $ex) {
$exF = $ex;
echo $exF;
}

Fou-Lu
10-25-2012, 12:20 AM
foreach is a waste, you only use that if you need to iterate. Using array_search, in_array, or isset for offsets would be faster.
I'd still recommend filters. They are easy to work with, but tricky if you wanted to make them dynamic (it appears to spawn a new instance of Iterator each recursive iteration, so you can't create a method like addIgnoreExtension to it without dealing at a static level). Filters stack, so I can say ignore .php, then later add one to ignore .css or any file starting with ., or add a Regex filter, or anything of the sorts. Super handy.

sonny
10-25-2012, 12:31 AM
foreach is a waste, you only use that if you need to iterate. Using array_search, in_array, or isset for offsets would be faster.
I'd still recommend filters. They are easy to work with, but tricky if you wanted to make them dynamic (it appears to spawn a new instance of Iterator each recursive iteration, so you can't create a method like addIgnoreExtension to it without dealing at a static level). Filters stack, so I can say ignore .php, then later add one to ignore .css or any file starting with ., or add a Regex filter, or anything of the sorts. Super handy.

if you say it, Its most likely the best way to go, but I can't code like you, I wish I knew a quarter of what you know, besides this is checking over 3000 files and is working fine

when I try that in_array I get Wrong datatype for second argument
could I just wrap a foreach like I posted above around that? and do both vars?

Sonny

Fou-Lu
10-25-2012, 12:39 AM
No, don't use a foreach as you have to evaluate every item in the array to the current iteration. Effectively bringing your magnitude up a lot.
What is the actual error, it should tell you what the datatype is. If you have it as this:


$exclude_file = array('file1.php1','file2.php','test/file3.php'); //don't check these files
$exclude_ext = array('.php','html'); //don't check these extensions
if (in_array($file, $exclude_file) || in_array(substr($file, -4), $exclude_ext))

Then the datatypes should be fine, both exclude_file and exclude_ext are arrays.

sonny
10-25-2012, 01:08 AM
No, don't use a foreach as you have to evaluate every item in the array to the current iteration. Effectively bringing your magnitude up a lot.
What is the actual error, it should tell you what the datatype is. If you have it as this:


$exclude_file = array('file1.php1','file2.php','test/file3.php'); //don't check these files
$exclude_ext = array('.php','html'); //don't check these extensions
if (in_array($file, $exclude_file) || in_array(substr($file, -4), $exclude_ext))

Then the datatypes should be fine, both exclude_file and exclude_ext are arrays.

this is the complete error
Warning: in_array() [function.in-array]: Wrong datatype for second argument

Its this line below


if (in_array($file, $exclude_file) || in_array(substr($file, -4), $exclude_ext))

Fou-Lu
10-25-2012, 01:19 AM
Yes, how is it relative to the two set variables though? Are they scope local variables, and are they created in the same branch?

sonny
10-25-2012, 01:22 AM
Yes, how is it relative to the two set variables though? Are they scope local variables, and are they created in the same branch?

you mean do they contain anything? they are set as
global $exclude_file, $exclude_ext; Yes

Sonny

Fou-Lu
10-25-2012, 01:26 AM
Where have you set the exclude_file and exclude_ext.
If they are set they can be a debugging nightmare (since they are globals). If it never works and applies an invalid type, then that indicates its never been set. But if it has been set anywhere before it became to scope, has worked and then stopped, that indicates something has modified them, and the only way to determine what is to debug it.

sonny
10-25-2012, 01:35 AM
Where have you set the exclude_file and exclude_ext.
If they are set they can be a debugging nightmare (since they are globals). If it never works and applies an invalid type, then that indicates its never been set. But if it has been set anywhere before it became to scope, has worked and then stopped, that indicates something has modified them, and the only way to determine what is to debug it.

Now What?, your right, I moved those inside the function to test and it ran without error
now I will see if it will exclude, that's odd I thought global always works? can I even set them as global vars? they run through about 5 functions to pass in.

I will post back on how it went
Thanks
Sonny

Fou-Lu
10-25-2012, 01:42 AM
You can, but they have to be declared before you call the function. Global is such a nightmare since it will automatically create a variable without warning. It can also be used to create global variables that begin with numbers which is forbidden as a variable name.

sonny
10-25-2012, 03:32 AM
You can, but they have to be declared before you call the function. Global is such a nightmare since it will automatically create a variable without warning. It can also be used to create global variables that begin with numbers which is forbidden as a variable name.


Hi I tested it
the $exclude_ext part works fine,


if (in_array($file, $exclude_file) || in_array(substr($file, -4), $exclude_ext))

but the exclude file does not work at all.

It only works by using this with a var


if ((strcmp($file, $exclude_file) == 0)


is there something that works like strcmp
that I can use within a in_array?

Thanks
Sonny

Fou-Lu
10-25-2012, 03:43 AM
No, but it doesn't matter since you are only comparing for equality.

That doesn't verify that its not an array though. strcmp when given an invalid datatype will return null, which is equal to 0. Make sure you enable your error reporting, it will tell you of improper datatypes with either in_array or strcmp.

sonny
10-25-2012, 04:02 AM
No, but it doesn't matter since you are only comparing for equality.

That doesn't verify that its not an array though. strcmp when given an invalid datatype will return null, which is equal to 0. Make sure you enable your error reporting, it will tell you of improper datatypes with either in_array or strcmp.

I have error reporting on, and it did show errors over that global problem I had earlier

I can't understand why in the world this below works but not the in_array
they must do something different



if ((strcmp($file, $exclude_file) == 0)

Fou-Lu
10-25-2012, 04:11 AM
If there are no errors, then that indicates that $exclude_file is a string, not an array.
Global will never trigger error reporting; that is part of the reason it is such a nightmare.

sonny
10-25-2012, 05:46 AM
If there are no errors, then that indicates that $exclude_file is a string, not an array.
Global will never trigger error reporting; that is part of the reason it is such a nightmare.

Cleaned everything up, no more global s at all
Yep you guessed it, everything works now.

Thanks
Sonny



EZ Archive Ads Plugin for vBulletin Copyright 2006 Computer Help Forum