php://
伪协议:
php://
是 PHP 中的一个虚拟协议(或称为流包装器),用于访问 PHP 内部流资源。它是 PHP 提供的内置流协议之一,允许你通过流(stream)方式访问 PHP 内部的数据流、文件或其他资源。与 file://
等协议不同,php://
并不直接映射到文件系统,而是用于处理 PHP 特有的资源,如输入输出流、临时文件、PHP 自身的内存流等。
php://
协议是 PHP 流包装器的一部分,允许在 PHP 脚本中灵活地处理不同类型的资源。php://
有多个子协议,它们提供不同的功能,常见的子协议有 php://input
、php://output
、php://memory
等。
1. php://input
:读取原始 POST 数据
php://input
是一个只读流,用于读取原始的 POST 数据。与 $_POST
不同,php://input
允许你直接访问 HTTP 请求中提交的原始数据,特别是对于非表单数据(如 JSON、XML 或其他自定义格式的内容)非常有用。
语法:
php://input
使用场景:
- 处理
application/json
或application/xml
类型的请求体,直接读取原始数据而不通过 PHP 的$_POST
全局数组。 - 读取大数据量的流数据,避免将其加载到内存中。
示例:读取 JSON 格式的请求体
// 假设接收到的 POST 数据是一个 JSON 字符串
$json_data = file_get_contents("php://input");
$data = json_decode($json_data, true);
print_r($data);
在这个例子中,file_get_contents("php://input")
会读取 HTTP 请求体中的原始数据(例如,一个 JSON 字符串)。然后,使用 json_decode()
解析数据。
注意:
php://input
只能读取一次,因为它是流的形式,读取后就无法再次访问相同的数据。因此,如果需要多次处理请求体,应该将其数据存储到一个变量中。- 它只能用于读取原始数据,不能像
$_POST
数组一样处理表单数据。
2. php://output
:输出流
php://output
是一个写入流,允许你将数据直接写入到 PHP 的输出缓冲区。这意味着你可以将内容写入 HTTP 响应,而不需要直接使用 echo
或 print
。
语法:
php://output
使用场景:
- 动态构建响应内容并将其输出到浏览器,而不是立即发送数据。
- 与
ob_start()
和ob_get_contents()
配合使用,缓存输出内容并在需要时发送到浏览器。
示例:将数据写入 php://output
// 打开 php://output 流
$output = fopen('php://output', 'w');
fwrite($output, "Hello, this is written to output.\n");
fclose($output);
在这个例子中,php://output
被用作一个写入流,将字符串写入 PHP 输出缓冲区。数据随后会发送到浏览器。
3. php://memory
:内存中的临时文件
php://memory
是一个内存流,允许你在内存中创建一个临时文件。这类似于操作文件,但数据存储在内存中,不会写入磁盘。
语法:
php://memory
使用场景:
- 当你需要快速读写临时数据,且不希望占用磁盘空间时,可以使用
php://memory
。 - 适用于需要快速操作的小型数据集,如缓存、临时存储等。
示例:使用 php://memory
创建一个内存中的文件
// 打开 php://memory 流进行写操作
$handle = fopen('php://memory', 'w+');
fwrite($handle, "This is some data in memory.");
rewind($handle); // 将文件指针移回文件开头
$content = fread($handle, 1024);
fclose($handle);
echo $content; // 输出:This is some data in memory.
在这个例子中,php://memory
用作内存流,可以在内存中快速读写数据。
4. php://temp
:临时文件(使用内存或磁盘)
php://temp
是一个临时文件流,类似于 php://memory
,但它可以根据文件大小自动切换存储方式:对于小文件,数据存储在内存中;对于较大的文件,数据会自动写入临时磁盘文件。
语法:
php://temp
使用场景:
- 处理临时数据,自动管理内存和磁盘存储。
- 适用于需要临时存储的数据,但又不希望事先知道数据量的情况。
示例:使用 php://temp
创建一个临时文件
// 打开 php://temp 流
$handle = fopen('php://temp', 'w+');
fwrite($handle, "This is a temporary file.\n");
rewind($handle);
$content = fread($handle, 1024);
fclose($handle);
echo $content; // 输出:This is a temporary file.
5.php://stdin
和 php://stdout
php://stdin
:用于读取标准输入流(stdin)。这是命令行 PHP 脚本中常用的流协议。php://stdout
:用于向标准输出流(stdout)写入数据。在命令行环境中,通常使用它来输出信息。
示例:使用 php://stdin
和 php://stdout
// 读取标准输入数据并写入标准输出
$input = fopen("php://stdin", "r");
$output = fopen("php://stdout", "w");
fwrite($output, "Enter some text: ");
$line = fgets($input);
fwrite($output, "You entered: " . $line);
php://filter
伪协:
php://filter
是 PHP 提供的一个特殊协议,它允许在文件流操作中应用各种过滤器。通过使用 php://filter
,你可以在读取文件或写入文件时对内容进行过滤或转换。这种功能非常适用于处理压缩、加密、解密、字符编码转换等需求,而不必手动处理文件内容。
基本概念
php://filter
是通过组合流协议和过滤器来实现的。它允许你在访问文件流时应用一个或多个过滤器,过滤器可以改变数据的表现形式或内容。
语法
php://filter
的基本格式如下:
php://filter/[filter_name]/resource=[resource]
filter_name
:过滤器的名称,指定要应用的过滤器。resource
:资源名称,指示操作的实际文件或流。
常见过滤器
php://filter
支持多种过滤器,它们可以用于对文件内容进行多种处理。过滤器可以分为以下几类:
1. 压缩和解压缩过滤器
这些过滤器可以将数据流进行压缩或解压缩。
zlib.deflate
:将数据流压缩为 DEFLATE 格式(无文件扩展名)。适用于压缩文本数据。zlib.gzip
:将数据流压缩为 GZIP 格式。zlib.gunzip
:解压缩 GZIP 格式的文件。bzip2.compress
:将数据流压缩为 BZIP2 格式。bzip2.decompress
:解压缩 BZIP2 格式的文件。
示例:使用 zlib.deflate
压缩数据
$compressed = file_get_contents("php://filter/zlib.deflate/resource=/path/to/file.txt");
echo $compressed;
此代码会读取 /path/to/file.txt
文件的内容,并将其压缩为 DEFLATE 格式。
2. 字符编码过滤器
这些过滤器允许你转换字符编码格式。
convert.iconv.*
:转换字符编码格式。例如,convert.iconv.ISO-8859-1/UTF-8
将文件从 ISO-8859-1 编码转换为 UTF-8 编码。
示例:使用 convert.iconv
转换字符编码
$content = file_get_contents("php://filter/convert.iconv.ISO-8859-1/UTF-8/resource=/path/to/file.txt");
echo $content;
这会将 /path/to/file.txt
文件从 ISO-8859-1 编码转换为 UTF-8 编码。
3. 加密与解密过滤器
一些过滤器可用于对文件内容进行加密或解密操作。
mcrypt.encrypt
和mcrypt.decrypt
:使用 Mcrypt 库对数据进行加密或解密。
示例:使用 mcrypt
加密
$encrypted = file_get_contents("php://filter/mcrypt.encrypt/resource=/path/to/file.txt");
echo $encrypted;
4. 其他常见过滤器
string.toupper
:将文件内容转换为大写。string.tolower
:将文件内容转换为小写。string.strip_tags
:去除 HTML 标签。string.rot13
:将文本进行 ROT13 加密。
示例:将文件内容转换为大写
$content = file_get_contents("php://filter/string.toupper/resource=/path/to/file.txt");
echo $content;
使用 php://filter
的一些示例
1. 读取并压缩文件内容
如果你想在读取文件的同时进行压缩,可以使用 php://filter
配合 zlib.deflate
过滤器:
// 压缩文件内容并输出
$compressed_content = file_get_contents("php://filter/zlib.deflate/resource=/path/to/large_file.txt");
echo $compressed_content;
这段代码会读取 /path/to/large_file.txt
文件的内容,并将其压缩成 DEFLATE 格式输出。
2. 转换文件编码
假设你有一个文件使用 ISO-8859-1 编码,但你需要将其内容转换为 UTF-8 编码后读取,可以使用 convert.iconv
过滤器:
$content = file_get_contents("php://filter/convert.iconv.ISO-8859-1/UTF-8/resource=/path/to/file.txt");
echo $content;
3. 加密文件内容
如果你需要对文件内容进行加密,可以使用 mcrypt.encrypt
过滤器(注意,Mcrypt 扩展在 PHP 7.1 之后已被标记为弃用,但仍然可以在一些 PHP 版本中使用):
$encrypted_content = file_get_contents("php://filter/mcrypt.encrypt/resource=/path/to/file.txt");
echo $encrypted_content;
组合过滤器
php://filter
允许你将多个过滤器组合起来使用。多个过滤器会依次应用于文件流,顺序非常重要。例如,你可以先压缩文件内容,再转换编码:
// 先进行压缩,再转换字符编码
$content = file_get_contents("php://filter/zlib.deflate/convert.iconv.ISO-8859-1/UTF-8/resource=/path/to/file.txt");
echo $content;
在这个例子中,文件内容会先被压缩,然后再从 ISO-8859-1 转换为 UTF-8 编码。
data://
伪协议:
data://
伪协议是 PHP 中的一种特殊协议,允许在不依赖外部文件的情况下,直接将数据嵌入到 PHP 代码中进行处理。data://
协议常用于嵌入小型的数据内容(如文本或图像),它通过在 URL 中直接包含数据的方式,简化了文件操作的需求,尤其适用于在 Web 应用中处理嵌入式资源时的场景。
data://
伪协议的语法
data://
协议的基本语法如下:
data://[MIME-type];base64,[data]
data://
:协议标识符,表示这是一个data
协议。MIME-type
:可选的 MIME 类型,指定数据的格式。例如:text/plain
、image/png
等。base64
:如果数据是二进制数据(如图片或其他文件),则通常采用 Base64 编码。这个标识符表示数据部分是经过 Base64 编码的。[data]
:要嵌入的数据部分。如果数据是文本,可以直接使用;如果是二进制数据,通常需要进行 Base64 编码。
语法解释
data://
协议头:指定了这是一个数据协议。MIME-type
:定义数据的类型。例如,如果是文本数据,通常是text/plain
;如果是图像,可能是image/png
或image/jpeg
等。base64
(可选):这是一个标记,表示数据是经过 Base64 编码的。Base64 编码常用于将二进制数据(如图片或文件内容)转为 ASCII 字符串,这样它就可以嵌入到 URL 中。[data]
:实际的数据。文本数据直接嵌入;二进制数据需要经过 Base64 编码。
示例
1. 简单的文本数据
如果你想通过 data://
协议嵌入一段简单的文本数据,你可以按如下方式写:
$data = file_get_contents("data://text/plain,Hello%20World%21");
echo $data; // 输出: Hello World!
在这个示例中:
data://text/plain,Hello%20World%21
是一个包含文本 “Hello World!” 的数据 URL。text/plain
是 MIME 类型,表示这是普通的文本数据。Hello%20World%21
是 URL 编码的文本,表示Hello World!
,空格被编码为%20
,感叹号被编码为%21
。
2. Base64 编码的二进制数据
对于图像或其他二进制数据,你通常需要使用 Base64 编码。这是因为 data://
协议能够传输二进制数据,但必须以文本的形式进行表示。
例如,如果你有一个小的图像文件并希望将其嵌入到 PHP 中,你首先需要将图像进行 Base64 编码:
$img_data = file_get_contents('image.png');
$base64_img = base64_encode($img_data);
$data_url = "data:image/png;base64," . $base64_img;
echo $data_url;
在这个示例中:
file_get_contents('image.png')
读取了一个 PNG 图像文件。base64_encode($img_data)
将图像数据编码为 Base64 格式。data:image/png;base64,...
就是包含图像数据的data://
URL。
如果你需要显示这个图像,可以在 HTML 中使用这个 data://
URL:
<img src="data:image/png;base64,..." />
...
代表你的 Base64 编码数据,浏览器会解析并显示这个图像。
3. 小型嵌入的文本文件
如果你有一个小的文本文件,并且希望将其嵌入到 PHP 中以进行读取或操作,可以使用 data://
协议。比如:
$text = file_get_contents("data://text/plain,This%20is%20a%20test%20file");
echo $text; // 输出: This is a test file
在这个示例中,data://text/plain,This%20is%20a%20test%20file
是一个包含文本 This is a test file
的数据 URL。
file://
伪协议:
file://
协议是 PHP 中用于访问文件系统的标准协议,允许你通过 URL 形式访问本地文件系统中的文件。这使得 PHP 脚本能够直接与文件交互,比如读取文件内容或写入数据。file://
协议的核心作用是提供一个统一的接口,使得 PHP 可以在不同的文件系统中通过一致的方式进行文件操作。
file://
语法详解
file://
协议的基本语法如下:
file://[host]/path/to/file
file://
:协议标识符,表示文件协议。[host]
(可选):在某些系统中,file://
可以包含一个主机部分。通常这个部分对于本地文件系统来说可以忽略,特别是在 UNIX 或 Linux 系统中。/path/to/file
:文件路径,指定你要访问的文件的完整路径。在 Windows 系统中,路径通常以盘符开始(如C:/path/to/file
);在类 UNIX 系统(如 Linux、macOS)中,路径通常从根目录/
开始。
1. 访问本地文件
在最常见的用法中,file://
协议用于访问本地文件系统中的文件。你可以将文件路径通过 file://
协议指定为 URL,从而使用诸如 file_get_contents()
、fopen()
等函数读取或写入文件。
1.1 UNIX 和 Linux 系统
在 UNIX 和 Linux 系统中,文件路径从根目录 /
开始。假设你有一个位于 /var/www/html/test.txt
的文件,你可以使用 file://
协议来访问它:
// 读取文件内容
$contents = file_get_contents("file:///var/www/html/test.txt");
echo $contents;
file://
是协议标识符,表示这是一个本地文件访问。/var/www/html/test.txt
是文件的绝对路径。
1.2 Windows 系统
在 Windows 系统中,路径通常以盘符(如 C:
)开始,路径分隔符为反斜杠 \
,但在 file://
协议中,反斜杠需要转换为正斜杠 /
。例如,如果文件位于 C:\xampp\htdocs\test.txt
,可以用 file://
协议访问:
// 读取文件内容
$contents = file_get_contents("file:///C:/xampp/htdocs/test.txt");
echo $contents;
在这个例子中:
file://
协议标识符表示本地文件。C:/xampp/htdocs/test.txt
是文件的路径,注意这里的路径分隔符是/
而不是反斜杠\
。
2. 访问远程文件系统(网络共享)
在某些情况下,file://
协议可以用于访问远程的文件系统或网络共享资源,尤其是在网络文件系统(NFS)、SMB(Samba)等协议支持的环境中。在这种情况下,file://
协议的路径可以包含主机名和共享路径。
2.1 网络共享路径
例如,如果你需要访问一个 Windows 网络共享文件夹,路径可能如下所示:
// 访问远程共享的文件夹
$contents = file_get_contents("file://192.168.1.100/shared-folder/test.txt");
echo $contents;
192.168.1.100
是共享文件夹所在计算机的 IP 地址。/shared-folder/test.txt
是共享文件夹中的文件路径。
2.2 Windows 文件共享(SMB)
在 Windows 网络共享中,路径格式通常为 \\server\share\path
。在 file://
协议中,反斜杠 \
需要转换为正斜杠 /
,并且前面需要加上 file://
前缀。例如,访问一个共享文件夹时的路径可能如下:
// 访问 Windows 文件共享
$contents = file_get_contents("file:server/shared-folder/test.txt");
echo $contents;
这里,//server/shared-folder/test.txt
是网络共享文件的路径,server
是共享计算机的名称。
3. 使用 file://
协议进行文件读取
PHP 提供了多个函数来使用 file://
协议进行文件操作,最常用的是 file_get_contents()
和 fopen()
。
3.1 file_get_contents()
file_get_contents()
是 PHP 中读取文件内容的一个常用函数。你可以通过 file://
协议指定文件路径,读取本地或远程的文件。
$contents = file_get_contents("file:///path/to/file.txt");
echo $contents;
该函数读取整个文件并返回文件内容。对于大文件,可能需要使用流式读取(例如 fopen()
)来避免内存消耗过大。
3.2 fopen()
和其他文件操作函数
你也可以使用 fopen()
、fread()
、fwrite()
等函数进行文件操作。它们支持 file://
协议来访问本地文件:
$handle = fopen("file:///path/to/file.txt", "r");
if ($handle) {
$contents = fread($handle, filesize("file:///path/to/file.txt"));
fclose($handle);
echo $contents;
}
这个例子中,fopen()
打开文件并返回文件句柄,fread()
读取文件内容,fclose()
关闭文件。
3.3 写入文件
你可以使用 file_put_contents()
或 fopen()
+ fwrite()
来向文件写入数据:
// 使用 file_put_contents 写入文件
file_put_contents("file:///path/to/file.txt", "Hello, World!");
或者使用 fopen()
和 fwrite()
:
$handle = fopen("file:///path/to/file.txt", "w");
if ($handle) {
fwrite($handle, "Hello, World!");
fclose($handle);
}