=IF(B3=&quot 转译回来;&quot 转译回来;,&quot 转译回来;&quot 转译回来;,SUMIF(入库!C:C,B3,入库!E:E))是什么意思

SUM & SUMIF使用方法-工作总结范文网
全站搜索:
您现在的位置:&>&&>&计算机软件及应用
SUM & SUMIF使用方法
SUM函数的使用语法:SUM(参数1,参数2,...,参数30)结果:返回所有参数中的数字之和。说明:参数最多只能有30个,并且可以省略(即,,间没有参数或最后有一个,);参数可以为引用、返回数值和文本及逻辑值的计算表达式、数组;参数如为引用,可以是区域联合、区域交叉、三维区域引用,只要引用不再参与数组运算就可以
如果参数为错误值或为不能转换成数字的文本,将会导致错误。下面作一些详细的分析:A.对文本、逻辑值及错误值的计算对引用中的文本、数字型的文本、逻辑值忽略不计算。
=SUM(H11:J14),只计单元格中的数值,不计文本、逻辑值
和I12格中的文本
1000对数组中的文本、数字型的文本、逻辑值忽略不计。3500数组公式,不带{、}号输入,按ctrl+shift+enter三键结束。公式{=SUM({&姓名&,&a1&,&1000&,TRUE,2000,FALSE,1500},H11:H14=&a2&)}
excel的帮助中有错误。F中提出的方法。参数或作为参数的计算表达式为逻辑值时,TRUE算1,FALSE算0。34公式为=SUM(10,2&1,1&2,TRUE,FALSE,&2&,&2&&&0&)其中的2&1为逻辑值TRUE算1,直接参数TRUE算1,其他的FALSE算0,文本2和表达式文本B.以引用的运算作参数区域联合86此运算在SUM函数中算1个参数,当SUM中的参数多于30个时可用此法来减少参数。区域交叉70注意括号及2个引用间的空格,交叉引用在SUM函数中也只算1个参数,此处实际运算返回的是H31:K32和I29:J34相交的B31:C32区域。联合区域不能在数组公式中继续进行计算。交叉引用在数组公式中可以可以继续进行计算。42公式为{=SUM(((H29:K34 I:I)&12)*(H29:K34 I:I))}实际计算的是I29:I34区域大于12的值的和C.以三维引用作参数63公式为=SUM(SUM:SUMIF!H29:H34),其中SUM:SUMIF!H29:H34为对从SUM工作表开始至的H29:H34的区域引用。象这样的直接三维引用不可继续用于数组计算中。象下面这样的数组公式为什么是可以正确运算的?191公式为{=SUM((H28:H34,I34,J29:K29),((H29:K34 I:I)&12)*(H29:K34 I:I),SUM:SUMIF!H29:H请注意上面的数组公式中SUM函数有3个参数,第1个是联合区域引用,第2个是交叉区域引用计算的数由于联合区域和三维引用区域均没有继续进行数组运算,所以在SUM函数的数组公式中作为单独的参数提示:我们在使用SUM函数的数组公式时,经常只考虑有1个参数,其实是忘了SUM函数最多可有30个
D.以没有打开的工作薄的指定表的指定区域引用作参数600公式为=SUM('C:\excelhomefunction\[INDIRECT函数的使用.xls]Sheet2'!$B:$B)引用了C:\excelhomefunction\INDIRECT函数的使用.xls
工作薄Sheet2表的整个B列。只要路径所指定的文件存在就不需要打开文件,如不存在就返回错误。E.以(由一个元素的数组参数产生的)单元格区域引用作SUMSUM函数不作为其他函数的参数可以使用,见G54格,公式为=SUM(INDIRECT(&H&&ROW()/2&&:J&&ROW()/2+4))实际相当于SUM(INDIRECT({&H27:J31&})),即对H27:J31区域求和。H54格是将这样的SUM函数放在IF函数中作为参数,就错误了,因为ROW()返回的是一个数组并不是一个数值,这样在数组公式中INDIRECT函数返回的并不是一个二而是三维的区域引用(第3维的尺寸是1),所以SUM的计算出错。可以将公式改为I54格的样子(本论坛的会员提出的方法,先用SUM函数将ROW函数的数组变为数值),或E.以(由多个元素的数组参数产生的)单元格区域引用作SUM函数的参数一般是INDIRECT函数和OFFSET函数才能以多个数组元素,产生一系列对多个单元格区域的引用,返回SUM函数只能对第1个元素指定的区域求和,如H64格的公式。61用内嵌SUMIF函数代替就正确了,见H65格。130F.以非数字型文本作参数的方法A中指出参数或作为参数的计算表达式为不是数字型的文本,返回错误。要解决直接参数为非数字的问题,可按图设置。#VALUE!按图设置后,Lotus1-2-不利因素是,所有的公式均按很多excel的表达式就会出错G.SUM函数在数组公式中的一些应用多条件计数A部门的男性员工有几人?3姓名部门性别工资(B92:B105=&A&)*(C92:C105=&男&)返回2个逻辑数组的乘积,A1A男1000TRUE*TRUE=1;TRUE*FALSE=0;FALSE*FALSE=0A2B女1500所以此处是逻辑与的关系,在excel的IF函数的条件中,0表示A3C女1000去除IF函数可以简化公式为3A4D女800A、B两部门的男性员工有几人?4A5B女2000基于TRUE+FALSE=1;FALSE+FALSE=0;TRUE+TRUE=2A6C男2500而(B92:B105=&A&)和(B92:B105=&B&)不可能同时满足,所以此A7D男1500再乘以(C92:C105=&男&)作为并列条件。A8A男1000A部门所有女性员工和A部门工资1500以上的男性员工总数是A9C女10003A10D男2000因为(C92:C105=&女&)和(D92:D105&=1500)可能同时满足,所A11A男3000NOT(TRUE)=FALSE;NOT(FALSE)=TRUE;NOT(0)=TRUA12B男900A13A女1800A14A女2500多条件求和A部门女性员工的工资总额是多少?4300基于:FALSE*任何数=0;TRUE*任何数=原来的数(B92:B105=&A&)*(C92:C105=&女&)为并列条件,*D92:D105后就是满足条件的工资。所有女性员工的工资和男性员工工资1500以上的工资总额是多少?19600如加IF函数就可以不用NOT(NOT())19600提示:以(C92:C105=&女&)+(D92:D105&=1500)这样的形式表示条件或的关系,在条件可能同时满足时要
或用IF函数判别。否则会多计数量的。统计偶数行的工资总和是多少?11300其中的(MOD(ROW(D92:D105),2)=0)就是判别是否偶数行。特别提示:SUM函数在绝大多数的情况下用于数组公式中只能返回一个值,以后会讲到在某些特殊的
在多单元格数组公式中,可在不同的单元格返回不同的值,好象是返回了一个数组,但那
中表现,而不能继续进行数组运算的。Excelhome.net中有很多的相关帖子,请大家多看看。引用不再参与数组运算就可以;
2和表达式文本20转换后计算。SUM工作表开始至SUMIF工作表结束3个是三维区域引用。7529助中有错误。F中提出的方法。式作为参数LSE算0,文本
H34为对从9:K34 I:I),SUM:SUMIF!H29:H34)}2个是交叉区域引用计算的数组,第的数组公式中作为单独的参数是可以的。是忘了SUM函数最多可有30个参数。s]Sheet2'!$B:$B)薄Sheet2表的整个B列。
CT函数返回的并不是一个二维的区域引用,ROW函数的数组变为数值),或用SUMIF代替(见J54格)。对多个单元格区域的引用,返回的是三维的区域引用,置后,就按Lotus1-2-3的方式忽略文本。见H69格。素是,所有的公式均按Loutus1-2-3的方式处理,excel的表达式就会出错。男&)返回2个逻辑数组的乘积,基于E=0;FALSE*FALSE=0cel的IF函数的条件中,0表示FALSE,非0的数值表示TRUE。如有2个以上并列条件,可将几个条件式相乘。+FALSE=0;TRUE+TRUE=2=&B&)不可能同时满足,所以此处是条件或的关系,资1500以上的男性员工总数是多少?105&=1500)可能同时满足,所以再用NOT(NOT())转换,基于LSE)=TRUE;NOT(0)=TRUE;NOT(非0数值)=FALSE关系,在条件可能同时满足时要用NOT(NOT())转换值,以后会讲到在某些特殊的函数组合中好象是返回了一个数组,但那只能在单元格
上一篇: 下一篇:
All rights reserved Powered by
copyright &copyright 。文档资料库内容来自网络,如有侵犯请联系客服。c语言scanf()停止接受输入及scanf(&%c&,&c)吃掉回车或者空格字符的问题
scanf()函数接收输入数据时,遇以下情况结束一个数据的输入:(不是结束该scanf函数,scanf函数仅在每一个数据域均有数据,并按回车后结束)。
① 遇空格、“回车”、“跳格”键。
② 遇宽度结束。
③ 遇非法输入。
问题二:scanf()函数不能正确接受有空格的字符串?如: I love you!
int main()
char str[80];
scanf("%s",str);
printf("%s",str);
输入:I live you!
scanf()函数接收输入数据时,遇以下情况结束一个数据的输入:(不是结束该scanf函数,scanf函数仅在每一个数据域均有数据,并按回车后结束)。
① 遇空格、“回车”、“跳格”键。
② 遇宽度结束。
③ 遇非法输入。
所以,上述程序并不能达到预期目的,scanf()扫描到"I"后面的空格就认为对str的赋值结束,并忽略后面的"love you!".这里要注意是"love you!"还在键盘缓冲区(关于这个问题,网上我所见的说法都是如此,但是,我经过调试发现,其实这时缓冲区字符串首尾指针已经相等了,也就是说缓冲区清空了,scanf()函数应该只是扫描stdin流,这个残存信息是在stdin中)。我们改动一下上面的程序来验证一下:
int main()
char str[80];
char str1[80];
char str2[80];
scanf("%s",str);/*此处输入:I love you! */
printf("%s",str);
sleep(5);/*这里等待5秒,告诉你程序运行到什么地方*/
scanf("%s",str1);/*这两句无需你再输入,是对键盘盘缓冲区再扫描
scanf("%s",str2);/*这两句无需你再输入,是对键盘盘缓冲区再扫描
printf("/n%s",str1);
printf("/n%s",str2);
输入:I love you!
好了,原因知道了,那么scanf()函数能不能完成这个任务?回答是:能!别忘了scanf()函数还有一个 %[] 格式控制符(如果对%[]不了解的请查看本文的上篇),请看下面的程序:
#include "stdio.h"
int main()
char string[50];
/*scanf("%s",string);不能接收空格符*/
scanf("%[^/n]",string);
printf("%s/n",string);
问题三:键盘缓冲区残余信息问题
int main()
scanf("%d",&a);
scanf("%c",&c);
printf("a=%d
c=%c/n",a,c);
/*printf("c=%d/n",c);*/
}while(c!='N');
scanf("%c",&c);这句不能正常接收字符,什么原因呢?我们用printf("c=%d/n",c);将C用int表示出来,启用printf("c=%d/n",c);这一句,看看scanf()函数赋给C到底是什么,结果是 c=10 ,ASCII值为10是什么?换行即/n.对了,我们每击打一下"Enter"键,向键盘缓冲区发去一个“回车”(/r),一个“换行"(/n),在这里/r被scanf()函数处理掉了(姑且这么认为吧^_^),而/n被scanf()函数“错误”地赋给了c.
解决办法:可以在两个scanf()函数之后加个fflush(stdin);,还有加getch(); getchar();也可以,但是要视具体scanf()语句加那个,这里就不分析了,读者自己去摸索吧。但是加fflush(stdin);不管什么情况都可行。
函数名: fflush
功 能: 清除一个流
用 法: int fflush(FILE *stream);
int main()
scanf("%d",&a);
fflush(stdin);
scanf("%c",&c);
fflush(stdin);
printf("a=%d
c=%c/n",a,c);
}while(c!='N');
这里再给一个用“空格符”来处理缓冲区残余信息的示例:
运行出错的程序:
int main()
for(i = 0;i < 10;i&#43;&#43;)
scanf("%c",&j);/*这里%前没有空&#26684;*/
使用了空&#26684;控制符后:
int main()
for(i = 0;i < 10;i&#43;&#43;)
scanf(" %c",&j);/*注意这里%前有个空&#26684;*/
可以运行看看两个程序有什么不同。
如何处理scanf()函数误输入造成程序死锁或出错?
int main()
int a,b,c; /*计算a&#43;b*/
scanf("%d,%d",&a,&b);
c=a&#43;b;
printf("%d&#43;%d=%d",a,b,c);
如上程序,如果正确输入a,b的&#20540;,那么没什么问题,但是,你不能保证使用者每一次都能正确输入,一旦输入了错误的类型,你的程序不是死锁,就是得到一个错误的结果,呵呵,这可能所有人都遇到过的问题吧?
解决方法:scanf()函数执行成功时的返回&#20540;是成功读取的变量数,也就是说,你这个scanf()函数有几个变量,如果scanf()函数全部正常读取,它就返回几。但这里还要注意另一个问题,如果输入了非法数据,键盘缓冲区就可能还个有残余信息问题。
正确的例程:
int main()
int a,b,c; /*计算a&#43;b*/
while(scanf("%d,%d",&a,&b)!=2)fflush(stdin);
c=a&#43;b;
printf("%d&#43;%d=%d",a,b,c);
void main(){
printf("input a integer\n");
scanf("%d",&a);
//这里需要吸收 回车符
下面有种方法,第二种我没看懂 谁能改下代码 告诉我第二种怎么用
printf("input a char\n");
scanf("%c",&b);
printf("%d,%c\n",a,b);
(1)用getchar()清除
(2)用"%1s"来限制
(3)用格式串中空格或"%*c"来"吃掉"
(4)用函数fflush(stdin)清除全部剩余内容
*/#include
int main(){
printf("input a integer\n");
scanf("%d",&a);
//这里需要吸收 回车符
下面有种方法,第二种我没看懂 谁能改下代码 告诉我第二种怎么用
printf("input a char\n");
scanf("%1s",&b);
printf("%d %c\n",a,b);
system("pause");
}环境(dev c&#43;&#43;)
可以看出a的&#20540;异常了,为什么呢?vcD4KPHA+CtXi06a4w7rNseDS68b309C52M+1o6zS8s6qJTFztcTK5Mjrt73KvbXEzsrM4qGjPC9wPgo8cD4KveK+9re9t6jT0MG91tajujwvcD4KPHA+CrXa0rujujwvcD4KPHA+CjwvcD4KCgoKPHN0cm9uZz5bY3BwXTwvc3Ryb25nPiB2aWV3CiBwbGFpbmNvcHkKCgoKCjxvbCBzdGFydD0="1" class="dp-cpp">
将这两个变量的声明换一下,哈哈,以前老师说过。但我感觉着不是解决方法,如果还有其他的变量,这种方式是不是还会危害其他呢。
[cpp] view
int main(){
char b[2];
printf("input a integer\n");
scanf("%d",&a);
//这里需要吸收 回车符
下面有种方法,第二种我没看懂 谁能改下代码 告诉我第二种怎么用
printf("input a char\n");
scanf("%1s",&b);
printf("%d %c\n",a,b[0]);
system("pause");
b声明成字符创的形式,哈哈,这个好。。。。
(window.slotbydup=window.slotbydup || []).push({
id: '2467140',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467141',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467142',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467143',
container: s,
size: '1000,90',
display: 'inlay-fix'
(window.slotbydup=window.slotbydup || []).push({
id: '2467148',
container: s,
size: '1000,90',
display: 'inlay-fix'工作中的&注册&流程以及代码备份
简要:&&&&&&& 我觉得我们项目中用的注册流程好麻烦啊,可能是我是第一次给APP端写接口,token设计,存储,处理以及传输 都有好多啊,下面我将分步介绍.......&&&&&& 注意点: 两个token access_token 1 天 refresh_token 30 天 ,存储到redis, 采用string类型&&&&& 流程: - 注册用户时,判断手机号格式是否正确 - 在没发送验证码之前, 判断手机号是否已经被注册过 - 密码和确认密码判断是否一致 - 新创建两个token
setex access_token 1天
setex refresh_token 30天 - 注册完成后, 将两个token返回给用户, 并且默认用户是登录的&&& 设计&#26684;式:
- 生成的两个token组合方式:
$accessToken =
md5(&#39;at&#39; . $mobile . $userId .time());
$refreshToken = md5(&#39;rt&#39; . $mobile . $userId . time());
- 将两个token和user_id之间创建联系,然后存储到redis上,以后可以通过token获取对应的user_id
user:at:{$access_token} =& {$user_id}
user:rt:{$refresh_token} =& {$user_id}说明: 当生成好两个token后, 将他们与user_id建立起来,然后我将两个token返回给APP端.&&&&& 注册:代码如下:
* Action Register
* 用户注册
public function actionRegister()
$params = Yii::$app-&request-&post();
$mAccount = new Account();
$util = Yii::$app-&
//规格: 由8-16位的数字,字母组成的密码,其中不能有空格,不能全是数字,不能全是字母
$regular = &/((?=.*/d)(?=.*/D)|(?=.*[a-zA-Z])(?=.*[^a-zA-Z]))^.{8,16}$/&;
if (!$params) {
return $util-&formatResData(1101, &#39;无参数提供&#39;, (object)[], false);
if (!isset($params[&#39;mobile&#39;]) || !$params[&#39;mobile&#39;]) {
return $util-&formatResData(1102, &#39;手机号不能为空&#39;, (object)[], false);
if (!$util-&regularMobile($params[&#39;mobile&#39;])) {
return $util-&formatResData(1103, &#39;手机号码格式不正确&#39;, (object)[], false);
if (!isset($params[&#39;vcode&#39;]) || !$params[&#39;vcode&#39;]) {
return yii::$app-&util-&formatResData(1104, &#39;验证码不能为空&#39;, (object)[], false);
if (!isset($params[&#39;password&#39;]) || !$params[&#39;password&#39;]) {
return yii::$app-&util-&formatResData(1105, &#39;密码不能为空&#39;, (object)[], false);
if (!isset($params[&#39;confirm_password&#39;]) || !$params[&#39;confirm_password&#39;]) {
return yii::$app-&util-&formatResData(1106, &#39;确认密码不能为空&#39;, (object)[], false);
$users = $mAccount-&isExistMobile($params[&#39;mobile&#39;], &#39;user_id, salt, status&#39;);
$status = 0;
if ($users) {
$status = $users[&#39;status&#39;];
//如果该用户存在,且状态为可用|禁用,都提示已注册
if (($status == Account::STATUS_ENABLE) || ($status == Account::STATUS_DISABLE)){
return $util-&formatResData(1107, &#39;该手机号已被注册&#39;, (object)[], false);
//TODO 判断验证码是否正确
$mobie_white_list = array(&#39;手机号&#39;, &#39;手机号1&#39;);
if(in_array($params[&#39;mobile&#39;], $mobie_white_list)) {
} else if (($result = $this-&checkSmsVcode(&#39;reg&#39;, $params[&#39;mobile&#39;], $params[&#39;vcode&#39;])) !== true) {
$mInviteCode = new Invitecode();
//判断邀请码是否存在
if (isset($params[&#39;code&#39;]) && $params[&#39;code&#39;]) {
$isBindMobile = $mInviteCode-&isBindMobile($params[&#39;code&#39;], $params[&#39;mobile&#39;]);
if (!$isBindMobile) {
return $util-&formatResData(1108, &#39;该手机号与邀请码未绑定&#39;, (object)[], false);
$data[&#39;is_receive_invokecode&#39;] = HmcUser::STATUS_INVOKECODE_RECEIVED;
$tmp = $this-&judgePassword($params[&#39;password&#39;], $params[&#39;confirm_password&#39;], $regular);
if ($tmp) {
//从redis中获取用户ID
$data = $this-&getUid();
if (!isset($data[&#39;user_id&#39;]) || !$data[&#39;user_id&#39;]) {
$params[&#39;user_id&#39;] = $data[&#39;user_id&#39;];
unset($params[&#39;confirm_password&#39;], $params[&#39;vcode&#39;], $params[&#39;code&#39;]);
$mHmcUser = new HmcUser();
if (!$status) {
$result = $mAccount-&add($params);
$params[&#39;user_id&#39;] = $users[&#39;user_id&#39;];
$updateVal[&#39;salt&#39;] = $util-&random(6);
$updateVal[&#39;password&#39;] = md5(md5($params[&#39;password&#39;]).$updateVal[&#39;salt&#39;]);
$updateVal[&#39;status&#39;] = Account::STATUS_ENABLE;
$result = $mAccount-&renew($params[&#39;mobile&#39;], $updateVal);
if ($result) {
$data[&#39;user_id&#39;] = $params[&#39;user_id&#39;];
$data[&#39;mobile&#39;] = $params[&#39;mobile&#39;];
if (!$status) {
$userDetail = $mHmcUser-&add($data);
//创建token,并将token存储在redis
$handleData = $this-&handleSession($params[&user_id&], $params[&mobile&]);
if (!isset($handleData[&#39;variable&#39;]) || !$handleData[&#39;variable&#39;]) {
return $handleData[&#39;error&#39;];
$session = $handleData[&#39;variable&#39;];
Yii::$app-&api-&account_import((string)$params[&user_id&], (string)$params[&user_id&], &#39;&#39;);
$smsData = [&#39;mobile&#39;=& $params[&#39;mobile&#39;], &#39;business_type&#39; =& &#39;reg&#39;];
$result = $this-&renewSmsUseage($smsData);
} catch (/Exception $e) {
//TODO 将短信使用情况出现错误的地方写到日志里面
return $util-&formatResData(0, &#39;注册成功&#39;, $session, false);
return $util-&formatResData(1201, &#39;注册失败&#39;, (object)[], false);
}&刷新refresh_token步骤&&& 流程如图所示:代码如下:
* Action RefreshToken
* 刷新refresh_token
public function actionRefreshToken()
$params = Yii::$app-&request-&get();
if (!isset($params[&#39;refresh_token&#39;]) || !$params[&#39;refresh_token&#39;]) {
return yii::$app-&util-&formatResData(1101, &#39;未传递refresh_token参数&#39;, (object)[], false);
Yii::info($params[&#39;refresh_token&#39;], &#39;api/refreshtoken&#39;);
$cache = Yii::$app-&cache-&instance(&#39;base&#39;);
$rtCountKey = &#39;user:rtcount:&#39; . $params[&#39;refresh_token&#39;];
$unitMseconds = 500000;
$count = $cache-&incr($rtCountKey);
$cache-&expire($rtCountKey, 10);
if ($count & 1 && $count &= 10) {
// usleep($unitMseconds * $count);
usleep($unitMseconds);
$tokenKey = &user:rt:& . $params[&#39;refresh_token&#39;];
$tmp = $cache-&get($tokenKey);
//判断refresh_token是否过期
if (!$tmp) {
$tokens = $cache-&exists(&#39;user:oldrt:&#39; . $params[&#39;refresh_token&#39;]);
if (!$tokens) {
return yii::$app-&util-&formatResData(1102, &#39;refresh_token过期&#39;, (object)[], false);
$tokensKey = &#39;user:oldrt:&#39; . $params[&#39;refresh_token&#39;];
$session[&#39;user_id&#39;] = $cache-&hget($tokensKey, &#39;user_id&#39;);
$session[&#39;access_token&#39;] = $cache-&hget($tokensKey, &#39;access_token&#39;);
$session[&#39;refresh_token&#39;] = $cache-&hget($tokensKey, &#39;refresh_token&#39;);
$session[&#39;sig&#39;] = $cache-&hget($tokensKey, &#39;sig&#39;);
//如果不过期,user:rt:refresh_token 获取对应的用户ID,然后先删除rt,再重新创建两个token
$userId = $
$cache-&del($tokenKey);
$mAccount = new Account();
$users = $mAccount-&getByUid($userId, &#39;mobile&#39;);
//重新创建两个token
$handleData = $this-&handleSession($userId, $users[&#39;mobile&#39;]);
//创建旧的refresh_token,与新的refresh_token之间关联的数据,防止并发导致找不到已经删过的refresh_token, 10s
if (!isset($handleData[&#39;variable&#39;]) || !$handleData[&#39;variable&#39;]) {
return $handleData[&#39;error&#39;];
$session = $handleData[&#39;variable&#39;];
$accessToken = $session[&#39;access_token&#39;];
$refreshToken = $session[&#39;refresh_token&#39;];
$tmpTokenKey = &user:oldrt&;
$oldRefreshToken = $params[&#39;refresh_token&#39;];
$sig = Yii::$app-&sig-&getSig($userId);
$cache-&hmset(&#39;user:oldrt:&#39; . $oldRefreshToken, &#39;access_token&#39;, $accessToken, &#39;refresh_token&#39;, $refreshToken, &#39;user_id&#39;, $userId, &#39;sig&#39;, $sig);
$cache-&expire(&#39;user:oldrt:&#39; . $oldRefreshToken, 60);
return yii::$app-&util-&formatResData(0, &#39;refresh_token刷新成功&#39;, $session, false);
} catch (/Exception $e) {
return yii::$app-&util-&formatResData(-1, &#39;服务器连接失败,请稍后重试&#39;, (object)[], false);
}里面涉及的方法:1: 创建token方法 handleSession
* 创建token,并将token存储在redis上
* @param string $userId 用户ID
* @param string $mobile 手机号
* @param int
access_token保存时间
* @param int
refresh_token保存时间
* @return array
* 说明: 返回的值: access_token,refresh_token,user_id,sig
// protected function handleSession($userId, $mobile, $atTime = 300, $rtTime = 2592000)
// protected function handleSession($userId, $mobile, $atTime = 120, $rtTime = 2592000)
protected function handleSession($userId, $mobile, $atTime = 86400, $rtTime = 2592000)
$now = time();
$accessToken =
md5(&#39;at&#39; . $mobile . $userId . $now);
$refreshToken = md5(&#39;rt&#39; . $mobile . $userId . $now);
$token = [&#39;access_token&#39; =& $accessToken, &#39;refresh_token&#39; =& $refreshToken];
// FIXED: 设置过期时间设置的为经过多少秒过去而不是时间点,如果是时间点应该单独使用expireat
$cache = Yii::$app-&cache-&instance(&#39;base&#39;);
$cache-&setex(&#39;user:at:&#39; . $accessToken, $atTime, $userId);
$cache-&setex(&#39;user:rt:&#39; . $refreshToken, $rtTime, $userId);
$sig = Yii::$app-&sig-&getSig($userId);
$result[&#39;variable&#39;] = [
&#39;access_token&#39; =& $accessToken,
&#39;refresh_token&#39; =& $refreshToken,
&#39;user_id&#39; =& $userId,
&#39;sig&#39; =& $sig
} catch (/Exception $e) {
$result[&#39;error&#39;] = yii::$app-&util-&formatResData(-100, &#39;连接redis服务器失败,请稍后重试 &#39;, (object)[], false);
}2:验证手机号&#26684;式方法: regularMobile()
* 中国移动
const CHINA_MOBILE_EXPR = &#39;/^134[0-8]/d{7}$|^(?:13[5-9]|147|15[0-27-9]|178|18[2-478])/d{8}$/&#39;;
* 中国联通
const CHINA_UNION_EXPR = &#39;/^(?:13[0-2]|145|15[56]|176|18[56])/d{8}$/&#39;;
* 中国电信
const CHINA_TELCOM_EXPR = &#39;/^(?:133|153|177|18[019])/d{8}$/&#39;;
* 手机正则表达式验证
* @param string $mobile 手机
* @return int false 表示验证失败 true表示成功
public function regularMobile($mobile)
return preg_match(self::CHINA_MOBILE_EXPR, $mobile)
|| preg_match(self::CHINA_UNION_EXPR, $mobile)
|| preg_match(self::CHINA_TELCOM_EXPR, $mobile)
|| preg_match(self::CHINA_OTHER_EXPR, $mobile);
}3: 判断密码和确认密码 judgePassword()
* 判断密码和确认密码
public function judgePassword($password, $confirmPwd, $regular)
if (!preg_match($regular, $password)) {
return yii::$app-&util-&formatResData(1401, &#39;密码格式不正确&#39;, (object)[], false);
if (!preg_match($regular, $confirmPwd)) {
return yii::$app-&util-&formatResData(1402, &#39;确认密码格式不正确&#39;, (object)[], false);
if ($password !== $confirmPwd) {
return yii::$app-&util-&formatResData(1403, &#39;密码与确认密码不一致&#39;, (object)[], false);
}* 为什么要创建两个token ?&&&&&&& - 假如你只设置一个token表示app端用户的登录状态, 那么如果你的token被别人采用非正当手段截取了, 他是不是就可以&为所欲为&了, 而我们设计两个token, access_token设置1天, refresh_token设置30天,&&&&&&& 如果access_token过期了, refresh_token会刷新重新创建新的两个token, 并且把旧的refresh_token删掉. 由于access_token生存时间短暂, 那么假如被人盗取了, 没关系, 我们access_token过期后, 会用refresh_token刷新, 再重新创建新的两个token, 即便是refresh_token被盗取了, 也没关系, 因为又重新创建两个新的access_token和refresh_token, 你说这样是不是就比较完美了!&总结:&&&&&&&& 我只是把部分的流程列了出来,以后要是再碰到类&#20284;的,我就可以直接使用了,对于我来说,现在该学会的就是能够拿别人的代码应用到我的应用中,即便是我没明白,但是功能实现是第一步,因为工作领导不管你怎么样,人家要的是结果,因为现实的社会很残酷,不管你是谁,你是女生还是男生。& 所以加油,我可以的,不能被别人看不起!
最新教程周点击榜
微信扫一扫

我要回帖

更多关于 js quot 的文章

 

随机推荐