Register Register Member Login Member Login Member Login Forgot Password ??
PHP , ASP , ASP.NET, VB.NET, C#, Java , jQuery , Android , iOS , Windows Phone
 

Registered : 109,027

HOME > PHP > PHP Forum > ทำยังไงจึงจะใช้ SplHeap, ArrayIterator ในการเรียงลำดับไฟล์ที่เรียกมาด้วย RecursiveDIrectoryIterator+RecursiveIteratorIterator แล้วสามารถเรียกใช้ getDepth() ได้



 

ทำยังไงจึงจะใช้ SplHeap, ArrayIterator ในการเรียงลำดับไฟล์ที่เรียกมาด้วย RecursiveDIrectoryIterator+RecursiveIteratorIterator แล้วสามารถเรียกใช้ getDepth() ได้

 



Topic : 136172



โพสกระทู้ ( 4,719 )
บทความ ( 8 )



สถานะออฟไลน์




Code (PHP)
<?php
/**
 * Create example folders and files (empty file).
 */


/**
 * Recursively delete directory and contents.
 *
 * @link https://stackoverflow.com/a/3338133/128761 Original source code.
 * @param string $dir
 * @return void
 */
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);
    }
}


if (is_dir('example-dir')) {
    rrmdir('example-dir');
}

if (!is_dir('example-dir')) {
    mkdir('example-dir/level1-1/1.1/1.1.1', 0777, true);
    mkdir('example-dir/level1-1/1.1/1.1.2', 0777, true);
    mkdir('example-dir/level1-1/1.1/1.1.3', 0777, true);
    mkdir('example-dir/level1-1/1.1/1.1.4', 0777, true);
    mkdir('example-dir/level1-1/1.2', 0777, true);
    mkdir('example-dir/level1-1/1.3', 0777, true);
    mkdir('example-dir/level1-2/2.1', 0777, true);
    mkdir('example-dir/level1-2/2.2', 0777, true);
    mkdir('example-dir/level1-3', 0777, true);
    mkdir('example-dir/level1-4', 0777, true);

    for ($i = 1; $i <= 2; $i++) {
        file_put_contents('example-dir/file' . $i . '.txt', '');
    }
    for ($i = 1; $i <= 5; $i++) {
        file_put_contents('example-dir/level1-1/file1.' . $i . '.txt', '');
    }
    for ($i = 1; $i <= 5; $i++) {
        file_put_contents('example-dir/level1-1/1.1/file1.1.' . $i . '.txt', '');
    }
    for ($i = 1; $i <= 5; $i++) {
        file_put_contents('example-dir/level1-2/file2.' . $i . '.txt', '');
    }
}

create-example-files.php สำหรับสร้างโฟลเดอร์และไฟล์ตัวอย่าง.




Code (PHP)
<?php

$targetDir = 'example-dir';


if (!is_dir($targetDir)) {
    die('Please run create-example-files.php');
} else {
    $targetDir = realpath($targetDir);
}

_config.php




Code (PHP)
<?php


class BuildNestedArray
{


    protected function buildArrayDir($RII): array
    {
        $output = [];

        foreach ($RII as $File) {
            if (!$File->isDIr()) {
                continue;
            }

            if ($File->isDir()) {
                $subItem = [
                    'dir_' . $File->getFilename() => [
                        'filePath' => $File->getPathname(),// full path to file.
                        'depth' => $RII->getDepth(),
                        'children' => [],
                    ],
                ];
            }// endif; is dir.
            for ($depth = ($RII->getDepth() - 1); $depth >= 0; $depth--) {
                $subItem = [
                    'dir_' . $RII->getSubIterator($depth)->current()->getFilename() => [
                        'children' => $subItem,
                    ],
                ];
            }

            $output = array_merge_recursive($output, $subItem);

            unset($depth, $subItem);
        }// endforeach;
        unset($File);

        return $output;
    }// buildArrayDir


    public function build($RII): array
    {
        $output = [];
        $output = $this->buildArrayDir($RII);

        $i = 0;
        foreach ($RII as $filename => $File) {
            if ($File->isDIr()) {
                continue;
            }

            if (!$File->isDir()) {
                $subItem = [
                    'file_' . $i => [
                        'filePath' => $File->getPathname(),// full path to file.
                        'depth' => $RII->getDepth(),
                    ],
                ];
            }// endif not is dir.
            for ($depth = ($RII->getDepth() - 1); $depth >= 0; $depth--) {
                $subItem = [
                    'dir_' . $RII->getSubIterator($depth)->current()->getFilename() => [
                        'children' => $subItem,
                    ],
                ];
            }// endfor;
            $output = array_merge_recursive($output, $subItem);

            unset($depth, $subItem);

            $i++;
        }// endforeach;
        unset($File, $filename, $i);

        return $output;
    }// build


}

