मैं PHP में किसी निर्देशिका और उसकी संपूर्ण सामग्री (फाइल + सब डायर) को कैसे हटा सकता हूँ?


133

मैं PHP में एक निर्देशिका और इसकी संपूर्ण सामग्री (फ़ाइलें और उपनिर्देशिका) को कैसे हटाऊँ?


जवाबों:


207

उपयोगकर्ता के योगदान पृष्ठ के मैनुअल पेज 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); 
   } 
 }

1
@ पिक्सेल डेवलपर - मैंने यह दिखाने वाला एक उत्तर जोड़ा ।
सलातो

2
समाधान की जाँच करें जो किसी ने मुझे एक ही सवाल के लिए दिया था: ग्लोब काम करने के लिए अच्छा लगता है: stackoverflow.com/questions/11267086/…
NoodleOfDeath

यह is_dirप्रत्येक रिकार्स्ड निर्देशिका के लिए दो बार कॉल करता है । यदि तर्क एक सिमलिंक है, तो यह सिमिलिंक को हटाने के बजाय इसका अनुसरण भी करता है, जो आप चाहते हैं या नहीं हो सकता है। किसी भी मामले में, ऐसा नहीं rm -rfहै।
व्लादिमीर पेंटेलेव

116

पर बिल्डिंग पिक्सेल डेवलपर की टिप्पणी , एसपीएल का उपयोग कर एक टुकड़ा दिखाई देंगे:

$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हो सकता है । महत्वपूर्ण बिंदु यह है कि बच्चों (फ़ाइलों) को उनके माता-पिता (फ़ोल्डर) से पहले पुन: व्यवस्थित करने के लिए उपयोग किया जाता है।ifelseCHILD_FIRST


SKIP_DOTSकेवल PHP 5.3 में पेश किया गया था? आपने वह कहां देखा?
एलिक्स एक्सल

धन्यवाद। इसके अलावा: क्या आपको getPathname()इसके बजाय विधि का उपयोग नहीं करना चाहिए getRealPath()?
एलिक्स एक्सल

3
यह समाधान अच्छी तरह से काम करता है, हालांकि यह सब कुछ हटा देता है ... निर्देशिका को छोड़कर (चाहे खाली हो या न हो)। rmdir($dir)स्क्रिप्ट के अंत में होना चाहिए ।
laurent

3
यहाँ एक ही कार्य है , unwrapped डॉक-अवरुद्ध है, और साथ संगत कर दिया rmdir()और unlink()साथ, जैसे रोकता E_WARNINGऔर रिटर्न trueया falseयह दर्शाता है सफलता।
mindplay.dk

2
@dbf नहीं, ऐसा नहीं होगा, FilesystemIteratorएक पुनरावर्ती पुनरावृत्ति नहीं है।
सलाथि

17

मार्ग में सभी फ़ाइलों और फ़ोल्डरों को हटाता है।

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);
}

1
rm -rf /== recurseRmdir('/'):)
हारून एसाव

5
कृपया ध्यान दें कि यह सिमलिंक सुरक्षित नहीं है! आपको यह देखने के लिए is_dir के बाद एक sanity check की आवश्यकता है कि यह is_link है, क्योंकि अन्यथा आप किसी बाहरी फ़ोल्डर से सहानुभूति ले सकते हैं जिसे तब हटा दिया जाता है और इसे सुरक्षा छेद माना जा सकता है। तो अगर आप बदलना चाहिए is_dir("$dir/$file")करने के लिएis_dir("$dir/$file") && !is_link("$dir/$file")
Kira एम Backes

13

* निक्स के लिए आप विंडोज के shell_execलिए rm -Rया उसके DEL /S folder_nameलिए उपयोग कर सकते हैं ।


2
कैसे के बारे DEL /S folder_nameमें विंडोज के लिए
ankitjaininfo

@ गोर्डन RMDIR /S /Q folder_nameमेरे लिए क्या काम करता है
ब्रायन लीशमैन

2
@ वाईआर 3 डी जब तक निष्पादन कमांड में कोई उपयोगकर्ता इनपुट नहीं है, आपको अच्छा होना चाहिए। Ex:exec('rm -rf ' . __DIR__ . '/output/*.log');
ब्रायन हनेय

5
<?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;
}

काफी जटिल सुझाव ;-)
फिलिप

@Philipp हाँ मुझे लगता है। अच्छी तरह से मैंने एक कांटा निकाल दिया। gith.github.com/mindplay-dk/a4aad91f5a4f1283a5e2 क्योंकि मुझे यह काम करने के लिए नहीं मिला था इसलिए मैंने सोचा था कि मैं भी इसे साझा कर सकता हूं।
XzaR

वहाँ एक समस्या है। सभी फ़ाइलों को हटा दिए जाने के बाद यह खाली फ़ोल्डरों को नहीं हटाता है। नीचे दिए गए उत्तर के रूप में थोड़ा संशोधित संस्करण पोस्ट करना।
व्लादिस्लाव रास्ट्रुसनी

