Jump to content

Checking for '.' and '..' as a Condition for Invoking Recursion


iwato

Recommended Posts

You should change your declaration to this:
function rrmdir_override($path, &$fld_count=0, &$file_cnt=0)

No, I should not. There is nothing wrong with my code. It works fine, just as it is. Try it, and you will see.Roddy
Link to comment
Share on other sites

I think the lack of default values was the part that was not making sence... I haven't really done any reference accepting functions lately, so I didn't know if one is allowed to give default values for arguments passed by reference. I was planning to try it, but I guess I won't have to :) .
What do you mean, lack of default values? Read my code again. Better yet try the function. It works fine. You and JSG are spinning wheels without having ever ridden the bike.Roddy
Link to comment
Share on other sites

No, I should not. There is nothing wrong with my code. It works fine, just as it is. Try it, and you will see.
That isn't the point.
However, the passing by reference at call time is deprecated, because its behaviour is undefined (therefore unpredictable) for functions that were not meant to take values by reference.See the manual on passing by reference for other examples.
Just because it works, doesn't mean it should be used. There are a lot of deprecated functions that may still work, but they are unstable or insecure and thus deprecated. Meaning you shouldn't use them because there are better ways to do whatever it is you're doing.
What do you mean, lack of default values? Read my code again. Better yet try the function. It works fine. You and JSG are spinning wheels without having ever ridden the bike.
If you know the answers, why do you ask questions? Perhaps you should try understanding the responses you get before slinging mud in people's faces...
Link to comment
Share on other sites

No, I should not. There is nothing wrong with my code.
OK pal, you go right ahead and keep using things that are deprecated. One day you'll install your code on a new machine and wonder why it throws errors when it didn't used to do that on previous versions of PHP. Why do you even ask for people's input if you're just going to turn around and assert that your code has "nothing wrong" without even reading the documentation on what you're using? You posted your code, you asked for people's input, we told you that you're using features that have been deprecated, how to do it correctly, and you say we're wrong.
You and JSG are spinning wheels without having ever ridden the bike.
Yeah, and you're heading into a brick wall with 100% confidence that you know what you're doing.
Link to comment
Share on other sites

I think the lack of default values was the part that was not making sence... I haven't really done any reference accepting functions lately, so I didn't know if one is allowed to give default values for arguments passed by reference. I was planning to try it, but I guess I won't have to :) .
Check #3 under the "Other New Language Features" section:http://devzone.zend.com/article/1714-Whats-New-in-PHP-5
Link to comment
Share on other sites

What do you mean, lack of default values? Read my code again. Better yet try the function. It works fine. You and JSG are spinning wheels without having ever ridden the bike.Roddy
I meant the lack of default values in my example... the one you didn't agree with:
function rrmdir_override($path, &$fld_count, &$file_cnt)

THAT example, I thought, was not making sence due to me remembering the PHP4 way (default values for arguments passed by reference not allowed), and never trying to do the PHP5 way (default values for arguments passed by reference are allowed), which is what justsomeguy later confirmed will work:

function rrmdir_override($path, &$fld_count=0, &$file_cnt=0)

If you change that AND call your function with

rrmdir_override($member_path, $fld_count, $file_cnt)

you'll be using references properly. Right now, the function works, but it relies on a deprecated feature (the passing by reference at call time).

