मैं PHP में एक निर्देशिका और इसकी संपूर्ण सामग्री (फ़ाइलें और उपनिर्देशिका) को कैसे हटाऊँ?
मैं PHP में एक निर्देशिका और इसकी संपूर्ण सामग्री (फ़ाइलें और उपनिर्देशिका) को कैसे हटाऊँ?
जवाबों:
उपयोगकर्ता के योगदान पृष्ठ के मैनुअल पेज rmdir
में एक अच्छा कार्यान्वयन शामिल है:
function rrmdir($dir) {
if (is_dir($dir)) {
$objects = scandir($dir);
foreach ($objects as $object) {
if ($object != "." && $object != "..") {
if (is_dir($dir. DIRECTORY_SEPARATOR .$object) && !is_link($dir."/".$object))
rrmdir($dir. DIRECTORY_SEPARATOR .$object);
else
unlink($dir. DIRECTORY_SEPARATOR .$object);
}
}
rmdir($dir);
}
}
is_dir
प्रत्येक रिकार्स्ड निर्देशिका के लिए दो बार कॉल करता है । यदि तर्क एक सिमलिंक है, तो यह सिमिलिंक को हटाने के बजाय इसका अनुसरण भी करता है, जो आप चाहते हैं या नहीं हो सकता है। किसी भी मामले में, ऐसा नहीं rm -rf
है।
पर बिल्डिंग पिक्सेल डेवलपर की टिप्पणी , एसपीएल का उपयोग कर एक टुकड़ा दिखाई देंगे:
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($files as $fileinfo) {
$todo = ($fileinfo->isDir() ? 'rmdir' : 'unlink');
$todo($fileinfo->getRealPath());
}
rmdir($dir);
नोट: यह कोई पवित्रता की जाँच नहीं करता है और PHP 5.3.0 में FilesystemIterator के साथ शुरू किए गए SKIP_DOTS ध्वज का उपयोग करता है। बेशक, a / $todo
हो सकता है । महत्वपूर्ण बिंदु यह है कि बच्चों (फ़ाइलों) को उनके माता-पिता (फ़ोल्डर) से पहले पुन: व्यवस्थित करने के लिए उपयोग किया जाता है।if
else
CHILD_FIRST
SKIP_DOTS
केवल PHP 5.3 में पेश किया गया था? आपने वह कहां देखा?
getPathname()
इसके बजाय विधि का उपयोग नहीं करना चाहिए getRealPath()
?
rmdir($dir)
स्क्रिप्ट के अंत में होना चाहिए ।
rmdir()
और unlink()
साथ, जैसे रोकता E_WARNING
और रिटर्न true
या false
यह दर्शाता है सफलता।
FilesystemIterator
एक पुनरावर्ती पुनरावृत्ति नहीं है।
मार्ग में सभी फ़ाइलों और फ़ोल्डरों को हटाता है।
function recurseRmdir($dir) {
$files = array_diff(scandir($dir), array('.','..'));
foreach ($files as $file) {
(is_dir("$dir/$file")) ? recurseRmdir("$dir/$file") : unlink("$dir/$file");
}
return rmdir($dir);
}
rm -rf /
== recurseRmdir('/')
:)
is_dir("$dir/$file")
करने के लिएis_dir("$dir/$file") && !is_link("$dir/$file")
* निक्स के लिए आप विंडोज के shell_exec
लिए rm -R
या उसके DEL /S folder_name
लिए उपयोग कर सकते हैं ।
DEL /S folder_name
में विंडोज के लिए
RMDIR /S /Q folder_name
मेरे लिए क्या काम करता है
exec('rm -rf ' . __DIR__ . '/output/*.log');
<?php
use RecursiveDirectoryIterator;
use RecursiveIteratorIterator;
use SplFileInfo;
# http://stackoverflow.com/a/3352564/283851
# https://gist.github.com/XzaR90/48c6b615be12fa765898
# Forked from https://gist.github.com/mindplay-dk/a4aad91f5a4f1283a5e2
/**
* Recursively delete a directory and all of it's contents - e.g.the equivalent of `rm -r` on the command-line.
* Consistent with `rmdir()` and `unlink()`, an E_WARNING level error will be generated on failure.
*
* @param string $source absolute path to directory or file to delete.
* @param bool $removeOnlyChildren set to true will only remove content inside directory.
*
* @return bool true on success; false on failure
*/
function rrmdir($source, $removeOnlyChildren = false)
{
if(empty($source) || file_exists($source) === false)
{
return false;
}
if(is_file($source) || is_link($source))
{
return unlink($source);
}
$files = new RecursiveIteratorIterator
(
new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);
//$fileinfo as SplFileInfo
foreach($files as $fileinfo)
{
if($fileinfo->isDir())
{
if(rrmdir($fileinfo->getRealPath()) === false)
{
return false;
}
}
else
{
if(unlink($fileinfo->getRealPath()) === false)
{
return false;
}
}
}
if($removeOnlyChildren === false)
{
return rmdir($source);
}
return true;
}
यहां अधिक उदाहरणों के साथ एक और धागा है: PHP के लिए एक पुनरावर्ती निकालें निर्देशिका फ़ंक्शन?
यदि आप Yii का उपयोग कर रहे हैं तो आप इसे ढांचे पर छोड़ सकते हैं:
CFileHelper::removeDirectory($my_directory);
'सरल' कोड जो काम करता है और दस साल पुराने द्वारा पढ़ा जा सकता है:
function deleteNonEmptyDir($dir)
{
if (is_dir($dir))
{
$objects = scandir($dir);
foreach ($objects as $object)
{
if ($object != "." && $object != "..")
{
if (filetype($dir . "/" . $object) == "dir")
{
deleteNonEmptyDir($dir . "/" . $object);
}
else
{
unlink($dir . "/" . $object);
}
}
}
reset($objects);
rmdir($dir);
}
}
कृपया ध्यान दें कि मैंने जो कुछ भी किया था उसका विस्तार / सरलीकरण और निर्धारण (गैर खाली डीआईआर के लिए काम नहीं किया गया) यहां समाधान: पीएचपी में मैं कैसे उन सभी फ़ोल्डरों को पुन: हटा सकता हूं जो खाली नहीं हैं?
बढ़ाया @Artefacto समाधान - टाइप किए गए टाइपो और सरलीकृत कोड को सुधारा, दोनों के लिए काम कर रहा है - खाली && गैर-रिक्त निर्देशिका।
function recursive_rmdir($dir) {
if( is_dir($dir) ) {
$objects = array_diff( scandir($dir), array('..', '.') );
foreach ($objects as $object) {
$objectPath = $dir."/".$object;
if( is_dir($objectPath) )
recursive_rmdir($objectPath);
else
unlink($objectPath);
}
rmdir($dir);
}
}
100% काम कर समाधान
public static function rmdir_recursive($directory, $delete_parent = null)
{
$files = glob($directory . '/{,.}[!.,!..]*',GLOB_MARK|GLOB_BRACE);
foreach ($files as $file) {
if (is_dir($file)) {
self::rmdir_recursive($file, 1);
} else {
unlink($file);
}
}
if ($delete_parent) {
rmdir($directory);
}
}
कुछ इस तरह?
function delete_folder($folder) {
$glob = glob($folder);
foreach ($glob as $g) {
if (!is_dir($g)) {
unlink($g);
} else {
delete_folder("$g/*");
rmdir($g);
}
}
}
ग्लोब () फ़ंक्शन के साथ उदाहरण । यह डॉट्स के साथ शुरू होने वाली फ़ाइलों सहित सभी फ़ाइलों और फ़ोल्डरों को पुन: हटा देगा।
delete_all( 'folder' );
function delete_all( $item ) {
if ( is_dir( $item ) ) {
array_map( 'delete_all', array_diff( glob( "$item/{,.}*", GLOB_BRACE ), array( "$item/.", "$item/.." ) ) );
rmdir( $item );
} else {
unlink( $item );
}
};
system('rm -fr folder')
अनलिंक फ़ंक्शन फ़ंक्शन को दिए गए पथ के सभी फ़ोल्डरों और फ़ाइलों को पुन: हटा देता है, यह सुनिश्चित करके कि यह स्क्रिप्ट को स्वयं नहीं हटाता है।
function unlinkr($dir, $pattern = "*") {
// find all files and folders matching pattern
$files = glob($dir . "/$pattern");
//interate thorugh the files and folders
foreach($files as $file){
//if it is a directory then re-call unlinkr function to delete files inside this directory
if (is_dir($file) and !in_array($file, array('..', '.'))) {
echo "<p>opening directory $file </p>";
unlinkr($file, $pattern);
//remove the directory itself
echo "<p> deleting directory $file </p>";
rmdir($file);
} else if(is_file($file) and ($file != __FILE__)) {
// make sure you don't delete the current script
echo "<p>deleting file $file </p>";
unlink($file);
}
}
}
यदि आप इस स्क्रिप्ट को रखने वाली सभी फ़ाइलों और फ़ोल्डरों को हटाना चाहते हैं, तो इसे निम्नानुसार कॉल करें
//get current working directory
$dir = getcwd();
unlinkr($dir);
अगर आप सिर्फ php फाइल को डिलीट करना चाहते हैं तो इसे निम्न प्रकार से कॉल करें
unlinkr($dir, "*.php");
आप फ़ाइलों को हटाने के लिए किसी अन्य पथ का उपयोग कर सकते हैं
unlinkr("/home/user/temp");
यह घर / उपयोगकर्ता / अस्थायी निर्देशिका में सभी फ़ाइलों को हटा देगा।
मैं इस कोड का उपयोग करता हूं ...
function rmDirectory($dir) {
foreach(glob($dir . '/*') as $file) {
if(is_dir($file))
rrmdir($file);
else
unlink($file);
}
rmdir($dir);
}
या यह एक ...
<?php
public static function delTree($dir) {
$files = array_diff(scandir($dir), array('.','..'));
foreach ($files as $file) {
(is_dir("$dir/$file")) ? delTree("$dir/$file") : unlink("$dir/$file");
}
return rmdir($dir);
}
?>
एक बार जब आप रनिंग टेस्ट समाप्त कर लेते हैं , तो कक्षा में #unlink और #rdir से # हटा दें ।
<?php
class RMRFiles {
function __construct(){
}
public function recScan( $mainDir, $allData = array() )
{
// hide files
$hidefiles = array(
".",
"..") ;
//start reading directory
$dirContent = scandir( $mainDir ) ;
//cycle through
foreach ( $dirContent as $key => $content )
{
$path = $mainDir . '/' . $content ;
// if is readable / file
if ( ! in_array( $content, $hidefiles ) )
{
if ( is_file( $path ) && is_readable( $path ) )
{
#delete files within directory
#unlink($path);
$allData['unlink'][] = $path ;
}
// if is readable / directory
else
if ( is_dir( $path ) && is_readable( $path ) )
{
/*recursive*/
$allData = $this->recScan( $path, $allData ) ;
#finally remove directory
$allData['rmdir'][]=$path;
#rmdir($path);
}
}
}
return $allData ;
}
}
header("Content-Type: text/plain");
/* Get absolute path of the running script
Ex : /home/user/public_html/ */
define('ABPATH', dirname(__file__) . '/');
/* The folder where we store cache files
Ex: /home/user/public_html/var/cache */
define('STOREDIR','var/cache');
$rmrf = new RMRFiles();
#here we delete folder content files & directories
print_r($rmrf->recScan(ABPATH.STOREDIR));
#finally delete scanned directory ?
#rmdir(ABPATH.STOREDIR);
?>
<?php
/**
* code by Nk (nk.have.a@gmail.com)
*/
class filesystem
{
public static function remove($path)
{
return is_dir($path) ? rmdir($path) : unlink($path);
}
public static function normalizePath($path)
{
return $path.(is_dir($path) && !preg_match('@/$@', $path) ? '/' : '');
}
public static function rscandir($dir, $sort = SCANDIR_SORT_ASCENDING)
{
$results = array();
if(!is_dir($dir))
return $results;
$dir = self::normalizePath($dir);
$objects = scandir($dir, $sort);
foreach($objects as $object)
if($object != '.' && $object != '..')
{
if(is_dir($dir.$object))
$results = array_merge($results, self::rscandir($dir.$object, $sort));
else
array_push($results, $dir.$object);
}
array_push($results, $dir);
return $results;
}
public static function rrmdir($dir)
{
$files = self::rscandir($dir);
foreach($files as $file)
self::remove($file);
return !file_exists($dir);
}
}
?>
cleanup.php:
<?php
/* include.. */
filesystem::rrmdir('/var/log');
filesystem::rrmdir('./cache');
?>
ऐसा लगता है कि अन्य सभी उत्तर मान लेते हैं कि फ़ंक्शन को दिया गया मार्ग हमेशा एक निर्देशिका है। यह संस्करण निर्देशिकाओं के साथ-साथ एकल फ़ाइलों को हटाने का काम करता है:
/**
* Recursively delete a file or directory. Use with care!
*
* @param string $path
*/
function recursiveRemove($path) {
if (is_dir($path)) {
foreach (scandir($path) as $entry) {
if (!in_array($entry, ['.', '..'])) {
recursiveRemove($path . DIRECTORY_SEPARATOR . $entry);
}
}
rmdir($path);
} else {
unlink($path);
}
}
DirectoryIterator और रिकर्सन का सही तरीके से उपयोग करना:
function deleteFilesThenSelf($folder) {
foreach(new DirectoryIterator($folder) as $f) {
if($f->isDot()) continue; // skip . and ..
if ($f->isFile()) {
unlink($f->getPathname());
} else if($f->isDir()) {
deleteFilesThenSelf($f->getPathname());
}
}
rmdir($folder);
}
मैंने कुछ स्टैकऑवरफ्लो चर्चाओं से यह कोड बनाया है। मैंने अभी तक लिनक्स वातावरण पर परीक्षण नहीं किया। यह पूरी तरह से एक फ़ाइल या निर्देशिका को हटाने के लिए बनाया गया है:
function splRm(SplFileInfo $i)
{
$path = $i->getRealPath();
if ($i->isDir()) {
echo 'D - ' . $path . '<br />';
rmdir($path);
} elseif($i->isFile()) {
echo 'F - ' . $path . '<br />';
unlink($path);
}
}
function splRrm(SplFileInfo $j)
{
$path = $j->getRealPath();
if ($j->isDir()) {
$rdi = new RecursiveDirectoryIterator($path, FilesystemIterator::SKIP_DOTS);
$rii = new RecursiveIteratorIterator($rdi, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($rii as $i) {
splRm($i);
}
}
splRm($j);
}
splRrm(new SplFileInfo(__DIR__.'/../dirOrFileName'));
function rmdir_recursive( $dirname ) {
/**
* FilesystemIterator and SKIP_DOTS
*/
if ( class_exists( 'FilesystemIterator' ) && defined( 'FilesystemIterator::SKIP_DOTS' ) ) {
if ( !is_dir( $dirname ) ) {
return false;
}
foreach( new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dirname, FilesystemIterator::SKIP_DOTS ), RecursiveIteratorIterator::CHILD_FIRST ) as $path ) {
$path->isDir() ? rmdir( $path->getPathname() ) : unlink( $path->getRealPath() );
}
return rmdir( $dirname );
}
/**
* RecursiveDirectoryIterator and SKIP_DOTS
*/
if ( class_exists( 'RecursiveDirectoryIterator' ) && defined( 'RecursiveDirectoryIterator::SKIP_DOTS' ) ) {
if ( !is_dir( $dirname ) ) {
return false;
}
foreach( new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dirname, RecursiveDirectoryIterator::SKIP_DOTS ), RecursiveIteratorIterator::CHILD_FIRST ) as $path ) {
$path->isDir() ? rmdir( $path->getPathname() ) : unlink( $path->getRealPath() );
}
return rmdir( $dirname );
}
/**
* RecursiveIteratorIterator and RecursiveDirectoryIterator
*/
if ( class_exists( 'RecursiveIteratorIterator' ) && class_exists( 'RecursiveDirectoryIterator' ) ) {
if ( !is_dir( $dirname ) ) {
return false;
}
foreach( new RecursiveIteratorIterator( new RecursiveDirectoryIterator( $dirname ), RecursiveIteratorIterator::CHILD_FIRST ) as $path ) {
if ( in_array( $path->getFilename(), array( '.', '..' ) ) ) {
continue;
}
$path->isDir() ? rmdir( $path->getPathname() ) : unlink( $path->getRealPath() );
}
return rmdir( $dirname );
}
/**
* Scandir Recursive
*/
if ( !is_dir( $dirname ) ) {
return false;
}
$objects = scandir( $dirname );
foreach ( $objects as $object ) {
if ( $object === '.' || $object === '..' ) {
continue;
}
filetype( $dirname . DIRECTORY_SEPARATOR . $object ) === 'dir' ? rmdir_recursive( $dirname . DIRECTORY_SEPARATOR . $object ) : unlink( $dirname . DIRECTORY_SEPARATOR . $object );
}
reset( $objects );
rmdir( $dirname );
return !is_dir( $dirname );
}
@ XzaR समाधान का संशोधित संस्करण। यह खाली फ़ोल्डरों को हटा देता है, जब सभी फाइलें उनसे हटा दी जाती हैं और यह त्रुटियों पर झूठे वापस करने के बजाय अपवादों को फेंक देता है।
function recursivelyRemoveDirectory($source, $removeOnlyChildren = true)
{
if (empty($source) || file_exists($source) === false) {
throw new Exception("File does not exist: '$source'");
}
if (is_file($source) || is_link($source)) {
if (false === unlink($source)) {
throw new Exception("Cannot delete file '$source'");
}
}
$files = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($source, RecursiveDirectoryIterator::SKIP_DOTS),
RecursiveIteratorIterator::CHILD_FIRST
);
foreach ($files as $fileInfo) {
/** @var SplFileInfo $fileInfo */
if ($fileInfo->isDir()) {
if ($this->recursivelyRemoveDirectory($fileInfo->getRealPath()) === false) {
throw new Exception("Failed to remove directory '{$fileInfo->getRealPath()}'");
}
if (false === rmdir($fileInfo->getRealPath())) {
throw new Exception("Failed to remove empty directory '{$fileInfo->getRealPath()}'");
}
} else {
if (unlink($fileInfo->getRealPath()) === false) {
throw new Exception("Failed to remove file '{$fileInfo->getRealPath()}'");
}
}
}
if ($removeOnlyChildren === false) {
if (false === rmdir($source)) {
throw new Exception("Cannot remove directory '$source'");
}
}
}
function deltree_cat($folder)
{
if (is_dir($folder))
{
$handle = opendir($folder);
while ($subfile = readdir($handle))
{
if ($subfile == '.' or $subfile == '..') continue;
if (is_file($subfile)) unlink("{$folder}/{$subfile}");
else deltree_cat("{$folder}/{$subfile}");
}
closedir($handle);
rmdir ($folder);
}
else
{
unlink($folder);
}
}
unlink
, rmdir
) opendir
+ readdir
काम तेजी से कि scandir
और RecursiveDirectoryIterator
यह भी सभी की तुलना में कम स्मृति का उपयोग कर रहा है। मुझे closedir
पहले फ़ोल्डर को हटाने के लिए , मैं इस पर अटक गया था। इस उत्तर के लिए धन्यवाद।