/** * 系统错误处理 * @param <type> message 错误信息 * @param <type>show 是否显示信息 * @param <type> save 是否存入日志 * @param <type>halt 是否中断访问 */ function system_error(message,show = true, save = true,halt = true) { ...... } /** * 更新 session * @global <type> _G * @staticvar booleanupdated * @param boolean force * @return boolean */ function updatesession(force = false) { ...... } /** * 获取 microtime float 数值,为了兼容php4 * @return <float> */ function dmicrotime() { ...... } /** * 设置全局 _G 中的变量 * @global <array>_G * @param <string> key 键 * @param <string>value 值 * @param <mix> group 组(准备废弃,尽量不用) * @return true * * @example * setglobal('test', 1); //_G['test'] = 1; * setglobal('config/test/abc') = 2; //_G['config']['test']['abc'] = 2; * */ function setglobal(key , value,group = null) { ...... } /** * 获取全局变量 _G 当中的某个数值 * @global_G * @param <type> key * @param <type>group 计划废弃的参数,不建议使用 * @return <mix> * * v = getglobal('test'); //v = _G['test'] *v = getglobal('test/hello/ok'); // v =_G['test']['hello']['ok'] */ function getglobal(key,group = null) { ...... } /** * 取出 get, post, cookie 当中的某个变量 * * @param string k key 值 * @param stringtype 类型 * @return mix */ function getgpc(k,type='GP') { ...... } /** * 根据uid 获取用户基本数据 * @staticvar array users 存放已经获取的用户的信息,避免重复查库 * @param <int>uid * @return <array> */ function getuserbyuid(uid) { ...... } /** * 获取当前用户的扩展资料 * @paramfield 字段 */ function getuserprofile(field) { ...... } /** * 对字符串或者输入进行 addslashes 操作 * @param <mix>string * @param <int> force * @return <mix> */ function daddslashes(string, force = 1) { ...... } /** * 对字符串进行加密和解密 * @param <string>string * @param <string> operation DECODE 解密 | ENCODE 加密 * @param <string>key 当为空的时候,取全局密钥 * @param <int> expiry 有效期,单位秒 * @return <string> */ function authcode(string, operation = 'DECODE',key = '', expiry = 0) { ...... } /** * 远程文件文件请求兼容函数 */ function dfsockopen(url, limit = 0,post = '', cookie = '',bysocket = FALSE, ip = '',timeout = 15, block = TRUE) { ...... } /** * HTML转义字符 * @paramstring - 字符串 * @return 返回转义好的字符串 */ function dhtmlspecialchars(string) { ...... } /** * 退出程序 同 exit 的区别, 对输出数据会进行 重新加工和处理 * 通常情况下,我们建议使用本函数终止程序, 除非有特别需求 * @param <type>message */ function dexit(message = '') { ...... } /** * 同 php header函数, 针对 location 跳转做了特殊处理 * @param <type>string * @param <type> replace * @param <type>http_response_code */ function dheader(string,replace = true, http_response_code = 0) { ...... } /** * 设置cookie * @paramvar - 变量名 * @param value - 变量值 * @paramlife - 生命期 * @param prefix - 前缀 * @paramhttponly - 安全属性 */ function dsetcookie(var,value = '', life = 0,prefix = 1, httponly = false) { ...... } /** * 获取cookie * @paramkey - cookie名称,不需要带前缀 */ function getcookie(key) { ...... } /** * 获取文件扩展名 * @paramfilename 文件名 */ function fileext(filename) { ...... } /** * 检查是否是以手机浏览器进入(IN_MOBILE) */ function checkmobile() { ...... } /** * 字符串方式实现 preg_match("/(s1|s2|s3)/",string, match) * @param stringstring 源字符串 * @param array arr 要查找的字符串 如array('s1', 's2', 's3') * @param boolreturnvalue 是否返回找到的值 * @return bool */ function dstrpos(string, &arr, returnvalue = false) { ...... } /** * 检查邮箱是否有效 * @paramemail 要检查的邮箱 * @param 返回结果 */ function isemail(email) { ...... } /** * 问题答案加密 * @paramquestionid - 问题 * @param answer - 答案 * @return 返回加密的字串 */ function quescrypt(questionid, answer) { ...... } /** * 产生随机码 * @paramlength - 要多长 * @param numberic - 数字还是字符串 * @return 返回字符串 */ function random(length, numeric = 0) { ...... } /** * 判断一个字符串是否在另一个字符串中存在 * * @param string 原始字串string * @param string 查找 find * @return boolean */ function strexists(string, find) { ...... } /** * 获取头像 * * @param intuid 需要获取的用户UID值 * @param string size 获取尺寸 'small', 'middle', 'big' * @param booleanreturnsrc 是否直接返回图片src * @param boolean real 是否返回真实图片 * @param booleanstatic 是否返回真实路径 * @param string ucenterurl 强制uc路径 */ function avatar(uid, size = 'middle',returnsrc = FALSE, real = FALSE,static = FALSE, ucenterurl = '') { ...... } /** * 加载语言 * 语言文件统一为lang = array(); * @param file - 语言文件,可包含路径如 forum/xxx home/xxx * @paramlangvar - 语言文字索引 * @param vars - 变量替换数组 * @paramdefault - 指定默认值,当找不到对应言包时生效 * @return 语言文字 */ function lang(file,langvar = null, vars = array(),default = null) { ...... } /** * 检查模板源文件是否更新 * 当编译文件不存时强制重新编译 * 当 tplrefresh = 1 时检查文件 * 当 tplrefresh > 1 时,则根据 tplrefresh 取余,无余时则检查更新 * */ function checktplrefresh(maintpl,subtpl, timecompare,templateid, cachefile,tpldir, file) { ...... } /** * 解析模板 * @return 返回域名 */ function template(file, templateid = 0,tpldir = '', gettplfile = 0,primaltpl='') { ...... } /** * 对某id进行个性化md5 */ function modauthkey(id) { ...... } /** * 获得当前应用页面选中的导航id */ function getcurrentnav() { ...... } /** * 读取缓存 * @paramcachenames - 缓存名称数组或字串 */ function loadcache(cachenames,force = false) { ...... } /** * 通过memcache\mysql\file等几种手段读缓存 * @param mixed cachenames 缓存名的数组或字串 */ function cachedata(cachenames) { ...... } /** * 格式化时间 * @param timestamp - 时间戳 * @paramformat - dt=日期时间 d=日期 t=时间 u=个性化 其他=自定义 * @param timeoffset - 时区 * @return string */ function dgmdate(timestamp, format = 'dt',timeoffset = '9999', uformat = '') { ...... } /** 得到时间戳 */ function dmktime(date) { ...... } /** * 更新缓存 * @param cachename - 缓存名称 * @paramdata - 缓存数据 */ function save_syscache(cachename,data) { ...... } /** * Portal模块 * @param parameter - 参数集合 */ function block_get(parameter) { ...... } /** * Portal 模块显示 * * @param parameter - 参数集合 */ function block_display(bid) { ...... } /** * 返回库文件的全路径 * * @param string libname 库文件分类及名称 * @param stringfolder 模块目录'module','include','class' * @return string * * @example require DISCUZ_ROOT.'./source/function/function_cache.php' * @example 我们可以利用此函数简写为:require libfile('function/cache'); * */ function libfile(libname,folder = '') { ...... } /** * 针对uft-8进行特殊处理的strlen * @param string str * @return int */ function dstrlen(str) { ...... } /** * 根据中文裁减字符串 * @param string - 字符串 * @paramlength - 长度 * @param doc - 缩略后缀 * @return 返回带省略号被裁减好的字符串 */ function cutstr(string, length,dot = ' ...') { ...... } /** * 论坛 aid url 生成 */ function aidencode(aid,type = 0, tid = 0) { ...... } /** * 返回论坛缩放附件图片的地址 url */ function getforumimg(aid, nocache = 0,w = 140, h = 140,type = '') { ...... } /** * 获取rewrite字符串 * @param string type 需要获取的rewite * @param booleanreturntype true:直接返回href, false:返回a标签 * @param string host 可选网站域名 * @return string */ function rewriteoutput(type, returntype,host) { ...... } /** * 手机模式下替换所有链接为mobile=yes形式 * @param file - 正则匹配到的文件字符串 * @paramfile - 要被替换的字符串 * @replace 替换后字符串 */ function mobilereplace(file, replace) { ...... } /** * 手机的output函数 */ function mobileoutput() { ...... } /** * 系统输出 * @return 返回内容 */ function output() { ...... } /** * ajax footer使用输出页面内容 */ function output_ajax() { ...... } /** * 运行钩子 */ function runhooks() { ...... } /** * 执行插件脚本 */ function hookscript(script, hscript,type = 'funcs', param = array(),func = '') { ...... } /** * 获取插件模块 */ function pluginmodule(pluginid,type) { ...... } /** * 执行积分规则 * @param String action: 规则action名称 * @param Integeruid: 操作用户 * @param array extrasql: common_member_count的额外操作字段数组格式为 array('extcredits1' => '1') * @param Stringneedle: 防重字符串 * @param Integer coef: 积分放大倍数 * @param Integerupdate: 是否执行更新操作 * @param Integer fid: 版块ID * @return 返回积分策略 */ function updatecreditbyaction(action, uid = 0,extrasql = array(), needle = '',coef = 1, update = 1,fid = 0) { ...... } /** * 检查积分下限 * @param string action: 策略动作Action或者需要检测的操作积分值使如extcredits1积分进行减1操作检测array('extcredits1' => -1) * @param Integeruid: 用户UID * @param Integer coef: 积分放大倍数/负数为减分操作 * @param Integerreturnonly: 只要返回结果,不用中断程序运行 */ function checklowerlimit(action,uid = 0, coef = 1,fid = 0, returnonly = 0) { ...... } /** * 批量执行某一条策略规则 * @param Stringaction: 规则action名称 * @param Integer uids: 操作用户可以为单个uid或uid数组 * @param arrayextrasql: common_member_count的额外操作字段数组格式为 array('extcredits1' => '1') * @param Integer coef: 积分放大倍数,当为负数时为反转操作 * @param Integerfid: 版块ID */ function batchupdatecredit(action,uids = 0, extrasql = array(),coef = 1, fid = 0) { ...... } /** * 添加积分 * @param Integeruids: 用户uid或者uid数组 * @param String dataarr: member count相关操作数组,例: array('threads' => 1, 'doings' => -1) * @param Booleancheckgroup: 是否检查用户组 true or false * @param String operation: 操作类型 * @param Integerrelatedid: * @param String ruletxt: 积分规则文本 */ function updatemembercount(uids, dataarr = array(),checkgroup = true, operation = '',relatedid = 0, ruletxt = '') { if(!empty(uids) && (is_array(dataarr) &&dataarr)) { require_once libfile('function/credit'); return _updatemembercount(uids,dataarr, checkgroup,operation, relatedid,ruletxt); } return true; } /** * 校验用户组 * @param uid */ function checkusergroup(uid = 0) { ...... } /** * 调试信息 */ function debuginfo() { ...... } /** * 随机取出一个站长推荐的条目 * @param module 当前模块 * @return array */ function getfocus_rand(module) { ...... } /** * 检查验证码正确性 * @param value 验证码变量值 */ function check_seccode(value, idhash) { ...... } /** * 检查验证问答正确性 * @paramvalue 验证问答变量值 */ function check_secqaa(value,idhash) { ...... } /** * 获取广告 */ function adshow(parameter) { ...... } /** * 显示提示信息 * @parammessage - 提示信息,可中文也可以是 lang_message.php 中的数组 key 值 * @param url_forward - 提示后跳转的 url * @paramvalues - 提示信息中可替换的变量值 array(key => value ...) 形式 * @param extraparam - 扩展参数 array(key => value ...) 形式 * 跳转控制 header header跳转 location location JS 跳转,限于 msgtype = 2、3 timeout 定时跳转 refreshtime 自定义跳转时间 closetime 自定义关闭时间,限于 msgtype = 2,值为 true 时为默认 locationtime 自定义跳转时间,限于 msgtype = 2,值为 true 时为默认 内容控制 alert alert 图标样式 right/info/error return 显示请返回 redirectmsg 下载时用的提示信息,当跳转时显示的信息样式 0:如果您的浏览器没有自动跳转,请点击此链接 1:如果 n 秒后下载仍未开始,请点击此链接 msgtype 信息样式 1:非 Ajax 2:Ajax 弹出框 3:Ajax 只显示信息文本 showmsg 显示信息文本 showdialog 关闭原弹出框显示 showDialog 信息,限于 msgtype = 2 login 未登录时显示登录链接 extrajs 扩展 js striptags 过滤 HTML 标记 Ajax 控制 handle 执行 js 回调函数 showid 控制显示的对象 ID */ function showmessage(message, url_forward = '',values = array(), extraparam = array(),custom = 0) { ...... } /** * 检查是否正确提交了表单 * @param var 需要检查的变量 * @paramallowget 是否允许GET方式 * @param seccodecheck 验证码检测是否开启 * @return 返回是否正确提交了表单 */ function submitcheck(var, allowget = 0,seccodecheck = 0, secqaacheck = 0) { ...... } /** * 分页 * @paramnum - 总数 * @param perpage - 每页数 * @paramcurpage - 当前页 * @param mpurl - 跳转的路径 * @parammaxpages - 允许显示的最大页数 * @param page - 最多显示多少页码 * @paramautogoto - 最后一页,自动跳转 * @param simple - 是否简洁模式(简洁模式不显示上一页、下一页和页码跳转) * @return 返回分页代码 */ function multi(num, perpage,curpage, mpurl,maxpages = 0, page = 10,autogoto = FALSE, simple = FALSE) { ...... } /** * 只有上一页下一页的分页(无需知道数据总数) * @paramnum - 本次所取数据条数 * @param perpage - 每页数 * @paramcurpage - 当前页 * @param mpurl - 跳转的路径 * @return 返回分页代码 */ function simplepage(num, perpage,curpage, mpurl) { ...... } /** * 词语过滤 * @parammessage - 词语过滤文本 * @return 成功返回原始文本,否则提示错误或被替换 */ function censor(message,modword = NULL, return = FALSE) { ...... } /** 词语过滤,检测是否含有需要审核的词 */ function censormod(message) { ...... } /** * 刷新重定向 */ function dreferer(default = '') { ...... } /** * 远程FTP使用 */ function ftpcmd(cmd, arg1 = '') { ...... } /** * 编码转换 * @param <string>str 要转码的字符 * @param <string> in_charset 输入字符集 * @param <string>out_charset 输出字符集(默认当前) * @param <boolean> ForceTable 强制使用码表(默认不强制) * */ function diconv(str, in_charset,out_charset = CHARSET, ForceTable = FALSE) { ...... } /** * 重建数组 * @param <string>array 需要反转的数组 * @return array 原数组与的反转后的数组 */ function renum(array) { ...... } /** * 获取当前脚本在线人数 * @param <int>fid 分类 ID,版块、群组 的 id, * @param <int> tid 内容 ID,帖子 的 id */ function getonlinenum(fid = 0, tid = 0) { ...... } /** * 字节格式化单位 * @paramfilesize - 大小(字节) * @return 返回格式化后的文本 */ function sizecount(size) { ...... } /** * 写入运行日志 */ function writelog(file, log) { ...... } /** * 调色板 * @param <type>colorid * @param <type> id * @param <type>background * @return <type> */ function getcolorpalette(colorid,id, background,fun = '') { ...... } /** * 取得某标志位的数值 (0|1) * * @param 数值 status * @param 位置position * @return 0 | 1 */ function getstatus(status,position) { ...... } /** * 设置某一bit位的数值 0 or 1 * * @param int position 1-16 * @param intvalue 0|1 * @param 原始数值 baseon 0x0000-0xffff * @return int */ function setstatus(position, value,baseon = null) { ...... } /** * 通知 * @param Integer touid: 通知给谁 * @param Stringtype: 通知类型 * @param String note: 语言key * @param Arraynotevars: 语言变量对应的值 * @param Integer system: 是否为系统通知 0:非系统通知; 1:系统通知 */ function notification_add(touid, type,note, notevars = array(),system = 0) { ...... } /** * 发送管理通知 * @param type - 通知类型 */ function manage_addnotify(type, from_num = 0,langvar = array()) { ...... } /** * 发送短消息(兼容提醒) * @param toid - 接收方id * @paramsubject - 标题 * @param message - 内容 * @paramfromid - 发送方id */ function sendpm(toid,subject, message,fromid = '', replypmid = 0,isusername = 0, type = 0) { ...... } /** * * 通过tid得到相应的单一post表名或post表集合 * @param <mix>tids: 允许传进单个tid,也可以是tid集合 * @param primary: 是否只查主题表 0:遍历所有表;1:只查主表 * @return 当传进来的是单一的tid将直接返回表名,否则返回表集合的二维数组例:array('forum_post' => array(tids),'forum_post_1' => array(tids)) * @TODO tid传进来的是字符串的,返回单个表名,传进来的是数组的,不管是不是一个数组,返回的还是数组,保证进出值对应 */ function getposttablebytid(tids, primary = 0) { ...... } /** * 获取论坛帖子表名 * @param <int>tableid: 分表ID,默认为:fourm_post表 * @param <boolean> prefix: 是否默认带有表前缀 * @return forum_post or forum_post_* */ function getposttable(tableid = 0, prefix = false) { ...... } /** * 内存读写接口函数 * * @param 命令cmd (set|get|rm|check) * @param 键值 key * @param 数据value * @param 有效期 ttl * @return mix * * @example set : 写入内存ret = memory('set', 'test', 'ok') * @example get : 读取内存 data = memory('get', 'test') * @example rm : 删除内存ret = memory('rm', 'test') * @example check : 检查内存功能是否可用 allow = memory('check') */ function memory(cmd, key='',value='', ttl = 0) { ...... } /** * ip允许访问 * @paramip 要检查的ip地址 * @param - accesslist 允许访问的ip地址 * @param 返回结果 */ function ipaccess(ip, accesslist) { ...... } /** * ip限制访问 * @paramip 要检查的ip地址 * @param 返回结果 */ function ipbanned(onlineip) { ...... } /** * 系统级消息 */ function sysmessage(message) { ...... } /** * 论坛权限 * @param permstr - 权限信息 * @paramgroupid - 只判断用户组 * @return 0 无权限 > 0 有权限 */ function forumperm(permstr,groupid = 0) { ...... } /** * PHP 兼容性函数 */ if(!function_exists('file_put_contents')) { if(!defined('FILE_APPEND')) define('FILE_APPEND', 8); function file_put_contents(filename,data, flag = 0) {return = false; if(fp = @fopen(filename, flag != FILE_APPEND ? 'w' : 'a')) { if(flag == LOCK_EX) @flock(fp, LOCK_EX);return = fwrite(fp, is_array(data) ? implode('', data) :data); fclose(fp); } returnreturn; } } //检查权限 function checkperm(perm) { global_G; return (empty(_G['group'][perm])?'':_G['group'][perm]); } /** * 时间段设置检测 * @param periods - 那种时间段settings[periods]settings['postbanperiods'] settings['postmodperiods'] * @paramshowmessage - 是否提示信息 * @return 返回检查结果 */ function periodscheck(periods,showmessage = 1) { ...... } /** * 用户操作日志 * @param int uid 用户ID * @param stringaction 操作类型 tid=thread pid=post blogid=blog picid=picture doid=doing sid=share aid=article uid_cid/blogid_cid/sid_cid/picid_cid/aid_cid/topicid_cid=comment * @return bool */ function useractionlog(uid,action) { ...... } /** * 得到用户操作的代码或代表字符,参数为数字返回字符串,参数为字符串返回数字 * @param string/int var * @return int/string 注意:如果失败返回false,请使用===判断,因为代码0代表tid */ function getuseraction(var) { ...... } /** * 获取我的中心中展示的应用 */ function getuserapp(panel = 0) { ...... } /** * 获取manyou应用本地图标路径 * @param <type>appid */ function getmyappiconpath(appid,iconstatus=0) { ...... } /** * 获取文字内的url列表 * * @param message 文字 * @return <array> url列表 * */ function get_url_list(message) { ...... } /** * 检查文字内的URL * * @param allowposturl 用户组设置中的值 0=禁止 1=允许但审核 2=允许但不解析 * @parammessage 待处理的文字内容 * @return 0=禁止 1=允许但审核 2=允许但不解析 */ function checkurl(allowposturl, &message) { ...... } /** * 更新页面和模块的关系 * @param string targettplname 页面名称 * @param arrayblocks 模块IDS */ function update_template_block(targettplname,blocks) { ...... } /** * 获取批定类型的关联连接 * * @param string extent 内容所需关联链接范围 article, forum, group, blog * @return string 有效的关联链接 */ function getrelatedlink(extent) { ...... } /** * 判断 Connect 链接参数有效性 * @global _G * @param arrayparams 参数数组 * @param array connect_params 返回参数 * @return boolean */ function connect_valid(params, &connect_params) { ...... } /** * 获取 Token * @global_G * @param string type * @return string */ function connect_get_access_token(type = 'USER') { ...... } /** * 获取 Connect 参数签名 * @param array params 参数数组 * @param stringaccess_token 加密 Token * @return string */ function connect_get_sig(params,access_token) { ...... } /** * 通过 AID 获取附件表名 * @param <int> aid */ function getattachtablebyaid(aid) { ...... } /** * 返回指定 TID 所对应的附件表编号 * @param <int> tid */ function getattachtableid(tid) { ...... } /** * 通过 TID 获取附件表名 * @param <int> tid */ function getattachtablebytid(tid) { ...... } /** * 通过 PID 获取附件表名 * @param <int> pid */ function getattachtablebypid(pid) { ...... } /** * 添加一个新的附件索引记录,并返回新附件 ID * @param <int> uid */ function getattachnewaid(uid = 0) { ...... } /** * 获取 SEO设置 * @param string page 调用哪个页面的 * @param arraydata 可替换数据 * @return array('seotitle', 'seodescription', 'seokeywords') */ function get_seosetting(page,data = array(), defset = array()) { ...... } /** * 需处理连续分隔符的str_replace() * @param arraysearchs 被替换的数组 * @param array replaces 用于替换的数组 * @param stringstr 目标字符串 */ function strreplace_strip_split(searchs,replaces, str) { ...... } /** * 返回带第几页的title * @global_G * @param string navtitle 源标题 * @param intpage 页码 * @return string */ function get_title_page(navtitle,page){ if(page>1) { ...... } /** * * 生成缩略图文件名 * @param StringfileStr: 原文件名,允许附带路径 * @param String extend: 新文件名后缀 * @param BooleanholdOldExt: 是否保留原扩展名 * @return 返加新的后缀文件名 */ function getimgthumbname(fileStr,extend='.thumb.jpg', holdOldExt=true) { ...... } /** * 更新数据的审核状态 * @param <string>idtype 数据类型 tid=thread pid=post blogid=blog picid=picture doid=doing sid=share aid=article uid_cid/blogid_cid/sid_cid/picid_cid/aid_cid/topicid_cid=comment * @param <array/int> ids ID 数组、ID 值 * @param <int>status 状态 0=加入审核(默认) 1=忽略审核 2=审核通过 */ function updatemoderate(idtype,ids, $status = 0) { ...... } /** * 显示漫游应用公告 */ function userappprompt() { ...... }
两种编程高手
第一种编程高手
- 给一段复杂的程序,比如有7个局部变量,5层循环和if嵌套,他能赤手空拳上阵,迅速领会程序意图、找到bug,不用借助任何工具甚至纸笔。
- 给一个复杂的问题,能在一个函数之内一气呵成,立马给出正确实现,这个函数可能有七个变量,5层循环和if嵌套。没有废话,删无可删,但是单一函数复杂度高,一般人要费老鼻子劲方能看懂。
第二种编程高手
- 给一段复杂的程序,比如有7个局部变量,5层循环和if嵌套,他无法马上看出程序的意图,但是他通常会借助纸笔写写画画,最终搞定。
- 给一个复杂的问题,要磨叽磨叽好半天,一般用几个函数组合起来实现,这些函数职责单一明确,身段苗条,通常一两个变量,循环和if不超过2层嵌套。单一函数复杂度低,一般人都能轻轻松松看懂。
第一种编程高手是天生的聪明人,他们处理复杂事物的能力是天生的,可以流利的心算三位数加三位数带进位的加法。根据认知负载理论,这类人的working memory容量超越常人,他们可以将多种因素同时纳入大脑进行思考而不会出现大脑过载。他们写出来的复杂程序,一般的看法是没有掌握分而治之的正确编程风格,其实际是他们脑筋太好使,普通人为了克服认知过载而发明的编程方法对他们而言纯粹就是多此一举。当遇到更为复杂的问题时,他们自然会分而治之。缺点是不经刻意训练,他们按照自己的认知能力写出来的程序普通人维护起来有困难。
第二种编程高手是天资正常的普通人,working memeory的容量大概就是可以心算两位数加两位数带进位的加法。但是他们掌握了解决认知负载的方法。阅读复杂代码的时候,他们借助纸笔,把对其中的小片段的分析结论先写下来,避免大脑缓存太多东西,然后就这些数量变少的中间结果再进行分析,始终保持放入大脑的东西不要太多。写代码的时候,他们无法一下子把所有的细节想清楚,因此需要分步搞定,要么先把关键步骤逐次实现好再去整合整个方案,要么先写好一个大而化之的框架,然后分头实现细节。往往写完之后会发现有一点顾此失彼,因此还要调整清理一番。特点是不管那种方法,大脑在任何一个阶段都不会过载。按照这种方法写出来的代码,也不会让它的读者大脑过载。
对于团队来说,我们希望程序员具有第一种编程高手的天份,同时写出来的代码要像第二种编程高手那样方便理解。需要注意提升的是第三种编程高手,他们缺乏第一种编程高手的天资,同时还没有掌握第二种编程高手的技能,经常自己被自己写出来的代码搞糊涂。
来自:http://www.techug.com/two-kind-of-programming-expert
Table ‘performance_schema.session_variables’ doesn’t exist
运行mysql时,提示Table ‘performance_schema.session_variables’ doesn’t exist
解决的方法是:
第一步:在管理员命令中输入:
mysql_upgrade -u root -p --force
第二步:重新启动mysql的服务:
net stop mysql
net start mysql
再次运行MySQL,就解决了。
注意,两步缺一不可。
送给和我一样曾经浮躁过的PHP程序猿
2012年偶决定开始写博客了,不为别的,就希望可以通过博客记录我的成长历程,同时也希望可以帮助一些刚毕业,刚入行业的兄弟姐们 们。我们是一群充满浮躁、抱怨、迷茫的程序猿,想一想3年就这么过去了,社会变得更浮躁了,鸭梨也越来越大,房?车?女人?… 抓狂…
决定写这样一篇文章,再次明确自己的职业规划,也送给浮躁的你,踏上程序猿这条路可谓是路途艰辛、乏味、枯燥,在这里把自己的学习心得、目前正在计划的规划列出来。希望对你有所帮助。
1、多动手,多思考
不要怕做不好,刚毕业或者刚入行最缺的就是工作经验,没有别的途径,只有做,做,做,多做经验就来了。项目做多了自然而然你就有了多种不同项目的业务逻辑,这些可是在大学根本无法学到的东西,也是企业最需要的。任何一个企业需要的是一个快速上手,马上解决业务任务的员工。
面对现在层出不穷的新技术,各种复杂的业务逻辑需求,你是如何去应对呢?很简单:做,做,做,我的学习过程就一个字:做!截止目前从 0 到 1 真的很辛苦,大大小小做了上百个(包括接的大大小小单子需求,之前公司各种业务需求解决),总结就一句话:做的多了,沟通就多了;沟通多了,就能更好的理 解客户需求和用户展示的一些基本经验。
2、少抱怨,多学习
当你刚进公司时,难免会做很多杂事,这个是无法避免的。我刚进这个行业做了大半年的杂事,什么DIV、 CSS、JS,调个模板,改个小东西,等等。一切都是熬出来的,只有当你的经验,技术积累到了足够应付业务需求的时候,你自然会被赏识,当然如果还是无法 赏识,建议你可以立马跳槽。
对于程序员来说,偶尔的跳槽也是成长的一部分,不知道对别人是否是这样,但对我来说,我的每次跳槽都会是一次快速成长。作为程序猿,我觉得如果 真想做好,必须要有兴趣,写代码会让你疯狂,让你疯癫,这样你才能写好它。如果你只是为了工作而去做,那么你只是一个工具而非程序猿,那么你也就不要过于 频繁跳槽,因为每次跳槽对你来说都是一个大的挑战。
有了兴趣,持之以恒,不要在乎任务多,压力大,能做就做,你的目的就是提高自己,让自己在明天比昨天更有价值。当价值积累到了足够的资本,很多公司会抢着要你,相信这个社会肯定会有识才的公司。耐心+机遇+坚定不移的信念,这就是我!一个简单的程序猿。
3、制定有效的学习计划
当你制定了计划,就一定要坚持的完成,如果不能,请你不要制定计划,因为这样会让你很痛苦。在公司或者各类 技术社区尽量多认识大牛,多加群,多交流、讨论,多帮助别人。在制定计划时,不要过于盲目。根据自身情况制定各个阶段计划,最好的计划是短期计划并且可以 保证顺利完成的计划,如果制定一个飘渺无期的计划,你更适合当一个演说家。
请不要吝啬,在你计划学习的过程中尽量写到博客。这样你既可以帮助新手,也可以让自己更深入的熟悉学习的知识,并在需要时以最快的速度查找到。 废话基本说完了,下面介绍下我近期整理的计划和一些学习心得,希望我们可以一起进步,一起提升,一起为了明天的更多薪资而努力。
PHP程序员突破成长瓶颈?
(整理于网上,并自己也在逐条实施中)对PHP的掌握不精(很多PHP手册都没有看完,库除外);知识面比 较窄(面对需求,除开使用PHP和MySQL,不知道其它的解决办法);PHP代码以过程为主,认为面向对象的实现太绕;看不懂这些 PHPer 在遇到需要高性能、处理高并发、大量数据的项目或业务逻辑比较复杂(系统需要解决多领域业务的问题)时,缺少思路。不能分析问题的本质,技术判断力比较 差,对于问题较快能找出临时的解决办法,但常常在不断临时性的解决办法中,系统和自己一步步走向崩溃。那怎么提高自己呢?怎么可以挑战难度更高的系统?
高性能系统的挑战在哪里?
如何选择 WEB 服务器?要不要使用 FAST-CGI 模式
要不要使用反向代理服务?选择全内存缓存还是硬盘缓存?
是否需要负载均衡?是基于应用层,还是网络层? 如何保证高可靠性?
你的 PHP 代码性能如何,使用优化工具后怎么样? 性能瓶颈在那里? 是否需要写成C的扩展?
用户访问有什么特点,是读多还是写多?是否需要读写分离?
数据如何存储?写入速度和读出速度如何? 数据增涨访问速读如何变化?
如何使用缓存? 怎么样考虑失效?数据的一致性怎么保证?
高复杂性系统的挑战在哪里?
能否识别业务所对应的领域?是一个还是多个?
能否合理对业务进行抽象,在业务规则变化能以很小的代价实现?
数据的一致性、安全性可否保证?
是否撑握了面向对象的分析和设计的方法
当我所列出的问题,你都能肯定的回答,我想在技术上你基本已经可能成为架构师了。
怎么样提高,突破瓶颈?
分析你所使用的技术的原理和背后运行的机制,这样可以提高你的技术判断力,提高你技术方案选择的正确性;学习大学期间重要的知识,操作系统原 理,数据结构和算法。知道你以前学习都是为了考试,但现在你需要为自己学习,让自己知其所以然。重新开始学习C语言,虽然你在大学已经学过。
这不仅是因为你可能需要写 PHP 扩展,而且还因为,在做C的应用中,有一个时刻关心性能、内存控制、变量生命周期、数据结构和算法的环境。学习面向对象的分析与设计,它是解决复杂问题的 有效的方法。学习抽象,它是解决复杂问题的唯一之道。“这么多的东西怎么学,这得学多久呀” ?如果你努力的话,有较好的规划,估计需要1~2年的时间。怎么学习的问题,我们后续再谈。
PHP学习的过程网上已经有很多教程了,就不列举了。基础+数据结构+算法(PHP这个比较弱) 不断重复的学习使用。其次是设计模式,尤其复杂的业务需求设计模式非常有帮助。
积累:把常用的一些库(用过的,自己写的)都收集起来,需要时拿出来用即可,非常方便。如:分页,图片处理,上传,下载,EMAIL 等等这些常用到的。
多方位动手:不光要写代码,把代码片段分析放到博客,也是进步提升的一个重要的环节,加深记忆不错的方法。
1. PHP基础入门(语法,常用函数和扩展)
2. 面向对象的PHP(书籍:《深入PHP,面向对象、模式与实践》)
3. 网站软件架构设计(设计模式、框架等)
4. 网站物理层次架构设计(分布式计算、存储、负载均衡、高可用性等)
引用:一个不错的网上找到的学习建议
如何有效的学习是一个大问题。
自己有些实践但很零散,不好总结。昨天晚上睡觉前,突然想到了RUP的核心,“以架构为中心,用例驱动,迭代开发”,借用这个思想,关于有效的学习的方法,可以这样来表述:以原理、模型或机制为中心,任务驱动,迭代学习。
目的:学习如何提高处理性能。
可迭代驱动的任务:通过IP找到所在地域。
这是WEB应用常见的任务,IP数据库是10万行左右的记录。
第一次迭代: 不考虑性能的情况下实现功能(通过PHP来实现)
因为无法直接通过KEY(IP)进行查找地域,所以直接放到数据或通过关联数组这种简单的方法都是不行的。思路还是先把数据进行排序,然后再进行查找
1. 如何通过IP查找? 已序的数据,二分查找是最快的。
2. 如何排序?用库函数 sort 当然是可以,但是即然是学习,那还是自己实现快速排序吧。
学习目标: 排序算法,查找算法
PHPer 数据结构和算法基础比较差,平时也没有这方面的任务,自己也不学习,因此这方面的知识很缺乏。但是,编程解决的问题,最终都会归结到数据结构和对这种数据 结构操作的算法。如果数据结构算法常在心中,那遇到问题就能清晰认识到它内在的结构,解决方法就会自然产生。
第二次迭代:优化数据的加载与排序
如果做到第一步,那基本上还是不可用,因为数据每次都需要加载和排序,这样太耗时间。
解决的思路是,数据一次加载排序后,放到每个 PHP 进程能访问到的地方,放到 memcached 这是大家容易想到的问题。其实放到共享内存(EA等加速器都支持)中是更快的方式,因为 memcached 还多了网络操作。数据是整体放入到共享内存,还是分块放入,如何测试性能? 如何分析瓶颈所在(xdebug)? 在这些问题的驱动下你会学习到。
学习目标: 检测、定位、优化PHP性能的方法;PHP实现结构对性能的影响。
第三次迭代: 编写PHP的扩展
怎么确定需要学习的机制和原理呢?
怎么找到驱动学习任务呢?
从这个技术的定位来找出需要学习的重点,即它怎么做到的(机制)和它为什么能这样做到 (模型或原理),列出这个技术最常见的应用,作为学习的任务,从简到难进行实践。
如果完全自学,找到需要学习的要点(机制、模型、原理),设定学习任务的确不是那么容易把握。如果找到一个有经验的人来指导你或加入一个学习型的团队,那学习的速度的确会大大提高。
最后简单总结下:
1、一定要有耐心,制定好计划一定要实施。
2、PHP 基础要吃透,手动多了自然就会记得更深(PHP手册一定要多次反复的阅读)。
3、学习 PHP 设计模式并在实际场景中尝试应用,不断地加强记忆和理解设计模式。
4、现在新东西真的太快,所以为了适应就必须要多下功夫。内存缓存,文件缓存,静态缓存,高并发处理,这些必须要熟练应用。
5、加强计算机系统原理的了解,熟悉常用数学知识,练习算法应用。计算机科学本质上讲是数学的一个学科。好的数学家中间会产出优秀的程序员。不要让你的数学能力丧失殆尽。
逻辑学、离散数学、微积分、概率论、统计学、抽象代数、数论、范畴论、偏序理论这些数学知识尽量多练习,多熟悉下。
6、关注 PHP 安全,了解最新 PHP,MYSQ L版本更新和 BUG 动态。
7、深入学习数据结构和算法,不论是什么语言,最核心的就是数据结构和算法。
8、开始学习C,或者同步和 PHP 进行也可以,看你的时间和学习强度计划了。C是必须要学,如果你想走程序猿这条道路的话。PHP 也是C写的,而且PHP运行机制也是通过编译器编译成C在电脑上运行,所以C学好了对你的开发之路只有益处。你的 money 也会赚的比以前更多!
最后: 认真做好每一项,学扎实,重复的去学。不知不觉中,你的能力会得到很快的提升。原文链接
Windows下安装Redis服务
1.下载windows版本redis
官方下载地址:http://redis.io/download,不过官方没有64位的Windows下的可执行程序,目前有个开源的托管在github上, 地址:https://github.com/ServiceStack/redis-windows
2.解压
3.文件介绍
文件名 | 简要 |
redis-benchmark.exe | 基准测试 redis-benchmark为redis性能测试工具 |
redis-check-aof.exe | aof AOF是AppendOnly File的缩写,是Redis系统提供了一种记录Redis操作的持久化方案 |
redischeck-dump.exe | dump redis的备份和还原,借助了第三方的工具,redis-dump |
redis-cli.exe | 客户端 |
redis-server.exe | 服务器 |
redis.windows.conf | 配置文件 |
4.redis.windows.conf文件中设置redis密码
5.点击redis-server.exe 启动redis服务器端
如下,启动成功
6.将redis注册为系统服务
cmd进入dos窗口
首先cd进入到redis目录下,然后注册为系统服务
命令行:
redis-server.exe --service-install redis.windows.conf --loglevel verbose redis-server --service-start
7.卸载服务, 可以保存为 uninstall-service.bat 文件
redis-server --service-stop redis-server --service-uninstall
————————————————————————————————————-至此,redis-windows版本安装完成—————————————————————————————————
1.redis.windows.conf各项配置参数介绍

