让phpcms支持https

2020-01-01 浏览:2102
让phpcms支持https
评论:(1)复制地址

本文整理自PHPCMS官方论坛的一篇文章,感谢作者的奉献。

假设已经配置好ssl证书,不知如何申请ssl证书者请自行百度。

1、如果已经安装好phpcms,则需要对caches/configs/system.php中的配置选项做替换,将"http://"全部替换为"https://"。如有必要,数据库中已存在的链接也要完全替换为https开头。

2、程序修改部分:
(1)修改phpcms/modules/admin/site.php 大约45行和128行的正则

('/http:\/\/(.+)\/$/i', $domain))

    修改为

('/(http|https):\/\/(.+)\/$/i', $domain))

(2)修改phpcms/modules/admin/templates/setting.tpl.php 大约18行中的正则

http:\/\/(.+)[^/]$

    修改为

http[s]?:\/\/(.+)[^/]$

(3)修改phpcms/modules/admin/templates/site_add.tpl.php 大约13行中的正则

http:\/\/(.+)\/$

    修改为

http[s]?:\/\/(.+)\/$

(4)修改phpcms/modules/admin/templates/site_edit.tpl.php 大约11行中的正则

http:\/\/(.+)\/$

    修改为

http[s]?:\/\/(.+)\/$

(5)修改phpcms/modules/link/index.php 大约41行和51行中的正则

/^http:\/\/(.*)/i

    修改为

/^http[s]?:\/\/(.*)/i

(6)修改phpcms/modules/link/templates/link_add.tpl.php 大约10行中的正则

^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&]*([^<>])*$

    修改为

^http[s]?:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&]*([^<>])*$

(7)修改phpcms/modules/link/templates/link_edit.tpl.php 大约11行中的正则

^http:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&]*([^<>])*$

    修改为

^http[s]?:\/\/[A-Za-z0-9]+\.[A-Za-z0-9]+[\/=\?%\-&]*([^<>])*$

    严格按照以上步骤修改后,注册用户 帐号登录等操作完全正常 和PHPSSO通信完全正常,后台添加信息和前台链接URL完全正常

    注意:
    a.如注册用户提示‘操作失败’,请在后台会员模块设置中关闭‘注册时可选会员模型’或者保证会员不少于两个会员模型

    b.在PHP5.6或以上的PHP版本中会出现和PHPSSO无法正常通信的情况,因为PHP5.6及以上fsockopen和file_get_contents等函数openssl需要验证目标的SSL证书是否可信,需要安装openssl根证书才可以,否则openssl会报警告信息 证书验证失败!
    如需在php5.6或以上版本中使用HTTPS的请参阅PHP官方有关php5.6和openssl的资料http://php.net/manual/en/migration56.openssl.php

3、经过上面修改后,phpcms中的内容可通过https访问,但分页出现错误。解决方法为:
    打开文件 phpcms\libs\functions \global.func.php ,找到738行的位置:

$url = str_replace(array('http://','//','~'), array('~','/','http://'), $url);

    修改为

$url = str_replace(array('https://','//','~'), array('~','/','https://'), $url);

4、栏目页如果绑定域名也需要修改,打开phpcms/modules/admin/templates 中的category_add.tpl.php和category_edit.tpl.php

两个文件顶部的script,大约11行

$("#url").formValidator({onshow:" ",onfocus:"<?php echo L('domain_name_format');?>",tipcss:{width:'300px'},empty:true}).inputValidator({onerror:"<?php echo L('domain_name_format');?>"}).regexValidator({regexp:"http:\/\/(.+)\/$",onerror:"<?php echo L('domain_end_string');?>"});

修改为

$("#url").formValidator({onshow:" ",onfocus:"<?php echo L('domain_name_format');?>",tipcss:{width:'300px'},empty:true}).inputValidator({onerror:"<?php echo L('domain_name_format');?>"}).regexValidator({regexp:"http[s]?:\/\/(.+)\/$",onerror:"<?php echo L('domain_end_string');?>"});


查找<th><?php echo L('domain')?>:</th>,将下方的

<?php if(preg_match('/^http:\/\/([a-z0-9\-\.]+)\/$/i',$url)) echo $url;?>">

修改为

<?php if(preg_match('/^http[s]?:\/\/([a-z0-9\-\.]+)\/$/i',$url)) echo $url;?>


category_edit.tpl.php 底部的script还需要修改

