CentOS 下 PHP 从 5.1.x升级到5.2.x

rpm --import http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka 

# vi /etc/yum.repos.d/CentOS-Base.repo 增加下面信息

[utterramblings]
name=Jason's Utter Ramblings Repo
baseurl=http://www.jasonlitka.com/media/EL$releasever/$basearch/
enabled=1
gpgcheck=1
gpgkey=http://www.jasonlitka.com/media/RPM-GPG-KEY-jlitka

执行命令,自动升级。

yum update php -y
yum install libmcrypt -y

dedecms 的cn_substr_utf8的商榷

在dedecms里面 cn_substr_utf8 函数是这样的

/**
 *  utf-8中文截取,单字节截取模式
 *
 * @access    public
 * @param     string  $str  需要截取的字符串
 * @param     int  $slen  截取的长度
 * @param     int  $startdd  开始标记处
 * @return    string
 */
if ( ! function_exists('cn_substr_utf8'))
{
    function cn_substr_utf8($str, $length, $start=0)
    {
        if(strlen($str) < $start+1)
        {
            return '';
        }
        preg_match_all("/./su", $str, $ar);
        $str = '';
        $tstr = '';

        //为了兼容mysql4.1以下版本,与数据库varchar一致,这里使用按字节截取
        for($i=0; isset($ar[0][$i]); $i++)
        {
            if(strlen($tstr) < $start)
            {
                $tstr .= $ar[0][$i];
            }
            else
            {
                if(strlen($str) < $length + strlen($ar[0][$i]) )
                {
                    $str .= $ar[0][$i];
                }
                else
                {
                    break;
                }
            }
        }
        return $str;
    }
}

其中

if(strlen($str) < $length + strlen($ar[0][$i]) )

一行可能会造成截取后多了一个字符,可以考虑改为

if(strlen($str) < $length + strlen($ar[0][$i]) -1 )

测试代码如下

 
$f = "你好fasdfa你fasdf#e#";
$pos = strpos($f,'#e#');
var_dump($pos);
var_dump(cn_substr_utf8($f,$pos));
var_dump(cn_substr_utf82($f,$pos));

function cn_substr($str, $slen, $startdd=0)
{
	global $cfg_soft_lang;
	if($cfg_soft_lang=='utf-8')
	{
		return cn_substr_utf8($str, $slen, $startdd);
	}
	$restr = '';
	$c = '';
	$str_len = strlen($str);
	if($str_len < $startdd+1)
	{
		return '';
	}
	if($str_len < $startdd + $slen || $slen==0)
	{
		$slen = $str_len - $startdd;
	}
	$enddd = $startdd + $slen - 1;
	for($i=0;$i<$str_len;$i++) 	{ 		if($startdd==0) 		{ 			$restr .= $c; 		} 		else if($i > $startdd)
		{
			$restr .= $c;
		}

		if(ord($str[$i])>0x80)
		{
			if($str_len>$i+1)
			{
				$c = $str[$i].$str[$i+1];
			}
			$i++;
		}
		else
		{
			$c = $str[$i];
		}

		if($i >= $enddd)
		{
			if(strlen($restr)+strlen($c)>$slen)
			{
				break;
			}
			else
			{
				$restr .= $c;
				break;
			}
		}
	}
	return $restr;
}

function cn_substr_utf8($str, $length, $start=0)
{
	if(strlen($str) < $start+1)
	{
		return '';
	}
	preg_match_all("/./su", $str, $ar);

	$str = '';
	$tstr = '';

	//为了兼容mysql4.1以下版本,与数据库varchar一致,这里使用按字节截取
	for($i=0; isset($ar[0][$i]); $i++)
	{
		if(strlen($tstr) < $start)
		{

			$tstr .= $ar[0][$i];
		}
		else
		{

			if(strlen($str) < $length + strlen($ar[0][$i])  )
			{

				$str .= $ar[0][$i];
			}
			else
			{

				break;
			}
		}
	}
	return $str;
}

function cn_substr_utf82($str, $length, $start=0)
{
	if(strlen($str) < $start+1)
	{
		return '';
	}
	preg_match_all("/./su", $str, $ar);

	$str = '';
	$tstr = '';

	//为了兼容mysql4.1以下版本,与数据库varchar一致,这里使用按字节截取
	for($i=0; isset($ar[0][$i]); $i++)
	{
		if(strlen($tstr) < $start)
		{

			$tstr .= $ar[0][$i];
		}
		else
		{

			if(strlen($str) < $length + strlen($ar[0][$i]) -1 ) // phpsir 加了 -1 
			{

				$str .= $ar[0][$i];
			}
			else
			{

				break;
			}
		}
	}
	return $str;
}

