Maison >développement back-end >tutoriel php >PHP utilise l'itération pour implémenter les opérations liées aux dossiers (copier, supprimer, etc.)

PHP utilise l'itération pour implémenter les opérations liées aux dossiers (copier, supprimer, etc.)

巴扎黑
巴扎黑original
2017-08-12 11:28:471378parcourir

Cet article présente principalement la méthode PHP pour réaliser la copie, la suppression, la vérification de la taille et d'autres opérations basées sur l'itération. Il explique brièvement le principe de l'itération et l'analyse sous forme d'exemples. copie, suppression et Pour les compétences de mise en œuvre connexes d'opérations courantes telles que la vérification de la taille, les amis dans le besoin peuvent se référer à

Cet article décrit la méthode de PHP pour implémenter la copie, la suppression, la vérification de la taille et d'autres opérations basées sur itération. Partagez-le avec tout le monde pour votre référence, les détails sont les suivants :

Article précédent PHP implémente de manière récursive les opérations de copie, de suppression et d'affichage de la taille des dossiers. Les techniques d'utilisation des opérations récursives sont analysées ici. techniques d’itération.

"Puisque la récursivité peut très bien le résoudre, pourquoi utiliser l'itération ?" La raison principale est des problèmes d'efficacité...

Le concept de récursion est d'appeler la fonction elle-même, décomposant un problème complexe en plusieurs sous-problèmes similaires à résoudre, ce qui peut réduire considérablement la quantité de code et rendre le le programme ressemble à très élégant.

Parce que le système alloue un espace d'exécution pour chaque appel de fonction et l'enregistre à l'aide du stack push. Une fois l'appel de fonction terminé, le système doit libérer de l'espace et ouvrir la pile pour restaurer le point d'arrêt. Le coût de la récursion reste donc relativement élevé.

Même si la conception du langage a si parfaitement optimisé les appels de fonction que le gaspillage de ressources provoqué par la récursion peut être ignoré, la profondeur de la récursion sera toujours limitée par la capacité de la pile du système, sinon une StackOverflowError sera levée.

Et l'itération peut faire bon usage des caractéristiques des ordinateurs qui sont adaptées aux opérations répétées, et théoriquement, toutes les fonctions récursives peuvent être converties en fonctions itératives, alors essayez d'éviter la récursion sans récursion et utilisez l'itération Utilisez l'itération plutôt.

Afficher la taille du dossier

L'idée de l'itération est de laisser l'ordinateur exécuter à plusieurs reprises un ensemble d'instructions, à chaque fois qu'il s'exécute cet ensemble d'instructions, d'autres nouvelles valeurs sont déduites de la valeur originale de la variable... Ce processus est répété jusqu'à ce que la condition finale soit atteinte ou qu'aucune nouvelle valeur ne soit générée.

Puisque la récursion est équivalente à une boucle plus une pile, la pile peut être utilisée en itération pour convertir la récursivité et l'itération.


/**
 * 文件夹大小
 * @param $path
 * @return int
 */
function dirsize($path)
{
  /* 初始条件 */
  $size = 0;
  $stack = array();
  if (file_exists($path)) {
    $path = realpath($path) . '/';
    array_push($stack, '');
  } else {
    return -1;
  }
  /* 迭代条件 */
  while (count($stack) !== 0) {
    $dir = array_pop($stack);
    $handle = opendir($path . $dir);
    /* 执行过程 */
    while (($item = readdir($handle)) !== false) {
      if ($item == '.' || $item == '..') continue;
      $_path = $path . $dir . $item;
      if (is_file($_path)) $size += filesize($_path);
      /* 更新条件 */
      if (is_dir($_path)) array_push($stack, $dir . $item . '/');
    }
    closedir($handle);
  }
  return $size;
}

Copier le dossier

L'itération et la récursivité ont des variables d'initialisation et des conditions de fin de jugement. quatre étapes pour effectuer des opérations réelles et générer de nouvelles variables se trouvent simplement à des endroits différents.

Par exemple, l'étape d'initialisation des variables est située au début de la fonction en itération, tandis qu'en récursion elle fait référence au processus de transmission des paramètres à d'autres fonctions

L'étape de jugement ; la condition de fin, elle est utilisée en itération pour déterminer si la boucle continue, et en récursion, elle est utilisée pour déterminer la position finale de la récursion ;

L'exécution d'opérations réelles est la partie essentielle de la fonction dans les deux récursions et itération, avant l'étape de génération de nouvelles variables ;

