php klasöründeki dosyaların adı. PHP kullanarak dosya ve dizinlerin bir listesini alma. Tek dizin listesi

  • 03.11.2019

Dosyalarla çalışma

Dosyalarla işlem yapma ihtiyacı, programcıdan çok sık ortaya çıkar. Komut dosyalarınız veritabanlarını kullanmıyorsa, dosyalar komut dosyası bilgileri için kabul edilebilir tek depolama alanıdır. Dosyaların komut dosyası yürütme bilgilerinin depoları olarak kullanılması, bunları çok çeşitli durumlarda kullanmanıza olanak tanır. Bir şeyin neredeyse tüm komut dosyaları-sayaçları, dosyalarla çalışma temelinde yazılır. Bir sürü başka örnek vermek de mümkündür, ancak doğrudan kelimelerden eylemlere geçmenin zamanı geldi.

Dosya ile çalışmaya izin verilmesi gerektiğini hemen söylemek istiyorum. Varsayılan olarak PHP, güvenlik nedenleriyle dosyanın değiştirilmesine izin vermez. CuteFTP FTP yöneticisinde bu yasağı kaldırmak için, dosya özelliklerindeki tüm onay kutularını işaretleyin, diğer yöneticilerde benzer bir şey olmalıdır.

dosya var

Bir dosya üzerinde işlem gerçekleştirmeden önce, genellikle belirtilen dosyanın var olduğundan emin olmak gerekir. file_exists işlevinin yaptığı budur. Bu işlev, anladığınız gibi yalnızca iki değer döndürebilir, DOĞRU(belirtilen dosya varsa) ve YANLIŞ. Bu işlevin olağan kullanımı şöyle görünür:

İşlevin yalnızca yerel dosyalarda çalıştığını unutmayın, yani Yandex'de bir robot.txt dosyası olup olmadığını kontrol etmek istiyorsanız, çabalarınız boşuna olacaktır. Ancak diğer yandan, bulunduğu dizinden bağımsız olarak yerel sunucuda bulunan herhangi bir dosyayı kontrol etmek mümkündür.

Bir dosyanın yolunu tanımlamak için bazı kurallar.

Dosya boyutu

Adından da anlaşılacağı gibi, işlev dosyanın boyutunu belirler ve onu bayt olarak döndürür. Dosyayı içinde bilgi olup olmadığını kontrol etmek istiyorsanız yararlıdır (anladığınız gibi, boş bir dosya 0 bayt içerir) ve ayrıca dosya boyutunu belirli bir sınırı aşıp aşmadığını kontrol etmek de mümkündür.

dosya

Bu işlev zaten doğrudan dosyayla çalışır. Belirtilen dosyanın içeriğini döndürür ve bunu her öğenin bir dosya satırı olduğu bir dizi olarak yapar. İşlev, çakışmaması gereken birkaç farklı değeri tek bir dosyada saklamak gerektiğinde kullanışlıdır. Daha sonra her değer ayrı bir satırda saklanır ve bir dizi döndüren dosya işlevi tarafından okunur, bunun sonucunda verilen değişkene, dosyadaki satıra karşılık gelen bir dizine sahip dizi öğesinin değeri okunarak erişilir.

Döndürülen dizinin tüm öğelerini tek bir değişkende yeniden birleştirmek de mümkündür. Bu, implode dizi işlevi kullanılarak yapılır.

fopen

Önceki işlev bağımsız ve genellikle diğer işlevlerle ilgisiz olsa da, sonraki dosya işlevleri fopen ile birlikte çalışır. Bu işlev belirtilen dosyayı açar ve hizmet amacıyla kullanılan dosya için bir bağlantı tanımlayıcısı döndürür. Bu işlevin dosyanın içeriğiyle hiçbir ilgisi yoktur.

fopen işlevinin birkaç dosya işleme modu vardır. Dosya adından sonra belirtilirler ve aşağıdaki tanımlamalardır:

    "r"
    Dosya yalnızca içeriğini okumak için açılır.

    "r+"
    Hem okuma hem de yazma için bir dosya açma.

    "w"
    Dosya yazmak amacıyla açılır.

    "w+"
    Dosyayı okumak ve yazmak için açın.

    "a"
    Dosya sonuna yazılmak üzere açılır (eklenir).

    "bir+"
    Yazmak ve okumak için açıldı.

fget'lar

fopen işlevi tarafından açılan bir dosyayı okumak için bir işlev. Ancak file işlevinden farklı olarak, bu işlev her yürütüldüğünde dosyanın yalnızca bir satırını döndürür ve dahili dosya işaretçisini, işlev bir sonraki çağrıldığında okuyacağı bir sonraki satıra taşır. Bu nedenle, dosyanın tamamını okumanız gerekiyorsa, bu işlevi bir döngü içinde kullanmalısınız.

fgets işlevinin, okunacak dosya satırının maksimum uzunluğunu belirten uzunluk adlı ek bir parametre kullandığını unutmayın. Dizenin uzunluğu bu sayıyı aşarsa, işlev onu "kesilmiş" bir biçimde bayt uzunluğunda döndürür. Varsayılan olarak, bu parametre 1024 bayta veya bir kilobayta ayarlanmıştır. Büyük dosyalar kullanıyorsanız bu parametreye özellikle dikkat edin, çünkü bu tür dosyaları okurken PHP yürütme arabelleği (boyutu konfigürasyon dosyasında belirtilir) taşabilir ve bu da askıda kalmaya neden olabilir.

Okunacak bir dosya belirlerken, dosya adını değil, fopen işlevi tarafından döndürülen dosya bağlantı tanımlayıcısını belirtmeniz gerektiğini unutmayın (örneğimizde bu, $file değişkeninin değeridir).

fput'lar

Bir dosyaya bilgi yazma işlevi ve bunu fgets işlevinin ilkesine göre yapar, yani dahili dosya işaretçisinin konumundan yazmaya başlar. Genel olarak, bu işlev yukarıdakine çok benzer: ayrıca isteğe bağlı olan yazılacak verilerin uzunluğunu da kullanır.

fclose

