「PHPの基礎 - 圧縮・解凍」の版間の差分

ナビゲーションに移動 検索に移動
5行目: 5行目:
以下に示す例では、非同期処理のサポート、ストリーミング処理による効率的なメモリ使用、エラーハンドリングを実装している。<br>
以下に示す例では、非同期処理のサポート、ストリーミング処理による効率的なメモリ使用、エラーハンドリングを実装している。<br>
また、3つの圧縮形式 (ZIP、tar.gz、tar.xz) に対応している。<br>
また、3つの圧縮形式 (ZIP、tar.gz、tar.xz) に対応している。<br>
<br>
* declare(strict_types=1);
*: これは、型の厳密なチェックを行うための宣言である。
*: 例えば、string型を期待する引数に整数を渡した場合にエラーとなる。
*: コードの信頼性を高めるために推奨されるが、必須ではない。
*: チーム開発で型の一貫性を保つ場合、バグの早期発見を重視する場合、型の安全性を重視する場合は記述する。
<br>
* namespaceを使用する場合
*: これは、名前空間を定義するための宣言である。
*: コードの整理や名前の衝突を避けるために使用する。
*: 大規模なプロジェクトやライブラリとして使用する場合に有効であるが、単独のスクリプトとして使用する場合は不要である。
*: また、コードを再利用可能なライブラリとして提供する場合、オートローディングを使用する場合、他のライブラリとの名前衝突を避けたい場合等に記述する。
<br>
<br>
==== ZIP形式 ====
==== ZIP形式 ====
318行目: 330行目:
     // tar.xz形式の場合
     // tar.xz形式の場合
     foreach ($compression->compressAsync('/path/to/source', '/path/to/output.zip', 'zip') as $status) {
     foreach ($compression->compressAsync('/path/to/source', '/path/to/output.zip', 'zip') as $status) {
      echo $status . PHP_EOL;
    }
}
catch (RuntimeException $e) {
    echo "エラーが発生しました: " . $e->getMessage();
}
</syntaxhighlight>
<br><br>
== 解凍 ==
以下に示す例では、非同期処理のサポート、ストリーミング処理による効率的なメモリ使用、エラーハンドリングを実装している。<br>
また、3つの解凍形式 (ZIP、tar.gz、tar.xz) に対応している。<br>
<br>
* declare(strict_types=1);
*: これは、型の厳密なチェックを行うための宣言である。
*: 例えば、string型を期待する引数に整数を渡した場合にエラーとなる。
*: コードの信頼性を高めるために推奨されるが、必須ではない。
*: チーム開発で型の一貫性を保つ場合、バグの早期発見を重視する場合、型の安全性を重視する場合は記述する。
<br>
* namespaceを使用する場合
*: これは、名前空間を定義するための宣言である。
*: コードの整理や名前の衝突を避けるために使用する。
*: 大規模なプロジェクトやライブラリとして使用する場合に有効であるが、単独のスクリプトとして使用する場合は不要である。
*: また、コードを再利用可能なライブラリとして提供する場合、オートローディングを使用する場合、他のライブラリとの名前衝突を避けたい場合等に記述する。
<br>
==== ZIP形式 ====
<syntaxhighlight lang="php">
declare(strict_types=1);
namespace Utils;
use RuntimeException;
use ZipArchive;
use Generator;
/**
  * ZIPファイルを解凍するメソッド
  *
  * @param string $sourceFile 解凍対象のZIPファイルパス
  * @param string $destinationPath 解凍先のディレクトリパス
  * @throws RuntimeException 解凍処理中のエラー発生時
  */