_BuildNestedArray.php




Code (PHP)
<?php

/*
 * This file is part of the Symfony package.
 *
 * (c) Fabien Potencier <[email protected]>
 *
 * For the full copyright and license information, please view the LICENSE
 * file that was distributed with this source code.
 */

namespace Symfony\Component\Finder\Iterator;

/**
 * SortableIterator applies a sort on a given Iterator.
 *
 * @author Fabien Potencier <[email protected]>
 */
class SortableIterator implements \IteratorAggregate
{
    public const SORT_BY_NONE = 0;
    public const SORT_BY_NAME = 1;
    public const SORT_BY_TYPE = 2;
    public const SORT_BY_ACCESSED_TIME = 3;
    public const SORT_BY_CHANGED_TIME = 4;
    public const SORT_BY_MODIFIED_TIME = 5;
    public const SORT_BY_NAME_NATURAL = 6;

    private $iterator;
    private $sort;

    /**
     * @param \Traversable $iterator The Iterator to filter
     * @param int|callable $sort     The sort type (SORT_BY_NAME, SORT_BY_TYPE, or a PHP callback)
     *
     * @throws \InvalidArgumentException
     */
    public function __construct(\Traversable $iterator, $sort, bool $reverseOrder = false)
    {
        $this->iterator = $iterator;
        $order = $reverseOrder ? -1 : 1;

        if (self::SORT_BY_NAME === $sort) {
            $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
                return $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
            };
        } elseif (self::SORT_BY_NAME_NATURAL === $sort) {
            $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
                return $order * strnatcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
            };
        } elseif (self::SORT_BY_TYPE === $sort) {
            $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
                if ($a->isDir() && $b->isFile()) {
                    return -$order;
                } elseif ($a->isFile() && $b->isDir()) {
                    return $order;
                }

                return $order * strcmp($a->getRealPath() ?: $a->getPathname(), $b->getRealPath() ?: $b->getPathname());
            };
        } elseif (self::SORT_BY_ACCESSED_TIME === $sort) {
            $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
                return $order * ($a->getATime() - $b->getATime());
            };
        } elseif (self::SORT_BY_CHANGED_TIME === $sort) {
            $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
                return $order * ($a->getCTime() - $b->getCTime());
            };
        } elseif (self::SORT_BY_MODIFIED_TIME === $sort) {
            $this->sort = static function (\SplFileInfo $a, \SplFileInfo $b) use ($order) {
                return $order * ($a->getMTime() - $b->getMTime());
            };
        } elseif (self::SORT_BY_NONE === $sort) {
            $this->sort = $order;
        } elseif (\is_callable($sort)) {
            $this->sort = $reverseOrder ? static function (\SplFileInfo $a, \SplFileInfo $b) use ($sort) { return -$sort($a, $b); } : $sort;
        } else {
            throw new \InvalidArgumentException('The SortableIterator takes a PHP callable or a valid built-in sort algorithm as an argument.');
        }
    }


    /**
     * @return \Traversable
     */
    public function getIterator()
    {
        if (1 === $this->sort) {
            return $this->iterator;
        }

        $array = iterator_to_array($this->iterator, true);

        if (-1 === $this->sort) {
            $array = array_reverse($array);
        } else {
            uasort($array, $this->sort);
        }

        return new \ArrayIterator($array);
    }


}

_SymfonySort.php
https://github.com/symfony/finder/blob/5.3/Iterator/SortableIterator.php <-- ตัว sort ของ Symfony










Code (PHP)
<?php

require '_config.php';
require '_BuildNestedArray.php';


// $targetDir = 'example-dir';


$RDI = new \RecursiveDirectoryIterator(
    $targetDir,
    \FilesystemIterator::SKIP_DOTS
);


$RII = new \RecursiveIteratorIterator(
    $RDI,
    \RecursiveIteratorIterator::SELF_FIRST,
    \RecursiveIteratorIterator::CATCH_GET_CHILD
);


$totalFiles = iterator_count($RII);
echo 'Total files: ' . $totalFiles . '<br>' . PHP_EOL;


