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

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 />\n";
include("http://www.test2.com/research/path/path.php");
?>

path1.php文件内容为:
<?php
echo "This is file path1.php in root directory\n";
?>
执行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\research\path\path.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\research\path\path.php on line 3

Warning: include() [function.include]: Failed opening 'http://www.test2.com/research/path/path.php' for inclusion (include_path='.;C:\php5\pear') in E:\myphp\research\path\path.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 />\n";
$name = include 'path1.php';
echo "name: $name<br />\n";
?>

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 />\n";
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 />\n";
include 'http://www.test2.com/research/path/path1.php?a=comefrom_path.php';
echo "name: $name<br />\n";
?>

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 />\n";//2009-12-13 09:03:19
echo 'file_get_contents:' . file_get_contents('1.php')."<br />\n";//返回为空

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



上一篇: PHP中用file_get_contents抓取网页
下一篇: PHP中文件上传时的注意事项
文章来自: 本站原创
引用通告: 查看所有引用 | 我要引用此文章
Tags: php
相关日志:
评论: 0 | 引用: 0 | 查看次数: 2539
发表评论
昵 称:
密 码: 游客发言不需要密码.
邮 箱: 邮件地址支持Gravatar头像,邮箱地址不会公开.
网 址: 输入网址便于回访.
内 容:
验证码:
选 项:
虽然发表评论不用注册,但是为了保护您的发言权,建议您注册帐号.
字数限制 1000 字 | UBB代码 开启 | [img]标签 关闭

 广告位

↑返回顶部↑