क्या आप के लिए भी पुनरावर्ती निर्देशिका traversing कहा जाता है देख रहे हैं। जिसका अर्थ है, आप सभी निर्देशिकाओं और सूची उपनिर्देशिकाओं और फ़ाइलों में से जा रहे हैं। यदि कोई उपनिर्देशिका है तो यह भी आगे बढ़ती है और इतनी आगे और आगे भी - तो यह पुनरावर्ती है।
जैसा कि आप कल्पना कर सकते हैं कि यह एक सामान्य बात है जब आपको सॉफ़्टवेयर लिखते हैं और PHP आपको इसका समर्थन करता है। यह एक RecursiveDirectoryIterator
प्रदान करता है ताकि निर्देशिका को फिर से घुमाया जा सके और ट्रैवर्सल करने के लिए मानक RecursiveIteratorIterator
किया जा सके। फिर आप आसानी से सभी फ़ाइलों और निर्देशिकाओं एक सरल यात्रा के साथ, उदाहरण के लिए foreach
के माध्यम से पहुँच सकते हैं:
$rootpath = '.';
$fileinfos = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($rootpath)
);
foreach($fileinfos as $pathname => $fileinfo) {
if (!$fileinfo->isFile()) continue;
var_dump($pathname);
}
सब से पहले यह उदाहरण निर्देशिका आप को पार करना चाहते हैं निर्दिष्ट करता है।मैं वर्तमान में ले जाने दिया गया है:
$rootpath = '.';
कोड की अगली पंक्ति में थोड़ा लंबा है, उसे the directory iterator का दृष्टांत है और फिर the iterator-iterator पेड़ की तरह संरचना एक एकल/फ्लैट पाश में चल जा सकता है ताकि :
$fileinfos = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator($rootpath)
);
ये $fileinfos
तो एक सरल foreach
साथ दोहराया जाता है:
foreach($fileinfos as $pathname => $fileinfo) {
अंदर इसके बारे में, सभी निर्देशिकाओं को आउटपुट होने से छोड़ने का एक परीक्षण है। यह SplFileInfo
ऑब्जेक्ट का उपयोग करके किया जाता है जिसे पुन: चालू किया जाता है। यह रिकर्सिव डायरेक्टरी इटरेटर द्वारा प्रदान किया जाता है और फ़ाइलों के साथ काम करते समय बहुत उपयोगी गुण और विधियां होती हैं। उदाहरण के लिए आप फ़ाइल एक्सटेंशन, आकार और समय के बारे में बेसनाम जानकारी और इतने पर और आगे भी लौट सकते हैं।
if (!$fileinfo->isFile()) continue;
अंत में मैं सिर्फ उत्पादन पथ नाम फ़ाइल का पूर्ण पथ है:
var_dump($pathname);
एक अनुकरणीय निर्गम (एक विंडोज़ ऑपरेटिंग सिस्टम पर यहाँ) इस प्रकार दिखाई देगा:
string(12) ".\.buildpath"
string(11) ".\.htaccess"
string(33) ".\dom\xml-attacks\attacks-xml.php"
string(38) ".\dom\xml-attacks\billion-laughs-2.xml"
string(36) ".\dom\xml-attacks\billion-laughs.xml"
string(40) ".\dom\xml-attacks\quadratic-blowup-2.xml"
string(40) ".\dom\xml-attacks\quadratic-blowup-3.xml"
string(38) ".\dom\xml-attacks\quadratic-blowup.xml"
string(22) ".\dom\xmltree-dump.php"
string(25) ".\dom\xpath-list-tags.php"
string(22) ".\dom\xpath-search.php"
string(27) ".\dom\xpath-text-search.php"
string(29) ".\encrypt-decrypt\decrypt.php"
string(29) ".\encrypt-decrypt\encrypt.php"
string(26) ".\encrypt-decrypt\test.php"
string(13) ".\favicon.ico"
यदि कोई उपनिर्देशिका है जो पहुंच योग्य नहीं है, तो निम्न अपवाद फेंक देगा। जब RecursiveIteratorIterator
instantiating यह व्यवहार कुछ झंडे के साथ नियंत्रित किया जा सकता:
$fileinfos = new RecursiveIteratorIterator(
new RecursiveDirectoryIterator('.'),
RecursiveIteratorIterator::LEAVES_ONLY,
RecursiveIteratorIterator::CATCH_GET_CHILD
);
मुझे आशा है कि इस जानकारीपूर्ण गया था। आप इसे अपने आप में एक श्रेणी में भी लपेट सकते हैं और आप निर्णय लेने के लिए FilterIterator
भी प्रदान कर सकते हैं कि फ़ाइल को सूचीबद्ध किया जाना चाहिए या foreach
लूप से बाहर नहीं होना चाहिए।
RecursiveDirectoryIterator
और RecursiveIteratorIterator
संयोजन की शक्ति इसका लचीलापन से बाहर आता है। ऊपर जो कवर नहीं किया गया था उसे FilterIterator
एस कहा जाता है। मैंने सोचा कि मैं एक और उदाहरण जोड़ता हूं जो उनमें से दो आत्म-लिखित रूपों का उपयोग कर रहा है, जो उन्हें गठबंधन करने के लिए एक-दूसरे में रखा गया है।
- एक को फिल्टर करने की सभी फ़ाइलों और निर्देशिकाओं कि और
- एक बिंदु के साथ शुरू करते हैं (उन यूनिक्स सिस्टम पर छिपी हुई फ़ाइलें माना जाता है ताकि आप बाहर करने के लिए है कि जानकारी नहीं देना चाहिए) एक और एक है कि फ़िल्टर कर रही है है केवल फाइलों की सूची। यही वह चेक है जो पहले फोरैच के अंदर था।
इस उपयोग का उदाहरण देखने में एक और परिवर्तन getSubPathname()
function कि सब-पाथ यात्रा के rootpath से शुरू रिटर्न का उपयोग करना है, इसलिए एक आप देख रहे हैं।
इसके अलावा, मैं स्पष्ट रूप से SKIP_DOTS
flag जो .
और ..
traversing रोकता जोड़ने (वास्तव में तकनीकी रूप से नहीं आवश्यक है क्योंकि फिल्टर उन के साथ-साथ वे निर्देशिका हैं फ़िल्टर कर जाएगा, फिर भी मुझे लगता है कि इसे और अधिक सही है) और UNIX_PATHS
के रूप में पथ के रूप में वापसी
$rootpath = '.';
$fileinfos = new RecursiveIteratorIterator(
new FilesOnlyFilter(
new VisibleOnlyFilter(
new RecursiveDirectoryIterator(
$rootpath,
FilesystemIterator::SKIP_DOTS
| FilesystemIterator::UNIX_PATHS
)
)
),
RecursiveIteratorIterator::LEAVES_ONLY,
RecursiveIteratorIterator::CATCH_GET_CHILD
);
foreach ($fileinfos as $pathname => $fileinfo) {
echo $fileinfos->getSubPathname(), "\n";
}
यह उदाहरण पिछले के समान है: तो रास्तों में से तार अंतर्निहित ऑपरेटिंग सिस्टम सामान्य रूप से एक अच्छा विचार है कौन सा उन मूल्यों को बाद में अपने मामले में के रूप में HTTP के माध्यम से अनुरोध है कि वे अगर की परवाह किए बिना हमेशा यूनिक्स की तरह रास्ते हैं एक यद्यपिकैसेनिर्माण थोड़ा अलग कॉन्फ़िगर किया गया है। विशेष रूप से फिल्टर के बारे में हिस्सा नया है:
new FilesOnlyFilter(
new VisibleOnlyFilter(
new RecursiveDirectoryIterator($rootpath, ...)
)
),
तो निर्देशिका इटरेटर एक फिल्टर में डाल दिया है और फिल्टर ही एक और फिल्टर में डाल दिया है। बाकी नहीं बदला।
कोड इन फिल्टर के लिए बहुत सीधे आगे है, वे accept
समारोह है कि या तो true
या false
जो लेने के लिए या को फ़िल्टर करना है के साथ काम:
class VisibleOnlyFilter extends RecursiveFilterIterator
{
public function accept()
{
$fileName = $this->getInnerIterator()->current()->getFileName();
$firstChar = $fileName[0];
return $firstChar !== '.';
}
}
class FilesOnlyFilter extends RecursiveFilterIterator
{
public function accept()
{
$iterator = $this->getInnerIterator();
// allow traversal
if ($iterator->hasChildren()) {
return true;
}
// filter entries, only allow true files
return $iterator->current()->isFile();
}
}
और वह इसे फिर से है। स्वाभाविक रूप से आप इन फिल्टरों को अन्य मामलों के लिए भी उपयोग कर सकते हैं। जैसे यदि आपके पास एक और प्रकार की निर्देशिका सूची है।
और $rootpath
के साथ एक और अनुकरणीय उत्पादन दूर कटौती:
test.html
test.rss
tests/test-pad-2.php
tests/test-pad-3.php
tests/test-pad-4.php
tests/test-pad-5.php
tests/test-pad-6.php
tests/test-pad.php
TLD/PSL/C/dkim-regdom.c
TLD/PSL/C/dkim-regdom.h
TLD/PSL/C/Makefile
TLD/PSL/C/punycode.pl
TLD/PSL/C/test-dkim-regdom.c
TLD/PSL/C/test-dkim-regdom.sh
TLD/PSL/C/tld-canon.h
TLD/PSL/generateEffectiveTLDs.php
कोई और अधिक .git
या .svn
निर्देशिका ट्रावर्सल या .builtpath
या .project
की तरह फाइलों की सूची।
नोट FilesOnlyFilter
और LEAVES_ONLY
के लिए: फिल्टर स्पष्ट निर्देशिका और लिंक SplFileInfo
वस्तु (only regular files that do exist) के आधार पर के उपयोग से इनकार करते हैं। तो यह फ़ाइल-सिस्टम के आधार पर एक असली फ़िल्टरिंग है।
डिफ़ॉल्ट LEAVES_ONLY
flag (यहां उदाहरणों में भी उपयोग किया जाता है) के कारण RecursiveIteratorIterator
के साथ गैर-निर्देशिका प्रविष्टियों के जहाजों को प्राप्त करने का एक और तरीका। यह ध्वज फ़िल्टर के रूप में काम नहीं करता है और अंतर्निहित पुनरावर्तक के लिए स्वतंत्र है। यह केवल निर्दिष्ट करता है कि पुनरावृत्ति शाखाओं को वापस नहीं करनी चाहिए (यहां निर्देशिका: निर्देशिका निर्देशिकाकर्ता के मामले में निर्देशिका)।
मैं आपके पास फ़ोल्डर संरचना को समझता हूं। अब आप अपना आउटपुट क्या चाहते हैं। अपने प्रश्न में अपना ** वांछित आउटपुट ** अपडेट करें! :) –
आप ऐसा क्यों करना चाहते हैं। मुझे PHP के साथ थोड़ा सा अनुभव है लेकिन मेरी राय में जो आपके खराब सर्वर को मार देगा। कल्पना करें कि 5000 लोग आपकी निर्देशिका संरचना के पठन कर रहे हैं !!! – Tanmay
वैसे मैं ऐसा क्यों करना चाहता हूं क्योंकि मेरे पास Flash as3 में एक स्क्रिप्ट है जो एक समय में एक फ़ाइल डाउनलोड कर सकती है। फ्लैश एक फ़ोल्डर और इसकी सामग्री डाउनलोड नहीं कर सकता है, इसलिए मैं php को फ़ोल्डर्स/उपफोल्डर्स की सभी सामग्री की स्ट्रिंग बनाने और उसे वापस फ्लैश पर भेजना चाहता हूं और यह ऐप में सामग्री को डाउनलोड करना शुरू कर सकता है। :) –