dedecms 分页标题提取方法

提取每个分页标题到模版里面

修改includes\arc.archives.class.php 的 GetPageTitlesST函数

pagetitle3

模版里面调用方法

首先保存 文章标题

{dede:field.title runphp=’yes’}$GLOBALS[“phpsir”]=@me;@me=””;{/dede:field.title}

调用方法是 pagetitle  style=’biaoti’ , 同时把原来文章标题附着在后面…..

{dede:pagetitle style=’biaoti’ runphp=”yes”}if(@me==” ) {@me = $GLOBALS[“phpsir”]; }else { @me = @me . “_” . $GLOBALS[“phpsir”]  ;} {/dede:pagetitle}

发布文章时候的格式是如下的

pagetitle2

 

参考网上文章为

http://www.veryhuo.com/a/view/6753.html

 

帝国备份王的用法变通-关于恢复

对于要备份很多表的用户来说,可以一次备份然后多次部分恢复数据库

方法是修改 备份文件夹里面 config.php 的 $b_table变量

$b_table 变量是一个很长的字符串,如果你备份的表多的话。把他分成几个部分

$b_table = “a,b,c,d,e,f,g,h”;

可以修改为

$b_table = “a,b”;

$b_table = “c,d,e”;

$b_table = “f,g”;

$b_table = “h”;

通过利用注释,来分别导入这部分的表格,从而达到避免出现 502 503 等问题!!!

 

discuz X3 游客无法浏览帖子,显示帖子不存在

今天一个朋友的discuzX3 的帖子在游客状态无法打开,后台权限都给过了,所以不存在权限问题,

显示帖子不存在,经处理后解决,思路如下
地址是 thread-NNNN-1-1.html
NNNN 一般是帖子的tid , 根据显示的关键字 “没有找到帖子” 查到 post_not_found 的语言项目,在 fetch_all_by_tid_range_position 函数里面想可能是某个tid的帖子没有找到,
在那个函数里面,居然发现 $end 变量也是1,而最终追溯到 $_G[‘ppp’] 这个值是NULL,
那么问题就好处理了 设置$_G[‘ppp’] = 10 ; 解决
如果你碰到这个问题,解决不了,可以QQ 733905

关于一例子cpu100%的处理方法

背景:

一家网站,帝国程序CMS,网站发布内容数据较多,症状是8核心cpu常常都满载

top 查看的情况是 php-cgi 进程满载,判断可能是1)访问量大或者被攻击,2)php代码问题

网站经过CDN,按理说,不应该造成大量的访问,出现问题完全是php代码访问造成,

本来服务器运行的是 spawn-cgi 来启动的php-cgi进程 , 后来改为php-fpm 也仍然是cpu满载,判断问题在php程序,开启 php-fpm 的slow.log 功能,把运行缓慢的php代码,记录起来立刻发现了问题!!!

根据slow.log 的情况,发现是一些更新网页代码,被当作 script 脚本 在网页里面,而那个更新脚本运行缓慢,当大量用户来的时候,造成了cpu满载,经过更换脚本名称,cpu立刻下降到正常水平。

解决方案:

把一些更新操作用linux的定时任务去完成,从而避免了放到网页里面。

ecshop的lib_payment.php的get_order_id_by_sn需要订正

get_order_id_by_sn 函数在通过order_id 在pay_log 表里查找支付记录的时候,不够严格,导致可能一个order_id 对应多个pay_log记录,需要找到的是最后也就是log_id 最大的那个。那么从这个角度看,这个代码就需要加一句 order by log_id  DESC 的字样

return $GLOBALS[‘db’]->getOne(“SELECT log_id FROM ” . $GLOBALS[‘ecs’]->table(‘pay_log’) . ” WHERE order_id=” . $order_sn . ‘ AND order_type=1’);

就需要修改为

return $GLOBALS[‘db’]->getOne(“SELECT log_id FROM ” . $GLOBALS[‘ecs’]->table(‘pay_log’) . ” WHERE order_id=” . $order_sn . ‘ AND order_type=1 order by log_id DESC ‘);

一个DiscuzX的奇怪问题的解答,用户中心出错

 

出错情形如下,dz-unserialize

