代码之家  ›  专栏  ›  技术社区  ›  PHLAK

如何使用PHP检查目录内容是否已更改?

  •  26
  • PHLAK  · 技术社区  · 17 年前

    我正在用PHP编写一个照片库脚本,并有一个用户存储图片的目录。我正在尝试设置页面缓存,只有在目录内容发生更改时才刷新缓存。我想我可以通过使用filemtime()函数缓存目录的最后修改时间并将其与目录的当前修改时间进行比较来实现这一点。然而,正如我所意识到的那样,目录修改时间不会随着文件的添加或从该目录中删除而改变(至少在Windows上,还不确定Linux机器)。

    所以我的问题是,检查目录内容是否已被修改的最简单方法是什么?

    11 回复  |  直到 17 年前
        1
  •  23
  •   troelskn    17 年前

    正如其他人已经提到的,解决这个问题的更好方法是在特定事件发生时触发一个函数,该函数会更改文件夹。 但是,如果您的服务器是unix,则可以使用 inotifywait

    #!/bin/sh
    inotifywait --recursive --monitor --quiet --event modify,create,delete,move --format '%f' /path/to/directory/to/watch |
      while read FILE ; do
        php /path/to/trigger.php $FILE
      done
    

    另请参见: http://linux.die.net/man/1/inotifywait

        2
  •  8
  •   scunliffe    17 年前

    那...呢 touching 用户提交图像后的目录?

        3
  •  7
  •   chic    15 年前

    php内置inotifywait

    $watchedDir = 'watch';
    
    $in = popen("inotifywait --monitor --quiet --format '%e %f' --event create,moved_to '$watchedDir'", 'r');
    if ($in === false)
        throw new Exception ('fail start notify');
    
    while (($line = fgets($in)) !== false) 
    {
        list($event, $file) = explode(' ', rtrim($line, PHP_EOL), 2);
        echo "$event $file\n";
    }
    
        4
  •  6
  •   MSpreij    17 年前

    嗯我只需存储目录列表的md5。如果内容发生变化,md5(目录列表)也会发生变化。你 可能 偶尔会发生md5冲突,但我认为这种机会很小。。


        5
  •  3
  •   Anton Gogolev    17 年前

    国际海事组织 edubem's answer 这是正确的做法,但你可以这样做:

    if (sha1(serialize(Map('/path/to/directory/', true))) != /* previous stored hash */)
    {
        // directory contents has changed
    }
    

    或者一个更弱/更快的版本:

    if (Size('/path/to/directory/', true) != /* previous stored size */)
    {
        // directory contents has changed
    }
    

    以下是所使用的函数:

    function Map($path, $recursive = false)
    {
        $result = array();
    
        if (is_dir($path) === true)
        {
            $path = Path($path);
            $files = array_diff(scandir($path), array('.', '..'));
    
            foreach ($files as $file)
            {
                if (is_dir($path . $file) === true)
                {
                    $result[$file] = ($recursive === true) ? Map($path . $file, $recursive) : $this->Size($path . $file, true);
                }
    
                else if (is_file($path . $file) === true)
                {
                    $result[$file] = Size($path . $file);
                }
            }
        }
    
        else if (is_file($path) === true)
        {
            $result[basename($path)] = Size($path);
        }
    
        return $result;
    }
    
    function Size($path, $recursive = true)
    {
        $result = 0;
    
        if (is_dir($path) === true)
        {
            $path = Path($path);
            $files = array_diff(scandir($path), array('.', '..'));
    
            foreach ($files as $file)
            {
                if (is_dir($path . $file) === true)
                {
                    $result += ($recursive === true) ? Size($path . $file, $recursive) : 0;
                }
    
                else if (is_file() === true)
                {
                    $result += sprintf('%u', filesize($path . $file));
                }
            }
        }
    
        else if (is_file($path) === true)
        {
            $result += sprintf('%u', filesize($path));
        }
    
        return $result;
    }
    
    function Path($path)
    {
        if (file_exists($path) === true)
        {
            $path = rtrim(str_replace('\\', '/', realpath($path)), '/');
    
            if (is_dir($path) === true)
            {
                $path .= '/';
            }
    
            return $path;
        }
    
        return false;
    }
    
        6
  •  3
  •   SchizoDuckie    17 年前

    /username

        7
  •  3
  •   Community Mohan Dere    9 年前

        8
  •  1
  •   Mario    17 年前

    当用户将文件上传到他的目录时,尝试删除缓存的版本。

        9
  •  1
  •   Moises Kirsch    16 年前

    http://www.franzone.com/2008/06/05/php-script-to-monitor-ftp-directory-changes/

    对我来说,这似乎是一个很好的解决方案,因为我有很多控制权(我将进行AJAX调用,看看是否有任何变化)。

        10
  •  1
  •   Aldekein    12 年前

    我在备份中使用它。

    $longString .= filesize($file);
    

    $longString .= crc32(file_get_contents($file));
    

    #!/usr/bin/php
    <?php
    
    $dirName = $argv[1];
    $basePath = '/var/www/vhosts/majestichorseporn.com/web/';
    $dataFile = './backup_dir_if_changed.dat';
    
    # startup checks
    if (!is_writable($dataFile))
        die($dataFile . ' is not writable!');
    
    if (!is_dir($basePath . $dirName))
        die($basePath . $dirName . ' is not a directory');
    
    $dataFileContent = file_get_contents($dataFile);
    $data = @unserialize($dataFileContent);
    if ($data === false)
        $data = array();
    
    # find all files ang concatenate their sizes to calculate crc32
    $files = glob($basePath . $dirName . '/*', GLOB_BRACE);
    
    $longString = '';
    foreach ($files as $file) {
        $longString .= filesize($file);
    }
    $longStringHash = crc32($longString);
    
    # do changed check
    if (isset ($data[$dirName]) && $data[$dirName] == $longStringHash)
        die('Directory did not change.');
    
    # save hash do DB
    $data[$dirName] = $longStringHash;
    
    file_put_contents($dataFile, serialize($data));
    die('0');
    
    推荐文章