• 首页
  • vue
  • TypeScript
  • JavaScript
  • scss
  • css3
  • html5
  • php
  • MySQL
  • redis
  • jQuery
  • touch()

    (PHP 4, PHP 5, PHP 7)

    设定文件的访问和修改时间

    说明

    touch(string $filename[,int $time= time()[,int $atime]]): bool

    尝试将由$filename给出的文件的访问和修改时间设定为给出的$time。注意访问时间总是会被修改的,不论有几个参数。

    如果文件不存在,则会被创建。

    参数

    $filename

    要设定的文件名。

    $time

    要设定的时间。如果没有提供参数$time则会使用当前系统的时间。

    $atime

    如果给出了这个参数,则给定文件的访问时间会被设为$atime,否则会设置为$time。如果没有给出这两个参数,则使用当前系统时间。

    返回值

    成功时返回TRUE,或者在失败时返回FALSE

    更新日志

    版本说明
    5.3.0能够修改 Windows 下目录的最后修改时间。

    范例

    Example #1touch()例子

    <?php
    if (touch($filename)) {
        echo $filename . ' modification time has been changed to present time';
    } else {
        echo 'Sorry, could not change modification time of ' . $filename;
    }
    ?>
    

    使用$time参数的touch()

    <?php
    // This is the touch time, we'll set it to one hour in the past.
    $time = time() - 3600;
    // Touch the file
    if (!touch('some_file.txt', $time)) {
        echo 'Whoops, something went wrong...';
    } else {
        echo 'Touched file with success';
    }
    ?>
    

    注释

    Note:

    注意:不同文件系统对时间的判断方法可能是不相同的。

    Warning

    在 PHP 5.3.0 之前无法修改 Windows 下目录的最后修改时间。

    Note that when PHP is called by f.e. apache or nginx instead of directly from the command line, touch() will not prefix the location of the invoking script, so the supplied filename must contain an absolute path.
    With script started from /home/user/www, this will not touch "/home/user/www/somefile":
    <?php
      touch( 'somefile' );
    ?>
    But this will:
    <?php
      touch( __DIR__ . '/somefile' );
    ?>
    
    I've been trying to set a filemtime into the future with touch() on PHP5.
    It seems touch $time has a future limit around 1000000 seconds (11 days or so). Beyond this point it reverts to a previous $time.
    It doesn't make much sense but I could save you hours of time.
    $time = time()+1500000;
    touch($cachedfile,$time);
    Update the access time without updating the modified time:
    Unix command: touch -a filename
    PHP: touch(filename, date('U', filemtime(filename)), time())
    If you're going to go around deleting (unlinking) files
    that you don't own just in order to change the modification
    time on the file, you darn well better chown() the file 
    back to it's original ownership after you are done and
    chmod() it back to it's correct permissions. Otherwise 
    you will almost certainly break things. Additionally the
    code listed for touch()ing a file you don't own should 
    set the file creation time back to it's original time if 
    what is wanted is to just change the modification time.
    Also, the code listed will break things if there is an i/o 
    error such as disk full or too many files in the directory.
    Here's how the code SHOULD be written:
    Create the new file FIRST, rather than last, with a different
    name such as $file.tmp.
    Read the ownership, permissions, and creation time of the old file.
    Set permissions and creation time of the new file the same as the old.
    Rename the new file to the name of the old.
    chown() the new file to the user that owned the file it's replacing.
    Please be careful adding to the documentation if you've 
    never taken programming 101.
    I has passed a small test to check which function is faster to create a new file. 
    file_put_contents vs touch
    <?php
    for($i = 0; $i < 100; $i++)
    {
       file_put_contents('dir/file'.$i, '');
    }
    ?>
    Average time: 0,1145s
    <?php
    for($i = 0; $i < 100; $i++)
    {
       touch('dir/file'.$i);
    }
    ?>
    Average time: 0,2322s
    So, file_put_contents is faster than touch, about two times.
    Only way to change modification date in catalogue is to create file in via touch() and dalete it with unlink():
    <?php
    $dir  = 'temp';
    $files1 = scandir($dir);
    $files1 = array_slice($files1, 2);
    foreach ($files1 as $key => $val) 
    {
      if (!is_dir($val)) continue;
      if (!touch($val)) 
      {
        touch($val . "/plik.txt");
        unlink($val . "/plik.txt");
      }
    }
    ?>
    
    Note: the script to touch a file you don't own will change it's owner so ensure permissions are correct or you could lose access to it
    Actually, Glen is right, PHP won't touch if it is not the current owner of the file, even if the directory and files are writeable by the PHP user.
    To touch a file without being owner, it is much easier:
    <?php
    function touchFile($file) {
     fclose(fopen($file, 'a'));
    }
    ?>
    
    At least on Linux, touch will not change the time on a symlink itself, but on the file/directory it points to. The only way to work around this is to unlink the symlink, then recreate it.
    It took a bit of searching to discover this. The OS itself provides no way to do it. Many people wondered why anyone would want to do this. I use symlinks inside a web tree to point to files outside the web tree. After a certain length of time has passed, I want the symlinks to die, so the files cannot be successfully hotlinked.
    I needed to use this to touch the /etc/cron.d directory when I updated some files in there. I know the docs say this isn't necessary, but I'm finding that i need to do it in order form my changes to be picked up quickly. 
    I ran into the permissions error as well and I found that using chmod 777 /etc/cron.d does the trick.
    So, you should be able to use the PHP touch function on a directory that has open write access.
    Of course, this isn't the most secure approach, but in our application it's not a big deal for that folder to not be super secure.
    A better explanation:
    For file $file and UNIX time stored in vars $access and $modified
    - change only access time
    \touch($file, \filemtime($file), $access);
    - change only modified time
    \touch($file, $modified, \fileatime($file));
    - change both access and modified time
    \touch($file, $modified, $access);
    Seeing the results:
    //use a session cookie stored in a custom folder
    $file = '/var/www/test_com/session/sess_qfn587cudfpgsijm1bs4d81s75';
    echo 'stats for sess_qfn587cudfpgsijm1bs4d81s75<br/>';
    \clearstatcache();
    echo 'access: '.\date("Y-m-d H:i:s", \fileatime($file)).'<br/>';
    echo 'modified: '.\date("Y-m-d H:i:s", \filemtime($file)).'<br/>';
    echo 'change access to now, modified +1 hour<br/>';
    \touch($x, \filemtime($file)+3600, time());
    \clearstatcache();
    echo 'access: '.\date("Y-m-d H:i:s", \fileatime($file)).'<br/>';
    echo 'modified: '.\date("Y-m-d H:i:s", \filemtime($file)).'<br/>';
    Notice the double call to clearstatcache()!
    In unix on the command-line, you can touch files you don't own - but like other comments on this page state - PHP's built in touch won't work.
    I simple alternative (on unix):
    <?php
      function touch_it_good($filename)
      {
        exec("touch {$filename}");
      }
    ?>
    
    Important info:
    touch() used on a directory always returns FALSE and prints "Permission denied" on NTFS and FAT Filesystem (tested on winXP).
    Here's a little workaround that allows the PHP user to touch a file it doesn't own:
    <?php
      $target_file = "/path/to/file/filename.txt"; //system filepath to your file
      $file_content = implode("",file($target_file));
      @unlink($target_file);
      if($savetofile = fopen($target_file, "w")) {
        fputs($savetofile, $file_content);
        fclose($savetofile);
      }
      $new_date = strtotime("23 April 2005"); // set the required date timestamp here
      touch($target_file,$new_date);
     
    ?>
    Of course, PHP needs to have write access to the folder containing the file you want to touch, but that should be easy to arrange.
    Neat little script that will give you a list of all modified files in a certain folder after a certain date:
    $filelist = Array();
    $filelist = list_dir("d:\\my_folder");
    for($i=0;$i<count($filelist);$i++){
      $test = Array();
      $test = explode("/",date("m/d/Y",filemtime($filelist[$i])));
    //example of files that are later then
    //06/17/2002
      if(($test[2] > 2001) && ($test[1] > 16) && ($test[0] > 5)){
        echo $filelist[$i]."\r\n";
      }
      clearstatcache();
    }
    function list_dir($dn){
      if($dn[strlen($dn)-1] != '\\') $dn.='\\';
      static $ra = array();
      $handle = opendir($dn);
      while($fn = readdir($handle)){
        if($fn == '.' || $fn == '..') continue;
        if(is_dir($dn.$fn)) list_dir($dn.$fn.'\\');
        else $ra[] = $dn.$fn;
      }
      closedir($handle);
      return $ra;
    }
    An earlier comment referenced a code snippet that showed file_put_contents() was faster the touch for creating files. I re-ran the same tests on PHP 5.5.9 and this seems to no longer be the case.
    <?php
    $startTime = microtime(true);
    for($i = 0; $i < 100000; $i++)
    {
      file_put_contents('dir/file'.$i, '');
      unlink('dir/file'.$i);
    }
    echo "Time: ".(microtime(true)-$startTime)."\n"; // Time: 2.6902809143066
    $startTime = microtime(true);
    for($i = 0; $i < 100000; $i++)
    {
      touch('dir/file'.$i);
      unlink('dir/file'.$i);
    }
    echo "Time: ".(microtime(true)-$startTime)."\n"; // Time: 2.3343770503998
    ?>
    

    上篇:tmpfile()

    下篇:umask()