Tahmin ettiğiniz gibi bu fonksiyon belirtilen dosyayı kapatır. Aslında, komut dosyası bittiğinde, PHP tarafından açılan tüm dosyaları kendisi kapatır, ancak bunu manuel olarak yapmak yine de daha iyidir. Bir fonksiyon parametresi olarak, dosyaya olan bağlantının tanımlayıcısını belirtmelisiniz.

Yukarıdaki işlevlerin kombinasyonunu göstermek için basit bir vuruş sayacı oluşturmaya bir örnek vereceğiz.

$dosya = fopen("sayaç.txt", "r");
$c = fgets($dosya, 150);
fclose($dosya);
$c++;
$dosya = fopen("sayaç.txt", "w");
fputs($dosya, $c);
fclose($dosya);
yankı $c;
?>

Dizinlerle çalışma

Dosyalar üzerindeki işlemlerle yakından ilişkili olan dizinler üzerindeki işlemlerdir. Onlarla çalışmak için algoritma, dosyalar üzerindeki işlemlere benzer: önce dizini açmanız, bazı eylemler gerçekleştirmeniz ve son olarak onu kapatmanız gerekir.

opendir

Bu işlev belirtilen dizini açar ve bağlantının hizmet kimliğini dizine döndürür. Dizin yolları aşağıdaki gibi belirtilmelidir:

Nokta, geçerli dizini aç anlamına gelir

. /Dosyalar/

klasör açma Dosyalar, geçerli dizinde bulunur

Mevcut olandan bir seviye daha yüksek bir klasör açma

okumak

İşlev, opendir tarafından açılan dizini okur. Her geçiş için, belirtilen dizindeki dosya veya klasörün adını döndürür ve dahili işaretçiyi bir sonraki dizin nesnesine ilerletir. Bu yüzden tüm dizini okumak için bir döngü içinde kullanılmalıdır.

Ayrıca, bu işlevin, klasörün hizmet nesnelerini döndürdüğüne de dikkat edilmelidir. . Ve .. , IF deyimi tarafından çıktı alındığında kesilebilir.

yakın

Bağlantı tanımlayıcısını klasörle argüman olarak belirterek dizini kapatıyoruz.

Bazen dizin işlevlerini kullanmak hayatı çok daha kolaylaştırır. Örneğin Fonksiyonlar bölümünde alfabetik sıraya göre fonksiyon listesini görebilirsiniz. Bu listenin tamamını bağlantılarla ve hatta alfabetik sıraya göre manuel olarak yazmanın ne kadar zaman alacağını hayal edin. Ve tam burada dizinle çalışmanın işlevleri bana yardımcı oldu. Her işlev, herhangi bir uzantı olmaksızın, işlevin adına karşılık gelen bir adla ayrı bir dosyaya yerleştirildi.

Böylece sayfayı her ziyaret ettiğinizde, yeni oluşturulmuş bir özellik listesi alırsınız.

Bu kadar. Bir sonraki derste görüşürüz.

Bu derste, bir PHP projesi üzerinde çalışırken ortaya çıkan tipik bir görevle ilgileneceğiz: dosya ve dizinlerin bir listesini almak. Her birinin artılarını ve eksilerini listeleyen birkaç temel ve daha karmaşık yaklaşımı tartışacağız. İlk üç çözüm, genel PHP işlevlerini kullanacak ve ardından SPL yineleyicileri kullanarak daha sağlam bir çözüm sunacağız.

Çözümün ve gösterimlerin kapsamlı bir tartışması için, dizin yapısının aşağıdaki gibi olduğunu varsayalım:

\---yönetici | \---kullanıcı | \---belge.txt | \---veri.dat | \---style.css |---article.txt |---master.dat |---script.php |---test.dat |---text.txt

Temel Çözümler

İlk çözüm grubu, opendir() , readdir() ve closedir() işlevlerinin bir kombinasyonu olan glob() işlevinin ve ayrıca scandir() işlevinin kullanılmasına dayanır.

glob() kullanma

İlk çözüm, kalıpları kullanarak yol aramaları yapmanızı sağlayan glob() işlevini kullanmaya dayanmaktadır. Fonksiyonun iki parametresi vardır:

  • $pattern (gerekli): arama modeli
  • $flags (isteğe bağlı): açıklaması belgelerde bulunabilecek bir veya daha fazla bayrak

Örnekleri düşünün. Adları ile biten tüm dosya ve dizinleri bir dizinde aramak için .Txt, şu kodu kullanmalısınız:

$filelist değişkenini çıkarırsak, şunu elde ederiz:

Array(0 => "makale.txt", 1 => "metin.txt")

Adları “te” ile başlayan dosya ve dizinlerin bir listesine ihtiyacınız varsa, kod şöyle görünecektir:

Ve çıktı şöyle görünür:

Array(0 => "test.dat", 1 => "text.txt")

Yalnızca "ma" içeren adlara sahip dizinlerin bir listesini almak için şu kodu kullanın:

Son örnek çıktı verecektir:

Dizi(0 => "yönetici")

Son örneğin, işlevin ikinci parametresi olarak GLOB_ONLYDIR bayrağını kullandığını unutmayın. Bu nedenle, master.dat dosyası listeden çıkarılır. glob() işlevinin kullanımı çok kolay olsa da bazen yeterince esnek değildir. Örneğin, yalnızca bir kalıpla eşleşen dosyaları (dizin yok) almak için bir bayrak yoktur.

opendir() , readdir() ve closedir() kullanıyoruz.

Dosyaları ve dizinleri listelemeye ilişkin tartışacağımız ikinci yaklaşım, opendir() , readdir() ve closedir() işlevlerini kullanmaktır.

opendir() işlevi bir dizini açar ve bağlantıya bir tanıtıcı döndürür. Tutamaç elde edildikten sonra readdir() işlevi kullanılabilir. Her çağrı ile bu işlev, açık dizindeki bir sonraki dosyanın veya dizinin adını döndürür. Tüm adlar zaten listelenmişse, işlev şunu döndürür: YANLIŞ. Tutamacı kapatmak için closedir() işlevi kullanılır.