@Vladislav Rastrusny वास्तव में? इससे मेरा काम बनता है। हो सकता है कि आपके पास केवल-पढ़ने के लिए या कुछ और के साथ एक फ़ोल्डर था।
XzaR

4

यहां अधिक उदाहरणों के साथ एक और धागा है: PHP के लिए एक पुनरावर्ती निकालें निर्देशिका फ़ंक्शन?

यदि आप Yii का उपयोग कर रहे हैं तो आप इसे ढांचे पर छोड़ सकते हैं:

CFileHelper::removeDirectory($my_directory);

1

'सरल' कोड जो काम करता है और दस साल पुराने द्वारा पढ़ा जा सकता है:

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);
    }
}

कृपया ध्यान दें कि मैंने जो कुछ भी किया था उसका विस्तार / सरलीकरण और निर्धारण (गैर खाली डीआईआर के लिए काम नहीं किया गया) यहां समाधान: पीएचपी में मैं कैसे उन सभी फ़ोल्डरों को पुन: हटा सकता हूं जो खाली नहीं हैं?


1

बढ़ाया @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); 
    } 
  }

1

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);
    }
  }

0

कुछ इस तरह?

function delete_folder($folder) {
    $glob = glob($folder);
    foreach ($glob as $g) {
        if (!is_dir($g)) {
            unlink($g);
        } else {
            delete_folder("$g/*");
            rmdir($g);
        }
    }
}

मैं समझा नहीं सकता कि मेरे लिए काम क्यों नहीं किया। यह एक फ़ोल्डर को हटाने की कोशिश करता रहा जो खाली नहीं था। ऊपर दिए गए दूसरे उत्तर ने ठीक काम किया।
laurent

1
@ Buggy3 आप किस विशिष्ट कोड का उल्लेख कर रहे हैं? लिंक केवल इस प्रश्न पृष्ठ से लिंक करता है।
cgogolin

0

ग्लोब () फ़ंक्शन के साथ उदाहरण । यह डॉट्स के साथ शुरू होने वाली फ़ाइलों सहित सभी फ़ाइलों और फ़ोल्डरों को पुन: हटा देगा।

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')
Itay Moav -Malimovka

0

अनलिंक फ़ंक्शन फ़ंक्शन को दिए गए पथ के सभी फ़ोल्डरों और फ़ाइलों को पुन: हटा देता है, यह सुनिश्चित करके कि यह स्क्रिप्ट को स्वयं नहीं हटाता है।

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");

यह घर / उपयोगकर्ता / अस्थायी निर्देशिका में सभी फ़ाइलों को हटा देगा।


0

मैं इस कोड का उपयोग करता हूं ...

 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); 
  } 
?>

क्या यह पुनरावर्ती है?
मार्टिन टूरनोइज

0

एक बार जब आप रनिंग टेस्ट समाप्त कर लेते हैं , तो कक्षा में #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);

?>

0
<?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');

?>

0

ऐसा लगता है कि अन्य सभी उत्तर मान लेते हैं कि फ़ंक्शन को दिया गया मार्ग हमेशा एक निर्देशिका है। यह संस्करण निर्देशिकाओं के साथ-साथ एकल फ़ाइलों को हटाने का काम करता है:

/**
 * 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);
    }
}

0

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);
}

-1

मैंने कुछ स्टैकऑवरफ्लो चर्चाओं से यह कोड बनाया है। मैंने अभी तक लिनक्स वातावरण पर परीक्षण नहीं किया। यह पूरी तरह से एक फ़ाइल या निर्देशिका को हटाने के लिए बनाया गया है:

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'));

-1
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 );

}

-1

@ 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'");
        }
    }
}

-1
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);
     }
}

1
यदि आप एक पुराने प्रश्न का उत्तर दे रहे हैं जिसमें पहले से ही एक स्वीकृत सहित कई उत्तर हैं, तो आपको केवल कोड ही नहीं, बल्कि आपका उत्तर क्या मूल्य जोड़ता है, इसका स्पष्टीकरण पोस्ट करने की आवश्यकता है। कोड-केवल उत्तर सामान्य रूप से, लेकिन विशेष रूप से इस मामले में डूबे हुए हैं।
जेरेड स्मिथ

मैंने इस उत्तर के लिए मतदान किया और उत्तर स्वीकार किया। यह मेरा बेंचमार्क की जांच से (बिना बुरा नहीं है, unlink, rmdir) opendir+ readdirकाम तेजी से कि scandirऔर RecursiveDirectoryIteratorयह भी सभी की तुलना में कम स्मृति का उपयोग कर रहा है। मुझे closedirपहले फ़ोल्डर को हटाने के लिए , मैं इस पर अटक गया था। इस उत्तर के लिए धन्यवाद।
वी
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.