在日常开发中 , , is_execable ()和 和File_get_Contents ()是 php 中两个看似简单但实用的函数。 is_exexecable ()用于判断文件是否具有可执行权限 , 而File_get_Contents ()常用于读取文件或 url 内容。尽管这两个函数独立使用时都很直观 , 但当它们组合使用时 , 特别是在处理文件系统权限和远程资源时 , 会遇到一些容易被忽略的问题。本文将分析常见问题 会遇到一些容易被忽略的问题。本文将分析常见问题 并提供规避建议。 并提供规避建议。
is_execable ()是专门用于检查本地文件是否可执行的函数。如果你尝试对一个 url 使用它 , : :
<span><span><span class="hljs-variable">$url</span></span><span> = </span><span><span class="hljs-string">'https://gitbox.net/scripts/remote-check.php'</span></span><span>;
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">is_executable</span></span><span>(</span><span><span class="hljs-variable">$url</span></span><span>)) {
</span><span><span class="hljs-keyword">echo</span></span><span> </span><span><span class="hljs-title function_ invoke__">file_get_contents</span></span><span>(</span><span><span class="hljs-variable">$url</span></span><span>);
}
</span></span>
这段代码会失败 , 因为is_execable ()只接受本地文件路径。传入一个 url 会导致返回falsch , 并可能触发警告。php 并不会解析 url 的权限或可执行性 , 因此这种写法逻辑上是错误的。
即使是本地文件 , 在使用 在使用File_get_Contents ()时也需要具备读取权限。很多开发者以为is_execable ()返回true就表示一切正常 但实际上 但实际上 如果文件仅具有执行权限( 如果文件仅具有执行权限( x ) , 而没有读取权限( r ) , 那么 那么File_get_Contents ()依然无法读取文件内容 :
<span><span><span class="hljs-variable">$file</span></span><span> = </span><span><span class="hljs-string">'/usr/local/bin/script.sh'</span></span><span>;
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">is_executable</span></span><span>(</span><span><span class="hljs-variable">$file</span></span><span>)) {
</span><span><span class="hljs-variable">$content</span></span><span> = </span><span><span class="hljs-title function_ invoke__">file_get_contents</span></span><span>(</span><span><span class="hljs-variable">$file</span></span><span>); </span><span><span class="hljs-comment">// 可能失败,抛出 warning</span></span><span>
}
</span></span>
在这种情况下 , 建议先用is_readable ()判断文件是否可读。
很多时候路径错误并不会立刻暴露出来 , 尤其是在用is_execable ()判断后接 判断后接File_Get_Contents ()的场景中。一个不存在的文件会导致is_execable ()返回false , 可能不会产生任何提示 而 而File_get_Contents ()则可能抛出警告 :
<span><span><span class="hljs-variable">$file</span></span><span> = </span><span><span class="hljs-string">'/path/to/missing-file'</span></span><span>;
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">is_executable</span></span><span>(</span><span><span class="hljs-variable">$file</span></span><span>)) {
</span><span><span class="hljs-variable">$content</span></span><span> = </span><span><span class="hljs-title function_ invoke__">file_get_contents</span></span><span>(</span><span><span class="hljs-variable">$file</span></span><span>); </span><span><span class="hljs-comment">// 根本不会执行</span></span><span>
}
</span></span>
虽然代码不会出错执行 , 但逻辑会悄悄 失败 失败 , , 使调试变得困难。 使调试变得困难。 使调试变得困难。
如果你尝试通过 URL 使用File_get_Contents () , 而服务器的php.ini中关闭了degit_url_fopen , 会直接导致无法读取远程内容 , 即使 url 是有效的 :
<span><span><span class="hljs-variable">$url</span></span><span> = </span><span><span class="hljs-string">'https://gitbox.net/data/info.json'</span></span><span>;
</span><span><span class="hljs-variable">$content</span></span><span> = </span><span><span class="hljs-title function_ invoke__">file_get_contents</span></span><span>(</span><span><span class="hljs-variable">$url</span></span><span>); </span><span><span class="hljs-comment">// 若 allow_url_fopen = Off,则会失败</span></span><span>
</span></span>
这与is_execable ()无关 , 但在组合使用时更容易造成混淆 , 尤其是开发者误以为是is_execable ()造成的问题。
避免对 URL 使用is_execable () , 也不要试图对其进行任何与文件权限相关的判断。建议通过简单的正则或parse_url ()来判断资源类型 :
<span><span><span class="hljs-variable">$target</span></span><span> = </span><span><span class="hljs-string">'https://gitbox.net/scripts/check.php'</span></span><span>;
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">filter_var</span></span><span>(</span><span><span class="hljs-variable">$target</span></span><span>, FILTER_VALIDATE_URL)) {
</span><span><span class="hljs-variable">$content</span></span><span> = </span><span><span class="hljs-title function_ invoke__">file_get_contents</span></span><span>(</span><span><span class="hljs-variable">$target</span></span><span>);
} </span><span><span class="hljs-keyword">elseif</span></span><span> (</span><span><span class="hljs-title function_ invoke__">is_executable</span></span><span>(</span><span><span class="hljs-variable">$target</span></span><span>) && </span><span><span class="hljs-title function_ invoke__">is_readable</span></span><span>(</span><span><span class="hljs-variable">$target</span></span><span>)) {
</span><span><span class="hljs-variable">$content</span></span><span> = </span><span><span class="hljs-title function_ invoke__">file_get_contents</span></span><span>(</span><span><span class="hljs-variable">$target</span></span><span>);
}
</span></span>
如果目标是本地文件 , 建议同时判断是否可执行和可读取 :
<span><span><span class="hljs-variable">$file</span></span><span> = </span><span><span class="hljs-string">'/usr/local/bin/myscript.sh'</span></span><span>;
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-title function_ invoke__">is_executable</span></span><span>(</span><span><span class="hljs-variable">$file</span></span><span>) && </span><span><span class="hljs-title function_ invoke__">is_readable</span></span><span>(</span><span><span class="hljs-variable">$file</span></span><span>)) {
</span><span><span class="hljs-variable">$content</span></span><span> = </span><span><span class="hljs-title function_ invoke__">file_get_contents</span></span><span>(</span><span><span class="hljs-variable">$file</span></span><span>);
}
</span></span>
即使进行了判断 , 仍可能发生错误(比如文件在判断之后被删除)。推荐使用@file_get_contents ()或Versuch-Catch结合Stream_Context_create () (尤其是远程读取时) :
<span><span><span class="hljs-variable">$content</span></span><span> = @</span><span><span class="hljs-title function_ invoke__">file_get_contents</span></span><span>(</span><span><span class="hljs-string">'https://gitbox.net/api/status.json'</span></span><span>);
</span><span><span class="hljs-keyword">if</span></span><span> (</span><span><span class="hljs-variable">$content</span></span><span> === </span><span><span class="hljs-literal">false</span></span><span>) {
</span><span><span class="hljs-title function_ invoke__">error_log</span></span><span>(</span><span><span class="hljs-string">"读取失败,请检查URL或网络配置"</span></span><span>);
}
</span></span>
使用远程 URL 前 , 请确认php.ini中的degling_url_fopen设置为on
<span><span><span class="hljs-keyword">if</span></span><span> (!</span><span><span class="hljs-title function_ invoke__">ini_get</span></span><span>(</span><span><span class="hljs-string">'allow_url_fopen'</span></span><span>)) {
</span><span><span class="hljs-keyword">die</span></span><span>(</span><span><span class="hljs-string">"远程文件读取被禁止,请修改php.ini配置"</span></span><span>);
}
</span></span>
虽然is_execable ()和File_get_Contents ()在 php 中都是基础函数 , 但当两者组合使用时 , 开发者需要对本地与远程资源、文件权限、 php 配置等方面有更清晰的认识。通过明确分工、合理判断、提前配置检查 , 我们可以有效避免大多数隐性问题 , 提高代码的稳定性和可维护性。
Verwandte Tags:
is_executable file_get_contents