正常应该是这样的

dz-unserialize2

那么到底是什么出了问题呢,经过一番代码搜索,发现在数据库读取 pre_common_setting 表里面 skey = profilegroup 的svalue 值 无法反串行化 unserialize
从而无法得到数组,导致更新失败,从而无法在这里显示,究其原因,可能是dz之前是gbk版本,后来改为utf8,此字段没有正常修改,从新安装的utf8版本的discuzX 复制进去svalue 后,成功恢复。

 

最土团购的项目编辑多图上传kindedit编辑器

最土团购网站的项目编辑部分,本单详情的内容编辑器采用的kindeditor 比较简陋,可以用最新版本的替换,
下载最新版放入 static/kindeditornew 目录 ,然后修改 include/template/manage/manage_header.html
加入定制内容
注意里面的 textarea[name=”detail”] 是关键

<link rel="stylesheet" href="/static/js/kindeditornew/themes/default/default.css" />
<script type="text/javascript" src="/static/js/kindeditornew/kindeditor-min.js"></script>
<script charset="utf-8" src="/static/js/kindeditornew/lang/zh_CN.js"></script>
<script>
var editor;
KindEditor.ready(function(K) {
editor = K.create('textarea[name="detail"]', {
allowFileManager : true
});

});
</script>

phpdisk 支付宝支付的一个可能缺陷

在phpdisk z-Core 3.5 版本 的
plugin/payment/alipay/class/alipay_function.php 的 para_filter 函数 没有去除干净符合支付宝的参数,在alipay_config.php 里面定义的返回地址包含了额外的参数 action=alipay,

return_url = $settings[‘phpdisk_url’].’payment.php?action=alipay’;
所以必须把这个也去除,方式是如下图,
否则的话,计算md5 值可能出错!从而导致支付失败

phpdisk_alipay

 

 

ecshop 注册送红包

