语言参考
在线手册:中文  英文

支持的协议和封装协议

PHP 带有很多内置 URL 风格的封装协议,可用于类似 fopen()copy()file_exists()filesize() 的文件系统函数。 除了这些封装协议,还能通过 stream_wrapper_register() 来注册自定义的封装协议。

Note: 用于描述一个封装协议的 URL 语法仅支持 scheme://... 的语法。 scheme:/scheme: 语法是不支持的。

Table of Contents


语言参考
在线手册:中文  英文

用户评论:

dave at 4mation dot com dot au (2013-06-03 04:46:24)

The use of php://temp/maxmemory as a stream counts towards the memory usage of the script; you are not specifying a new memory pool by using this type of stream.
As noted in the documentation however, this stream type will start to write to a file after the specified maxmemory limit is exceeded. This file buffer is NOT observed by the memory limit.
This is handy if you want your script to have a reasonably small memory limit (eg 32MB) but but still be able to handle a huge amount of data in a stream (eg 256MB)

The only works if you use stream functions like fputs(); if you use $buffer .= 'string'; or $buffer = $buffer . 'string'; you're calling your stream data back into PHP and this will hit the limiter.

As a practical example:

<?php
// 0.5MB memory limit
ini_set('memory_limit''0.5M');
// 2MB stream limit
$buffer fopen('php://temp/maxmemory:1048576''r+');
$x 0;
// Attempt to write 1MB to the stream
while ($x 1*1024*1024) {
    
fputs($buffer'a');
    
$x++;
}
echo 
"This will never be displayed";
?>

However, change fopen to use php://temp/maxmemory:1 (one byte, rather than one megabyte) and it will begin writing to the unlimited file stream immediately, avoiding memory limit errors.

Anonymous (2013-05-01 21:17:58)

In PHP 5.4+ you can read multipart data via php://input if you set enable_post_data_reading to Off.
Of course if you set it to off, the $_POST and $_FILES superglobals won't be populated at all. It's entirely up to you to parse the data now.

Justin Megawarne (2013-04-23 16:42:46)

If my understanding of the implementing code is correct, every time you open a php://memory stream, you get new storage allocated. That is to say, php://memory isn't a shared bank of memory.

fabacrans__ at __nospamhotmail__ dot __com (2013-03-05 12:06:02)

You can use "php://input" to accept and parse "PUT", "DELETE", etc. requests.

<?php
// Example to parse "PUT" requests 
parse_str(file_get_contents('php://input'), $_PUT);

// The result
print_r($_PUT);
?>

(very useful for Restful API)

php at rapsys dot eu (2012-08-06 14:00:52)

Here is a snippet to read compressed raw post data without enabling global variables.

I needed it to read xml posted data submitted by ocs agent. The data was sent as Content-Type: application/x-compressed (zlib compressed data).

It seems related to an old bug which still seems broken :
https://bugs.php.net/bug.php?id=49411

The important part is the default window set to 15 instead of -15.

Code snippet
<?php
$data 
'';
$fh fopen('php://input''rb');
stream_filter_append($fh'zlib.inflate'STREAM_FILTER_READ, array('window'=>15));
while(!
feof($fh)) {
    
$data .= fread($fh8192);
}
?>

aaron dot mason+php at thats-too-much dot info (2012-06-05 01:46:18)