La génération de nouvelles variables en itération est la condition de la suite de l'itération, et en récursion c'est la base de la prochaine récursion. La génération de nouvelles variables permet la. récursivité ou itération pour continuer.


/**
 * 复制文件夹
 * @param $source
 * @param $dest
 * @return string
 */
function copydir($source, $dest)
{
  /* 初始条件 */
  $stack = array();
  $target = '';
  if (file_exists($source)) {
    if (!file_exists($dest)) mkdir($dest);
    $source = realpath($source) . '/';
    $dest = realpath($dest) . '/';
    $target = realpath($dest);
    array_push($stack, '');
  }
  /* 迭代条件 */
  while (count($stack) !== 0) {
    $dir = array_pop($stack);
    $handle = opendir($source . $dir);
    if (!file_exists($dest . $dir)) mkdir($dest . $dir);
    /* 执行过程 */
    while (($item = readdir($handle)) !== false) {
      if ($item == '.' || $item == '..') continue;
      $_source = $source . $dir . $item;
      $_dest = $dest . $dir . $item;
      if (is_file($_source)) copy($_source, $_dest);
      /* 更新条件 */
      if (is_dir($_source)) array_push($stack, $dir . $item . '/');
    }
    closedir($handle);
  }
  return $target;
}

Supprimer le dossier

Laissez de côté les fonctionnalités linguistiques, ce qui affecte le plus les performances est un code de redondance, le code redondant est généralement dû à une conception inadéquate.

Dans la plupart des cas, la récursivité a plus de code redondant que l'itération, ce qui est également un facteur majeur dans la faible efficacité de la récursivité.

Mais lorsque le code récursif est suffisamment concis et que la redondance est suffisamment faible, les performances de l'itération ne peuvent pas être supérieures à celles de la récursivité.

Par exemple, cette fonction de suppression de dossier implémentée par itération est 20 % plus lente que la récursion. La raison principale est le jugement de dossier vide, lorsque le dossier n'a pas de sous-dossier, la fonction supprimera directement tous les fichiers. et le dossier actuel, la récursion se termine.

Même si le dossier est vide lors de l'itération, il doit être stocké dans la pile. Il sera jugé s'il est vide lors de l'itération suivante avant de pouvoir être supprimé. Par rapport à la récursivité, cela nécessite des opérations plus redondantes telles que déterminer que le fichier est vide, le stocker sur la pile et supprimer des itérations, de sorte que la vitesse de traitement sera plus lente que la récursivité.


/**
 * 删除文件夹
 * @param $path
 * @return bool
 */
function rmdirs($path)
{
  /* 初始化条件 */
  $stack = array();
  if (!file_exists($path)) return false;
  $path = realpath($path) . '/';
  array_push($stack, '');
  /* 迭代条件 */
  while (count($stack) !== 0) {
    $dir = end($stack);
    $items = scandir($path . $dir);
    /* 执行过程 */
    if (count($items) === 2) {
      rmdir($path . $dir);
      array_pop($stack);
      continue;
    }
    /* 执行过程 */
    foreach ($items as $item) {
      if ($item == '.' || $item == '..') continue;
      $_path = $path . $dir . $item;
      if (is_file($_path)) unlink($_path);
      /* 更新条件 */
      if (is_dir($_path)) array_push($stack, $dir . $item . '/');
    }
  }
  return !(file_exists($path));
}

Afficher le temps d'exécution

Il s'agit d'une vue du temps d'exécution du code (en millisecondes ) La fonction exécute le code cible (ou la fonction) via un rappel et calcule enfin le temps d'exécution (millisecondes). Grâce à cet outil, vous pouvez comparer l'écart de performances entre les fonctions. C'est un outil très simple et pratique.


/**
 * 函数执行毫秒数
 * @param $func
 * @return int
 */
function exec_time($func)
{
  $start = explode(' ', microtime());
  $func();// 执行耗时操作
  $end = explode(' ', microtime());
  $sec_time = floatval($end[0]) - floatval($start[0]);
  $mic_time = floatval($end[1]) - floatval($start[1]);
  return intval(($sec_time + $mic_time) * 1000);
}
echo exec_time(function () {
  /* 执行的耗时操作 */
});

Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!

Déclaration:
Le contenu de cet article est volontairement contribué par les internautes et les droits d'auteur appartiennent à l'auteur original. Ce site n'assume aucune responsabilité légale correspondante. Si vous trouvez un contenu suspecté de plagiat ou de contrefaçon, veuillez contacter admin@php.cn