You and JSG are spinning wheels without having ever ridden the bike.
Who needs a bike when you have a car :) ?(I just happen to do things in ways where I don't ever need references. As soon as something gets complicated enough for me to need references, I make an object instead, and the once complicated function becomes a method)
Link to comment
Share on other sites

Check #3 under the "Other New Language Features" section:http://devzone.zend.com/article/1714-Whats-New-in-PHP-5
Yes, JSG, the following also works well and is now consistent with the prescription provided above.
function rrmdir_override($path, $mode=0755, &$fld_count = 0, &$file_cnt = 0) {	if (!is_dir($path)) {		throw new Exception('"' . basename($path) . '" is not a folder. Revise your path\'s destination.', 1);	}	$old_umask = umask();	umask(0);	chmod($path, $mode);	$members = scandir($path);	foreach ($members as $member) {		if ($member != '.' && $member != '..') {			$member_path = $path.DIRECTORY_SEPARATOR.$member;			chmod($member_path, $mode);			if (is_dir($member_path)) {				rrmdir_override($member_path, $mode, &$fld_count, &$file_cnt); 			} else {				unlink($member_path);				$file_cnt++;			}		}	}	rmdir($path);	umask($old_umask);	$fld_count++;	$doc_count =  array('Folder Count' => $fld_count, 'File Count' => $file_cnt, 'Total Count' => ($fld_count + $file_cnt));	if (!empty($doc_count)) {		return $doc_count;	} else {		return false;	}}

Roddy

Link to comment
Share on other sites

You're still using references at call time. The part:

rrmdir_override($member_path, $mode, &$fld_count, &$file_cnt);

should be

rrmdir_override($member_path, $mode, $fld_count, $file_cnt);

Here's my new iteration in light of the idea about forcing deletion and your desire for counters... I have a different idea about what constitutes a useful report though, so instad of sticking to a particular type (yours or mine), I've defined the forth argument as a callback to be executed after each deletion attempt. You can format the resulting array (or whatever) there by use()-ing it as a reference on the callback.Here it is:

/** * Removes a folder with all of its contents. * * @author boen_robot * @param string $path The directory to remove * @param bool $continueOnError Whether to keep deleting items even after a * failure on a child item. * @param bool $force Whether to force the deletion, * i.e. attempt to take privilages and ownership if required. * @param callback $onAfterDelete a function to be executed after the * deletion attempt of each item. Takes the full path, error code, and path type * as arguments, in this order. * @return bool TRUE on success, FALSE on failure. */function rrmdir($path, $continueOnError = false, $force = false, $onAfterDelete = null) {	if (!is_dir($path)) {		throw new Exception("Directory '{$path}' not found", 1);	}	if (!is_writable($path)) {		if ($force) {			if (fileowner($path) !== getmyuid()) {				if (!chown($path, getmyuid())) {					if ($continueOnError) {						if ($onAfterDelete !== null) $onAfterDelete(realpath($path), 2);						return false;					}					throw new Exception("Unable to take ownership of '{realpath($path)}'", 2);				}			}			if (!chmod($realpath, 0777)) {				if ($continueOnError) {					if ($onAfterDelete !== null) $onAfterDelete(realpath($path), 3);					return false;				}				throw new Exception("Unable to change permissions of '{realpath($path)}'", 3);			}		}else {			if ($continueOnError) {				if ($onAfterDelete !== null) $onAfterDelete(realpath($path), 4);				return false;			}			throw new Exception("Permission denied for '{realpath($path)}'", 4);		}	}	$hasFailed = false;	$hasLchown = function_exists('lchown');	$iterator =		new RecursiveIteratorIterator(			new RecursiveDirectoryIterator(					$path,					FilesystemIterator::CURRENT_AS_FILEINFO			),			RecursiveIteratorIterator::CHILD_FIRST		);	foreach($iterator as $current) {		$realpath = $current->getRealPath();		$currentType = strpos(((int) is_file($realpath)) . ((int) is_dir($realpath)) . ((int) is_link($realpath)), '1');		if ($currentType === false) $currentType = -1;		if (!is_writable($realpath)) {			if ($force) {				if (fileowner($realpath) !== getmyuid()) {					$chown = ($hasLchown && ($currentType === 2)) ? 'lchown' : 'chown';					if (!$chown($realpath, getmyuid())) {						if ($continueOnError) {							$hasFailed = true;							if ($onAfterDelete !== null) $onAfterDelete($realpath, 5, $currentType);							continue;						}						throw new Exception("Unable to take ownership of '{$realpath}'", 5);					}				}				if (!chmod($realpath, 0777)) {					if ($continueOnError) {						$hasFailed = true;						if ($onAfterDelete !== null) $onAfterDelete($realpath, 6, $currentType);						continue;					}					throw new Exception("Unable to change permissions of '{$realpath}'", 6);				}			}else {				if ($continueOnError) {					$hasFailed = true;					if ($onAfterDelete !== null) $onAfterDelete($realpath, 7, $currentType);					continue;				}				throw new Exception("Permission denied for '{$realpath}'", 7);			}		}		switch($currentType) {		case 0:		case 2:			if (!unlink($realpath)) {				if ($continueOnError) {					$hasFailed = true;					if ($onAfterDelete !== null) $onAfterDelete($realpath, 8, $currentType);					continue 2;				}				throw new Exception("Unlinking a child file or link '{$realpath}' failed", 8);			}			break;		case 1:			if (!rmdir($realpath)) {				if ($continueOnError) {					$hasFailed = true;					if ($onAfterDelete !== null) $onAfterDelete($realpath, 9, $currentType);					continue 2;				}				throw new Exception("Removing a child directory '{$realpath}' failed", 9);			}			break;		default:			if ($continueOnError) {				$hasFailed = true;				if ($onAfterDelete !== null) $onAfterDelete($realpath, 10, $currentType);				continue 2;			}			throw new Exception("Unable to remove '{$realpath}'", 10);		}		clearstatcache(true, $realpath);		if ($onAfterDelete !== null) $onAfterDelete($realpath, 0, $currentType);	}	$realpath = realpath($path);	if ($hasFailed) {		if ($onAfterDelete !== null) $onAfterDelete($realpath, 11, 1);		return false;	}	if (!rmdir($realpath)) {		if ($continueOnError) {			if ($onAfterDelete !== null) $onAfterDelete($realpath, 12, 1);			return false;		}		throw new Exception("Removing the directory '{$realpath}' failed", 12);	}	if ($onAfterDelete !== null) $onAfterDelete($realpath, 0, 1);	return true;}

Link to comment
Share on other sites

Archived

This topic is now archived and is closed to further replies.

×
×
  • Create New...