【PHP】PHP上で長大なデータを圧縮文字列にする

  • 2020年6月5日
  • PHP

 この記事で紹介するのはPHP上であるデータを可逆圧縮する方法と例です。通信内容のログなど何かしら大きなデータをデータベースに格納する時に特に役に立つ方法です。
 使うのはZlib関数のgzcompress, gzencode, gzdeflateです。これらはgzip圧縮の様な(gzencodeはgzip圧縮そのもの)圧縮をします。それぞれ対応する解凍関数があり、PHP上(メモリ上)のみで完結できます。
PHP: Zlib – Manual
PHP: gzcompress – Manual
PHP: gzencode – Manual
PHP: gzdeflate – Manual
 使用例は次です。

<?php
/** @see http://sandbox.onlinephpfunctions.com/code/b61e09f21ce9ec4f0c03cff5b625845c2aecfcad */ 
// $data = random_str(1e6); // 英数字ランダム
// $data = str_repeat('a',1e7); // 同じ文字を繰り返し
$data = serialize(range(1, 1000)); // 規則的な文字列
echo 'strlen($data) : ' . strlen($data) . "\n\n";

$gzc = gzcompress($data);
echo 'strlen(gzcompress($data))    : ' . strlen($gzc) . "\n";
echo 'strlen(gzcompress($data, 9))    : ' . strlen(gzcompress($data, 9)) . "\n";
echo 'gzuncompress($gzc) === $data : ' . (gzuncompress($gzc) === $data ? 'true' : 'false') . "\n\n";

$gze = gzencode($data);
echo 'strlen(gzencode($data))  : ' . strlen($gze) . "\n";
echo 'strlen(gzencode($data, 9))  : ' . strlen(gzencode($data, 9)) . "\n";
echo 'gzdecode($gze) === $data : ' . (gzdecode($gze) === $data ? 'true' : 'false') . "\n\n";

$gzd = gzdeflate($data);
echo 'strlen(gzdeflate($data))  : ' . strlen($gzd) . "\n";
echo 'strlen(gzdeflate($data, 9))  : ' . strlen(gzdeflate($data, 9)) . "\n";
echo 'gzinflate($gze) === $data : ' . (gzinflate($gzd) === $data ? 'true' : 'false') . "\n";

function random_str($length)
{
	$bytes = random_bytes($length);
	
	return substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $length);
}

// strlen($data) : 11792
//
// strlen(gzcompress($data))    : 1395
// strlen(gzcompress($data, 9))    : 1391
// gzuncompress($gzc) === $data : true
//
// strlen(gzencode($data))  : 1407
// strlen(gzencode($data, 9))  : 1403
// gzdecode($gze) === $data : true
//
// strlen(gzdeflate($data))  : 1389
// strlen(gzdeflate($data, 9))  : 1385
// gzinflate($gze) === $data : true

 第二引数は圧縮レベルです。例では1/10以下になる圧縮率で非常に強力な動作をしていますがこれは元データの規則性に左右されます。圧縮率の振れ幅は英数字完全ランダムでは3/4程度、同じ文字がひたすら続くならば1/1000程度と大きいです。
 実行速度は格別遅いような感覚もなく自然に使えます。データベースに保存する場合、直接人間がSQLを叩いてログを読めなくなりますが、ディスクをあまり占有しない上カラムで指定されたデータサイズより大きなデータを格納しようとする問題を起きにくくできます。

>株式会社シーポイントラボ

株式会社シーポイントラボ

TEL:053-543-9889
営業時間:9:00~18:00(月〜金)
住所:〒432-8003
   静岡県浜松市中央区和地山3-1-7
   浜松イノベーションキューブ 315
※ご来社の際はインターホンで「316」をお呼びください

CTR IMG