$(function(){
		var url = $('#url').val();
		if(!url.match(/^http:\/\//)) $('#url').val('');
	})


$(function(){
		var url = $('#url').val();
		if(!url.match(/^http[s]?:\/\//)) $('#url').val('');
	})


后端内容列表显示链接错误也要修改

打开phpcms/modules/content/templates/content_list.tpl.php,找到

if($status==99) {
			if($r['islink']) {
				echo '<a href="'.$r['url'].'" target="_blank">';
			} elseif(strpos($r['url'],'http://')!==false) {
				echo '<a href="'.$r['url'].'" target="_blank">';
			} else {
				echo '<a href="'.$release_siteurl.$r['url'].'" target="_blank">';
			}
		}


修改为

if($status==99) {
    if($r['islink']) {
        echo '<a href="'.$r['url'].'" target="_blank">';
    } elseif(strpos($r['url'],'http://')!==false || strpos($r['url'],'https://')!==false) {
        echo '<a href="'.$r['url'].'" target="_blank">';
    } else {
        echo '<a href="'.$release_siteurl.$r['url'].'" target="_blank">';
    }
}


后台单页面管理-点击访问 链接错误的修复

phpcms/modules/content/templates/content_page.tpl.php,找到下面代码

<a href="<?php if(strpos($category['url'],'http://')===false) echo siteurl($this->siteid);echo $category['url'];?>" target="_blank"><em><?php echo L('click_vistor');?></em></a>

替换成

<a href="<?php if(strpos($category['url'],'http')===false) echo siteurl($this->siteid);echo $category['url'];?>" target="_blank"><em><?php echo L('click_vistor');?></em></a>


5、会员登录的https修改

打开phpcms/modules/member/classes/client.class.php 


将361行修改如下:

$port = !empty($matches['port']) ? $matches['port'] : ( strtolower($matches['scheme'])=='https' ? 443 : 80 );


第386行的

$fp = @fsockopen(($ip ? $ip : $host), $port, $errno, $errstr, $timeout);


修改为

$contextOptions = array(
    'ssl' => array(
        'verify_peer' => false,
        'verify_peer_name' => false
    )
);
$context = stream_context_create($contextOptions);
$fp = stream_socket_client("ssl://{$host}:{$port}", $errno, $errstr, $timeout, STREAM_CLIENT_CONNECT, $context);

修改完成后,清理缓存,重新登陆

6、关于phpsso后台修改用户信息后,通信信息中会显示通信失败的修改方法:打开phpsso_server/phpcms/modules/admin/functions/global.func.php,搜索ps_post,将这个函数换成下面代码

function ps_post($url, $limit = 0, $post = '', $cookie = '', $ip = '', $timeout = 15, $block = true) {
		$return = '';
		$matches = parse_url($url);
		$host = $matches['host'];
		$path = $matches['path'] ? $matches['path'].($matches['query'] ? '?'.$matches['query'] : '') : '/';
		
		// --- 核心修复 1:自动判断协议和端口 ---
		$is_https = ($matches['scheme'] == 'https');
		$port = !empty($matches['port']) ? $matches['port'] : ($is_https ? 443 : 80);
		$ssl_host = ($is_https ? 'ssl://' : '') . ($ip ? $ip : $host);
		// ------------------------------------

		$siteurl = get_url();
		if($post) {
			$out = "POST $path HTTP/1.1\r\n";
			$out .= "Accept: */*\r\n";
			$out .= "Referer: ".$siteurl."\r\n";
			$out .= "Accept-Language: zh-cn\r\n";
			$out .= "Content-Type: application/x-www-form-urlencoded\r\n";
			// 兼容某些环境下没有 HTTP_USER_AGENT 的情况
			$ua = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'PHPCMS/V9';
			$out .= "User-Agent: $ua\r\n";
			$out .= "Host: $host\r\n" ;
			$out .= 'Content-Length: '.strlen($post)."\r\n" ;
			$out .= "Connection: Close\r\n" ;
			$out .= "Cache-Control: no-cache\r\n" ;
			$out .= "Cookie: $cookie\r\n\r\n" ;
			$out .= $post ;
		} else {
			$out = "GET $path HTTP/1.1\r\n";
			$out .= "Accept: */*\r\n";
			$out .= "Referer: ".$siteurl."\r\n";
			$out .= "Accept-Language: zh-cn\r\n";
			$ua = isset($_SERVER['HTTP_USER_AGENT']) ? $_SERVER['HTTP_USER_AGENT'] : 'PHPCMS/V9';
			$out .= "User-Agent: $ua\r\n";
			$out .= "Host: $host\r\n";
			$out .= "Connection: Close\r\n";
			$out .= "Cookie: $cookie\r\n\r\n";
		}

		// --- 核心修复 2:使用带 ssl:// 前缀的 $ssl_host ---
		$fp = @fsockopen($ssl_host, $port, $errno, $errstr, $timeout);
		if(!$fp) return '';

		stream_set_blocking($fp, $block);
		stream_set_timeout($fp, $timeout);
		@fwrite($fp, $out);
		$status = stream_get_meta_data($fp);

		if($status['timed_out']) return '';	
		while (!feof($fp)) {
			// 这里的判断增加了 trim,增强了对 header 结束标志检测的鲁棒性
			$header = @fgets($fp);
			if($header && ($header == "\r\n" || $header == "\n")) break;				
		}
		
		$stop = false;
		while(!feof($fp) && !$stop) {
			$data = fread($fp, ($limit == 0 || $limit > 8192 ? 8192 : $limit));
			$return .= $data;
			if($limit) {
				$limit -= strlen($data);
				$stop = $limit <= 0;
			}
		}
		@fclose($fp);

		return $return;
	}



经过以上几步,phpcms完美支持https,结合页面静态化和url伪静态规则,亲测静态页面也可用https。
此时的网站实际上通过http和https都能访问,如果要强制全站跳转到https。


评论:(1)复制地址
发布:苗景云 | 分类:IT技术&设计 | Tags:phpcms

评论列表:

guja

评论于2020-02-19 14:47:37
88单号网 一单一用 免费试用 免费单号 快递单号www.88danhaowang.com - 回复该评论

发表评论:

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。