为了服务器安全考虑,很多主机商禁用了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( 。 |