Be aware of code injection, folks - like anything else you take from the user, SANITISE IT FIRST. This cannot be stressed enough - if I had a dollar for each time I saw code where form input was taken and directly used (by myself as well, I've been stupid too) I'd probably own PHP. While using data from a form in a URL wrapper is asking for trouble, you can greatly minimise the trouble by making sure your inputs are sane and not likely to provide an opening for the LulzSec of the world to cause havoc.

Toby (2012-05-18 22:12:18)

Dangerous stuff. Had php injection attacks like:
?-dallow_url_include%253don+-dauto_prepend_file%253dphp://input
due to this

Anonymous (2012-05-04 07:00:07)

For php://filter the /resource=foo part must come last. And foo needs no escaping at all.
php://filter/resource=foo/read=somefilter would try to open a file 'foo/read=somefilter' while php://filter/read=somefilter/resource=foo will open file 'foo' with the somefilter filter applied.

Rakesh Verma [rakeshnsony at gmail dot com] (2012-03-19 10:18:43)

/**********************************/
Example JSON Request:
{
    "username" : "rakeshnsony",
    "password" : "abcdefg"
}
/**********************************/
<?php

//To access json format data
$requestBody file_get_contents('php://input');
$requestBody json_decode($requestBody);

echo 
"username is: ".$requestBody->username;

echo 
"<br /><br />";

echo 
"password is: ".$requestBody->password;
//

leonid at shagabutdinov dot com (2011-07-22 21:45:18)

For https for windows enable this extension:
extension=php_openssl.dll

kwedeth at gmail dot com (2011-05-24 18:04:04)

When daisy-chaining wrappers, I've found that the stream context only applies to the outside wrapper. For example, the following code will not work:

<?php

$options 
= array('http'=>array('header'=>"Accept-Encoding: gzip\r\n"));
$context stream_context_create($options);

$html file_get_contents('compress.zlib://http://example.com/resource.gz'0$context);

?>

The context in this case is useless for the compress.zlib:// wrapper but it does not get applied to http:// and the header will not be sent.

sebastian dot krebs at kingcrunch dot de (2011-02-04 16:49:01)

The stream php://temp/maxmemory:$limit stores the data in memory unless the limit is reached. Then it will write the whole content the a temporary file and frees the memory. I didnt found a way to get at least some of the data back to memory.

gjaman at gmail dot com (2008-05-15 14:15:11)

You can decompress (gzip) a input stream by combining wrappers:
eg: $x = file_get_contents("compress.zlib://php://input");
I used this method to decompress a gzip stream that was pushed to my webserver

jerry at gii dot co dot jp (2007-08-17 10:11:43)

Not only are STDIN, STDOUT, and STDERR only allowed for CLI programs, but they are not allowed for programs that are read from STDIN. That can confuse you if you try to type in a simple test program.

sander at medicore dot nl (2007-06-14 04:25:26)

to create a raw tcp listener system i use the following:
xinetd daemon with config like:
service test
{
disable = no
type = UNLISTED
socket_type = stream
protocol = tcp
bind = 127.0.0.1
port = 12345
wait = no
user = apache
group = apache
instances = 10
server = /usr/local/bin/php
server_args = -n [your php file here]
only_from = 127.0.0.1 #gotta love the security#
log_type = FILE /var/log/phperrors.log
log_on_success += DURATION
}
now use fgets(STDIN) to read the input. Creates connections pretty quick, works like a charm.Writing can be done using the STDOUT, or just echo. Be aware that you're completely bypassing the webserver and thus certain variables will not be available.

ben dot johansen at gmail dot com (2006-10-25 14:57:21)

followup:
I found that if I added this line to the AJAX call, the values would show up in the $_POST
xhttp.setRequestHeader('Content-Type',
'application/x-www-form-urlencoded');

ben dot johansen at gmail dot com (2006-08-29 11:02:31)

Example of how to use the php://input to get raw post data
//read the raw data in
$roughHTTPPOST = file_get_contents("php://input");
//parse it into vars
parse_str($roughHTTPPOST);
if you do readfile("php://input") you will get the length of the post data

ben dot johansen at gmail dot com (2006-08-29 00:33:17)

In trying to do AJAX with PHP and Javascript, I came upon an issue where the POST argument from the following javascript could not be read in via PHP 5 using the $_REQUEST or $_POST. I finally figured out how to read in the raw data using the php://input directive.
    
Javascript code:
=============
      //create request instance      
      xhttp = new XMLHttpRequest();
      // set the event handler
      xhttp.onreadystatechange = serviceReturn;
      // prep the call, http method=POST, true=asynchronous call
      var Args = 'number='+NbrValue;
      xhttp.open("POST", "http://<?php echo $_SERVER['SERVER_NAME'?>/webservices/ws_service.php", true);
      // send the call with args
      xhttp.send(Args);

PHP Code:
    //read the raw data in
    $roughHTTPPOST = file_get_contents("php://input"); 
    //parse it into vars
    parse_str($roughHTTPPOST);

heitorsiller at uol dot com dot br (2006-07-07 07:55:04)

For reading a XML stream, this will work just fine:
<?php

$arq 
file_get_contents('php://input');

?>

Then you can parse the XML like this:

<?php

$xml 
xml_parser_create();

xml_parse_into_struct($xml$arq$vs);

xml_parser_free($xml);

$data "";

foreach(
$vs as $v){

        if(
$v['level'] == && $v['type'] == 'complete')
                
$data .= "\n".$v['tag']." -> ".$v['value'];
}

echo 
$data;

?>

PS.: This is particularly useful for receiving mobile originated (MO) SMS messages from cellular phone companies.

opedroso at NOSPAMswoptimizer dot com (2006-04-12 11:07:51)

php://input allows you to read raw POST data. It is a less memory intensive alternative to $HTTP_RAW_POST_DATA and does not need any special php.ini directives.
Example use:
$httprawpostdata = file_get_contents("php://input");
When reading a base64 encoded stream using php://input, be aware that you do not need to decode it, it will automatically be done for you.

nyvsld at gmail dot com (2005-11-27 10:28:15)

php://stdin supports fseek() and fstat() function call,
while php://input doesn't.

drewish at katherinehouse dot com (2005-09-24 23:50:08)

Be aware that contrary to the way this makes it sound, under Apache, php://output and php://stdout don't point to the same place.

<?php
$fo 
fopen('php://output''w');
$fs fopen('php://stdout''w');

fputs($fo"You can see this with the CLI and Apache.\n");
fputs($fs"This only shows up on the CLI...\n");

fclose($fo);
fclose($fs);
?>

Using the CLI you'll see:
  You can see this with the CLI and Apache.
  This only shows up on the CLI...

Using the Apache SAPI you'll see:
  You can see this with the CLI and Apache.

chris at free-source dot com (2005-04-26 12:52:45)

If you're looking for a unix based smb wrapper there isn't one built in, but I've had luck with http://www.zevils.com/cgi-bin/viewcvs.cgi/libsmbclient-php/ (tarball link at the end).

nargy at yahoo dot com (2004-09-24 03:16:07)

When opening php://output in append mode you get an error, the way to do it:
$fp=fopen("php://output","w");
fwrite($fp,"Hello, world !<BR>\n");
fclose($fp);

aidan at php dot net (2004-05-27 03:34:21)

The contants:
* STDIN
* STDOUT
* STDERR
Were introduced in PHP 4.3.0 and are synomous with the fopen('php://stdx') result resource.

lupti at yahoo dot com (2003-11-29 02:04:02)

I find using file_get_contents with php://input is very handy and efficient. Here is the code:
$request = "";
$request = file_get_contents("php://input");
I don't need to declare the URL filr string as "r". It automatically handles open the file with read.
I can then use this $request string to your XMLparser as data.

sam at bigwig dot net (2003-08-15 08:02:24)

[ Editor's Note: There is a way to know. All response headers (from both the final responding server and intermediate redirecters) can be found in $http_response_header or stream_get_meta_data() as described above. ]
If you open an HTTP url and the server issues a Location style redirect, the redirected contents will be read but you can't find out that this has happened.
So if you then parse the returned html and try and rationalise relative URLs you could get it wrong.

易百教程