简体   繁体   English

使用PHP-PHAR将数据附加到tar文件

[英]Append data to tar file using PHP-PHAR

I'm using the following code to create and append data to a tar-archive in PHP. 我正在使用以下代码在PHP中创建数据并将其附加到tar归档文件中。 The problem is that phar does not use an exclusive lock on the tar-file causing problem when I have atomic writes to the same file. 问题是,当我对同一文件进行原子写入时,phar不会在tar文件上使用排他锁,从而导致问题。

function phar_put_contents($fname, $archive, $data) { 
  $i=0;
  do { 
    $fp = @fopen($archive.'.lock', 'w');
    if(!$fp) { 
      usleep(25);
      continue;
    } 
    if(flock($fp, LOCK_EX)) { 
      try{
        $myPhar = new PharData($archive.'.tar',0);
        $myPhar[$fname] = $data;
        $myPhar->stopBuffering();
        flock($fp, LOCK_UN) && @fclose($fp);
        @unlink($archive.'.lock');
        return true;
      } catch (Exception $e) { 
        error_log($e->getMessage()." in ".$e->getFile().":".$e->getLine(),0);
        unset($e);
        @flock($fp, LOCK_UN) && @fclose($fp);
      } 
    } 
  } while ($i++<8);
  return false;
}

Using a look file seems to be a "good" solution but it's not optimal since my archives gets currupted quite frequently. 使用外观文件似乎是一个“不错”的解决方案,但这并不是最佳选择,因为我的存档经常损坏。

Ok, it seems like the Phar and PharData classes in PHP is somewhat unfinished, they neither have lock() nor close() making my approach for external locking nonworking.. 好的,似乎PHP中的Phar和PharData类还没有完成,它们既没有lock()也没有close()这使我的外部锁定方法不起作用。

The following code is what I used to try to have a function that appends data to a tar archive. 以下代码是我用来尝试具有将数据追加到tar存档的功能的代码。

function phar_put_contents($fname, $archive, $data) { 
  $i=0;
  do { 
    $fp = @fopen($archive.'.lock', 'w');
    if(!$fp) { 
      usleep(25);
      continue;
    } 
    if(flock($fp, LOCK_EX)) { 
      try{
        file_put_contents('/tmp/'.$fname, $data);
        $tarCmd = "tar ". (file_exists($archive.".tar") ? "-rf ":"-cf ") .$archive.".tar  -C /tmp ".$fname;
        exec($tarCmd, $result, $status);
        if($status!=0)
          throw new Exception($tarCmd . implode($result, "\n"));
        @unlink('/tmp/'.$fname);
        flock($fp, LOCK_UN) && @fclose($fp);
        @unlink($archive.'.lock');
        return true;
      } catch (Exception $e) { 
        error_log($e->getMessage()." in ".$e->getFile().":".$e->getLine(),0);
        unset($e);
        @flock($fp, LOCK_UN) && @fclose($fp);
      } 
    } 
  } while ($i++<8);
  return false;
}

Note that I'm using exec() and calls the external version of tar . 请注意,我正在使用exec()并调用tar的外部版本。 This were a necessity since Phar does very unreliable flushes to the archive, making the tar-file broken since two instances of the code can modify the same file at the same time. 这是有必要的,因为Phar会对存档进行非常不可靠的刷新,由于文件的两个实例可以同时修改同一个文件,因此tar文件被破坏了。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM