微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!
uchome的ajaxget函数传递中文值的问题及解决
uchome中有一个方便的ajaxget函数,用于向某段php代码传递若干个值进行处理,然后将得到的结果显示到指定的html元素中。类似:ajaxget(‘custom.php?op=getinfo&countryname=’ + countryname, ‘tdprovinces’);第一个参数(蓝色)是表示进行后台处理的url地址,第二个参数(红色)表示将处理返回结果显示到id=tdprovinces的元素中去(我这里是一个单元格)。环境:mysql 5.x.xx gbk浏览器 firefox 3.5现象是:当counrtryname的值是数字或者英文的时候,能够正常返回结果并显示到中去,但是一旦counrtryname的值为中文的时候,php运行没有报错,没有返回任何字符串。首先排查是否代码错误(因为ajaxget这里如果代码错误是看不到报错的,只表现为无返回结果),于是单独提出这段查询代码运行(新写一个php 文件,手工给定变量的值$provincename = ‘北京’),运行能够得到结果,说明代码无错,是ajax传输过程中的字符编码问题。先看看传递过来后变成什么样子了吧,于是在php页面里测试输出$_GET['countryname'],发现是一段%6E%…..类似的,汗(IE应该会显示一段utf-8版的乱码)明白了,应该是sql语句中的 cname = {$countryname}这里,因为$countryname不是一个合法的gbk字符串(mysql能识别的GBK格式——’北京’),所以导致查找不到任何记录。查资料,提示是需要将url进行编码,于是改成ajaxget(encodeURI(encodeURI(’tigtag_custom.php?op=getschools&provincename=’ + provincename)), ‘tdschools’);这次还是不行,测试输出仍然是一段代码“%5E%xxxxxx”,甚至用escape也不行,估计ajaxget函数已经把这个操作封装了。再进行一次是多此一举。汗,最后想到,是不是需要在php代码里用iconv将ajax传递过来的字符串转换成gbk的呢?因为ajax好像默认是传递utf-8格式的。好,加上一段 $provincename = iconv(”UTF-8″,”GBK”,$provincename); 试试看,强制地UTF-8转GBK再次输出$provincename测试,已经是正常的汉字“北京”了。同时mysql也能认出来并正常查询了,查询结果显示也没问题。解决。看来ajax的编码的问题,要从几个地方考虑啊,1.来源地 2.url是否需要转码 3.数据库的编码 4……====================================最新补充:我本地的测试环境是 WAMP;需要进行iconv,而在linux服务器下,反而无法输出$provincename,取消iconv操作后一切正常。百思不得其解!
uchome模板全解析(一)
 本文分两部分:第一部分是uchome模板文件的功能说明,即每个模板页面分别表示哪个功能;所有内容均以uchome1.5版为准第二部分是模板页面内使用的语法,用几个具体的例子来解释。一. 原系统模板页面简介uchome 1.5的系统模板页面主要在/templates/default目录下,命名大致分为以下几类:以cp_开头的文件(主要是用户进行数据‘操作’的模板)以do_开头的文件(注册、登陆等)以network_开头的文件(主要‘显示’随便看看里面使用)以space_开头的文件(主要用于‘显示’用户各类信息的模板)单独文件(header、footer等)样式表/templates/default/style.css****很多页面调用的模板可以从url地址中猜测出来比如左侧“日志”的链接为:http//home.xxx.com/space.php?do=blog,那么把space和blog连接起来为space_blog,然后再看该页面显示了什么,在这里这个页面显示了日志的列表,而/template/default/下面有个文件正好是space_blog_list.htm,呵呵……然后我们分别点击这个页面顶上的功能导航好友最新日志 我的日志 我踩过的日志 大家的日志 发现页面右边会显示不同的内容,有时是“按作者查看”,有时是“日志分类”,我们打开space_blog_list.htm,找到</DIV一行,发现从这里开始有两个IF判断,这就表示这两个不同的显示都整合到这一个模板页面里啦。。。>同样也可以从模板文件的名称来猜测前台页面的url,比如看到一个模板文件network_blog.htm,不晓得干什么的,那么我们就拆分它,在url里输入http://home.xxx.com/network.php?ac=blog 就可以访问了一般url里面的参数有 do cp ac 等等几个 后面连接的是功能名,如blog日志,mtag群组,thread群组话题,album相册 等等。二. 二次开发的插件使用的模版页面二次开发的插件模板页面一般位于插件文件夹下的view/文件夹下,比如结伴同行插件目录为/partner,那么模板文件在/partner/view下,样式表位于/partner/css下三. 图片文件夹一些公用的图片(如应用的icon等)放在/image/目录下,大部分与界面有关的图片位于/templates/default/image目录下四. 系统模板页面功能详细说明***注:说明里面一般是表示通过这几步操作可以看到该页面cp_advance.htm : 说明: 个人设置-》高级管理cp_album.htm : 说明: 相册-》我的相册-》管理相册主界面,包括编辑相册、编辑图片、删除相册、删除图片cp_avatar.htm : 说明: 个人设置-》我的头像cp_blog.htm : 说明: 日志-》我的日志-》发表新日志、编辑日志等操作cp_class.htm : 说明: 日志分类操作,日志-我的日志-右侧日志分类的编辑和删除cp_comment.htm : 说明: 评论的操作,包括编辑、删除、以及对别人评论的回复cp_common.htm : 说明: 举报、屏蔽通知等操作cp_credit.htm : 说明: 个人设置-》积分cp_doing.htm : 说明: 心情记录-》回复或者删除cp_domain.htm : 说明: 设置个人二级域名-现在不用管cp_feed.htm : 说明: 删除某个动态以及,消息-》通知 某个通知后面图标表示的“屏蔽”cp_friend.htm : 说明: 对好友的所有操作 ,如列表、查找、批准等等cp_header.htm : 说明: 个人设置页面的头部 ,如我的头像、个人资料、主页风格等cp_import.htm : 说明: 日志-》发表日志-》导入cp_invite.htm : 说明: 页面最顶部-》“邀请”cp_mtag.htm : 说明: 群组的操作页面,包括新建、删除、修改等cp_password.htm : 说明: 设置-》账号设置cp_pm.htm : 说明: 最顶部-》消息 包括发 删cp_poke.htm : 说明: 打招呼 包括向别人打招呼 管理别人的招呼cp_privacy.htm : 说明: 顶部-》隐私 (个人隐私设置)cp_profile.htm : 说明: 设置-》个人资料cp_sendmail.htm : 说明: 邮件相关cp_share.htm : 说明: 处理“分享”操作 例如在博客列表标题后点击分享弹出的界面cp_space.htm : 说明: 好像与“应用”有关cp_task.htm : 说明: 参与活动 例如进入首页的 “更新个人头像”,等等。。cp_theme.htm : 说明: 设置-》主页风格cp_thread.htm : 说明: 群组中 “话题”的相关操作页面cp_upload.htm : 说明: 左侧 “相册”的上传链接cp_userapp.htm : 说明: 管理用户app应用 ,暂时不管do_ajax.htm : 说明: 一些ajax操作的结果界面do_inputpwd.htm : 说明: 密码验证do_login.htm : 说明: 登陆 退出后 点击最顶部的“登录”do_lostpasswd.htm : 说明: 忘记密码do_register.htm : 说明: 退出后 点击最顶部的“注册”do_swfupload.htm : 说明: 相册上传的 “批量操作”footer.htm : 说明: 页脚header.htm : 说明:页头help.htm : 说明: 帮助页面 help.php可以看到iframe.htm : 说明: 不清楚 待研究index.htm : 说明: 首页—未登录状态的欢迎页面,聚合了blog、相册等invite.htm : 说明: 点击别人发过来的邀请链接后出现的界面network_album.htm : 说明: 随便看看-相册network_blog.htm : 说明: 随便看看-博客network_doing.htm : 说明: 随便看看-记录network_header.htm : 说明: 随便看看-顶部那几个链接network_index.htm : 说明: 随便看看-全部network_mtag.htm : 说明: 随便看看-群组network_share.htm : 说明: 随便看看-分享network_space.htm : 说明: 随便看看-成员network_thread.htm : 说明: 随便看看-话题sendmail.htm : 说明: 系统邮件的模板showmessage.htm : 说明: 信息提示space_album_list.htm : 说明: 相册列表space_album_pic.htm : 说明: 查看某个照片的页面space_album_view.htm : 说明: 点击相册,列出该相册的照片(注:区分album和pic)space_blog_list.htm : 说明: 博客列表space_blog_view.htm : 说明: 查看某博客内容space_comment_li.htm : 说明: 显示评论列表某条(这个在很多有评论功能的页面都引用了,用循环这个“小小”模板的方式列出所有评论)space_doing.htm : 说明: 心情记录space_feed.htm : 说明: 个人动态页面space_feed_li.htm : 说明: 个人动态列表(被包含在space_feed.htm里,用循环方式引用)space_friend.htm : 说明: 点击顶部“好友”space_guide.htm : 说明: 用户刚开通空间时候的向导页面,提示上传头像等space_index.htm : 说明: 点击顶部“个人主页”space_list.htm : 说明: 用户列表(被network_space.htm包含)space_menu.htm : 说明: 个人空间顶部的链接菜单space_mood.htm : 说明: 个人主页-同心情的朋友space_mtag.htm : 说明: 群组-我的群组space_mtag_field.htm : 说明: 群组-热门群组(有群组分类)space_mtag_index.htm : 说明:群组-进入某个群组space_mtag_list.htm : 说明: 群组-进入某个群组-讨论区space_mtag_member.htm : 说明: 群组-进入某个群组-成员列表space_notice.htm : 说明:顶部-通知space_pm.htm : 说明:顶部-通知-消息space_post_li.htm : 说明: 被space_thread_view.htm文件引用(被循环调用显示帖子)space_privacy.htm : 说明: 隐私相关,正在研究space_rss.htm : 说明: 订阅的,不用管space_share_li.htm : 说明: 分享-查看某条项目(被下面的space_share_list列表页循环引用)space_share_list.htm : 说明: 分享-列表space_share_view.htm : 说明: 查看某条分享的内容,在分享列表点评论的时候会出现space_tag_list.htm : 说明: 打开某篇日志——标题下如果有标签——点击标签——标签列表space_tag_view.htm : 说明: 查看某个标签space_thread_list.htm : 说明: 群组话题列表 点左侧的群组默认页面space_thread_view.htm : 说明: 查看某个主题space_wall.htm : 说明: 留言板,包括给自己留言给别人留言style.css : 说明: 样式表userapp.htm : 说明:用户添加应用或管理应用操作,不用管五. 插件模板文件说明以结伴同行为例/partner/viewpartner.htm : 说明: 首页以及信息列表页partner_header.htm : 说明: 头部文件,一般包括此插件的几个功能导航partner_post.htm : 说明: 发布新信息partner_view.htm : 说明: 浏览某条信息的内容 
uchome模板全解析(二)
本篇主要以几个例子来详细说明下uchome的模板文件结构及语法说明。必须先来了解一下uchome的模板文件解析过程,我们以“随便看看”里的“博客”为例:它的url地址是http://home.xxx.com/network.php?ac=blog,那么我们先打开/network.php看一下,我们看到第25行有一段//允许的方法$acs = array(’space’, ‘doing’, ‘blog’, ‘album’, ‘mtag’, ‘thread’, ’share’);$ac = (empty($_GET['ac']) || !in_array($_GET['ac'], $acs))?’index’:$_GET['ac'];这里是保证不会出现其他不存在的模块。看到里面有个’blog’了吧。然后又看到第37行里面有一段//数据处理include_once(S_ROOT.”./source/network_{$ac}.php”);这个实际上引用了/source/network_blog.php文件,而network_blog.php里面进行相关的博客数据准备及其他操作,为下一步的解析模板做准备 最后第49行有//模板调用include_once template(”network_$ac”);即用template函数解析对应的静态htm模板页面再进行调用,template函数就不详细说了,主要是定位到模板文件夹下的指定模板页面(例如这里就是/template/default/network_blog.htm),然后用正则表达式替换模板文件中的变量和模板语法语句,填充上一步得到的博客数据,然后输出到屏幕之所以使用模板页面,而不直接在php里面写htm代码输出,是为了使程序代码和模板页面分离,便于设计师和程序员的工作互不影响。好了废话了很多,先看一下uchome的基本模板语法就以/template/default/network_blog.htm为例,它的内容是(绿色的和褐色底色的就是嵌入到模板页面里面的语法代码了)<!–{eval $_TPL['titles'] = array(’日志’, ‘随便看看’);}–><!–{template header}–><!–{template network_header}–><div id=“search” class=“h_status”><div id=“m_search”<!–{if !empty($gets) || !empty($_GET['view'])}–> ”display:none;”<!–{/if}–>><form method=“get” action=“network.php”><input type=“text” name=“key” value=“$_GET[key]“ size=“26″ class=“t_input” /><input type=“hidden” name=“ac” value=“$ac” /><input type=“hidden” name=“searchmode” value=“1″ /><input type=“submit” name=“searchsubmit” value=“搜索日志” class=“submit” /><a href=“java script:;”onclick=“document.getElementById(’m_search’).style.display=’none’; document.getElementById(’adv_search’).style.display=’block’”>高级搜索< /a></form></div><form method=“get” action=“network.php”><table cellspacing=“0″ cellpadding=“0″ class=“formtable” id=“adv_search”<!–{if empty($gets) &&empty($_GET['view'])}–> ”display:none;”<!–{/if}–>><tr><th width=“60″>关键字*</th><td><input type=“text” name=“key” value=“$_GET[key]“ size=“26″ class=“t_input” /></td></tr><tr><th>作者名*</th><td><input type=“text” name=“username” value=“$_GET[username]“ size=“26″ class=“t_input” /></td></tr><tr><th>时间范围</th><td><input type=“text” name=“starttime” value=“$_GET[starttime]“ size=“10″ class=“t_input” /> ~ <inputtype=“text” name=“endtime” value=“$_GET[endtime]“ size=“10″ class=“t_input” />格式为 YYYY-MM-DD</td></tr><tr><th>搜索方式</th><td><label for=“subject”><input id=“subject” type=“radio” value=“subject”name=“type”$typearr[subject]>搜索标题</label><label for=“fulltext”><input id=“fulltext” type=“radio” value=“fulltext” name=“type”$typearr[fulltext]>全文搜索</label></td></tr><tr><th>结果排序</th><td><select name=“orderby”><option value=“dateline”>发布时间</option><option value=“replynum”$orderbyarr[replynum]>回复数量</option><option value=“viewnum”$orderbyarr[viewnum]>浏览次数</option></select><select name=“ascdesc”><option value=“asc”>按升序排列</option><option value=“desc”$ascdescarr[desc]>按降序排列</option></select></td></tr><tr><th>&nbsp;</th><td><input type=“hidden” name=“ac” value=“$ac” /><input type=“hidden” name=“searchmode” value=“1″ /><input type=“submit” name=“searchsubmit” value=“搜索” class=“submit” /></td></tr></table></form></div><!–{if $list}–><div class=“entry_list”><ul><!–{loop $list $value}–><li><div class=“avatar48″><a href=“space.php?uid=$value[uid]“><img src=“<!–{avatar($value[uid],small)}–>” class=“avatar” /></a></div><div class=“title”><div class=“r_option”><a href=“cp.php?ac=share&type=blog&id=$value[blogid]“id=“a_share_$value[blogid]“ onclick=“ajaxmenu(event, this.id, 99999,” , -1)” class=“a_share”>分享</a></div><h4><a href=“space.php?uid=$value[uid]&do=blog&id=$value[blogid]“>$value[subject]</a></h4><div><a href=“space.php?uid=$value[uid]“>{$_SN[$value[uid]]}</a> <span class=“time”><!–{date(’Y-m-d H:i’,$value[dateline],1)}–></span></div></div><div class=“detail image_right l_text s_clear” id=“blog_article_$value[blogid]“><!–{if $value[pic]}–><p class=“image”><a href=“space.php?uid=$value[uid]&do=blog&id=$value[blogid]“><img src=“$value[pic]“ /> $value[message]</div><div><!–{if $value[viewnum]}–><a href=“space.php?uid=$value[uid]&do=blog&id=$value[blogid]“>$value[viewnum] 次阅读</a><spanclass=“pipe”>|</span><!–{/if}–><!–{if $value[replynum]}–><a href=“space.php?uid=$value[uid]&do=blog&id=$value[blogid]#comment”>$value[replynum] 个评论</a><!–{else}–>没有评论<!–{/if}–></div></li><!–{/loop}–></ul></div
uchome2.0的ajax技术流程研究心得
前言:基于uchomer的插件如果没有使用ajax或flex,可以说无论如何也做不到完美的。而相比于flex,ajax使用的较多。好多插件开发者在研究 uchome的ajax的使用过程中花费了不少时间,此文意在减少插件开发者的研究时间。flex相关插件的说明,敬请关注!此文整理花了本同学4个小时以上的时间,如果版主觉得对大家有帮助,请加精!非常感谢:) 我们举日志回复为例:一、局部刷新的部分(先看看现象)图一: 1、评论条数由原来的a修改为a+1;2、评论内容。从数据库里读取显示于此;3、提示语,这里的“搞好了”,是我修改之后的,原来好像是“你执行的操作已成功”。当然里的内容也可能是“你发帖的时间太短了,请等等59秒后再发”之类的。注意,用innerHTML来展示的还有右上角的红色loading…,不过因为出现的时间太短,不方便截图,而且大家也很容易理解,在此不多解释。二、好了,看完现象之后,我们要从代码来研究执行过程了1、模板文件template/default/space_blog_view.htm评论表单代码里的 onclick=”ajaxpost(’quickcommentform_{$id}’, ‘comment_add’)” />     点击“评论”的时候要调用的java script函数ajaxpost(),ajaxpost函数在哪里呢?在2、source/script_ajax.js的267行代码 1 function ajaxpost(formid, func, timeout) {  2 showloading();  3  4 if(ajaxpostHandle != 0) {  5 return false;  6 }  7 var ajaxframeid = ‘ajaxframe’;  8 var ajaxframe = $(ajaxframeid);  9 if(ajaxframe == null) { 10 if (is_ie && !is_opera) { 11 ajaxframe = document.createElement(”<iframe name=’” + ajaxframeid + “‘ id=’” + ajaxframeid + “‘></iframe>”); 12 } else { 13 ajaxframe = document.createElement(”iframe”); 14 ajaxframe.name = ajaxframeid; 15 ajaxframe.id = ajaxframeid; 16 } 17 ajaxframe.style.display = ‘none’; 18 $(’append_parent’).appendChild(ajaxframe); 19 } 20 21 //产生异步的十字路口 22 $(formid).target = ajaxframeid; 23 $(formid).action = $(formid).action + ‘&inajax=1′; 24 25 ajaxpostHandle = [formid, func, timeout]; 26 27 if(ajaxframe.attachEvent) { 28 ajaxframe.detachEvent (’onload’, ajaxpost_load); 29 ajaxframe.attachEvent(’onload’, ajaxpost_load); 30 } else { 31 document.removeEventListener(’load’, ajaxpost_load, true); 32 ajaxframe.addEventListener(’load’, ajaxpost_load, false); 33 } 34 $(formid).submit(); 35 return false; 36 }  代码解读:在这里,此函数只接到两个参数表单名quickcommentform_{$id}和函数名comment_adda、showloading();显示上面说的“右上角的红色loading…”;b、ajaxframe.style.display = ‘none’;$(’append_parent’).appendChild(ajaxframe);创建一个名字ajaxframe的iframe标签之后让它隐藏起来以避免跟观众见面(一会我们会了解到,此iframe为默默无闻的幕后黑手),让ajaxframe作append_parent节点,有些同学可能一直纳闷为何header.htm总有一个<div id=”append_parent”></div>空层,在这里我们终于知道它是为儿子ajaxframe而存在的。c、$(formid).target = ajaxframeid;$(formid).action = $(formid).action + ‘&inajax=1′;这个很关键哦。设置表单的target属性为隐藏的ajaxframe可以说是此流程的核心。它使表单提交之后,页面不动弹。接着是修改表单的action属性值,在后面加个参数inajax,让处理表单的action知道这个是使用ajax技术的,要特殊照顾。设置target和action为不同值,可以说是使用表单产生异步的关键点。d、ajaxpostHandle = [formid, func, timeout];设置句柄,为下面调用ajaxpost_load函数准备两个参数formid和func;e、ajaxframe.detachEvent (’onload’, ajaxpost_load);ajaxframe.attachEvent(’onload’, ajaxpost_load);为隐藏的ajaxframe设置监听,此两行是用于ie系统的浏览器,else下面的那两行是用于其他的浏览器。f、好了,以上工作都做好,然后怎么办?提交表单呗–$(formid).submit()。我们看看表单的action代码:3、模板文件template/default/space_blog_view.htm评论表单代码里的: action=”cp.php?ac=comment”   实际上action的值已经被修改为cp.php?ac=comment&inajax=1了,重申,此表单的target的值已为ajaxframe,用于监听。4、action开始处理了,程序代码为cp_comment.php。下面拿几个重要的函数来说说。a.        //入库$cid = inserttable(’comment’, $setarr, 1);第335行。顾名思义,把数据保存到数据库里啦;b、                        //提示语//$msg = ‘do_success’;$msg = ‘搞好了’;第373行。还记得刚才的“搞好了”三个字从哪里来吗?就在这里定义的。c、每468行。showmessage($msg, $_POST['refer'], 0, $magvalues);把结果“搞好了” echo出来。具体看看showmessage函数的代码:5、source/function_common.php第221行  代码 1 //对话框 2  3 function showmessage($msgkey, $url_forward=”, $second=1, $values=array()) { 4  5 global $_SGLOBAL, $_SC, $_SCONFIG, $_TPL, $space, $_SN; 6  7  8  9 obclean();10 11 12 13 //去掉广告14 15 $_SGLOBAL['ad'] = array();16 17 18 19 //语言20 21 include_once(S_ROOT.’./language/lang_showmessage.php’);22 23 if(isset($_SGLOBAL['msglang'][$msgkey])) {24 25 $message = lang_replace($_SGLOBAL['msglang'][$msgkey], $values);26 27 } else {28 29 $message = $msgkey;30 31 }32 33 //手机34 35 if($_SGLOBAL['mobile']) {36 37 include template(’showmessage’);38 39 exit();40 41 }42 43 //显示44 45 if(empty($_SGLOBAL['inajax']) && $url_forward && empty($second)) {46 47 header(”HTTP/1.1 301 Moved Permanently”);48 49 header(”Location: $url_forward”);50 51 } else {52 53 if($_SGLOBAL['inajax']) {54 55 if($url_forward) {56 57 $message = “<a href=”$url_forward”>$message</a><ajaxok>”;58 59 }60 61 //$message = “<h1>”.$_SGLOBAL['msglang']['box_title'].”</h1><a href=”java script:;” onclick=”hideMenu();” class=”float_del”>X</a><div class=”popupmenu_inner”>$message</div>”;62 63 echo $message;64 65 ob_out(); //输入message内容以备获取66 67 } else {68 69 if($url_forward) {70 71 $message = “<a href=”$url_forward”>$message</a><script>setTimeout(”window.location.href =’$url_forward’;”, “.($second*1000).”);</script>”;72 73 }74 75 include template(’showmessage’);76 77 }78 79 }80 81 exit();82 83 } 84   这个函数比较重要,解读一下吧。a、obclean();把缓存里的echo出来的数据清空,具体原理百度一下吧。b、$message = “<a href=”$url_forward”>$message</a><ajaxok>”;这一行定义好要echo的内容了c、echo $message;echo出来d、ob_out(); //输入message内容以备获取 紧接echo,捕获上面echo的内容,然后编辑之。具体看ob_out函数代码6、source/function_common.php第936行代码 1 //调整输出 2 function ob_out() { 3 global $_SGLOBAL, $_SCONFIG, $_SC; 4  5 [color=Blue]$content = ob_get_contents();[/color] 6  7 $preg_searchs = $preg_replaces = $str_searchs = $str_re
【推荐】UCHome Authcode 详解
 define('UC_KEY', 'g3e2G1fbe3M973fet7n5j3t0Zcz8u2g9edj1g9J4B7h1aaB7ya6489M0z0f4E5Mb'); // 与 UCenter 的通信密钥, 要与 UCenter 保持一致  代码 1   2  3 //定义默认函数初始值   4 //$string="admin";初始化$srting变量数值在   5 //$keyc中调用   6 function authcode($string='admin', $operation = 'DECODE', $key = '', $expiry = 0) {          7 $ckey_length = 4;        // 随机密钥长度 取值 0-32;                                   8 // 加入随机密钥,可以令密文无任何规律,   9 //即便是原文和密钥完全相同,加密结果也会每次不同,增大破解难度。                                  10 // 取值越大,密文变动规律越大,密文变化 = //16 的 $ckey_length 次方                                  11 // 当此值为 0 时,则不产生随机密钥                                 12 $Mykey = md5(UC_KEY);  //对UC_KEY进行一次md5加密                                 13 echo "$Mykey  -- $Mykey  "; //输出  14 //$Mykey==c647d451bb5792d9cc1693a672380641          15 $key="";//定义key为empty                 16 $key = md5($key ? $key : UC_KEY);  //使用三原操作符,如果$key为  17 //空则对UC_KEY进行md5加密 否则对$key加密结果为$Mykey                18   echo "$key  -- $key  ";//输出$key==c647d451bb5792d9cc1693a672380641                  19 $key="abcdefghijklmnopqrstuvwsyz "; //定义$key=abcdefghijklmnopqrstuvwsyz 测试$keya结果              20     $keya = md5(substr($key, 0, 16));//用substr对$key进行截取得到从第一个到第16个字符                  21 echo "$keya is $keya ";//输出$keya=abcdefghijklmnop        22   $key="abcdefghijklmnopqrstuvwsyz123456";//定义$key         23 $keyb =md5(substr($key, 16, 16));//通过substr对$key进行截取   24 //截取方法为从第16位开始 向后截取到第32位结束         25 echo "$keyb $keyb ";//       26    //$keyc 使用的2层的三原操作符,理解如下$keyc = $ckey_length 的时候  27 //返回($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length))   28 //否则返回empty  29 //上面的理解为$operation == 'DECODE';时候用substr截取$string变量的值,  30 //截取大小为从第0个到第$ckey_length个默认$ckey_length为4$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';echo "$keyc is $keyc ";  31 //输出按照我们初始的测试$keyc为admi$cryptkey = $keya.md5($keya.$keyc);//这个我估计不用说了   32 //就是单纯的字符串拼接和md5之后再拼接  33 echo "$cryptkey is $cryptkey";$key_length = strlen($cryptkey);//计算$cryptkey的长度本例为64  34 echo "$key_length  is $key_length ";//base64_decode对encoded_data 进行解码,返回原始数据,  35 //失败则返回 FALSE。返回的数据可能是二进制的         36 $string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;        $string_length = strlen($string);       37 echo "$satring is $string_length ";          38 $result = '';//range() 返回数组中从 low 到 high 的单元,包括它们本身。  39 如果 low > high,  40 //则序列将从 high 到 low。//根据cuh的设置,说的白话一点就是生成一个0到255的纯数字数组      41     $box = range(0, 255);         42 echo "$box is $box[1] ";       43    $rndkey = array();        //$i 输出0到255个整数        44   for($i = 0; $i <= 255; $i++) {        //ord()函数返回一个字符的askii码值;         45 //$rndkey[$i]根据$i /$key_length的余数然后用ord处理          46 //$cryptkey[$i % $key_length]返回$cryptkey  47 数组里的键值$i=2返回第二位        48   //$rndkey[$i]从数组的第$i位开始返回$rndkey[$i]的值               49    $rndkey[$i] = ord($cryptkey[$i % $key_length]);                //echo "$rndkey[$i] is $rndkey[2]   ";        }       50    for($j = $i = 0; $i < 256; $i++) {  51 //$j是三个数相加与256取余                 52 $j = ($j + $box[$i] + $rndkey[$i]) % 256;                 53 $tmp = $box[$i];                54   $box[$i] = $box[$j];                  55 $box[$j] = $tmp;                //echo "$j is $j  ";        }//如果$i小于设定的随机密钥长度则$i加1        56   for($a = $j = $i = 0; $i < $string_length; $i++) {                  57 //在上面基础上再加1 然后和256取余  58 $a = ($a + 1) % 256;                  59 $j = ($j + $box[$a]) % 256;//$j加$box[$a]的值 再和256取余                 60 $tmp = $box[$a];                61   $box[$a] = $box[$j];               62    $box[$j] = $tmp;                // ^  位运算符允许对整型数中指定的位进行置位。  63 //如果左右参数都是字符串,则位运算符将操作字符的 ASCII 值                 64 //chr 返回相对应于 ascii 所指定的单个字符 。  65 //也就是说根据chr函数里生成的数的ascii来指定要输出的字符                 66 $result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));        }//这么多吧!后边的我把函数给大家 就是算法的反复重用了,  67 //还调用了时间函数。//base64_encode() returns 使用 base64 对 data 进行编码。  68 //设计此种编码是为了使二进制数据可以通过非纯 8-bit 的传输层传输,  69 //例如电子邮件的主体。 //str_replace() 函数使用一个字符串替换字符串中的另一些字符。  70 /*str_replace(find,replace,string,count)find 规定要查找的值。   71 *replace 规定替换 find 中的值的值。   72 *0string 规定被搜索的字符串。  73 *count 一个变量,对替换数进行计数。  74 */         75 if($operation == 'DECODE') {                 76 if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {                         77 return substr($result, 26);                  78 } else {                        return '';                }         79 } else {                return $keyc.str_replace('=', '', base64_encode($result));        }          80 }81    $key=authcode(’blog123456′,’ENCO
UCHome中数据库操作类(class_mysql.php)页面的代码分析
UCHome的数据库操作类,相对来说还是比较容易让人理解的 代码  1 <?php  2 /*  3 [UCenter Home] (C) 2007-2008 Comsenz Inc.  4 $Id: class_mysql.php 2009-10-22 1:15:00  5 @author ymaozi  6 @copyright http://www.codedesign.cn  7 @uchome源码交流QQ群:83400263  8 */  9  10 if(!defined('IN_UCHOME')) { 11 exit('Access Denied'); 12 } 13  14 class dbstuff { 15 var $querynum = 0; 16 var $link; 17 var $charset; 18  19 /** 20 * 建立数据库连接 21 * @param string $dbhost 22 * @param string $dbuser 23 * @param string $dbpw 24 * @param string $dbname 25 * @param int $pconnect 26 * @param bool $halt 27 */ 28 function connect($dbhost, $dbuser, $dbpw, $dbname = '', $pconnect = 0, $halt = TRUE) { 29 if($pconnect) {//是否采用了持久连接, 30 if(!$this->link = @mysql_pconnect($dbhost, $dbuser, $dbpw)) {//建立永久连接,永久连接不能通过mysql_close关闭 31 $halt &amp;&amp; $this->halt('Can not connect to MySQL server'); 32 } 33 } else { 34 if(!$this->link = @mysql_connect($dbhost, $dbuser, $dbpw, 1)) {//建立数据库连接 35 $halt &amp;&amp; $this->halt('Can not connect to MySQL server'); 36 } 37 } 38  39 <span id="more-106"></span> 40  41 if($this->version() > '4.1') { 42 if($this->charset) { 43 @mysql_query("SET character_set_connection=$this->charset, character_set_results=$this->charset, character_set_client=binary", $this->link); 44 } 45 if($this->version() > '5.0.1') { 46 @mysql_query("SET sql_mode=''", $this->link); 47 } 48 } 49 if($dbname) { 50 @mysql_select_db($dbname, $this->link); 51 } 52 } 53 /** 54 * 选择数据库 55 * @param string $dbname 数据库名 56 * @return bool 57 */ 58 function select_db($dbname) { 59 return mysql_select_db($dbname, $this->link); 60 } 61  62 /** 63 * 获取查询的数组 64 * @param object $query 65 * @param string $result_type MYSQL_ASSOC 只得到关联索引,MYSQL_NUM 只得到数字索引 66 * @return array 67 */ 68 function fetch_array($query, $result_type = MYSQL_ASSOC) { 69 return mysql_fetch_array($query, $result_type); 70 } 71  72 /** 73 * 执行一条sql语句 74 * @param string $sql 要执行的sql语句 75 * @param string $type 如果$type为UNBUFFERED:则执行mysql_unbuffered_query();他与mysql_query的区别是,执行后不获取和缓存结果的行 76 * @return object 77 */ 78 function query($sql, $type = '') { 79 if(D_BUG) { 80 global $_SGLOBAL; 81 $sqlstarttime = $sqlendttime = 0; //sql开始时间与结束时间 82 $mtime = explode(' ', microtime()); 83 $sqlstarttime = number_format(($mtime[1] + $mtime[0] - $_SGLOBAL['supe_starttime']), 6) * 1000; 84 } 85 //如果定义$type='UNBUFFERED' 则执行mysql_unbuffered_query()函数 86 $func = $type == 'UNBUFFERED' && @function_exists('mysql_unbuffered_query') ? 87 'mysql_unbuffered_query' : 'mysql_query'; 88 if(!($query = $func($sql, $this->link)) && $type != 'SILENT') { 89 $this->halt('MySQL Query Error', $sql); 90 } 91 if(D_BUG) { 92 $mtime = explode(' ', microtime()); 93 $sqlendttime = number_format(($mtime[1] + $mtime[0] - $_SGLOBAL['supe_starttime']), 6) * 1000; 94 $sqltime = round(($sqlendttime - $sqlstarttime), 3);//获取php的结束时间 95  96 $explain = array(); 97 $info = mysql_info();//取得最近一条查询的信息 98 if($query && preg_match("/^(select )/i", $sql)) { 99 $explain = mysql_fetch_assoc(mysql_query('EXPLAIN '.$sql, $this->link));100 }101 $_SGLOBAL['debug_query'][] = array('sql'=>$sql, 'time'=>$sqltime, 'info'=>$info, 'explain'=>$explain);102 }103 $this->querynum++; //将执行的query数加1104 return $query;105 }106 /**107 * 取得前一次 MySQL 操作所影响的记录行数108 * @return int109 */110 function affected_rows() {111 return mysql_affected_rows($this->link);112 }113 /**114 * 返回上一个 MySQL 操作产生的文本错误信息115 * @return string116 */117 function error() {118 return (($this->link) ? mysql_error($this->link) : mysql_error());119 }120 /**121 * 返回上一个 MySQL 操作中的错误信息的数字编码122 * @return int123 */124 function errno() {125 return intval(($this->link) ? mysql_errno($this->link) : mysql_errno());126 }127 /**128 * 取指定的结果集129 * @param object $query130 * @param int $row131 * @return string132 */133 function result($query, $row) {134 $query = @mysql_result($query, $row);135 return $query;136 }137 /**138 * 取得结果集的行数139 * @param object $query140 * @return int141 */142 function num_rows($query) {143 $query = mysql_num_rows($query);144 return $query;145 }146 /**147 * 取得字段数148 * @param object $query149 * @return int150 */151 function num_fields($query) {152 return mysql_num_fields($query);153 }154 /**155 * 释放结果内存156 * @param object $query157 * @return bool158 */159 function free_result($query) {160 return mysql_free_result($query);161 }162 /**163 * 取得上一步 INSERT 操作产生的 ID164 * @return int165 */166 function insert_id() {167 return ($id = mysql_insert_id($this->link)) >= 0 ? $id : $this->result($this->query("SELECT last_insert_id()"), 0);168 }169 /**170 * 从查询语句中取一条记录171 * @param object $query172 * @return array173 */174 function fetch_row($query) {175 $query = mysql_fetch_row($query);176 return $query;177 }178 /**179 * 从结果集中取得列信息180 * @param object $query181 * @ret
UCHOME积分与经验机制
uchome的积分和经验机制,是为了让社区用户更好的互动,比如对日志的评论,上传图片等等一系列的互动操作。与积分和经验有关的数据库表uchome_space:会员的信息表,字段credit:积分,experience:经验。uchome_creditrule:积分规则表,奖励和扣除积分的类型(比如“一次性”,“一天一次”,“无周期”)uchome_creditlog:积分日志表,记录会员奖励和扣除积分。后台的操作,UCHOME定义好了一系列的类型,如果想要自己添加积分奖罚类型,就只能自己做二次开发。function_common文件的getreward函数获取指定动作能获得多少积分和经验,getreward第一个参数是类型,第二个是更新,第三个是奖罚uid,第四个是去除重复,第五个是否更新cookie。  =================================================== //获取指定动作能获得多少积分/**     Jackie 函数 getreward 5个参数 :*    $action         所执行动作*    $update       1:更新用户积分和经验并录入积分历史 0:不更新用户积分和经验也录入积分历史*    $uid               用户ID*    $needle        未知*    $setcookie  1 可选 有新值则重新记录cookie 反之*/function getreward($action, $update=1, $uid=0, $needle=”, $setcookie = 1) {}使用:getreward(‘report’, 1, $uid, ”, 0);  因为report不限次数与周期,所以可以尽情测试
uchome的积分机制
UCHOME2.0积分机制分析A:管理员在后台修改积分规则B:数据被写入数据表creditrule 中,其中rewardtype=1表示奖励措施rewardtype=0表示处罚措施并将数据写入缓存文件data/data_creditrule.php 中C:用户发表文章或者进行其他操作的时候,通过getreward函数来获取奖罚积分D:然后通过SQL语句将数据写入用户数据库表space中,从而增加或减少用户积分E:getreward函数部分通过包含data/data_creditrule.php 缓存文件来调用积分规则UCHOME积分变动提示是通过footer.htm监控的,代码如下:<script type="text/javascript">  showreward();</script> 查下source/script_common.js中showreward函数,找到AJAX处理页面为source/do_ajax.php中的getreward部分,代码如下代码} elseif($op == 'getreward') {    $reward = '';    if($_SCOOKIE['reward_log']) {        $log = explode(',', $_SCOOKIE['reward_log']);        if(count($log) == 2 && $log[1]) {            @include_once(S_ROOT.'./data/data_creditrule.php');            $query = $_SGLOBAL['db']->query("SELECT * FROM ".tname('creditlog')." WHERE clid='$log[1]'");            $creditlog = $_SGLOBAL['db']->fetch_array($query);            $rule = $_SGLOBAL['creditrule'][$log[0]];            $rule['cyclenum'] = $rule['rewardnum']? $rule['rewardnum'] - $creditlog['cyclenum'] : 0;        }        ssetcookie('reward_log', '');    }    }   功能都在这里了,下面就开始往表creditlog里插条数据,我这里加的是天声人语的奖励规则。SQL如下:代码INSERT INTO `前缀_creditrule` (`rid` ,`rulename` ,`action` ,`cycletype` ,`cycletime` ,`rewardnum` ,`rewardtype` ,`norepeat` ,`credit` ,`experience`)VALUES (NULL , '天声人语', 'publishtsry', '1', '0', 1', '1', '0', '10', '1'); 你也可直接用PHPMYADMIN进行添加,值的含义参照后台其他积分的规则,更新一下缓存(重要)。然后在需要显示积分提示的地方加上:(注意红色地方是自定义的积分动作)//积分提示代码$reward = getreward('publishtsry', 0);$_SGLOBAL['db']->query('UPDATE '.tname('space')." SET credit=credit+$reward[credit], experience=experience+$reward[experience] WHERE uid='{$_SGLOBAL['supe_uid']}'");