glob() işlevini kullanmanın aksine, bu yaklaşım daha karmaşıktır çünkü döndürülen dosya adları ve dizinlerin listesini filtrelemeye yardımcı olacak seçenekleriniz yoktur. İstenilen sonucu elde etmek için filtrelemeyi kendiniz gerçekleştirmelisiniz.

Aşağıdaki örnek, "te" ile başlayan dosya adları ve dizinlerin bir listesini döndürür:

Yukarıdaki kodu çalıştırırken, $entry değişkeni “.” gibi inklüzyonlar içerecektir. Ve "..". Bunlar, her dosya sistemi dizininde bulunan iki sanal dizindir. Sırasıyla geçerli dizini ve ana dizini temsil ederler.

İkinci örnek, yalnızca verilen dizinde bulunan dosyaları verir.

Örnek aşağıdaki çıktıyı verecektir:

Dizi (0 => "makale.txt", 1 => "master.dat", 2 => "script.php", 3 => "test.dat", 4 => "text.txt")

scandir() kullanma

Son olarak scandir() fonksiyonunu tanıtalım. Yalnızca bir gerekli parametresi vardır: okuma yolu. İşlev, belirtilen yolda bulunan bir dizi dosya ve dizin döndürür. Belirli bir kritere göre dosya ve dizinlerin bir listesini almak için ek filtreleme yapmanız gerekir. Öte yandan, çözüm daha özlüdür ve tanımlayıcı yönetimi gerektirmez.

Bu örnek, adları "te" ile başlayan dosya ve dizinlerin bir listesinin nasıl alınacağını gösterir:

SPL yineleyicilerini kullanalım

Şimdi SPL yineleyicileri kullanmayı düşünün. Ancak problemimizi çözmeye başlamadan önce, SPL kitaplığına ve yineleyicilere bir giriş yapalım. SPL kitaplığı, nesne yönelimli veri yapıları, yineleyiciler, dosya tanımlayıcıları ve daha fazlası için bir dizi sınıf sağlar.

Yineleyicilerin bir avantajı, sınıf olmaları ve kendi ihtiyaçlarınıza göre genişletilebilmeleridir. Diğer bir avantaj, yineleyicilerin birçok ortak görev için yararlı olan ve tek bir yerde bulunan kendi yöntemlerine sahip olmasıdır. FilesystemIterator'a karşı readdir() kullanımına ilişkin bir örneğe bakın. Her iki yöntem de bir döngü kullanır, ancak readdir() durumunda yalnızca bir dize işlersiniz, FilesystemIterator ise dosya veya dizin hakkında ek bilgiler (boyut, sahip, izinler vb.) içerebilen bir nesneyle çalışır.

Elbette PHP, bu bilgileri dosya boyutu() ve dosya sahibi() gibi işlevleri kullanarak elde etme yeteneği sağlar. Ancak PHP5, OOP konseptini kullanmaya dayanmaktadır. Bu nedenle, bir programlama diliyle çalışmanın modern yöntemlerini kullanmak daha iyidir. Sitemizde yineleyicilerle çalışma dersleri var.

Eğitimin su bölümünde tartışıldığı gibi, FilesystemIterator , RecursiveDirectoryIterator ve GlobIterator kullanımına bakacağız. İlki DirectoryIterator öğesinden ve geri kalanı FilesystemIterator öğesinden devralır. Hepsi iki parametre alan aynı kurucuya sahiptir:

  • $path (gerekli): üzerinde işlem yapılacak dosya sistemi noktasının yolu
  • $flags (isteğe bağlı): belgelerde listelenen bir veya daha fazla bayrak

Bu yineleyicilerdeki gerçek fark, belirli bir yolda gezinmek için nasıl kullanıldıklarıdır.

Dosya SistemiYineleyici

FilesystemIterator'ı kullanmak çok basittir. Eylemde görelim. İki örnek sunuyoruz. İlki, adları "te" ile başlayan tüm dosya ve dizinlerin arandığını gösterir. İkinci örnek, adları "t.dat" veya "t.php" ile biten tüm dosya ve dizinleri bulmak için başka bir RegexIterator kullanır. RegexIterator, sonucu normal ifadelere göre filtrelemek için kullanılır.

getFilename(), "te") === 0) ( $filelist = $entry->getFilename(); ) )

Yukarıdaki kod, önceki örneklere benzer bir sonuç üretecektir.

RegexIterator kullanan ikinci örnek:

getFilename(); )

Çıktı alacak:

Array(0 => "script.php", 1 => "test.dat")

Özyinelemeli DizinYineleyici

RecursiveDirectoryIterator, dosya sistemi dizinleri arasında yinelemeli olarak yineleme yapmak için bir arabirim sağlar. GetChildren() ve hasChildren() gibi, bir dizinse geçerli konum için bir yineleyici döndüren ve geçerli giriş noktasının bir dizin olup olmadığını kontrol eden birkaç yararlı yöntemi vardır. Aşağıdaki örnek, RecursiveDirectoryIterator ve getChildren() kullanımını gösterir. Sonuç, önceki örneklerdekiyle aynı olacaktır.

getChildren(), "/t\.(php|dat)$/"); $dosya listesi = dizi(); foreach($filter as $giriş) ( $filelist = $entry->getFilename(); )

Globİteratör

GlobIterator, dosya sisteminde glob() işleviyle aynı şekilde gezinir. İlk parametre, ad için bir joker karakter içerebilir. Örnek, GlobIterator'ın kullanımını öncekiyle aynı sonuçla gösterir.

getFilename(); )

Çözüm

Bu ders, aynı amaca ulaşmak için farklı yaklaşımların kullanımını gösterir: dosya ve dizinlerin bir listesini almak. Aşağıdaki kilit noktalar hatırlanmalıdır:

  • glob() işlevi yerleşik bir çözümdür, ancak yeterince esnek değildir.
  • opendir() , readdir() ve closedir() temelli çözüm daha karmaşıktır ve ek filtreleme gerektirir, ancak daha esnektir.
  • scandir() işlevi ek filtreleme gerektirir, ancak tanımlayıcıyı kullanmadan çalışır.
  • Bir OOP yaklaşımı kullanıyorsanız, SPL kitaplığını kullanmalısınız. Ek olarak, sınıfları kendi işlevselliğinizle genişletebilirsiniz.
  • GlobIterator'ın bir ön filtreleme özelliği vardır ve diğerleri bir RegexIterator kullanır.

