Tôi đang cố gắng lặp qua thư mục chứa nhiều tệp PHP và phát hiện các lớp nào được xác định trong mỗi tệp.Kết hợp các kết quả lặp đệ quy: trẻ em với cha mẹ
xem xét như sau:
$php_files_and_content = new PhpFileAndContentIterator($dir);
foreach($php_files_and_content as $filepath => $sourceCode) {
// echo $filepath, $sourceCode
}
Các $php_files_and_content
biến trên đại diện cho một iterator nơi quan trọng là filepath, và nội dung là mã nguồn của tập tin (như thể đó không phải là rõ ràng từ ví dụ).
này sau đó được cung cấp vào một iterator mà sẽ phù hợp với tất cả các lớp được định nghĩa trong mã nguồn, ala:
class DefinedClassDetector extends FilterIterator implements RecursiveIterator {
public function accept() {
return $this->hasChildren();
}
public function hasChildren() {
$classes = getDefinedClasses($this->current());
return !empty($classes);
}
public function getChildren() {
return new RecursiveArrayIterator(getDefinedClasses($this->current()));
}
}
$defined_classes = new RecursiveIteratorIterator(new DefinedClassDetector($php_files_and_content));
foreach($defined_classes as $index => $class) {
// print "$index => $class"; outputs:
// 0 => Class A
// 1 => Class B
// 0 => Class C
}
Lý do các $index
không được tuần tự số lượng là vì 'Class C' được định nghĩa trong tệp mã nguồn thứ hai, và do đó mảng được trả về bắt đầu từ chỉ mục 0 một lần nữa. Điều này được bảo toàn trong RecursiveIteratorIterator vì mỗi bộ kết quả đại diện cho một Iterator riêng biệt (và do đó các cặp khóa/giá trị). Dù sao, những gì tôi đang cố gắng làm bây giờ là tìm cách tốt nhất để kết hợp những thứ này, như vậy khi tôi lặp qua trình lặp mới, tôi có thể lấy khóa là tên lớp (từ trình biến đổi $defined_classes
) và giá trị là đường dẫn tệp ban đầu, ala:
foreach($classes_and_paths as $filepath => $class) {
// print "$class => $filepath"; outputs
// Class A => file1.php
// Class B => file1.php
// Class C => file2.php
}
Và đó là nơi tôi bị kẹt cho đến nay. Tại thời điểm này, giải pháp duy nhất hiện ra trong đầu là tạo một RecursiveIterator mới, ghi đè phương thức current() để trả về khóa lặp() (đây sẽ là filepath gốc) và khóa () để trả về giá trị hiện tại của iterator(). Nhưng tôi không thiên về giải pháp này vì:
- Nghe có vẻ phức tạp (có nghĩa là mã sẽ trông gớm ghiếc và nó sẽ không được trực quan
- Các quy tắc kinh doanh được mã hóa cứng bên trong lớp, trong khi tôi muốn xác định một số vòng lặp chung chung và có thể kết hợp chúng theo cách như vậy để tạo ra kết quả cần thiết.
Bất kỳ ý tưởng hoặc gợi ý biết ơn nhận được.
tôi cũng nhận ra có rất xa nhanh hơn, hiệu quả hơn cách làm điều này, nhưng thứ cũng là một bài tập trong sử dụng Iterator cho bản thân và cũng là một bài tập trong việc thúc đẩy tái sử dụng mã, vì vậy bất kỳ Iterator mới nào phải được viết nên càng nhỏ càng tốt và cố gắng tận dụng chức năng hiện có.
Cảm ơn
+1 để tăng thanh và sử dụng OOP trong PHP –