找回密码
 立即注册

手机短信,快捷登录

快捷登录

QQ登录

只需一步,快速开始

查看: 17397|回复: 1

fsockopen该函数需要 php.ini 中 allow_url_fopen 选项开启

[复制链接]
发表于 2012-10-31 23:52:14 | 显示全部楼层 |阅读模式 来自: 中国黑龙江齐齐哈尔
为了服务器安全考虑,很多主机商禁用了php的fsockopen函数,
比如用cos-html-cache生成静态文件,有类似提示:

Warning: fsockopen() has been disabled for security reasons in *:\...\cos-html-cache\cos-html-cache.php on line 35

换了其他版本的cos-html-cache,还是不行。后来找到下面的方法。 = =、(结果不行,因为函数都被禁用了。)

大家试下,遇到类似情况,用其他替代函数。

这里为大家分析一下相关知识,服务器如何开启fsockopen函数,在discuz 和 phpwind 中,看到不少人,被这个问题困扰!自己多方寻找终于找到解决的正规方法!在此公布一下,希望能帮助大家,注意:此方法本人在iis6.0服务器上亲自测试,绝对正常, Apache服务器没有测试过。


首先,如何开启fsockopen函数

只要搭建好服务器,都会有个php.ini文件,里面有很多php的相关配置,php.ini文件的位置,一般在你服务器的C:\WINDOWS\php.ini
第一步
找到php.ini文件,用记事本打开,查找 allow_url_fopen = 看看后面是 off 还On , 如果是On,直接看下一步,如果是off 那就修改成On,需要注意完整的是allow_url_fopen = On等号的左右有空格,为了避免代码修改出错,请直接复制下面的替换原来的即可。
第二步
继续在php.ini文件中,查找,查找extension=php_openssl.dll 找到以后大家注意,extension=php_openssl.dll这段代码前面会有个 ; 号,只要把这个 ; 号删除,然后保存。
第三步
重启IIS,打开IIS信息服务管理器,右键点击XX(本地计算机),选择 所有服务 点击 重新启动IIS ,等待重新启动完成,(XX代表你的服务器管理用户名),重启动完成后,fsockopen函数 应该成功开启了,如果你正在安装网站程序,需要刷新你的网站程序,然后即可看到,由原来的服务器不支持fsockopen函数,变成 支持fsockopen函数。就这么简单。


其次、如何禁用fsockopen()

下面是两种常用的禁用fsockopen的方法。
1、修改php.ini,将 disable_functions = 后加入 fsockopen
2、修改php.ini,将 allow_url_fopen = On 改为 allow_url_fopen = Off

最后、如何解决fsockopen函数被禁用

1、如果服务器没有同时禁用pfsockopen,那么直接将fsockopen函数替换为pfsockopen。
具体操作:搜索程序中的字符串 fsockopen( 替换为 pfsockopen( 。示例如下
修改前:$fp = fsockopen($host, 80, $errno, $errstr, 30);

修改后:$fp = pfsockopen($host, 80, $errno, $errstr, 30);

2、如果服务器同时禁用了pfsockopen,那么用其他函数代替,如stream_socket_client()。注意:stream_socket_client()和fsockopen()的参数不同。
具体操作:搜索程序中的字符串 fsockopen( 替换为 stream_socket_client( ,然后,将原fsockopen函数中的端口参数“80”删掉,并加到$host。示例如下
修改前:$fp = fsockopen($host, 80, $errno, $errstr, 30);

修改后$fp = stream_socket_client($host."80", $errno, $errstr, 30);

3、如果PHP版本低于5.0,fsockopen被禁用,又没有stream_socket_client()怎么办呢?自己写一个函数实现fsockopen的功能,参考代码:<div>function b_fsockopen($host, $port, &$errno, &$errstr, $timeout) {</div><div>$ip = gethostbyname($host);</div><div>$s = socket_create(AF_INET, SOCK_STREAM, 0);</div><div>if (socket_set_nonblock($s)) {</div><div>  $r = @socket_connect($s, $ip, $port);</div><div>  if ($r || socket_last_error() == EINPROGRESS) {</div><div>   $errno = EINPROGRESS;</div><div>   return $s;</div><div>  }</div><div>}</div><div>$errno = socket_last_error($s);</div><div>$errstr = socket_strerror($errno);</div><div>socket_close($s);</div><div>return false;</div><div>}</div>

具体操作:

1.首先找到使用fsockopen函数的代码段,将上面代码加至其上端,搜索该代码段中的字符串 fsockopen( 替换为 b_fsockopen( 。
2.因为fsockopen函数返回文件指针所以可以被文件函数操作,但是这个b_fsockopen函数没能返回文件指针,需要继续修改代码段:用socket_read( 替换掉 fread( ,用socket_write( 替换掉fwrite( ,用socket_close( 替换掉fclose( 。
(小小赏金只为给深夜码字的楼主买杯咖啡!)
 发表于 2012-11-16 19:18:53
转播微博[tthread=KANGXI787936569, 康熙仔]http://app.qlogo.cn/mbloghead/146649210089f9970358[/tthread]
(小小赏金只为给深夜码字的楼主买杯咖啡!)
您需要登录后才可以回帖 登录 | 立即注册  

本版积分规则

QQ|营业执照|Archiver|手机版|小黑屋|富裕信息网 ( 黑ICP备20003456号 )

GMT+8, 2025-8-4 09:41 , Processed in 0.225636 second(s), 35 queries .

Powered by Discuz! X3.4

© 2001-2023 Discuz! Team.

快速回复 返回顶部 返回列表