Raketenwilli: PHP: Verzeichnis rekursiv löschen (neue Version, Diskussion)

Beitrag lesen

Na gut. Das schon lange existierende Skript hat aus der Mode geratene Eigenheiten, speziell die Fehlerunterdrückung mit @befehl „gefällt 2022 nicht mehr jedem“.

Das gab mir Anlass über meine Version nochmal nachzudenken.

Die Rückgabe der gelöschte Dateien und Verzeichnisse als Array hat sich dabei als Unsinn erwiesen, das braucht niemand - vor allem weil es bei einem Fehler nicht erfolgte. Eine umfassende Speicherung in einem Array würde die Sache unnötig aufblähen und die Auswertung der Rückgabe zu kompliziert machen. Das will auch kaum jemand ...

Allerdings habe ich in die neue Version eine Möglichkeit eingebaut, diese Löschvorgänge (und den Erfolg) ggf. als E_USER_NOTICE zu loggen.

Die eigentliche Funktion ist sogar deutlich kürzer als vorher… ich hoffe, sie ist brauchbar.

Ich werde das aus $Gründen aber nicht einfach mal ins Wiki setzen.

<?php

/** function rmdirRecursive löscht ein Verzeichnis rekursiv.
* Parameter:
*   $dirName   : zu löschendes Verzeichnis
*   $logDelete : true ->  Erfolg (gelöschte Dateien) wird geloggt.
*              : false -> Gelöschte Dateien) nicht loggen.
*              : default = false
*   $errorType : siehe https://www.php.net/manual/de/errorfunc.constants.php
*              : sinnvoller default =  E_USER_ERROR
*/

function rmdirRecursive (
	$dirName,
	$logDelete = false,
	$errorType = E_USER_ERROR
) {
	if ( ! is_dir( $dirName ) ) {
		trigger_error (
          "'$dirName' existiert nicht oder ist kein Verzeichnis.",
          $errorType
		);
		return false;
	}

	foreach( scandir( $dirName ) as $item ) {
		
		if ( 
			   '..' == $item
			or '.'  == $item
		) continue; 
		
		$dso = $dirName . '/' . $item;
		if ( 
			   is_file( $dso ) 
			or is_link( $dso )
		) {
			if ( ! unlink( $dso ) ) {
				trigger_error (
					"Datei '$dso' konnte nicht gelöscht werden.",
					$errorType
				);
				return false;
			} elseif ( $logDelete )  {
				trigger_error (
					"Datei '$dso' wurde gelöscht",
					E_USER_NOTICE
				);
			}
		} else {
			$r = rmdirRecursive( $dso, $logDelete, $errorType );
			if ( false === $r ) {
				trigger_error (
					"Datei '$dso' konnte nicht gelöscht werden.",
					$errorType
				);
				return false;				   
			} 
		}
	}
	if ( rmdir( $dirName ) ) {
		if ( $logDelete ) {
			trigger_error (
				"Verzeichnis '$dirName' wurde gelöscht",
				E_USER_NOTICE
			);
		}
		return true;
	} else {
		trigger_error (
			"Verzeichnis '$dirName' konnte nicht gelöscht werden.",
			$errorType
		);
		return false;		
	}
}

### Usage example:

## 1. Dateien und Verzeichnisse erzeugen (Linux)
# /*
exec("
mkdir /tmp/a;
mkdir /tmp/a/a;
touch /tmp/a/a/a;
touch /tmp/a/a/.a;
touch '/tmp/a/a/a a';
mkdir /tmp/a/b;
touch /tmp/a/b/a;
touch /tmp/a/b/b;
touch /tmp/a/b/c;
mkdir /tmp/a/c;
");
# */

## 2. Error-Reporting optimieren
#error_reporting ( error_reporting() &~ E_USER_NOTICE );
error_reporting ( E_ALL );
ini_set( 'display_errors', 0);

## 3. Das Zeug wieder löschen
if ( rmdirRecursive( '/tmp/a', true, E_USER_ERROR ) ) { 
	echo 'Erfolgreich gelöscht' . PHP_EOL;
} else  {
	echo 'Fehler. Sehen Sie im Error-Log nach.' . PHP_EOL;
}