// display files and folders listing --------------------------
echo '<ol>' . PHP_EOL;
foreach ($RII as $File) {
    echo '<li>' . PHP_EOL;
    echo $File->getPathname();
    echo '</li>' . PHP_EOL;
}// endforeach;
echo '</ol>' . PHP_EOL;
// end display files and folders listing -----------------------


// build nested array ----------------------------------------
$BuildNestedArray = new BuildNestedArray();
$nestedArray = $BuildNestedArray->build($RII);
echo '<hr>' . PHP_EOL;
echo '<h5>Nested array</h5>' . PHP_EOL;
echo '<pre>' . print_r($nestedArray, true) . '</pre>';
unset($nestedArray, $BuildNestedArray);
// end build nested array ------------------------------------

01-basic-list.php




Code (PHP)
<?php

require '_config.php';
require '_BuildNestedArray.php';


// $targetDir = 'example-dir';


$RDI = new \RecursiveDirectoryIterator(
    $targetDir,
    \FilesystemIterator::SKIP_DOTS
);


$RII = new \RecursiveIteratorIterator(
    $RDI,
    \RecursiveIteratorIterator::SELF_FIRST,
    \RecursiveIteratorIterator::CATCH_GET_CHILD
);


$totalFiles = iterator_count($RII);
echo 'Total files: ' . $totalFiles . '<br>' . PHP_EOL;


// paginated files listing. ------------------------------
// prepare data for limit pagination
$offset = ($_GET['offset'] ?? 0);
if (!is_numeric($offset)) {
    $offset = 0;
} else {
    $offset = (int) $offset;
}
$limit = 12;
$paginated = true;
// limit pagination here.
$RII = new \LimitIterator($RII, $offset, $limit);
// end paginated files listing. --------------------------


// display files and folders listing --------------------------
echo '<ol>' . PHP_EOL;
foreach ($RII as $File) {
    echo '<li>' . PHP_EOL;
    echo $File->getPathname();
    echo '</li>' . PHP_EOL;
}// endforeach;
echo '</ol>' . PHP_EOL;
// end display files and folders listing -----------------------


// display pagination -----------------------------------------
if (isset($paginated) && true === $paginated && $totalFiles > $limit) {
    echo '<br>' . PHP_EOL;
    $totalPages = ceil($totalFiles/$limit);
    for ($i = 1; $i <= $totalPages; $i++) {
        $loopOffset = (int) (($i-1)*$limit);
        if ($loopOffset === $offset) {
            echo '<strong>';
        }
        echo '<a href="?offset=' . $loopOffset . '">' . $i . '</a> ';
        if ($loopOffset === $offset) {
            echo '</strong>';
        }
    }
    unset($i, $totalPages, $loopOffset);
}
// end display pagination --------------------------------------


// build nested array ----------------------------------------
$BuildNestedArray = new BuildNestedArray();
$nestedArray = $BuildNestedArray->build($RII);
echo '<hr>' . PHP_EOL;
echo '<h5>Nested array</h5>' . PHP_EOL;
echo '<pre>' . print_r($nestedArray, true) . '</pre>';
unset($nestedArray, $BuildNestedArray);
// end build nested array ------------------------------------

02-pagination-list.php




Code (PHP)
<?php

require '_config.php';
require '_BuildNestedArray.php';
require '_SymfonySort.php';


// $targetDir = 'example-dir';


$RDI = new \RecursiveDirectoryIterator(
    $targetDir,
    \FilesystemIterator::SKIP_DOTS
);


$RII = new \RecursiveIteratorIterator(
    $RDI,
    \RecursiveIteratorIterator::SELF_FIRST,
    \RecursiveIteratorIterator::CATCH_GET_CHILD
);


$totalFiles = iterator_count($RII);
echo 'Total files: ' . $totalFiles . '<br>' . PHP_EOL;


// sort the list ----------------------------------------
$RII = (new \Symfony\Component\Finder\Iterator\SortableIterator($RII, 6))->getIterator();
// end sort the list ------------------------------------


// paginated files listing. ------------------------------
// prepare data for limit pagination
$offset = ($_GET['offset'] ?? 0);
if (!is_numeric($offset)) {
    $offset = 0;
} else {
    $offset = (int) $offset;
}
$limit = 12;
$paginated = true;
// limit pagination here.
$RII = new \LimitIterator($RII, $offset, $limit);
// end paginated files listing. --------------------------


// display files and folders listing --------------------------
echo '<ol>' . PHP_EOL;
foreach ($RII as $File) {
    echo '<li>' . PHP_EOL;
    echo $File->getPathname();
    echo '</li>' . PHP_EOL;
}// endforeach;
echo '</ol>' . PHP_EOL;
// end display files and folders listing -----------------------