修改配置后,如果配置文件涉及到中文内容记得将文件存为UTF-8编码。
2.redis-cli.exe 客户端使用
点击redis-cli.exe
测试服务器启动连接情况
127.0.0.1:6379> ping PONG
查看服务器级别信息(测试服务器)

3.redis-benchmark 性能测试工具
默认双击打开是按照默认的测试参数进行测试,而且它自己测试跑完之后,就会自动关闭DOS窗口了。
输入如下命令后会看到如下信息,表明同时并发10个连接,总共100次操作。通俗易懂的说就是10个用户同时操作,总共每人操作10次的意思
100 requests completed in 0.01 seconds (100个请求完成于0.01秒) 10 parallel clients (10个客户端并发) 3 bytes payload (每次写入3个字节) keep alive: 1 (保存一个链接数) 100.00% <= 1 milliseconds (100%的操作小于1秒完成) 16666.67 requests per second (每秒完成16666.67次查询)
命令参数说明
redis-benchmark [-h <host>] [-p <port>] [-c <clients>] [-n <requests]> [-k <boolean>] -h <hostname> 主机名 (默认 127.0.0.1) -p <port> 主机端口 (默认 6379) -s <socket> 主机套接字 (覆盖主机和端口) -c <clients> 并发连接的数量 (默认 50) -n <requests> 请求总数 (默认 10000) -d <size> SET/GET数据的字节大小(默认 2) -k <boolean> 1=keep alive 0=reconnect (默认 1) -r <keyspacelen> SET/GET/INCR使用随机产生的key, SADD使用随机值使用这个选项 get/set keys时会用mykey_rand:000000012456代替常量key, <keyspacelen>参数决定了随机数产生的最大值,比如,设置参数为10,那么产生的随机数范围是rand:000000000000 -rand:000000000009 -P <numreq> Pipeline请求的数量. 默认 1 (不使用pipeline). -q 展示query/sec值 --csv 以CSV格式输出 -l 本地循环. 一直运行测试 -t <tests> 在运行逗号分割列表的测试. 测试的名字与产生输出的名字一样。 -I 空闲模式. 打开 N 个空闲连接,然后等待.
运行示例
对指定服务器、端口进行20个同时并发操作,总共操作100000次 redis-benchmark -h 192.168.1.136 -p 6379 -n 100000 -c 20 测试set写入操作1000000次,随机数范围在100000000 redis-benchmark -t set -n 1000000 -r 100000000 测试ping、set、get操作100000次,结果输出用csv格式 redis-benchmark -t ping,set,get -n 100000 –-csv redis-benchmark -r 10000 -n 10000 lpush mylist ele:rand:000000000000
4.redis-check-aof 基本用法
检查本地日志信息,加–fix参数为修复log文件
redis-check-aof.exe log.aof
5.redis-check-dump 检查数据库文件
redis-check-dump.exe dump.rdb 会输出该文件大小、使用情况。
Google voice的永久号码
Google voice的永久号码,可以免费拨打及接听美国加拿大电话收发美国加拿大短信,还可用于推特账号保护。但注册该号码需要一个美国或加拿大的电话,大家可以下载一个 Textnow 应用,申请一个美国的电话号码,送五分钟通话时间,用来激活Google voice的号码。
为Web开发者准备的10个最新工具
Web开发设计是一个很有前途的职业。然而,这其中也有许多挑战。现在的企业和品牌正在朝网络进军。这给了web开发者非常多的机会来展示他们的技能,并在他们的职业上取得成功。然而,随着web开发需求的不断增长,web开发人员的数量也越来越多。这就是为什么这一领域的竞争开始变得愈演愈烈。但好消息是,如果你有天赋和意愿,那么你总能找到新的方法来创造独特的设计和想法。
作为web开发人员,很有可能你必须总是寻找新的工具和资源。新的工具和资源,不仅使你的工作更方便,也会提高你的工作质量。这将进一步有助于谈成更多的业务和客户。web开发的趋势总是在不断变化中,这就是为什么我们有必要总是与时俱进。下面要介绍的是2016年3月web开发人员不可错过的非常方便的新鲜资源,它们将帮助你夺得竞争优势。一起看一看吧!
1.JS Tips
JS Tips是JavaScript技巧的集合,其中有一些关于语法,关于代码效率和性能,还有特别针对框架,如AngularJS的内容。新的技巧每天都会增加,目前发布了50条。它本质上是一个每个web开发人员必备的书签网站。
官方网站:http://www.jstips.co/
2.Vagrant Manager
Vagrant Manager是一个GUI应用程序用来控制Vagrant。类似MAMP,让你可以停止或运行Vagrant,看哪个Vagrant当前正在运行。该应用程序可用于OS X和Windows。如果你不知道Vagrant是什么,那么欢迎查看我们先前关于《How to install WordPress locally with Vagrant》的文章。
官方网站:http://vagrantmanager.com/
3.Bulma
Bulma是一个前端框架。该软件包包括一些常见的UI web组件,例如导航、下拉菜单、以及网格,网格是完全用Flexbox建立的。唯一缺少(至少到目前为止)的功能是JavaScript组件。Bulma组件相对于Bootstrap更苗条,但它应该足以让你建立一个小型却又有模有样的网站。
官方网站:http://bulma.io/
4.Gutenberg
Gutenberg,以发明者Johannes Gutenberg的名字命名。Gutenberg是针对设置在web上的排版样式规则的集合。样式规则设定基线,字体大小和比例,以及行高。一个伟大的样式库可以让你的网站内容看起来漂亮得多。
官方网站:https://github.com/matejlatin/Gutenberg
5.OkayNav
OkayNav是一个jQuery用来建立一个负责任的导航,而且不仅仅如此。该插件对响应式设计有一个略为不同的看法:视口被调整到更小,每个菜单被逐渐地合并进一个图标中以容忍有限的视口大小。听起来很酷,不是吗?
官方网站:https://github.com/VPenkov/okayNav
6.New Web Typography
New Web Typography是一篇深刻的和令人大开眼界的关于排版的文章。它讨论了从书本初期的样式到现今我们在web上构建和使用的办法。精心研究后提供了多个插图,并且是经过充分参考的,这篇由Robin Rendle写的长篇文章,绝对值得一读,可以帮助你更好地了解排版。
官方网站:https://robinrendle.com/essays/new-web-typography/
7.Color Safe
Color Safe是用于web的颜色发生器板。不像我们以前提到的这个系列的工具,Color Safe只会遵守对于颜色无障碍的WCAG标准来生成颜色。
官方网站:http://colorsafe.co/
8.Accessible Modal Dialog
这是一个很小(仅0.5KB~)的JavaScript库,用来建立一个模式对话框窗口。通过它,用户能够很方便地用键盘和鼠标通过对话框来打开,关闭,以及导航。该软件包是简单的空白JavaScript,没有样式,你可以自由地塑造你喜欢的任何方式的对话框模式。
官方网站:https://github.com/edenspiekermann/accessible-modal-dialog
9.Mo.js
Mo.js是JavaScript动画库的一个完整的程序包。它配备了若干预置,因此你可以设置并快速运行动画。它采用模块化设计,允许你删除不必要的功能,以保持通顺和流畅。作为一个全新的库,很不幸的是,它的文档还没有准备好(到目前为止)。
官方网站:http://mojs.io/
10.Particles
这个库可在你的网站添加漂浮的粒子网络,只为了让你的网站立马看上去更酷。粒子可以对光标移动做出反应。反应活动以及如颜色,距离和形状等元素可以通过选择进行配置。
官方网站:http://vincentgarreau.com/particles.js/
以上就是为Web开发者准备的10个最新工具,希望对你有所帮助。
如何判断微信内置浏览器(JS & PHP)
微信内置浏览器的 User Agent
如何判断微信内置浏览器,首先需要获取微信内置浏览器的User Agent,经过在 iPhone 上微信的浏览器的检测,它的 User Agent 是:
Mozilla/5.0 (iPhone; CPU iPhone OS 6_1_3 like Mac OS X) AppleWebKit/536.26 (KHTML, like Gecko) Mobile/10B329 MicroMessenger/5.0.1
所以通过识别 MicroMessenger 这个关键字来确定是否微信内置的浏览器了。
通过 JavaScript 判断
function is_weixin(){ var ua = navigator.userAgent.toLowerCase(); if(ua.match(/MicroMessenger/i)=="micromessenger") { return true; } else { return false; } }
通过 PHP 判断
function is_weixin(){ if ( strpos($_SERVER['HTTP_USER_AGENT'], 'MicroMessenger') !== false ) { return true; } return false; }
How to write an example
test
forum_post 的 status 字段备注
2109 8765 4321 0987 6543 2109 8765 4321 序号
#B 0000 0000 0000 0000 0000 0000 0000 0001 帖子被屏蔽
#B 0000 0000 0000 0000 0000 0000 0000 0010 帖子被警告
#B 0000 0000 0000 0000 0000 0000 0000 0100 帖子审核后再编辑标记,用于防止重复加分
#B 0000 0000 0000 0000 0000 0000 0000 1000 手机版发帖标示
#B 0000 0000 0000 0000 0000 0000 0001 0000 微博回流的帖子标记
#B 0000 0000 0000 0000 0000 0000 0010 0000 [手机]是否显示地理位置
#B 0000 0000 0000 0000 0000 0000 0100 0000 [手机]含手机录音
#B 0000 0000 0000 0000 0000 0000 1000 0000 [手机型号(联动)] 001(1):iOS
#B 0000 0000 0000 0000 0000 0001 0000 0000 [手机型号(联动)] 010(2):Android 011(3):WindowsPhone
#B 0000 0000 0000 0000 0000 0010 0000 0000 [手机型号(联动)] 100:
#B 0000 0000 0000 0000 0000 0100 0000 0000 标记水帖