Reg.ru: etki alanları ve barındırma

Rusya'daki en büyük kayıt şirketi ve barındırma sağlayıcısı.

2 milyondan fazla alan adı hizmette.

Promosyon, etki alanı için posta, iş için çözümler.

Dünya çapında 700 binden fazla müşteri şimdiden seçimini yaptı.

*Kaydırmayı duraklatmak için fareyle üzerine gelin.

İleri geri

PHP ile klasörlerin bir listesini alma

PHP kullanarak dizinleri listeleme veya dizinleri listeleme

Bir üst dizindeki dosyaların ve dizinlerin tümünü veya bir kısmını listeleyen genel bir sorgu olarak bir dizin listesine atıfta bulunacağız - çoğu web sunucusu tarafından sağlanan dizin sayfasına benzer bir işlem, ancak hakkında içerik ve biçimlendirme üzerinde daha fazla kontrol.

Bu betiğin bir başka avantajı, PHP kullanarak dosyalar üzerinde belirli eylemleri gerçekleştirme yeteneğidir. Her durumda, atmamız gereken ilk adım, dosya ve dizinlerin bir listesini döndürmek için dosya sistemini sorgulamaktır.

Aşağıdaki işlevler, belirli bir dizinden dosya adlarını ve diğer özellikleri almanıza veya alt kategoriler arasında yinelemeli olarak yinelemenize olanak tanır.

Yorum: PHP5'in bir işlevi var tarama"verilen yoldaki bir dizindeki dosya ve dizinlerin bir listesini döndürür", ancak dizin içindeki dosyalar hakkında herhangi bir ek bilgi görüntülemez.

Tek dizin listesi

Başlamak için, bir dizinden dosyaların, dizinlerin ve özelliklerinin bir listesini döndüren basit bir işleve bir örnek (bu işlevin daha gelişmiş sürümlerini bu derste biraz sonra bulacaksınız).

