ファイル操作を実行する場合、特にマルチスレッド環境で大きなファイルをコピーしたり、ファイルをコピーしたりする場合、同時の競合の問題に遭遇する可能性があります。一般的な並行性の問題は、ファイルがコピープロセス中に他のプロセスによってアクセスまたは変更されることです。これは、ファイルの破損を引き起こすだけでなく、予測不可能なエラーを引き起こす可能性があります。 PHPでは、 Stream_Supports_Lock()関数を使用することにより、この問題を回避できます。この記事では、この関数を使用して、ファイルのコピー中に同時競合がないことを確認する方法について説明します。
Stream_supports_lock()は、指定されたストリームがファイルロックをサポートするかどうかをチェックするPHPの組み込み関数です。ファイルロックは、複数のプロセスまたはスレッドで同じファイルへのアクセスを制御するために使用されるメカニズムであり、複数のプロセスが同時にファイルを書き込んだり読み取ったりしたときの競合を回避します。 Stream_supports_lock()関数は、ファイル操作を実行する前にファイルロックを使用してデータセキュリティを確保できるかどうかを開発者が確認するのに役立ちます。
<span><span><span class="hljs-keyword">bool</span></span><span> </span><span><span class="hljs-title function_ invoke__">stream_supports_lock</span></span><span> ( resource </span><span><span class="hljs-variable">$stream</span></span><span> )
</span></span>
パラメーター:この関数は、通常はFOPEN()関数を介して取得される有効なファイルストリームリソースであるパラメーター$ストリームを受け入れます。
戻り値:ストリームがファイルロックをサポートする場合、関数はtrueを返し、それ以外の場合はfalseを返します。
ファイルをコピーする前に、最初にソースファイルとターゲットファイルを開く必要があります。これは、PHPのFOPEN()関数で実行でき、ファイルが読み取りワイトモードで開かれることを保証します。
<span><span><span class="hljs-variable">$sourceFile</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fopen</span></span><span>(</span><span><span class="hljs-string">"source.txt"</span></span><span>, </span><span><span class="hljs-string">"r"</span></span><span>);
</span><span><span class="hljs-variable">$destFile</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fopen</span></span><span>(</span><span><span class="hljs-string">"destination.txt"</span></span><span>, </span><span><span class="hljs-string">"w"</span></span><span>);
</span></span>
ファイル操作を実行する前に、 Stream_Supports_Lock()を使用して、ファイルストリームがロックをサポートしているかどうかを確認します。ファイルロックがサポートされていない場合は、同時の競合を回避するために他の方法を使用することを検討してください(たとえば、データベースロックまたはアプリケーションレベルの並行性コントロールを使用してください)。
<span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">stream_supports_lock</span></span><span>(</span><span><span class="hljs-variable">$sourceFile</span></span><span>) && </span><span><span class="hljs-title function_ invoke__">stream_supports_lock</span></span><span>(</span><span><span class="hljs-variable">$destFile</span></span><span>)) {
</span><span><span class="hljs-comment">// サポートロック,続く</span></span><span>
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"文件流不サポートロック,並行性のセキュリティを確保することができません!"</span></span><span>;
</span><span><span class="hljs-keyword">exit</span></span><span>;
}
</span></span>
ファイルストリームがロックをサポートする場合、 Flock()関数を使用してソースファイルとターゲットファイルをロックできます。 Flock()関数を使用すると、ファイル操作中にロックできます。これにより、他のプロセスやスレッドが同時にファイルにアクセスすることを回避できます。
<span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">flock</span></span><span>(</span><span><span class="hljs-variable">$sourceFile</span></span><span>, LOCK_SH) && </span><span><span class="hljs-title function_ invoke__">flock</span></span><span>(</span><span><span class="hljs-variable">$destFile</span></span><span>, LOCK_EX)) {
</span><span><span class="hljs-keyword">while</span></span><span> (!</span><span><span class="hljs-title function_ invoke__">feof</span></span><span>(</span><span><span class="hljs-variable">$sourceFile</span></span><span>)) {
</span><span><span class="hljs-variable">$data</span></span><span> = </span><span><span class="hljs-title function_ invoke__">fgets</span></span><span>(</span><span><span class="hljs-variable">$sourceFile</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">fwrite</span></span><span>(</span><span><span class="hljs-variable">$destFile</span></span><span>, </span><span><span class="hljs-variable">$data</span></span><span>);
}
</span><span><span class="hljs-comment">// ロックを解放します</span></span><span>
</span><span><span class="hljs-title function_ invoke__">flock</span></span><span>(</span><span><span class="hljs-variable">$sourceFile</span></span><span>, LOCK_UN);
</span><span><span class="hljs-title function_ invoke__">flock</span></span><span>(</span><span><span class="hljs-variable">$destFile</span></span><span>, LOCK_UN);
} </span><span><span class="hljs-keyword">else</span></span><span> {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-string">"ファイルロックを取得できません,操作に失敗しました!"</span></span><span>;
</span><span><span class="hljs-keyword">exit</span></span><span>;
}
</span></span>
lock_sh :共有ロック。他のプロセスが読み取り専用モードでファイルにアクセスできるようにします。
lock_ex :他のプロセスがファイルにアクセスすることを禁止する排他的ロック。
lock_un :ロック解除。
ファイルのコピーが完了したら、ファイルストリームを閉じてシステムリソースを解放することを忘れないでください。
<span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$sourceFile</span></span><span>);
</span><span><span class="hljs-title function_ invoke__">fclose</span></span><span>(</span><span><span class="hljs-variable">$destFile</span></span><span>);
</span></span>
Stream_supports_lock()およびflock()関数を使用することにより、PHPは、ファイルのコピー中に同時競合が発生しないことを保証する効果的なファイルロックメカニズムを提供します。合理的なファイルロック制御により、データの整合性を保証し、ファイルの破損またはコピーエラーを回避できます。マルチプロセスまたはマルチスレッドファイル操作の場合、ファイルロックを使用することは、並行性セキュリティを確保するための重要な手段です。