[タイトル] PHPのis_writeable()関数にはバグがあり、ディレクトリ/ファイルが書き込み可能かどうかを正確に判定できません。ディレクトリ/ファイルが完全に書き込み可能かどうかを判定する関数を作成してください。
【レベル】レベル6
【解決策】 以下はCodeIgniterのis_really_writable関数の解決策です。詳細は関数のコメントを参照してください
。
このバグは 2 つの側面で存在します。
1. Windows では、ファイルが読み取り専用属性しか持たない場合、is_writeable() 関数は true を返しても、ファイルは書き込み可能であるとは限りません。
ディレクトリの場合は、そのディレクトリ内に新しいファイルを作成し、そのファイルを開いて判断します。
ファイルの場合は、ファイルを開く (fopen) ことで、ファイルが書き込み可能かどうかをテストできます。
2. Unix では、php 設定ファイルでセーフモードがオンになっている場合 (safe_mode=on)、is_writeable() も使用できません。
構成ファイルを読んで、safe_mode がオンになっているかどうかを確認します。
<code><span>/** * Tests for file writability * * is_writable() returns TRUE on Windows servers when you really can't write to * the file, based on the read-only attribute. is_writable() is also unreliable * on Unix servers if safe_mode is on. * *<span> @access</span> private *<span> @return</span> void */</span><span>if</span> ( ! function_exists(<span>'is_really_writable'</span>)) { <span><span>function</span><span>is_really_writable</span><span>(<span>$file</span>)</span> {</span><span>// If we're on a Unix server with safe_mode off we call is_writable</span><span>if</span> (DIRECTORY_SEPARATOR == <span>'/'</span><span>AND</span> @ini_get(<span>"safe_mode"</span>) == <span>FALSE</span>) { <span>return</span> is_writable(<span>$file</span>); } <span>// For windows servers and safe_mode "on" installations we'll actually</span><span>// write a file then read it. Bah...</span><span>if</span> (is_dir(<span>$file</span>)) { <span>$file</span> = rtrim(<span>$file</span>, <span>'/'</span>).<span>'/'</span>.md5(mt_rand(<span>1</span>,<span>100</span>).mt_rand(<span>1</span>,<span>100</span>)); <span>if</span> ((<span>$fp</span> = @fopen(<span>$file</span>, FOPEN_WRITE_CREATE)) === <span>FALSE</span>) { <span>return</span><span>FALSE</span>; } fclose(<span>$fp</span>); @chmod(<span>$file</span>, DIR_WRITE_MODE); @unlink(<span>$file</span>); <span>return</span><span>TRUE</span>; } <span>elseif</span> ( ! is_file(<span>$file</span>) <span>OR</span> (<span>$fp</span> = @fopen(<span>$file</span>, FOPEN_WRITE_CREATE)) === <span>FALSE</span>) { <span>return</span><span>FALSE</span>; } fclose(<span>$fp</span>); <span>return</span><span>TRUE</span>; } }</code>