read())) ( // gizli dosyaları atla if($entry == ".") devamı; if(is_dir("$dir$entry")) ( $retval = array("name" => "$dir$ input/", "size" => 0, "lastmod" => filemtime("$dir$entry")); ) elseif(is_readable("$dir$entry")) ( $retval = array("name" = > "$dir$entry", "size" => dosya boyutu("$dir$entry"), "lastmod" => filemtime("$dir$entry")); ) ) $d->close(); dönüş $retval; ) ?>

Bu işlevi aşağıdaki gibi kullanabilirsiniz:

Dönüş değeri, dosya bir dizin değilse, dosya yolu bilgisi, boyut ve son değişiklik tarihi de dahil olmak üzere ilişkilendirilebilir bir dosya dizisidir; bu durumda dosyanın boyutu yerine "(dir)" dizesi gelir.

Örnek 1:

",print_r($dizin listesi),""; /* örnek çıktı Dizi ( => Dizi ( => images/background0.jpg => image/jpeg => 86920 => 1077461701) => ...) */ ?>

Örnek 2:

",print_r($dizin listesi),""; /* örnek çıktı Dizi ( => Dizi ( => ./images/background0.jpg => image/jpeg => 86920 => 1077461701) => ...) */ ?>

Dosyaları HTML ile listeleme

Sayfadaki çıktı sonuçlarını HTML'de almak için, döndürülen diziyi bir döngü aracılığıyla döngüye alırız.

\n"; yankı " İsimtipboyutSon mod.\n"; foreach($dirlist as $dosya) ( echo " \n"; yankı " ($dosya["ad"])\n"; yankı " ($dosya["tür"])\n"; yankı " ($dosya["boyut"])\n"; yankı " \n"; yankı "\n"; ) yankı "\n\n"; ?>

Bu kodun değiştirilmesi oldukça kolaydır, örneğin:

  • - listeleme sonuçlarını bir tablo yerine bir listede görüntüleme;
  • - dosya adlarını aktif bağlantılar yapın;
  • - dosyanın türüne göre isimleri simgelerle değiştirin;
  • vb.

Örneğin, yalnızca PNG dosyalarının çıktısını almak için çıktı döngüsüne basit bir koşul ekleyin:

\n"; yankı " İsimtipboyutSon mod.\n"; foreach($dirlist as $file) ( // dosyanın PNG'ye ait olup olmadığını kontrol edin if(!preg_match("/\.png$/", $file["name"])) devam; echo " \n"; yankı " ($dosya["ad"])\n"; yankı " ($dosya["tür"])\n"; yankı " ($dosya["boyut"])\n"; yankı " ",tarih("r", $dosya["lastmod"]),"\n"; yankı "\n"; ) yankı "\n\n"; ?>

Bu örnek, adları ile biten tüm dosyaları atlayacak ve gizleyecektir. .png. Dosya türüne, boyutuna veya son değiştirilme tarihine göre ek koşullar da uygulayabilirsiniz.

Örneğin, bir küçük resim, daha büyük bir görüntüye bağlantı veya hatta bir video görüntülemek istiyorsanız, bu 2 dosyaya aynı adları verin ve yukarıdaki komut dosyasında kullanın. str_replace veya bağlantıların içeriğini değiştirmek için benzer bir işlev.

Özyinelemeli dizin listesi

Buraya kadar geldiğimize göre, özyinelemeli liste çağrısı işlevinde ve alt kategorilerde yalnızca küçük değişiklikler olacak. İşleve ikinci bir parametre ekleyerek, tek bir dizini listelemenin önceki işlevselliğini koruyoruz.

read())) ( // gizli dosyaları atla if($entry == ".") devamı; if(is_dir("$dir$entry")) ( $retval = array("name" => "$dir$ input/", "size" => 0, "lastmod" => filemtime("$dir$entry")); if($recurse && is_readable("$dir$entry/")) ( $retval = array_merge($ retval, getFileList("$dir$entry/", true)); ) elseif(is_readable("$dir$entry")) ( $retval = array("name" => "$dir$entry", "size" " => dosya boyutu("$dir$entry"), "lastmod" => filemtime("$dir$entry")); ) ) $d->close(); dönüş $retval; ) ?>

Yeni işlevin çalışması için bir değer girmeniz gerekir doğru(veya 1) ikinci parametre olarak.

Komut dosyasını tekrarlamadan önce, alt dizinlerin okunabilir olup olmadığını kontrol edin ve erişim hatalarından kaçınmak için bu dersin son paragrafını da okuyun.

Daha önce olduğu gibi, dönüş değeri dizilerle ilişkilendirilen bir dizidir. Aslında, tek ekleme, özyinelemeli listeleme için başka bir ekstra seçenektir.

Özyineleme Derinlik Sınırı

Bu son örnek, başka bir özellik ekler - özyinelemenin ne kadar "derine" gitmesi gerektiğini belirleme yeteneği. Önceki kod, bitene kadar iç içe dizinleri keşfetmeye devam edecektir. Bu komut dosyası, iç içe geçmiş dizinlerin düzeylerinin sayısı üzerindeki sınırı belirlemeye yardımcı olacaktır.

read())) ( // gizli dosyaları atla if($entry == ".") devamı; if(is_dir("$dir$entry")) ( $retval = array("name" => "$dir$ input/", "size" => 0, "lastmod" => filemtime("$dir$entry")); if($recurse && is_readable("$dir$entry/")) ( if($depth == = false) ( $retval = array_merge($retval, getFileList("$dir$entry/", true)); ) elseif($depth > 0) ( $retval = array_merge($retval, getFileList("$dir$entry) /", true, $depth-1)); ) ) elseif(is_readable("$dir$entry")) ( $retval = array("name" => "$dir$entry", "size" => dosya boyutu("$dir$entry"), "lastmod" => filemtime("$dir$entry")); ) ) $d->close(); dönüş $retval; ) ?>

Daha önce olduğu gibi, sadece 1 yeni parametre ve birkaç satır kod ekledik. Özyineleme derinliği için varsayılan değer ayarlanmadıysa, YANLIŞ. Bu, önceki özelliklerin kaldığından ve işlev değiştirildiğinde sonraki kodun "bozulmayacağından" emin olmamızı sağlar.

Dizin listeleme, belirli bir üst dizin için dizinler ve dosyalar hakkında bilgi almanın yanı sıra çıktıyı düzeltmek için bu verilere çeşitli filtreler uygulama yeteneğidir.

Bu örnekte, hemen hemen her görevde görünen tipik bir görevle başa çıkmaya çalışacağız. PHP proje - dizinlerin ve (veya) dosyaların bir listesini almak. Örnek, her tekniğin artıları ve eksileri özetlenen birkaç temel ve daha karmaşık yaklaşımı kullanır. İlk üç çözüm, genel PHP işlevlerini kullanır. PHP SPL yineleyicilerini kullanan son daha sağlam çözüm.


Daha görsel bir temsil için aşağıdaki forma sahip dizin yapısını kullanıyoruz:


\-Uygulama | \-Kullanıcı | \veri.apk | \stil.css | \-test.txt |-readme.txt |-script.php |-serial.txt |-test.html |-test.js

Temel Çözümler
İlk örnek grubu işlevleri kullanır küre() ve fonksiyon kombinasyonları açıkdır(), oku(), kapatdir() işlevinin yanı sıra taramadır().

glob() kullanma

Bir php işlevi kullanma örneği küre(), bir kalıba göre bir yol aramanıza izin verir.
İşlev küre( $ desen,$bayraklar) iki argümanla çalışır:
  • $ desen(gerekli): arama kalıbı dizesi
  • $bayraklar
    • GLOB_MARK- Döndürülen her dizine bir eğik çizgi ekler.
    • GLOB_NOSORT- Dosyaları dizinde oldukları gibi döndürür (sıralama olmadan). Bu bayrak belirtilmezse, adlar alfabetik olarak sıralanır.
    • GLOB_NOCHECK- Kullanan hiçbir dosya bulunamadıysa arama düzenini döndürür.
    • GLOB_NOESCAPE- Ters eğik çizgiler meta karakterlerden kaçmaz.
    • GLOB_BRACE- (a,b,c)'yi "a", "b" veya "c" ile eşleşecek şekilde genişletir.
    • GLOB_ONLYDIR- Yalnızca kalıpla eşleşen dizinleri döndürür.
    • GLOB_ERR- Okuma hatalarında durur (örneğin, okuma izni olmayan dizinler), hatalar varsayılan olarak yok sayılır.
Adları .txt ile biten tüm dosya ve dizinleri bir dizinde aramak için aşağıdaki kodu kullanın:Çıktıda şu sonucu elde ederiz: array(2) ( => string(10) "readme.txt" => string(10) "serial.txt" ) isimler "te" ile başlar:Çıktıda şu sonucu elde ederiz: array(2) ( => string(9) "test.html" => string(7) "test.js" ) Listeye sadece isimleri "er" içeren dizinleri almak :Çıktıda şu sonucu elde ederiz: array(1) ( => string(4) "User" )

Son örnek bayrağı kullanır GLOB_ONLYDIR işlevin ikinci argümanı olarak. Bu nedenle, sadece "er" içeren adındaki "Kullanıcı" dizini listeye dahil edildi. glob() işlevinin kullanımı çok kolaydır, ancak bazen yeterince esnek değildir. Yalnızca kalıpla eşleşen dosyaları (dizin yok) almak için bir bayrak yoktur.

opendir(), readdir() ve closedir() kullanarak.

Dosya ve dizinlerin listesini almanın bir sonraki yöntemi PHP işlevlerini kullanmaktır. açıkdır(), oku() Ve kapatdir().

İşlev açıkdır() açık dizine bir tanıtıcı döndürür. Tutamaç alındıktan sonra işlevi kullanabilirsiniz. oku(). Tanımlayıcıya erişirken, işlev oku() sonraki dosyanın veya dizinin adını döndürür. Tanımlayıcıda bulunan tüm öğeler zaten listelenmişse, işlev oku() geri dönücek YANLIŞ. Kolu kapatmak için işlevi kullanın kapatdir().


php işlevini kullanmanın aksine , bu yaklaşım biraz daha karmaşıktır. Döndürülen dosya ve dizin adlarının listesini önceden oluşturmaya yardımcı olan filtreleme parametreleri ayarlamak mümkün değildir. Gerekli dosya ve dizin listesini elde etmek için filtrelemeyi kendiniz yapmanız gerekir.


Yukarıdaki örnek, "Biz" ile başlayan dosya adlarının ve dizinlerin bir listesini döndürür:Çıktı şöyle görünecektir: array(1) ( => string(4) "Kullanıcı" ) Aşağıdaki örnek sadece verilen dizinde bulunan dosyaları yazdıracaktır.Çıktı şöyle görünecektir: dizi(5) ( => string(10) "script.php" => string(7) "test.js" => string(9) "test.html" => string(10 ) "serial.txt" => string(10) "benioku.txt")

scandir() kullanarak.

Tamamlamak için, php işlevini kullanma örneğini görelim taramadır(). Tek bir gerekli özniteliği vardır - okunacak dizinin yolu. İşlevin sonucu, argümanda belirtilen yolda bulunan bir dizi dosya ve dizindir. Önceki örnekte olduğu gibi, filtrelenmiş bir dosya ve dizin listesi almak için bunu kendiniz yapmanız gerekir. Görsel olarak çözüm daha kısadır ve tanımlayıcı yönetimi gerekmez.


Örnek, adları "te" ile başlayan dosya ve dizinlerin bir listesinin nasıl alınacağını gösterir:Çıktı şöyle görünecektir: array(2) ( => string(9) "test.html" => string(7) "test.js" )

PHP SPL kullanan gelişmiş çözüm
SPL yineleyicileri kullanan daha sağlam çözüm Dosya SistemiYineleyici, Özyinelemeli DizinYineleyici Ve Globİteratör.

SPL yineleyicilerini kullanma.

SPL yineleyicileri kullanmayı düşünün. Problemi çözmeye başlamadan önce SPL php kütüphanesi ve yineleyiciler ile tanışalım. SPL kitaplığı, nesne yönelimli veri yapıları, yineleyiciler, dosya tanımlayıcıları ve daha fazlası için özel bir sınıf kümesi sağlar.


Yineleyicilerin ana avantajı, sınıf olmaları ve PHP'nin standart sınıf miras mekanizması kullanılarak genişletilebilmeleridir. Diğer bir artı, yineleyicilerin tipik sorunları çözmek için yararlı olabilecek kendi yöntemlerine sahip olmaları ve hepsinin tek bir yerde bulunmasıdır. Bir kullanım örneğine bakalım Dosya SistemiYineleyici ve ile karşılaştırmak oku(). Her iki yöntem de bir döngü kullanır, ancak bu durumda oku() sadece bir satırı işlemek mümkün olacak ve Dosya SistemiYineleyici bir nesne ile çalışabilir. Bu, dosya veya dizin hakkında sahip, boyut, izinler vb. gibi ek bilgiler içerebilir.


Elbette PHP bu bilgiyi fonksiyonları kullanarak elde etme yeteneğine sahiptir, Dosya boyutu(), dosya sahibi() ve diğerleri. Ancak PHP, herhangi bir programlama dili gibi, değiştirilebilecek özelliklere sahiptir. PHP5'te, OOP kavramlarını kullanmak için artan bir istek var. Bu nedenle, bir programlama diliyle çalışmanın modern yöntemlerini kullanmak daha iyidir.


kullanmayı düşünün Dosya SistemiYineleyici, Özyinelemeli DizinYineleyici Ve Globİteratör. İlk yineleyici şuradan miras alınır: DizinYineleyici, ve geri kalanı Dosya SistemiYineleyici. Hepsinin iki argüman alan aynı yapıcısı var:

  • $yol(gerekli): işlemlerin gerçekleştirildiği dosya sistemi noktasının yolu
  • $bayraklar(isteğe bağlı): bir veya daha fazla bayrak
    • FilesystemIterator::CURRENT_AS_PATHNAME FilesystemIterator::current() yönteminin bir yol döndürmesine neden olur.
    • FilesystemIterator::CURRENT_AS_FILEINFO FilesystemIterator::current() yönteminin bir SplFileInfo örneği döndürmesine neden olur.
    • FilesystemIterator::CURRENT_AS_SELF FilesystemIterator::current() yönteminin $this (FilesystemIterator) döndürmesine neden olur.
    • FilesystemIterator::CURRENT_MODE_MASK Maskeler Dosya SistemiIterator::current()
    • FilesystemIterator::KEY_AS_PATHNAME FilesystemIterator::key() yönteminin bir yol döndürmesine neden olur.
    • FilesystemIterator::KEY_AS_FILENAME FilesystemIterator::key() yönteminin dosya adını döndürmesine neden olur.
    • FilesystemIterator::FOLLOW_SYMLINKS RecursiveDirectoryIterator::hasChildren() yönteminin sembolik bağları izlemesine neden olur.
    • FilesystemIterator::KEY_MODE_MASK Maskeler Dosya SistemiIterator::key()
    • FilesystemIterator::NEW_CURRENT_AND_KEY FilesystemIterator ile aynı::KEY_AS_FILENAME | FilesystemIterator::CURRENT_AS_FILEINFO.
    • Dosya sistemiIterator::SKIP_DOTS Nokta dosyalarını (. ve ..) atlar.
    • FilesystemIterator::UNIX_PATHS Tüm yolları, sistem varsayılanlarından bağımsız olarak Unix tarzı ters eğik çizgi kullanmaya zorlar.

Bu yineleyicilerdeki fark, belirli bir yolda gezinmek için nasıl kullanıldıklarıdır.

Dosya SistemiYineleyici

Kullanmak Dosya SistemiYineleyiciÇok basit.
Örnek, adları "te" ile başlayan tüm dosya ve dizinler için bir aramayı gösterir.

getFilename(),"te")===0): $arFileList = $obFile->getFilename(); endif; uç foreach; //Sonucu göster var_dump($arFileList); ?> Çıktıda şu sonucu elde ederiz: array(2) ( => string(7) "test.js" => string(9) "test.html" )