function extractZip(string $sourceFile, string $destinationPath): void
{
    try {
      if (!file_exists($sourceFile)) {
          throw new RuntimeException('指定されたZIPファイルが存在しません');
      }
      $zip = new ZipArchive();
      $result = $zip->open($sourceFile);
      if ($result !== true) {
          throw new RuntimeException("ZIPファイルのオープンに失敗しました(エラーコード: {$result})");
      }
      // 解凍先ディレクトリが存在しない場合は作成
      if (!file_exists($destinationPath)) {
          if (!mkdir($destinationPath, 0777, true)) {
            throw new RuntimeException('解凍先ディレクトリの作成に失敗しました');
          }
      }
      if (!$zip->extractTo($destinationPath)) {
          throw new RuntimeException('ZIPファイルの解凍に失敗しました');
      }
      $zip->close();
    }
    catch (\Exception $e) {
      throw new RuntimeException("ZIP解凍処理中にエラーが発生しました: {$e->getMessage()}");
    }
}
</syntaxhighlight>
<br>
<syntaxhighlight lang="php">
// 使用例
$decompression = new Utils\DecompressionUtils();
try {
    // ZIP解凍の例
    $decompression->extractZip('/path/to/archive.zip', '/path/to/destination');
}
catch (RuntimeException $e) {
    echo "エラーが発生しました: " . $e->getMessage();
}
</syntaxhighlight>
<br>
==== tar.gz形式 ====
<syntaxhighlight lang="php">
declare(strict_types=1);
namespace Utils;
use RuntimeException;
use Generator;
/**
  * tar.gzファイルを解凍するメソッド
  *
  * @param string $sourceFile 解凍対象のtar.gzファイルパス
  * @param string $destinationPath 解凍先のディレクトリパス
  * @throws RuntimeException 解凍処理中のエラー発生時
  */
function extractTarGz(string $sourceFile, string $destinationPath): void
{
    try {
      if (!file_exists($sourceFile)) {
          throw new RuntimeException('指定されたtar.gzファイルが存在しません');
      }
      // 解凍先ディレクトリの作成
      if (!file_exists($destinationPath)) {
          if (!mkdir($destinationPath, 0777, true)) {
            throw new RuntimeException('解凍先ディレクトリの作成に失敗しました');
          }
      }
      // 一時的なTARファイルの作成
      $tempTarFile = tempnam(sys_get_temp_dir(), 'tar');
      // gzipファイルの解凍(ストリーミング処理)
      $gz = gzopen($sourceFile, 'rb');
      if ($gz === false) {
          throw new RuntimeException('GZIPファイルのオープンに失敗しました');
      }
      $tarHandle = fopen($tempTarFile, 'wb');
      if ($tarHandle === false) {
          throw new RuntimeException('一時ファイルの作成に失敗しました');
      }
      while (!gzeof($gz)) {
          fwrite($tarHandle, gzread($gz, 8192));
      }
      gzclose($gz);
      fclose($tarHandle);
      // tarの展開
      $currentDir = getcwd();
      chdir($destinationPath);
      exec("tar -xf {$tempTarFile}", $output, $returnCode);
      chdir($currentDir);
      if ($returnCode !== 0) {
          throw new RuntimeException('TARファイルの展開に失敗しました');
      }
      // 一時ファイルの削除
      unlink($tempTarFile);
    }
    catch (\Exception $e) {
      throw new RuntimeException("tar.gz解凍処理中にエラーが発生しました: {$e->getMessage()}");
    }
}
</syntaxhighlight>
<br>
<syntaxhighlight lang="php">
// 使用例
$decompression = new Utils\DecompressionUtils();
try {
    // tar.gz解凍の例
    $decompression->extractTarGz('/path/to/archive.tar.gz', '/path/to/destination');
}
catch (RuntimeException $e) {
    echo "エラーが発生しました: " . $e->getMessage();
}
</syntaxhighlight>
<br>
==== tar.xz形式 ====
<syntaxhighlight lang="php">
declare(strict_types=1);
namespace Utils;
use RuntimeException;
use Generator;
/**
  * tar.xzファイルを解凍するメソッド
  *
  * @param string $sourceFile      解凍対象のtar.xzファイルパス
  * @param string $destinationPath 解凍先のディレクトリパス
  * @throws RuntimeException      解凍処理中のエラー発生時
  */