// display pagination -----------------------------------------
if (isset($paginated) && true === $paginated && $totalFiles > $limit) {
    echo '<br>' . PHP_EOL;
    $totalPages = ceil($totalFiles/$limit);
    for ($i = 1; $i <= $totalPages; $i++) {
        $loopOffset = (int) (($i-1)*$limit);
        if ($loopOffset === $offset) {
            echo '<strong>';
        }
        echo '<a href="?offset=' . $loopOffset . '">' . $i . '</a> ';
        if ($loopOffset === $offset) {
            echo '</strong>';
        }
    }
    unset($i, $totalPages, $loopOffset);
}
// end display pagination --------------------------------------


// build nested array ----------------------------------------
$BuildNestedArray = new BuildNestedArray();
$nestedArray = $BuildNestedArray->build($RII);
echo '<hr>' . PHP_EOL;
echo '<h5>Nested array</h5>' . PHP_EOL;
echo '<pre>' . print_r($nestedArray, true) . '</pre>';
unset($nestedArray, $BuildNestedArray);
// end build nested array ------------------------------------

03-sort-list.php





คือถ้าผมเอาตัว sort ออกไปเลย (01, 02) มันจะเรียกใช้ getDepth() ที่เป็น method ของ RecursiveIteratorIterator ได้ และผมจำเป็นต้องใช้มันเพราะจะเอามาสร้าง nested array สำหรับแสดงผลซ้อนๆกันเช่นไฟล์ลูกในแต่ละโฟลเดอร์จะซ้อนอยู่ข้างใน array ของ folder อีกที.

แต่ทีนี้ถ้าผมต้องการจัดเรียงด้วย เนื่องจากบน Windows, Linux แสดงผลไม่เหมือนกัน ใน Linux มันไม่เรียงมาให้ ผมต้องมาเรียงมันใหม่ ทีนี้ไม่ว่า extends SplHeap, ArrayIterator (ของ Symfony) ก็จะทำให้ไม่สามารถเรียกใช้ getDepth(), getSubIterator() ได้อีกต่อไป.
ทำยังไงจึงจะให้มันเรียกใช้ได้ครับ?


ข้อจำกัด
เนื่องจากไฟล์ที่จะเรียกมาแสดงมีจำนวนมหาศาล 7000 ไฟล์เป็นอย่างน้อย ดังนั้นวิธีอื่นๆที่มีไม่เหมาะเลย ไม่ว่าจะเป็น scandir, opendir, ... เพราะผมเข้าใจว่าโค้ดของ Spl ตรงนี้มันทำหน้าที่เหมือนกับรับคำสั่งก่อนแล้วดึงรายการมาแสดงทีหลัง เลยแยกแบ่งหน้าได้ให้มันทำงานเบาลงด้วย กรองชื่อไฟล์ได้ด้วย (อ่านเพิ่มเติมได้ที่ https://stackoverflow.com/questions/28210368/what-is-the-advantage-of-using-spl-iterators-in-traversing-the-file-system) ผมก็เข้าใจว่าอย่างงั้น เพราะผมลองไฟล์เยอะๆกว่านี้มากๆ ก็ยังไม่ทำให้ server เดี้ยง.
เพราะงั้นเลยไม่คิดว่าคำสั่งอื่นๆจะเหมาะเท่าอันนี้?



Tag : PHP









ประวัติการแก้ไข
2021-06-11 01:04:48
2021-06-11 01:11:50
Move To Hilight (Stock) 
Send To Friend.Bookmark.
Date : 2021-06-08 04:07:23 By : mr.v View : 514 Reply : 8
 

 

No. 1



โพสกระทู้ ( 4,719 )
บทความ ( 8 )



สถานะออฟไลน์


ได้ละ เพิ่ม class extends IteratorIterator เข้าไป

Code (PHP)
class CustomProperty extends \IteratorIterator
{


    /**
     * For use with class extends \FilterIterator
     */
    public function accept(): bool
    {
        $File = $this->getInnerIterator()->current();
        $File->depth = $this->getInnerIterator()->getDepth();
        return true;
    }
    
    
    /**
     * For use with class extends \IteratorIterator
     */
    public function current()
    {
        $File = $this->getInnerIterator()->current();
        $File->depth = $this->getDepth();
        return parent::current();
    }
    


}




หน้าหลักก่อน sort ก็เรียกใช้
Code (PHP)
$RII = new \SPLFile\CustomProperty($RII);



จากนั้นแทนที่จะเรียกใช้ getDepth() ก็เรียกใช้ property depth เฉยๆ






แสดงความคิดเห็นโดยอ้างถึง ความคิดเห็นนี้
Date : 2021-06-08 12:26:14 By : mr.v
 


 

No. 2



โพสกระทู้ ( 4,719 )
บทความ ( 8 )



สถานะออฟไลน์


สุดท้ายใช้ getSubIterator() ไม่ได้อยู่ดี


ประวัติการแก้ไข
2021-06-09 20:02:05
แสดงความคิดเห็นโดยอ้างถึง ความคิดเห็นนี้
Date : 2021-06-09 10:32:47 By : mr.v
 

 

No. 3



โพสกระทู้ ( 296 )
บทความ ( 0 )



สถานะออฟไลน์


Code (PHP)
$RII = new \LimitIterator($RII, $offset, $limit);  // $RII สุดท้าย


เพราะ $RII สุดท้าย เป็น Iterator ชนิด LimitIterator ซึ่งไม่มี getDepth() รวมทั้ง method อื่นๆ จากคลาส RecursiveIteratorIterator ด้วย
method จากคลาส RecursiveIteratorIterator ที่ไม่มีในคลาส LimitIterator
beginChildren beginIteration callGetChildren callHasChildren endChildren endIteration getDepth getMaxDepth getSubIterator nextElement setMaxDepth


การ inherit จาก IteratorIterator (ตาม No.1) ไม่แน่เสมอไปว่าจะสามารถเรียกใช้ getDepth method ของ RecursiveIteratorIterator เพราะในคลาส IteratorIterator ก็ไม่มีเช่นกัน...แต่ที่ได้ในกรณีนี้เนื่องจากในคลาสลูกมีการเรียก getInnerIterator method (ตามตัวอย่างคือ getIterator() ของ Symfony) มีการเชื่อมโยงไปยัง Iterator ชนิด RecursiveIteratorIterator ที่มี getDepth() พอดี...

ถ้าต้องการใช้เมธอดใดในคลาสหนึ่งที่ไม่มีอยู่ในคลาสหนึ่ง ก็ต้อง inherit เหมือนกัน



เป็นผมอาจไม่ใช้ LimitIterator เพื่อรักษาการเข้าถึง getDepth(), getMaxDepth(), getSubIterator(), ... ของ RecursiveIteratorIterator เอาไว้ ส่วน limit เพื่อทำ pagination ใช้ counter เอา

หมายเหตุ ไม่ได้ลงภาคสนาม...แค่อิงตามทฤษฎี และตามความเข้าใจ ดังนั้น อาจมีข้อมูลที่ผิดพลาดได้
แสดงความคิดเห็นโดยอ้างถึง ความคิดเห็นนี้
Date : 2021-06-10 22:15:17 By : TheGreatGod_of_Death
 


 

No. 4



โพสกระทู้ ( 4,719 )
บทความ ( 8 )



สถานะออฟไลน์


LimitIterator ไม่เกี่ยวเลยครับ มีปัญหาที่ตัวเรียงลำดับตัวเดียวเลย เพราะเอามาใส่แล้วใช้ getDepth, getSubIterator ไม่ได้
พอเอาออกแล้วใช้ได้ตามปกติทุกอย่าง


ประวัติการแก้ไข
2021-06-11 00:08:29
แสดงความคิดเห็นโดยอ้างถึง ความคิดเห็นนี้
Date : 2021-06-11 00:06:28 By : mr.v
 


 

No. 5



โพสกระทู้ ( 4,719 )
บทความ ( 8 )



สถานะออฟไลน์


Update โค้ดที่คำถาม ไฟล์ตัวอย่าง 01 02 ทำงานปกติแม้จะมี LimitIterator เพราะมันไม่เกี่ยวกันเลย มันไม่ใช่สาเหตุของการใช้ getDepth() ไม่ได้เลย
ส่วน 03 มี error เพราะใช้ทั้ง getDepth() และ getSubIterator() ไม่ได้
แสดงความคิดเห็นโดยอ้างถึง ความคิดเห็นนี้
Date : 2021-06-11 01:06:49 By : mr.v
 


 

No. 6



โพสกระทู้ ( 296 )
บทความ ( 0 )



สถานะออฟไลน์


จากที่ลองแบบผ่านๆ (1-2 ชม.) จาก PHP 2 version ได้ข้อสังเกตตามนี้

Quote:
PHP 7.1.1-1 : เรียก iterator ระดับเดียว คือ active/current iterator ดูผิด ทั้งสองได้ผลเหมือนกัน
PHP 7.3.3 : เรียก iterator สองระดับ คือ current iterator + inner iterator
PHP Others : Not tested.




ผลทดสอบต่อไปนี้ใช้ PHP 7.3.3

รายชื่อ Class ที่ดำเนินเรื่อง($RII) ของตัวอย่างแต่ละไฟล์
File Name | current iterator | inner iterator 01-basic-list.php | RecursiveIteratorIterator | RecursiveDirectoryIterator 02-pagination-list.php | LimitIterator | RecursiveIteratorIterator 03-sort-list.php | LimitIterator | ArrayIterator


ดู 03-sort-list.php ...เพราะ iterator จะเช็คจาก current(LimitIterator) ก่อน ถ้าไม่มีเมธอดหมุนไปดู inner(ArrayIterator) เมื่อไม่พบเมธอดตามคำสั่งทั้งสองระดับ จึงเกิด error (ที่ ArrayIterator)

วิธีแก้ (เฉพาะ error จากการเรียกใช้ method) คือ หาทางใช้ RecursiveIteratorIterator ให้ได้ไม่ว่าจะเป็น current หรือ inner iterator ...สุดท้ายออกมาแบบนี้

1. ใน symfony เปลี่ยน return value ของ getIterator method เป็นแบบ recursive (RecursiveIterator)

_SymfonySort.php (Only edited part)
//...

    /**
     * @return \Traversable
     */
    public function getIterator()
    {
        if (1 === $this->sort) {
            return $this->iterator;
        }

        $array = iterator_to_array($this->iterator, true);

        if (-1 === $this->sort) {
            $array = array_reverse($array);
        } else {
            uasort($array, $this->sort);
        }

        return new \RecursiveArrayIterator($array);
    }



2. ในตัวอย่าง 03 หลังจากเรียก getIterator() ครอบด้วย RecursiveIteratorIterator อีกที

03-sort-list.php (full)
<?php

require '_config.php';
require '_BuildNestedArray.php';
require '_SymfonySort.php';


// $targetDir = 'example-dir';


$RDI = new \RecursiveDirectoryIterator(
    $targetDir,
    \FilesystemIterator::SKIP_DOTS
);


$RII = new \RecursiveIteratorIterator(
    $RDI,
    \RecursiveIteratorIterator::SELF_FIRST,
    \RecursiveIteratorIterator::CATCH_GET_CHILD
);


$totalFiles = iterator_count($RII);
echo 'Total files: ' . $totalFiles . '<br>' . PHP_EOL;


// sort the list ----------------------------------------
$sort_type = 6;
$RII = (new \Symfony\Component\Finder\Iterator\SortableIterator($RII, $sort_type))->getIterator();
// end sort the list ------------------------------------

if ($sort_type !== 0) {
	$RII = new \RecursiveIteratorIterator(
		$RII,
		\RecursiveIteratorIterator::SELF_FIRST,
		\RecursiveIteratorIterator::CATCH_GET_CHILD
	);
}

// paginated files listing. ------------------------------
// prepare data for limit pagination
$offset = ($_GET['offset'] ?? 0);
if (!is_numeric($offset)) {
    $offset = 0;
} else {
    $offset = (int) $offset;
}
$limit = 12;
$paginated = true;
// limit pagination here.
$RII = new \LimitIterator($RII, $offset, $limit);
// end paginated files listing. --------------------------


// display files and folders listing --------------------------
echo '<ol>' . PHP_EOL;
foreach ($RII as $File) {
    echo '<li>' . PHP_EOL;
    echo $File->getPathname();
    echo '</li>' . PHP_EOL;
}// endforeach;
echo '</ol>' . PHP_EOL;
// end display files and folders listing -----------------------


// display pagination -----------------------------------------
if (isset($paginated) && true === $paginated && $totalFiles > $limit) {
    echo '<br>' . PHP_EOL;
    $totalPages = ceil($totalFiles/$limit);
    for ($i = 1; $i <= $totalPages; $i++) {
        $loopOffset = (int) (($i-1)*$limit);
        if ($loopOffset === $offset) {
            echo '<strong>';
        }
        echo '<a href="?offset=' . $loopOffset . '">' . $i . '</a> ';
        if ($loopOffset === $offset) {
            echo '</strong>';
        }
    }
    unset($i, $totalPages, $loopOffset);
}
// end display pagination --------------------------------------


// build nested array ----------------------------------------
$BuildNestedArray = new BuildNestedArray();
$nestedArray = $BuildNestedArray->build($RII);
echo '<hr>' . PHP_EOL;
echo '<h5>Nested array</h5>' . PHP_EOL;
echo '<pre>' . print_r($nestedArray, true) . '</pre>';
unset($nestedArray, $BuildNestedArray);
// end build nested array ------------------------------------



error หาย แต่ depth ก็ไปด้วย

after error gone



จากการขุดรอยระยะสั้นพบว่าฟังก์ชัน iterator_to_array จาก SPL มีการดึง sub-level ของ iterator ออกมานอกสุดทั้งหมด ก่อนเขียนลง array (ยังไงลองตรวจสอบเรื่องนี้อย่างละเอียดดูอีกที)


ประวัติการแก้ไข
2021-06-14 00:12:05
2021-06-14 00:12:38
แสดงความคิดเห็นโดยอ้างถึง ความคิดเห็นนี้
Date : 2021-06-13 19:58:47 By : TheGreatGod_of_Death
 


 

No. 7



โพสกระทู้ ( 4,719 )
บทความ ( 8 )



สถานะออฟไลน์


ตอบความคิดเห็นที่ : 6 เขียนโดย : TheGreatGod_of_Death เมื่อวันที่ 2021-06-13 19:58:47
รายละเอียดของการตอบ ::
ไปลองยังไงครับ PHP 7.1 ระดับเดียว PHP 7.3 สองระดับ???

ผมลองตั้งแต่ 7.0-8.0ทุกตัวไฟล์ 01 02 เหมือนกันเป๊ะ
ไฟล์ 03 ก็ error เหมือนกันเป๊ะตั้งแต่ PHP 7.1-8.0



ประวัติการแก้ไข
2021-06-13 21:48:00
แสดงความคิดเห็นโดยอ้างถึง ความคิดเห็นนี้
Date : 2021-06-13 21:46:31 By : mr.v
 


 

No. 8



โพสกระทู้ ( 296 )
บทความ ( 0 )



สถานะออฟไลน์


ตอบความคิดเห็นที่ : 7 เขียนโดย : mr.v เมื่อวันที่ 2021-06-13 21:46:31
รายละเอียดของการตอบ ::
น่าจะคัดวางแล้วลืมแก้...จำไม่ได้ว่าลองไปแบบไหน คงจะประมาณนี้

iter1.php (7.1.1-1)
<?php
$array = [
    'test' => 'value',
    'level_one' => [
        'level_two' => [
            'level_three_1' => [
                'level_four' => [
                    'level_five_1' => 'five_1_value',
                    'level_five_2' => 'five_2_value',
                    'level_five_3' => 'five_3_value',
                    'level_five_4' => 'another value'
                ]
            ],
            'level_three_2' => 'value'
        ]
    ]
];

$arrayIterator = new \RecursiveArrayIterator($array);
$recursiveIterator = new \RecursiveIteratorIterator($arrayIterator, \RecursiveIteratorIterator::SELF_FIRST);

echo "<h3>Total elements : " . iterator_count($recursiveIterator);

$limit = new LimitIterator($arrayIterator, 0, 6);

echo " | limit to : " . iterator_count($limit) . "</h3>";

foreach ($limit as $key => $value) {
  $d = $limit->getDepth();
  echo $limit->getPosition()+1 . ". depth=$d, k=$key, v=<span style='color:grey'>" . (is_array($value) ? print_r($value, 1) : $value) . "</span><br>";
}


iter2.php (7.3.3)
<?php
$array = [
    'test' => 'value',
    'level_one' => [
        'level_two' => [
            'level_three_1' => [
                'level_four' => [
                    'level_five_1' => 'five_1_value',
                    'level_five_2' => 'five_2_value',
                    'level_five_3' => 'five_3_value',
                    'level_five_4' => 'another value'
                ]
            ],
            'level_three_2' => 'value'
        ]
    ]
];

$arrayIterator = new \RecursiveArrayIterator($array);
$recursiveIterator = new \RecursiveIteratorIterator($arrayIterator, \RecursiveIteratorIterator::SELF_FIRST);

echo "<h3>Total elements : " . iterator_count($recursiveIterator);

$limit = new LimitIterator($recursiveIterator, 0, 6);

echo " | limit to : " . iterator_count($limit) . "</h3>";

foreach ($limit as $key => $value) {
  $d = $limit->getDepth();
  echo $limit->getPosition()+1 . ". depth=$d, k=$key, v=<span style='color:grey'>" . (is_array($value) ? print_r($value, 1) : $value) . "</span><br>";
}


จะเห็นเวอร์ชันต่าง และ script ต่าง...จึงได้ผลต่าง




สรุป ดูผิด จริงๆ ได้ผลเหมือนกัน แก้ให้แล้วใน No.6
แสดงความคิดเห็นโดยอ้างถึง ความคิดเห็นนี้
Date : 2021-06-14 00:22:29 By : TheGreatGod_of_Death
 

   

ค้นหาข้อมูล


   
 

แสดงความคิดเห็น
Re : ทำยังไงจึงจะใช้ SplHeap, ArrayIterator ในการเรียงลำดับไฟล์ที่เรียกมาด้วย RecursiveDIrectoryIterator+RecursiveIteratorIterator แล้วสามารถเรียกใช้ getDepth() ได้
 
 
รายละเอียด
 
ตัวหนา ตัวเอียง ตัวขีดเส้นใต้ ตัวมีขีดกลาง| ตัวเรืองแสง ตัวมีเงา ตัวอักษรวิ่ง| จัดย่อหน้าอิสระ จัดย่อหน้าชิดซ้าย จัดย่อหน้ากึ่งกลาง จัดย่อหน้าชิดขวา| เส้นขวาง| ขนาดตัวอักษร แบบตัวอักษร
ใส่แฟลช ใส่รูป ใส่ไฮเปอร์ลิ้งค์ ใส่อีเมล์ ใส่ลิ้งค์ FTP| ใส่แถวของตาราง ใส่คอลัมน์ตาราง| ตัวยก ตัวห้อย ตัวพิมพ์ดีด| ใส่โค้ด ใส่การอ้างถึงคำพูด| ใส่ลีสต์
smiley for :lol: smiley for :ken: smiley for :D smiley for :) smiley for ;) smiley for :eek: smiley for :geek: smiley for :roll: smiley for :erm: smiley for :cool: smiley for :blank: smiley for :idea: smiley for :ehh: smiley for :aargh: smiley for :evil:
Insert PHP Code
Insert ASP Code
Insert VB.NET Code Insert C#.NET Code Insert JavaScript Code Insert C#.NET Code
Insert Java Code
Insert Android Code
Insert Objective-C Code
Insert XML Code
Insert SQL Code
Insert Code
เพื่อความเรียบร้อยของข้อความ ควรจัดรูปแบบให้พอดีกับขนาดของหน้าจอ เพื่อง่ายต่อการอ่านและสบายตา และตรวจสอบภาษาไทยให้ถูกต้อง