Farklı bir yineleyici kullanma örneği Normal İfade Yineleyici adları "t.js" veya "t.php" ile biten tüm dosya ve dizinleri aramak için. yineleyici Normal İfade Yineleyici sonucu filtrelemek için kullanılır ve normal ifade motorunu kullanır.

getFilename(); uç foreach; //Sonucu göster var_dump($arFileList); ?> Çıktıda şu sonucu elde ederiz: array(2) ( => string(10) "script.php" => string(7) "test.js" )

Özyinelemeli DizinYineleyici

yineleyici Özyinelemeli DizinYineleyici dosya sistemi dizinlerini özyinelemeli olarak geçmek için bir arabirim sağlar. Gibi birkaç yararlı yöntemi vardır. getChildren() Ve Çocuk sahibi(), bu bir dizinse geçerli konum için bir yineleyici döndürür ve geçerli giriş noktasının bir dizin olup olmadığını kontrol eder.


Özyinelemeli DizinYineleyici Ve getChildren(). getChildren(), "/t\.(txt|css)$/"); $arFileList = dizi(); foreach($obFile olarak $rxIterator): $arFileList = $obFile->getFilename(); uç foreach; //Sonucu göster var_dump($arFileList); ?> Çıktıda, bu durumda şu sonucu elde ederiz - bu, "Kullanıcı" dizininden bir dosyadır: dizi(1) ( => string(8) "test.txt" )