function extractTarXz(string $sourceFile, string $destinationPath): void
{
    try {
      if (!extension_loaded('xz')) {
          throw new RuntimeException('XZ拡張機能がインストールされていません');
      }
      if (!file_exists($sourceFile)) {
          throw new RuntimeException('指定されたtar.xzファイルが存在しません');
      }
      // 解凍先ディレクトリの作成
      if (!file_exists($destinationPath)) {
          if (!mkdir($destinationPath, 0777, true)) {
            throw new RuntimeException('解凍先ディレクトリの作成に失敗しました');
          }
      }
      // 一時的なTARファイルの作成
      $tempTarFile = tempnam(sys_get_temp_dir(), 'tar');
      // xzファイルの解凍(ストリーミング処理)
      $xz = xzopen($sourceFile, 'rb');
      if ($xz === false) {
          throw new RuntimeException('XZファイルのオープンに失敗しました');
      }
      $tarHandle = fopen($tempTarFile, 'wb');
      if ($tarHandle === false) {
          throw new RuntimeException('一時ファイルの作成に失敗しました');
      }
      while (!xzeof($xz)) {
          fwrite($tarHandle, xzread($xz, 8192));
      }
      xzclose($xz);
      fclose($tarHandle);
      // tarの展開
      $currentDir = getcwd();
      chdir($destinationPath);
      exec("tar -xf {$tempTarFile}", $output, $returnCode);
      chdir($currentDir);
      if ($returnCode !== 0) {
          throw new RuntimeException('TARファイルの展開に失敗しました');
      }
      // 一時ファイルの削除
      unlink($tempTarFile);
    }
    catch (\Exception $e) {
      throw new RuntimeException("tar.xz解凍処理中にエラーが発生しました: {$e->getMessage()}");
    }
}
</syntaxhighlight>
<br>
<syntaxhighlight lang="php">
// 使用例
$decompression = new Utils\DecompressionUtils();
try {
    // tar.gz解凍の例
    $decompression->extractTarXz('/path/to/archive.tar.xz', '/path/to/destination');
}
catch (RuntimeException $e) {
    echo "エラーが発生しました: " . $e->getMessage();
}
</syntaxhighlight>
<br>
==== 非同期処理 ====
<syntaxhighlight lang="php">
/**
  * 非同期でファイル解凍を行うメソッド
  *
  * @param string $sourceFile      解凍対象のファイルパス
  * @param string $destinationPath  解凍先のディレクトリパス
  * @param string $type            解凍形式('zip', 'tar.gz', 'tar.xz'のいずれか)
  * @return Generator              解凍の進捗状況を返すジェネレータ
  */
function extractAsync(string $sourceFile, string $destinationPath, string $type): Generator
{
    yield '解凍処理を開始します...';
    try {
      switch ($type) {
          case 'zip':
            yield 'ZIPファイルの解凍を開始します...';
            $this->extractZip($sourceFile, $destinationPath);
            break;
          case 'tar.gz':
            yield 'tar.gzファイルの解凍を開始します...';
            $this->extractTarGz($sourceFile, $destinationPath);
            break;
          case 'tar.xz':
            yield 'tar.xzファイルの解凍を開始します...';
            $this->extractTarXz($sourceFile, $destinationPath);
            break;
          default:
            throw new RuntimeException('不正な解凍形式が指定されました');
      }
      yield '解凍処理が完了しました';
    }
    catch (\Exception $e) {
      yield "解凍処理中にエラーが発生しました: {$e->getMessage()}";
      throw $e;
    }
}
</syntaxhighlight>
<br>
<syntaxhighlight lang="php">
// 使用例
$decompression = new Utils\DecompressionUtils();
try {
    // 非同期処理の例
    // ZIP形式の場合
    foreach ($decompression->extractAsync('/path/to/archive.zip', '/path/to/destination', 'zip') as $status) {
      echo $status . PHP_EOL;
    }
    // tar.gz形式の場合
    foreach ($decompression->extractAsync('/path/to/archive.tar.gz', '/path/to/destination', 'gz') as $status) {
      echo $status . PHP_EOL;
    }
    // tar.xz形式の場合
    foreach ($decompression->extractAsync('/path/to/archive.tar.xz', '/path/to/destination', 'xz') as $status) {
       echo $status . PHP_EOL;
       echo $status . PHP_EOL;
     }
     }

案内メニュー