在user.php 的注册成功信息显示前面,大概是  show_message(sprintf($_LANG['register_success'].............前面加入
注意下下面的 $bonus_type_id = 1; 需要先在后台加入对应的红包的id

//phpsir 1111
$bonus_type_id=1;
$bonus = $db->getRow('SELECT * FROM ' . $ecs->table("bonus_type") . " WHERE send_type = 0 And type_id =  $bonus_type_id", true); 
if($bonus){ if(time()<($bonus['send_end_date']+28800)){
 $sql = "INSERT INTO " . $ecs->table('user_bonus') . "(bonus_type_id, bonus_sn, user_id, used_time, order_id, emailed) " . "VALUES ('$bonus[type_id]', 0, '$_SESSION[user_id]', 0, 0, 0)";
 $db->query($sql); } } 
//phpsir 1111_end

phpcms 的 sso 通信失败的解决和思路

朋友的phpcms 在sso 登陆设置中,出现通信失败,最终调试发现,服务器本机linux,无法访问本身域名的ip,这个vps是虚拟的ip,内部ip,蛋疼的是,他无法访问外部隐射ip,从而导致,file_get_contents(“http://域名/api.php………”);无法得到结果

解决方法是手动在本地 hosts 里面加入一行
10.0.8.99  www.domainname.com
也就是虚拟ip和域名的对应关系
程序无需修改,自动就通信成功了。

发现此类问题的服务器是 息壤VPS,不知道其他的VPS商是否也有此类问题,并且,是否如DiscuZ Ucenter 也会出现此类问题,不得而知,在此记录一下心得

ecshop的paypal sandbox 测试支付,需要修改的部分

QQ截图20130503164129

QQ截图20130503163955

下面是代码,方便复制

get_code函数里面
 $def_url  = '<br /><form style="text-align:center;" action="https://www.sandbox.paypal.com/cgi-bin/webscr" method="post" target="_blank">' .   // 不能省略
respond 函数里面
// post back to PayPal system to validate
$header = "POST /cgi-bin/webscr HTTP/1.0\r\n";
$header .= "HOST: www.sandbox.paypal.com\r\n";
$header .= "Content-Type: application/x-www-form-urlencoded\r\n";
$header .= "Content-Length: " . strlen($req) ."\r\n\r\n";
$fp = fsockopen ('ssl://www.sandbox.paypal.com', 443, $errno, $errstr, 30);

ecshop 农行支付接口的返回respond部分

function respond()
{
$result = false;

$originData = $_POST["MSG"];
$xmlData = base64_decode($originData);
$retCodStartStr = "<ReturnCode>";
$retCodEndStr = "</ReturnCode>";
$retCodStartPos = strpos($xmlData,$retCodStartStr);
$retCodEndPos = strpos($xmlData,$retCodEndStr);
$retCode = substr($xmlData,$retCodStartPos+strlen("<ReturnCode>"),$retCodEndPos-$retCodStartPos-strlen("<ReturnCode>"));//注意不可使用$ReturnCode,否则会什么都不显示,可能是保留字

$errMesStartStr = "<ErrorMessage>";
$errMesEndStr = "</ErrorMessage>";
$errMesStartPos = strpos($xmlData,$errMesStartStr);
$errMesEndPos = strpos($xmlData,$errMesEndStr);
$ErrorMessage = substr($xmlData,$errMesStartPos+strlen("<ErrorMessage>"),$errMesEndPos-$errMesStartPos-strlen("<ErrorMessage>"));

$sigStartStr = "<Signature>";
$sigEndStr = "</Signature>";
$sigStartPos = strpos($xmlData,$sigStartStr);
$sigEndPos = strpos($xmlData,$sigEndStr);
$signature = substr($xmlData,$sigStartPos+strlen("<Signature>"),$sigEndPos-$sigStartPos-strlen("<Signature>"));

$mesStartStr = "<Message>";
$mesEndStr = "</Message>";
$mesStartPos = strpos($xmlData,$mesStartStr);
$mesEndPos = strpos($xmlData,$mesEndStr);
$message = substr($xmlData,$mesStartPos+strlen("<Message>"),$mesEndPos-$mesStartPos-strlen("<Message>"));
//验证签名有效性
$data = $message;
$fp = fopen(ROOT_PATH."MainServer.0001.pem", "r");
$pub_key = fread($fp, 8192);

$pubkeyid = openssl_get_publickey($pub_key);
$sig=base64_decode($signature);
if(openssl_verify($data,$sig,$pubkeyid)==1)
{
if($retCode=="0000")
{
//订单号
$OrderNoStartStr = "<OrderNo>";
$OrderNoEndStr = "</OrderNo>";
$OrderNoStartPos = strpos($xmlData,$OrderNoStartStr);
$OrderNoEndPos = strpos($xmlData,$OrderNoEndStr);
$OrderNo = substr($xmlData,$OrderNoStartPos+strlen("<OrderNo>"),$OrderNoEndPos-$OrderNoStartPos-strlen("<OrderNo>"));

//订单金额
$AmountStartStr = "<Amount>";
$AmountEndStr = "</Amount>";
$AmountStartPos = strpos($xmlData,$AmountStartStr);
$AmountEndPos = strpos($xmlData,$AmountEndStr);
$Amount = substr($xmlData,$AmountStartPos+strlen("<Amount>"),$AmountEndPos-$AmountStartPos-strlen("<Amount>"));

//批次号
$BatchNoStartStr = "<BatchNo>";
$BatchNoEndStr = "</BatchNo>";
$BatchNoStartPos = strpos($xmlData,$BatchNoStartStr);
$BatchNoEndPos = strpos($xmlData,$BatchNoEndStr);
$BatchNo = substr($xmlData,$BatchNoStartPos+strlen("<BatchNo>"),$BatchNoEndPos-$BatchNoStartPos-strlen("<BatchNo>"));

//传票号
$VoucherNoStartStr = "<VoucherNo>";
$VoucherNoEndStr = "</VoucherNo>";
$VoucherNoStartPos = strpos($xmlData,$VoucherNoStartStr);
$VoucherNoEndPos = strpos($xmlData,$VoucherNoEndStr);
$VoucherNo = substr($xmlData,$VoucherNoStartPos+strlen("<VoucherNo>"),$VoucherNoEndPos-$VoucherNoStartPos-strlen("<VoucherNo>"));

//会计日期
$HostDateStartStr = "<HostDate>";
$HostDateEndStr = "</HostDate>";
$HostDateStartPos = strpos($xmlData,$HostDateStartStr);
$HostDateEndPos = strpos($xmlData,$HostDateEndStr);
$HostDate = substr($xmlData,$HostDateStartPos+strlen("<HostDate>"),$HostDateEndPos-$HostDateStartPos-strlen("<HostDate>"));

//会计时间
$HostTimeStartStr = "<HostTime>";
$HostTimeEndStr = "</HostTime>";
$HostTimeStartPos = strpos($xmlData,$HostTimeStartStr);
$HostTimeEndPos = strpos($xmlData,$HostTimeEndStr);
$HostTime = substr($xmlData,$HostTimeStartPos+strlen("<HostTime>"),$HostTimeEndPos-$HostTimeStartPos-strlen("<HostTime>"));

//备注
$MerchantRemarksStartStr = "<MerchantRemarks>";
$MerchantRemarksEndStr = "</MerchantRemarks>";
$MerchantRemarksStartPos = strpos($xmlData,$MerchantRemarksStartStr);
$MerchantRemarksEndPos = strpos($xmlData,$MerchantRemarksEndStr);
$MerchantRemarks = substr($xmlData,$MerchantRemarksStartPos+strlen("<MerchantRemarks>"),$MerchantRemarksEndPos-$MerchantRemarksStartPos-strlen("<MerchantRemarks>"));

//支付方式
$PayTypeStartStr = "<PayType>";
$PayTypeEndStr = "</PayType>";
$PayTypeStartPos = strpos($xmlData,$PayTypeStartStr);
$PayTypeEndPos = strpos($xmlData,$PayTypeEndStr);
$PayType = substr($xmlData,$PayTypeStartPos+strlen("<PayType>"),$PayTypeEndPos-$PayTypeStartPos-strlen("<PayType>"));

//通知方式
$NotifyTypeStartStr = "<NotifyType>";
$NotifyTypeEndStr = "</NotifyType>";
$NotifyTypeStartPos = strpos($xmlData,$NotifyTypeStartStr);
$NotifyTypeEndPos = strpos($xmlData,$NotifyTypeEndStr);
$NotifyType = substr($xmlData,$NotifyTypeStartPos+strlen("<NotifyType>"),$NotifyTypeEndPos-$NotifyTypeStartPos-strlen("<NotifyType>"));

//todo:商户更新相关数据库操作

$order_sn = $OrderNo;
if(substr($order_sn,0,4)=="0000"){
$order_id = get_order_id_by_sn($order_sn,true);
order_paid($order_id);
}
else{
$order_id = get_order_id_by_sn($order_sn);
order_paid($order_id);
}
$result = true;
file_put_contents("abcbank.txt","支付成功1",FILE_APPEND);
}
else
{
file_put_contents("abcbank.txt","错误码:".$retCode."错误信息:".$ErrorMessage,FILE_APPEND);
}
}
else
{
file_put_contents("abcbank.txt","签名验证失败,该通知内容不可信",FILE_APPEND);
}

// free the key from memory
openssl_free_key($pubkeyid);
return $result;

}

一个还算漂亮的语法高亮的工具 prettify

从这里下载
https://code.google.com/p/google-code-prettify/
下载后,有用的文件是src 和 style 目录
用法

如下
<head>
<link rel="stylesheet" type="text/css" href="sunburst.css">
<script type="text/javascript" src="prettify.js" ></script>
</head>
<body onload="prettyPrint()">
<pre class="prettyprint">
@*你的代码片断*@
</pre>
</body>
参考了 http://www.lidongkui.com/use-prettify-to-highlight-code

dedecms 的一点经验分享

GetFileName 位于 include\helpers\chanelunit.helper.php 文件中

此函数 是 dedecms 用于生成文件名和获得文件url 地址的 关键文件!!!!!

而且是入口型文件,所有的文件名和url地址的获取都从此走出

jieqi 杰奇的图片水印增加在四角同时添加水印

杰奇的小说图片上传后可以加水印,目前的上中下左中右,随机都有了

现在需求是加在四角都有 修改 lib/image/imagewater.php

原来代码

$temp_wm_image = $this->getPos($src_image_w,$src_image_h,$this->wm_image_pos,$wm_image);
$wm_image_x = $temp_wm_image["dest_x"];
$wm_image_y = $temp_wm_image["dest_y"];

imagecopymerge($src_image, $wm_image,$wm_image_x,$wm_image_y,0,0,$wm_image_w,$wm_image_h,$this->wm_image_transition);

// 1 = top left 上左
// 2 = top middle 上中
// 3 = top right 上右
// 4 = middle left 中左
// 5 = middle 中中
// 6 = middle right 中右
// 7 = bottom left 下左
// 8 = bottom middle 下中
// 9 = bottom right 下右
// 10 = rand 随机

知道我们只要在 1 3 7 9 位置加就可以了

重复上面的代码 4次就可以搞定了。

QQ截图20130407134936