Globİteratör

yineleyici Globİteratör işlevine benzer bir dosya içinden geçiş gerçekleştirir. İlk öznitelik bir ad şablonu içerebilir.


Örnek kullanımı gösterir Globİteratöröncekiyle aynı sonuçla.getFilename(); uç foreach; //Sonucu göster var_dump($arFileList); ?> Çıktıda şu sonucu elde ederiz: array(2) ( => string(10) "/test.html" => string(8) "/test.js" )

Çözüm

Yukarıdaki örnekler, aynı amaca ulaşmak için farklı PHP yöntemlerine baktı: dosya ve dizinlerin bir listesini almak.

Örneklerden aşağıdaki önemli noktalar vurgulanabilir:

Bu derste, bir PHP projesi üzerinde çalışırken ortaya çıkan tipik bir görevle ilgileneceğiz: dosya ve dizinlerin bir listesini almak. Her birinin artılarını ve eksilerini listeleyen birkaç temel ve daha karmaşık yaklaşımı tartışacağız. İlk üç çözüm, genel PHP işlevlerini kullanacak ve ardından SPL yineleyicileri kullanarak daha sağlam bir çözüm sunacağız.

Çözümün ve gösterimlerin kapsamlı bir tartışması için, dizin yapısının aşağıdaki gibi olduğunu varsayalım:

\---yönetici | \---kullanıcı | \---belge.txt | \---veri.dat | \---style.css |---article.txt |---master.dat |---script.php |---test.dat |---text.txt

Temel Çözümler

İlk çözüm grubu, opendir() , readdir() ve closedir() işlevlerinin bir kombinasyonu olan glob() işlevinin ve ayrıca scandir() işlevinin kullanılmasına dayanır.

glob() kullanma

İlk çözüm, kalıpları kullanarak yol aramaları yapmanızı sağlayan glob() işlevini kullanmaya dayanmaktadır. Fonksiyonun iki parametresi vardır:

  • $pattern (gerekli): arama modeli
  • $flags (isteğe bağlı): açıklaması belgelerde bulunabilecek bir veya daha fazla bayrak

Örnekleri düşünün. Adları ile biten tüm dosya ve dizinleri bir dizinde aramak için .Txt, şu kodu kullanmalısınız:

$filelist değişkenini çıkarırsak, şunu elde ederiz:

Array(0 => "makale.txt", 1 => "metin.txt")

Adları “te” ile başlayan dosya ve dizinlerin bir listesine ihtiyacınız varsa, kod şöyle görünecektir:

Ve çıktı şöyle görünür:

Array(0 => "test.dat", 1 => "text.txt")

Yalnızca "ma" içeren adlara sahip dizinlerin bir listesini almak için şu kodu kullanın:

Son örnek çıktı verecektir:

Dizi(0 => "yönetici")

Son örneğin, işlevin ikinci parametresi olarak GLOB_ONLYDIR bayrağını kullandığını unutmayın. Bu nedenle, master.dat dosyası listeden çıkarılır. glob() işlevinin kullanımı çok kolay olsa da bazen yeterince esnek değildir. Örneğin, yalnızca bir kalıpla eşleşen dosyaları (dizin yok) almak için bir bayrak yoktur.

opendir() , readdir() ve closedir() kullanıyoruz.

Dosyaları ve dizinleri listelemeye ilişkin tartışacağımız ikinci yaklaşım, opendir() , readdir() ve closedir() işlevlerini kullanmaktır.

opendir() işlevi bir dizini açar ve bağlantıya bir tanıtıcı döndürür. Tutamaç elde edildikten sonra readdir() işlevi kullanılabilir. Her çağrı ile bu işlev, açık dizindeki bir sonraki dosyanın veya dizinin adını döndürür. Tüm adlar zaten listelenmişse, işlev şunu döndürür: YANLIŞ. Tutamacı kapatmak için closedir() işlevi kullanılır.

glob() işlevini kullanmanın aksine, bu yaklaşım daha karmaşıktır çünkü döndürülen dosya adları ve dizinlerin listesini filtrelemeye yardımcı olacak seçenekleriniz yoktur. İstenilen sonucu elde etmek için filtrelemeyi kendiniz gerçekleştirmelisiniz.

