入门客AI创业平台(我带你入门,你带我飞行)
博文笔记

PHP中打开或包含远程文件时要注意的问题

创建时间:2014-12-10 投稿人: 浏览次数:4030

1.如果要用fopen打开远程文件,则此时最好检查一下php.ini中的配置选项allow_url_fopen,如果为on则可以打开,否则不能打开
if (ini_get("allow_url_fopen")) {
    //可以打开远程文件
} else {
    //不能打开远程文件
}

; Whether to allow the treatment of URLs (like http:// or ftp://) as files.
allow_url_fopen = On

2.如果要包含远程文件,则此时最好检查一下php.ini中的配置选项allow_url_include,如果为on则可以包含,否则不能包含
; Whether to allow include/require to open URLs (like http:// or ftp://) as files.
allow_url_include = Off

做个简单的测试,此时allow_url_include的值为Off
测试前配置一下hosts文件,这样可以在一台电脑上面进行模拟测试
192.168.1.101 www.test1.com
192.168.1.102 www.test2.com

path.php文件内容为:
<?php
echo "This is file path.php<br /> ";
include("http://www.test2.com/research/path/path.php");
?>

path1.php文件内容为:
<?php
echo "This is file path1.php in root directory ";
?>
执行http://www.test1.com/research/path/path.php,输出如下
This is file path.php

Warning: include() [function.include]: URL file-access is disabled in the server configuration in E:myphp esearchpathpath.php on line 3

Warning: include(http://www.test2.com/research/path/path.php) [function.include]: failed to open stream: no suitable wrapper could be found in E:myphp esearchpathpath.php on line 3

Warning: include() [function.include]: Failed opening "http://www.test2.com/research/path/path.php" for inclusion (include_path=".;C:php5pear") in E:myphp esearchpathpath.php on line 3

将php.ini中的allow_url_include改为On,重新启动web服务器,再次执行http://www.test1.com/research/path/path.php,输出如下:
This is file path.php
This is file path1.php in root directory 
将allow_url_include设为On以后,就可以包含远程文件了,并且包含的是远程文件执行的结果。

3.测试文件包含的返回值
a.包含本地文件并获取被包含文件的返回值
path.php
<?php
echo "This is file path.php<br /> ";
$name = include "path1.php";
echo "name: $name<br /> ";
?>

path1.php
<?php
$name = "caihuafeng";
return $name; //注意这儿是return $name;
?>
运行path.php,输出如下:
This is file path.php
name: caihuafeng
说明path1.php的返回值成功包含在path.php中了

==============================
b.用readfile函数直接读取远程文件的执行结果
php手册中的说明
安全警告 
远程文件可能会经远程服务器处理(根据文件后缀以及远程服务器是否在运行 PHP 而定),但必须产生出一个合法的 PHP 脚本,因为其将被本地服务器处理。如果来自远程服务器的文件应该在远端运行而只输出结果,那用 readfile() 函数更好。另外还要格外小心以确保远程的脚本产生出合法并且是所需的代码。 

int readfile ( string filename [, bool use_include_path [, resource context]] )
读入一个文件并写入到输出缓冲。

测试如下:
path.php
<?php
echo "This is file path.php<br /> ";
readfile("http://www.test2.com/research/path/path1.php");
?>
readfile打开远程文件时allow_url_fopen必须设置为On

path1.php
<?php
$name = "caihuafeng";
echo $name; //因为readfile是要读取文件的执行结果,所以这儿要输出
?>
输出如下:
This is file path.php
caihuafeng

c.包含远程文件

php手册中的说明
处理返回值:可以在被包括的文件中使用 return() 语句来终止该文件中程序的执行并返回调用它的脚本。同样也可以从被包含的文件中返回值。可以像普通函数一样获得 include 调用的返回值。不过这在包含远程文件时却不行,除非远程文件的输出具有合法的 PHP 开始和结束标记(如同任何本地文件一样)。可以在标记内定义所需的变量,该变量在文件被包含的位置之后就可用了。 

用这种方式有点麻烦,就是被包含文件的输出必须是佥的php开始和结束标记(echo "<?php $name = "caihuafeng " . $a . ""; ?>";),就像下面path1.php的输出一样。
同时可以向被包含的文件中传递参数,被包含的文件接收到参数以后可以进行适当的处理。

path.php
<?php
echo "This is file path.php<br /> ";
include "http://www.test2.com/research/path/path1.php?a=comefrom_path.php";
echo "name: $name<br /> ";
?>

path1.php
<?php
$a = $_REQUEST["a"];
echo "<?php $name = "caihuafeng " . $a . ""; ?>";
?>

下面这些代码是php手册中的:
<?php

/* This example assumes that www.example.com is configured to parse .php *
* files and not .txt files. Also, "Works" here means that the variables *
* $foo and $bar are available within the included file.                 */

// Won"t work; file.txt wasn"t handled by www.example.com as PHP
include "http://www.example.com/file.txt?foo=1&bar=2";

// Won"t work; looks for a file named "file.php?foo=1&bar=2" on the
// local filesystem.
include "file.php?foo=1&bar=2";

// Works.
include "http://www.example.com/file.php?foo=1&bar=2";

$foo = 1;
$bar = 2;
include "file.txt";  // Works.
include "file.php";  // Works.

?> 

4.总结
php.ini中allow_url_fopen默认为On,allow_url_include默认为Off

一般本地的程序要与远程的程序进行交互,不推荐用include远程文件的方式,用fopen,fsockopen,readfile,file_get_contents,curl这些会比较好一点。

如果用fopen、readfile、file_get_contents打开远程文件时,必须将allow_url_fopen设为On

其中用fsockopen及curl来与远程的程序进行交互比较好,readfile也可以。

fopen: 打开的文件一般用来进行读写,也可以打开远程文件,对打开的远程文件进行操作,一般很少对打开的远程文件进行写操作。
fsockopen: 主要用于打开socket连接,需要指定ip地址及端口,进行相关的读写操作。
readfile: 读入一个文件的内容并且输出此内容,可以包含动态及静态文件,如果是动态文件,则返回的是执行的结果。
file_get_contents: 将整个文件读取一个字符串,可以是动态及静态文件,如果是动态文件,则返回的是执行的结果。

做了如下的一个测试,
file_get_contents包含本地或远程静态文件,则均有结果
file_get_contents包含远程动态文件,有结果返回,包含本地动态文件,无结果返回

readfile包含远程动态文件,有结果返回,包含本地动态文件,无结果返回
readfile包含本地或远程静态文件,则均有结果

echo file_get_contents("1.txt");//I am 1.txt
echo file_get_contents("http://www.test2.com/research/path/1.txt");//I am 1.txt

echo "file_get_cnotents:" . file_get_contents("http://www.test2.com/research/path/1.php")."<br /> ";//2009-12-13 09:03:19
echo "file_get_contents:" . file_get_contents("1.php")."<br /> ";//返回为空

readfile("http://www.test2.com/research/path/1.php");//2009-12-13 09:03:19
readfile("1.php");//返回为空

readfile("http://www.test2.com/research/path/1.txt");//I am 1.txt
readfile("1.txt");//I am 1.txt

声明:该文观点仅代表作者本人,入门客AI创业平台信息发布平台仅提供信息存储空间服务,如有疑问请联系rumenke@qq.com。