อัพโหลดแทรกรูปภาพ

Notice

เพื่อความปลอดภัยของเว็บบอร์ด ไม่อนุญาติให้แทรก แท็ก [img]....[/img] โดยการอัพโหลดไฟล์รูปจากที่อื่น เช่นเว็บไซต์ ฟรีอัพโหลดต่าง ๆ
อัพโหลดแทรกรูปภาพ ให้ใช้บริการอัพโหลดไฟล์ของไทยครีเอท และตัดรูปภาพให้พอดีกับสกรีน เพื่อความโหลดเร็วและไฟล์ไม่ถูกลบทิ้ง

   
  เพื่อความปลอดภัยและการตรวจสอบ กระทู้ที่แทรกไฟล์อัพโหลดไฟล์จากที่อื่น อาจจะถูกลบทิ้ง
 
โดย
อีเมล์
บวกค่าให้ถูก
<= ตัวเลขฮินดูอารบิก เช่น 123 (หรือล็อกอินเข้าระบบสมาชิกเพื่อไม่ต้องกรอก)







Exchange: นำเข้าสินค้าจากจีน, Taobao, เฟอร์นิเจอร์, ของพรีเมี่ยม, ร่ม, ปากกา, power bank, แฟลชไดร์ฟ, กระบอกน้ำ

Load balance : Server 05
ThaiCreate.Com Logo
© www.ThaiCreate.Com. 2003-2024 All Rights Reserved.
ไทยครีเอทบริการ จัดทำดูแลแก้ไข Web Application ทุกรูปแบบ (PHP, .Net Application, VB.Net, C#)
[Conditions Privacy Statement] ติดต่อโฆษณา 081-987-6107 อัตราราคา คลิกที่นี่