说我想知道传递给fopen的字符串是表示文件路径还是有效包装(例如"/home/user/example.txt"
vs "php://input"
)。这是为了创建一个从php://input
中的内容创建一个tmp文件,以解决PHP wrappers的fseek
ing限制。如何确定一个字符串是否指向PHP中的有效文件或包装?
如下图所示,file_exists
作品的文件,但不能用于包装的URI:
var_dump(file_exists("php://input"));
var_dump(file_exists("./exists.txt"));
var_dump(file_exists("./non_existent.txt"));
var_dump(file_exists("php://garbage"));
给
bool(false)
bool(true)
bool(false)
bool(false)
只有一个返回true是文件。我发现stream_get_wrappers(),但我想避免太复杂的检查(如使用字符串比较来尝试检测包装)。
使用stream_get_meta_data似乎也起作用,但它需要首先调用fopen,这会阻塞错误日志。
var_dump(stream_get_meta_data(fopen("php://input","r+")));
var_dump(stream_get_meta_data(fopen("./exists.txt","r+")));
var_dump(stream_get_meta_data(fopen("./non_existent.txt","r+")));
var_dump(stream_get_meta_data(fopen("php://garbage","r+")));
产生
array(9) {
["timed_out"]=>
bool(false)
["blocked"]=>
bool(true)
["eof"]=>
bool(false)
["wrapper_type"]=>
string(3) "PHP"
["stream_type"]=>
string(5) "Input"
["mode"]=>
string(2) "rb"
["unread_bytes"]=>
int(0)
["seekable"]=>
bool(true)
["uri"]=>
string(11) "php://input"
}
array(9) {
["timed_out"]=>
bool(false)
["blocked"]=>
bool(true)
["eof"]=>
bool(false)
["wrapper_type"]=>
string(9) "plainfile"
["stream_type"]=>
string(5) "STDIO"
["mode"]=>
string(2) "r+"
["unread_bytes"]=>
int(0)
["seekable"]=>
bool(true)
["uri"]=>
string(10) "./exists.txt"
}
NULL
NULL
我可以使用由stream_get_meta_data
返回的数组的wrapper_type
,但它仍然会喷涌到垃圾如果日志文件或包装URI不存在,我想避免。
什么是最好的方法来检测是否我的输入字符串(要传递给fopen)包含了现有文件或有效的PHP包装,或既无一个有效的文件路径?
更新:我找到了解决问题的解决方法,其代价是额外的fopen
调用。我已经在下面回答了这个问题。
似乎并没有成为一个东西,至少不是在PHP 7.0,也不是官方文档: 'PHP -R '的var_dump(function_exists( “is_stream”));'' '布尔(假) ' –
感谢downvote没有任何解释:(先前的研究有多少证据需要显示在这里? –