Aşağıdaki örnek, "te" ile başlayan dosya adları ve dizinlerin bir listesini döndürür:

Yukarıdaki kodu çalıştırırken, $entry değişkeni “.” gibi inklüzyonlar içerecektir. Ve "..". Bunlar, her dosya sistemi dizininde bulunan iki sanal dizindir. Sırasıyla geçerli dizini ve ana dizini temsil ederler.

İkinci örnek, yalnızca verilen dizinde bulunan dosyaları verir.

Örnek aşağıdaki çıktıyı verecektir:

Dizi (0 => "makale.txt", 1 => "master.dat", 2 => "script.php", 3 => "test.dat", 4 => "text.txt")

scandir() kullanma

Son olarak scandir() fonksiyonunu tanıtalım. Yalnızca bir gerekli parametresi vardır: okuma yolu. İşlev, belirtilen yolda bulunan bir dizi dosya ve dizin döndürür. Belirli bir kritere göre dosya ve dizinlerin bir listesini almak için ek filtreleme yapmanız gerekir. Öte yandan, çözüm daha özlüdür ve tanımlayıcı yönetimi gerektirmez.

Bu örnek, adları "te" ile başlayan dosya ve dizinlerin bir listesinin nasıl alınacağını gösterir:

SPL yineleyicilerini kullanalım

Şimdi SPL yineleyicileri kullanmayı düşünün. Ancak problemimizi çözmeye başlamadan önce, SPL kitaplığına ve yineleyicilere bir giriş yapalım. SPL kitaplığı, nesne yönelimli veri yapıları, yineleyiciler, dosya tanımlayıcıları ve daha fazlası için bir dizi sınıf sağlar.

Yineleyicilerin bir avantajı, sınıf olmaları ve kendi ihtiyaçlarınıza göre genişletilebilmeleridir. Diğer bir avantaj, yineleyicilerin birçok ortak görev için yararlı olan ve tek bir yerde bulunan kendi yöntemlerine sahip olmasıdır. FilesystemIterator'a karşı readdir() kullanımına ilişkin bir örneğe bakın. Her iki yöntem de bir döngü kullanır, ancak readdir() durumunda yalnızca bir dize işlersiniz, FilesystemIterator ise dosya veya dizin hakkında ek bilgiler (boyut, sahip, izinler vb.) içerebilen bir nesneyle çalışır.

Elbette PHP, bu bilgileri dosya boyutu() ve dosya sahibi() gibi işlevleri kullanarak elde etme yeteneği sağlar. Ancak PHP5, OOP konseptini kullanmaya dayanmaktadır. Bu nedenle, bir programlama diliyle çalışmanın modern yöntemlerini kullanmak daha iyidir. Sitemizde yineleyicilerle çalışma dersleri var.

Eğitimin su bölümünde tartışıldığı gibi, FilesystemIterator , RecursiveDirectoryIterator ve GlobIterator kullanımına bakacağız. İlki DirectoryIterator öğesinden ve geri kalanı FilesystemIterator öğesinden devralır. Hepsi iki parametre alan aynı kurucuya sahiptir:

  • $path (gerekli): üzerinde işlem yapılacak dosya sistemi noktasının yolu
  • $flags (isteğe bağlı): belgelerde listelenen bir veya daha fazla bayrak

Bu yineleyicilerdeki gerçek fark, belirli bir yolda gezinmek için nasıl kullanıldıklarıdır.

Dosya SistemiYineleyici

FilesystemIterator'ı kullanmak çok basittir. Eylemde görelim. İki örnek sunuyoruz. İlki, adları "te" ile başlayan tüm dosya ve dizinlerin arandığını gösterir. İkinci örnek, adları "t.dat" veya "t.php" ile biten tüm dosya ve dizinleri bulmak için başka bir RegexIterator kullanır. RegexIterator, sonucu normal ifadelere göre filtrelemek için kullanılır.

getFilename(), "te") === 0) ( $filelist = $entry->getFilename(); ) )

Yukarıdaki kod, önceki örneklere benzer bir sonuç üretecektir.

RegexIterator kullanan ikinci örnek:

getFilename(); )

Çıktı alacak:

Array(0 => "script.php", 1 => "test.dat")

Özyinelemeli DizinYineleyici

RecursiveDirectoryIterator, dosya sistemi dizinleri arasında yinelemeli olarak yineleme yapmak için bir arabirim sağlar. GetChildren() ve hasChildren() gibi, bir dizinse geçerli konum için bir yineleyici döndüren ve geçerli giriş noktasının bir dizin olup olmadığını kontrol eden birkaç yararlı yöntemi vardır. Aşağıdaki örnek, RecursiveDirectoryIterator ve getChildren() kullanımını gösterir. Sonuç, önceki örneklerdekiyle aynı olacaktır.

getChildren(), "/t\.(php|dat)$/"); $dosya listesi = dizi(); foreach($filter as $giriş) ( $filelist = $entry->getFilename(); )

Globİteratör

GlobIterator, dosya sisteminde glob() işleviyle aynı şekilde gezinir. İlk parametre, ad için bir joker karakter içerebilir. Örnek, GlobIterator'ın kullanımını öncekiyle aynı sonuçla gösterir.

getFilename(); )

Çözüm

Bu ders, aynı amaca ulaşmak için farklı yaklaşımların kullanımını gösterir: dosya ve dizinlerin bir listesini almak. Aşağıdaki kilit noktalar hatırlanmalıdır:

  • glob() işlevi yerleşik bir çözümdür, ancak yeterince esnek değildir.
  • opendir() , readdir() ve closedir() temelli çözüm daha karmaşıktır ve ek filtreleme gerektirir, ancak daha esnektir.
  • scandir() işlevi ek filtreleme gerektirir, ancak tanımlayıcıyı kullanmadan çalışır.
  • Bir OOP yaklaşımı kullanıyorsanız, SPL kitaplığını kullanmalısınız. Ek olarak, sınıfları kendi işlevselliğinizle genişletebilirsiniz.
  • GlobIterator'ın bir ön filtreleme özelliği vardır ve diğerleri bir RegexIterator kullanır.