1. <?php
  2. /**
  3. * Recursively validates file structures with memory optimization.
  4. *
  5. * @param string $root The root directory to validate.
  6. * @param array $expected_structure An array defining the expected file/directory structure.
  7. * @param array $validated_structure An array to store the validated structure.
  8. * @param int $level The current level of recursion (for debugging/logging).
  9. * @return bool True if the structure is valid, false otherwise.
  10. */
  11. function validateFileStructureRecursive(string $root, array $expected_structure, array &$validated_structure, int $level = 0): bool
  12. {
  13. // Check if the root directory exists
  14. if (!is_dir($root)) {
  15. error_log("Error: Root directory '$root' does not exist.");
  16. return false;
  17. }
  18. // Initialize validated structure if it's not already
  19. if (!isset($validated_structure[$root])) {
  20. $validated_structure[$root] = [];
  21. }
  22. // Iterate through the expected structure.
  23. foreach ($expected_structure as $item => $expected_type) {
  24. $full_path = $root . '/' . $item;
  25. // Check if the item exists.
  26. if (!is_dir($full_path) && !file_exists($full_path)) {
  27. error_log("Error: Expected item '$item' not found at '$full_path'.");
  28. return false;
  29. }
  30. //Validate based on expected type.
  31. if ($expected_type == 'directory') {
  32. //If it's a directory, recursively call the function.
  33. if (!is_dir($full_path)) {
  34. error_log("Error: '$full_path' is not a directory, but expected one.");
  35. return false;
  36. }
  37. if (!validateFileStructureRecursive($full_path, $expected_structure, $validated_structure, $level + 1)) {
  38. return false;
  39. }
  40. } elseif ($expected_type == 'file') {
  41. // Check if it's a file.
  42. if (!file_exists($full_path)) {
  43. error_log("Error: Expected file '$full_path' not found.");
  44. return false;
  45. }
  46. if (is_dir($full_path)) {
  47. error_log("Error: '$full_path' is a directory, but expected a file.");
  48. return false;
  49. }
  50. } else {
  51. error_log("Error: Invalid expected type '$expected_type' for item '$item'.");
  52. return false;
  53. }
  54. }
  55. //Add the validated structure to the main validated structure
  56. $validated_structure[$root] = $validated_structure[$root] ?? [];
  57. return true;
  58. }
  59. /**
  60. * Main function to call the validation process.
  61. *
  62. * @param string $root The root directory to validate.
  63. * @param array $expected_structure An array defining the expected file/directory structure.
  64. * @return bool True if the structure is valid, false otherwise.
  65. */
  66. function validateStructure(string $root, array $expected_structure): bool
  67. {
  68. $validated_structure = []; //Initialize the validated structure.
  69. return validateFileStructureRecursive($root, $expected_structure, $validated_structure);
  70. }
  71. //Example Usage:
  72. /*
  73. $expected_structure = [
  74. 'src' => 'directory',
  75. 'src/main.php' => 'file',
  76. 'src/helpers' => 'directory',
  77. 'src/helpers/utils.php' => 'file',
  78. 'tests' => 'directory',
  79. ];
  80. $root_directory = './my_project'; // Replace with your project root.
  81. if (validateStructure($root_directory, $expected_structure)) {
  82. echo "File structure is valid.\n";
  83. } else {
  84. echo "File structure is invalid.\n";
  85. }
  86. */
  87. ?>

Add your comment