php+mysql数据库查询及base64
本文实例讲述了php分页查询mysql结果的base64处理方法。分享给大家供大家参考,具体如下:
代码如下 | 复制代码 |
publicfunctionpublic_about(){ $sql="SELECTc.catid,c.catname,c.catdir,FROM_BASE64(p.content) FROM v9_page p JOINv9_category c ON c.catid=p.catid WHERE c.parentdir = 'jmwm/'"; if(isset($_REQUEST['biaoshi'])){ $sql="SELECTc.catid,c.catname,c.catdir,p.content FROM v9_page p JOIN v9_category c ONc.catid=p.catid WHERE c.catdir LIKE '{$_REQUEST['biaoshi']}%'"; } $mydb= pc_base::load_model('mymodel'); $mpages=$mydb->query_listinfo($sql); $this->array_to_base64($mpages); // $article['content']=base64_encode(toUtf8($article['content'])); $msg=array(); $msg['returncode']="0"; $msg['msg']= togbk("关于联系"); $msg['comment']=$mpages; echojsonFormat($msg); // return_Msg(0,"关于联系",$mpages); } publicfunctionarray_to_base64(&$array){ foreach($arrayas$key=>$value) { if(is_array($value)) { $this->array_to_base64($array[$key]); }elseif($key=="content"){ $array[$key]=base64_encode(toUtf8($value)); }else{ $array[$key]=togbk($value); } } } |
下面小编就为大家带来一篇PHP面向对象的解释器模式。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
最近在看 “深入PHP面向对象模式与实践” ,学习书中的内容后瞬间觉得自己有点高大上了,哈 ! 其实还是个菜。相信也会有新手朋友在看这本(我自己也是新手),对书中我个人认为比较难的内容的学习心得就想拿出来分享和交流,1是希望对自己所学知识能够起到巩固和加深理解的作用 2是希望对看到本文且感兴趣的新手朋友一些帮助。
这部分内容看了好几遍了代码也跟着敲了几遍,估计本文想要实现的功能大概就是用户在web页面上输入一些内容,然后通过后台程序解析后进行回复(感觉就是在废话)。例如我在前台web页面输入框里输入:
$input="4";
$inputequals"4"or$inputequals"four";
然后提交,系统就会回复类似 “条件成立” 或者 “条件不成立”的结果(有点类似直接在前台写代码并运行,后台解析后会返回一个结果。原书中虽然没有讲解整个前台输入到后台解析的过程但我猜这个后台解析应该还有一个使用正则表达式提取类似上面2行代码中关键字的过程)
上面这二行代码虽然是作者发明的语言,但根据字面含义也不难理解,第一行是定义一个变量并赋值,第二行是对变量进行一个判断(变量等于4或者等于four)。
废话不多说来看看这个模式定义的这几个类 (类图请自行看原文):
一、interpreterContext 这个类就像一个容器主要是用来存放和获取需要进行比较的值和比较的结果的,例如上述代码中的4, four,和比较结果 “true”或“false”,保存的形式是数组即类的属性$expressionstore,代码如下:
classInterpreterContext{
private$expressionstore=array();//存放比较的值和结果
functionreplace(Expression$exp,$value){ // 设置值
$this->expressionstore[$exp->getKey()] =$value;
}
functionlookup(Expression$exp){ //获取值
return$this->expressionstore[$exp->getKey()];
}
}
这个类就像一个工具,供其他类来使用(它和其他类不存在继承、组合或聚合的关系)。
二、Expression 这是一个表达式的抽象类,定义了抽象方法interpret() 和方法getKey()
代码如下:
abstractclassExpression {
privatestatic$keycount= 0; //计数用的
private$key; //存放一个唯一值
//主要实现将前台获取到的数据存放到上述InterpreterContext类中的功能,看到下面的内容就会发现继承他的类调用了InterpreterContext类的replace()方法
abstractfunctioninterpret (InterpreterContext$context);
//获取一个唯一值
functiongetKey(){
if(!isset($this->key)){
self::$keycount++;
$this->key= self::$keycount;
}
return$this->key;
}
}
下面将要讲到的类都将继承这个类,并且他和OperatorExpression(操作符表达式抽象类)是一个组合的关系,也就是说OperatorExpression在初始化时可以包含所有继承了Expression的子类(这也是本书一直在强调的要面向接口编程,这个Expression就是个接口,利用这个接口可以实现多态,不知道自己装B说的对不对,哈! 具体可以在看看原书的类图)
三、LiteralExpression 文字表达式类,作用就是将一个字符串保存到InterpreterContext这个小容器里,保存成一个索引数组,例如保存开头那二句自创代码中的 4 或者 four
代码如下:
classLiteralExpressionextendsExpression{
private$value;
function__construct ($value){ //初始化时传入要保存的值
$this->value=$value;
}
functioninterpret(InterpreterContext$context){ //调用InterpreterContext类的replace()将$value保存到InterpreterContext这个小容器里
$context->replace($this,$this->value);
}
}
四、VariableExpression 变量表达式类,和上面类的作用是一样的只不过数据将被保存成关联数组,关联数组中的健是变量名,值呢就是变量的值,例如开头二句中的变量"input" 和值 "4",
代码如下:
classVariableExpressionextendsExpression{
private$name; //变量名
private$val; //变量值
function__construct ($name,$val=null){
$this->name =$name;
$this->val =$val;
}
functioninterpret(InterpreterContext$context){
if(!is_null($this->val)){
$context->replace($this,$this->val);
$this->val = null;
}
}
functionsetValue($value){ //用于设置变量的值
$this->val =$value;
}
functiongetKey(){ //这个复写了父类的getKey()方法,在小容器InterpreterContext的lookup()方法调用这个类的实例的getKey()方法时 它将返回一个字符串(即变量名)而不是数字索引
return$this->name;
}
}
五、OperatorExpression 操作符表达式抽象基类,此类继承且组合了Expression抽象基类,实现的interpret()方法主要保存表达式的计算结果
代码如下:
abstractclassOperatorExpressionextendsExpression{
protected$l_op; //表达式左边的值
protected$r_op; //表达式右边的值
function__construct (Expression$l_op,Expression$r_op){ //初始化时可组合继承了Expression类的子类实例
$this->l_op =$l_op;
$this->r_op =$r_op;
}
functioninterpret(InterpreterContext$context){ //主要用于保存表达试的结果(保存到InterpreterContext 类的实例中)
$this->l_op->interpret($context); //将Expression子类实例的值或计算结果保存到InterpreterContext 类的实例中
$this->r_op->interpret($context);
$result_l=$context->lookup($this->l_op); //获取上一步的值或计算结果
$result_r=$context->lookup($this->r_op);
$this->doInterpret($context,$result_l,$result_r); //具体的比较运算由继承的子类来实现
}
protectedabstractfunctiondoInterpret(InterpreterContext$context,$result_l,$result_r);
}
六、EqualsExpression、BooleanOrExpression、BooleanAndExpression,分别为继承了OperatorExpression 抽象基类的相等表达式、或表达式、与表达式只有一个方法doInterpret()内部调用了InterpreterContext类的replace()方法将表达式的计算结果保存到InterpreterContext类的实例中
代码如下:
//相等表达式
classEqualsExpressionextendsOperatorExpression {
protectedfunctiondoInterpret(InterpreterContext$context,$result_l,$result_r){
$context->replace($this,$result_l==$result_r);
}
}
//或表达式
classBooleanOrExpressionextendsOperatorExpression{
protectedfunctiondoInterpret(InterpreterContext$context,$result_l,$result_r){
$context->replace($this,$result_l||$result_r);
}
}
//与表达式
classBooleanAndExpressionextendsOperatorExpression{
protectedfunctiondoInterpret(InterpreterContext$context,$result_l,$result_r){
$context->replace($this,$result_l&&$result_r);
}
}
到此为止此模式相关的类就介绍完毕,上述代码都是进过测试的,可直接复制粘贴运行来查看结果,现在我们就来看看客户端代码:
客户端代码一:
$context=newInterpreterContext();
$statement=newBooleanOrExpression ( //可尝试将此操作符表达式换成BooleanAndExpression 运行一下 看看执行结果
//可尝试将LiteralExpression中实例化的参数改成其他值看看运算结果,或者直接将EqualsExpression对象换成BooleanOrExpression 或BooleanAndExpression
newEqualsExpression(newLiteralExpression('four'),newLiteralExpression('four')),
newEqualsExpression(newLiteralExpression('b'),newLiteralExpression(Ɗ'))
);
$statement->interpret($context);
if($context->lookup($statement)){
echo'条件成立'
}else{
echo'条件不成立'
}
客户端代码二:
$context=newInterpreterContext();
$statement=newBooleanOrExpression(
newBooleanAndExpression(
newEqualsExpression(newLiteralExpression(Ɗ'),newLiteralExpression(Ɗ')),
newEqualsExpression(newLiteralExpression(Ɗ'),newLiteralExpression(Ɗ'))
),
newEqualsExpression(newLiteralExpression('b'),newLiteralExpression(Ɗ'))
);
$statement->interpret($context);
if($context->lookup($statement)){
echo'条件成立'
}else{
echo'条件不成立'
}
客户端代码三:
这是原文的客户端代码实例和上述客户端代码的区别在于使用了变量表达式VariableExpression
$context=newInterpreterContext();
$input=newVariableExpression('input'); //这里定义了一个变量input 但并未赋值
$statement=newBooleanOrExpression(
newEqualsExpression($input,newLiteralExpression('four')), //这里变量表达式和文字表达式的值将进行一个是否相等的比较
newEqualsExpression($input,newLiteralExpression(Ɗ'))
);
foreach(array("four","4","52")as$val){
$input->setValue($val); //对input这个变量赋值
print"变量input的值为:$val:
";
$statement->interpret($context); //进行比较并将比较结果存入InterpreterContext对象实例
if($context->lookup($statement)){ //获取比较的结果
print"条件成立
";
}else{
print"条件不成立
";
}
}
上述代码经过测试都可以正常运行,有需要的朋友可以复制下来,运行一下看看结果。
以上这篇PHP面向对象的解释器模式就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持本网站。
下面小编就为大家带来一篇PHP实现电商订单自动确认收货redis队列。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧一、场景
之前做的电商平台,用户在收到货之后,大部分都不会主动的点击确认收货,导致给商家结款的时候,商家各种投诉,于是就根据需求,要做一个订单在发货之后的x天自动确认收货。所谓的订单自动确认收货,就是在在特定的时间,执行一条update语句,改变订单的状态。
二、思路
最笨重的做法,通过linux后台定时任务,查询符合条件的订单,然后update。最理想情况下,如果每分钟都有需要update的订单,这种方式也还行。奈何平台太小,以及卖家发货时间大部分也是密集的,不会分散在24小时的每分钟。那么,定时任务的话,查询过多,不适合。这里可以先把将要自动确认收货的订单信息存储到其他介质上,比如redis,memcache,rabbitmq,然后执行的脚本从前面的介质获取到订单信息来判断,这里可以大大的减少数据库的查询压力。
redis队列的生产者
对此,我们选择每天在凌晨两点的时候,通过linux的定时任务把即将要确认收货的订单信息查询出来,然后存储在redis上,redis上我们选择的队列,队列处理的特点就是先进先出,前面的数据在查询订单时,通过发货时间排序,所以最先出队列的肯定是距离规定的自动收货时间最近的订单。代码如下
$successCount=0;
$failCount=0;
$screen_time= 3600*24*9;//设置筛选天数
$data=array();
$now_time= time();
//查询符合要求的数据
$sql="select id,send_timeasdeliver_time from `order` where is_send=1andis_del=0andis_cancel=0andis_token=0andsend_time>0andsend_time + {$screen_time} <$now_time
order by send_time asc";
$res=$con->query($sql);
//当队列还有数据时将数据记录并清除
while($redis->LLEN('auto_recevice_order')){
$txt='执行时间:'.date('Y-m-d H:i:s').',信息:'.$redis->RPOP('auto_recevice_order');
file_put_contents('./autoToken/fail_log.txt',$txt."\r\n".PHP_EOL,FILE_APPEND);
$failCount++;
}
//重新填充数据进队列
while($row=$res->fetch_assoc()) {
$successCount++;
$redis->LPUSH('auto_recevice_order',json_encode($row1));
}
$con->close();
$success=date('Y-m-d H:i:s').':[推送成功]:本次成功推送数据:'.$successCount.'条;记录上次处理失败数据:'.$failCount."条\r\n";
file_put_contents('./success_log.txt',$success."\r\n".PHP_EOL,FILE_APPEND);
redis队列的消费者
队列的消费者没有通过linux的定时任务去做,用linux的screen+php cli模式执行php脚本,消费者只需要不断的从队列中读取订单信息,然后判断订单信息中的发货时间,如果达到自动收货的要求,就执行update语句。同时如果没有达到收货的时间,而且与收货时间间距比较大的时候,可以让php脚本休眠sleep一定的时间数,这个时间数自己调节设计,获取出来的未达到时间要求的订单,需要重新推送到redis队列中去,而且还是队列的顶端。以便下次获取。代码如下:
$set_time= 3600*24*10;//设置几天后自动收货
while(true){
if($i%30==0){
usleep(10);//防止while 循环使CPU使用率过高
}
if($redis->LLEN('auto_recevice_order')){
$data= json_decode($redis->RPOP('auto_recevice_order'));
$id= (int)$data->id;//将数据转化为整形
$deliver_time= (int)$data->deliver_time;//将数据转化为整形
$res1=$res2=false;
$now_time= time();
if(($deliver_time+$set_time)<$now_time){
$sql1="update `order` set `is_token`=Ƈ',`token_time` = $now_time where id=$id and is_send=1 and is_del=0 and is_cancel=0 and is_token=0 and send_time + {$set_time} < $now_time";
$res1=$con->query($sql1);//更新数据
$rows= mysqli_affected_rows($con);
if($rows){
$ip=$this->getIp();
$sql2="insert into `order_log`(`order_id`,`log_msg`,`log_ip`,`log_role`,`log_user`,`log_order_state`,`log_time`) VALUES($id,'系统自动收货','$ip','系统','服务器','收货',$now_time)";//写入订单日志
$res2=$con->query($sql2);//添加日志数据
}
}
if($res1==false){//将没达到条件的数据重新插入队列中
$redis->RPUSH('auto_recevice_order',json_encode(array('id'=>$id,'deliver_time'=>$deliver_time)));
}
}
$i++;
}
这里执行php脚本,需要用到linux的screen或者supervisor、nohup守护进程。具体用法可自行百度.同样脚本里面最好有必须的日志记录。
三、思考
随着业务的增长,在队列中同一秒内,存在的多个需要处理的订单,而一次只能从队列中取出一个相关订单信息的时候,可以采用一个生产者多个消费者的模式,这种情况下,可以用到锁机制,保证一条消息只能到达一个消费者。当redis数据达到一定的量之后,也可以适当的调整生产者的执行频率和对应的条件。
以上这篇PHP实现电商订单自动确认收货redis队列就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持本网站。
下面小编就为大家带来一篇关于php中 strtr 和 str_replace 的效率问题。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧在网上看了一些php优化的指南,里面提到:使用strtr 函数 比 str_replace快4倍。 本着探索的精神动手验证。
代码
代码如下 | 复制代码 |
$string='abcdefg'; set_time_limit(300);
$start= microtime(true); for($i= 0;$i< 10000000;$i++) { $str=str_replace('a','123',$string); }
echomicrotime(true)-$start,'<br />';
$start= microtime(true); for($i= 0;$i< 10000000;$i++) { $str=strtr($string, ['a'=>'123']); }
echomicrotime(true)-$start,'<br />'; |
平台(笔记本):win10 + i5 + 8G固态
环境1:php 5.6 nts +apache
测试条件: 10000000次循环
结果: str_replace :3.2446131706238 秒
strtr: 36.379708051682 秒
环境2:php 7.0 nts +apache
测试条件: 10000000次循环
结果: str_replace :9.3426380157471秒
strtr: 9.3660399913788秒
环境3:php 5.6 nts + nginx
测试条件: 10000000次循环
结果: str_replace :3.2784769535065 秒
strtr: 35.701732158661 秒
环境4:php 7.0nts +nginx
测试条件: 10000000次循环
结果: str_replace :9.5572259426117 秒
strtr: 9.4987349510193 秒
意外发现, 5.6版本 str_replace 比 strtr 效率高10+倍, 7.0版本效率基本相同, 但5.6的 str_replace 竟比 7.0高 3倍
ps:以上测试,每个环境都测试了3+次,结果取平均值
以上这篇php中 strtr 和 str_replace 的效率问题就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持本网站。
相关文章
- 操作类就是把一些常用的一系列的数据库或相关操作写在一个类中,这样调用时我们只要调用类文件,如果要执行相关操作就直接调用类文件中的方法函数就可以实现了,下面整理了...2016-11-25
- 本文给大家分享C#连接SQL数据库和查询数据功能的操作技巧,本文通过图文并茂的形式给大家介绍的非常详细,需要的朋友参考下吧...2021-05-17
- 这篇文章主要介绍了C#从数据库读取图片并保存的方法,帮助大家更好的理解和使用c#,感兴趣的朋友可以了解下...2021-01-16
- 这篇文章主要介绍了Intellij IDEA连接Navicat数据库的方法,本文通过图文并茂的形式给大家介绍的非常详细,对大家的学习或工作具有一定的参考借价值,需要的朋友可以参考下...2021-03-25
- 在开发过程中,我们经常会将日期时间的毫秒数存放到数据库,但是它对应的时间看起来就十分不方便,我们可以使用一些函数将毫秒转换成date格式。 一、 在MySQL中,有内置的函数from_unixtime()来做相应的转换,使用如下: 复制...2014-05-31
- C#使用System.IO中的文件操作方法在Windows系统中处理本地文件相当顺手,这里我们还总结了在Oracle中保存文件的方法,嗯,接下来就来看看整理的C#操作本地文件及保存文件到数据库的基本方法总结...2020-06-25
- 通过内网连另外一台机器的mysql服务, 确发现速度N慢! 等了大约几十秒才等到提示输入密码。 但是ping mysql所在服务器却很快! 想到很久之前有过类似的经验, telnet等一些服务在连接请求的时候,会做一些反向域名解析(如果...2015-10-21
- 某些时候,例如为了搭建一个测试环境,或者克隆一个网站,需要复制一个已存在的mysql数据库。使用以下方法,可以非常简单地实现。假设已经存在的数据库名字叫db1,想要复制一份,命名为newdb。步骤如下:1. 首先创建新的数据库newd...2015-10-21
- mysqldump命令的用法1、导出所有库系统命令行mysqldump -uusername -ppassword --all-databases > all.sql 2、导入所有库mysql命令行mysql>source all.sql; 3、导出某些库系统命令行mysqldump -uusername -ppassword...2015-10-21
- 1005:创建表失败1006:创建数据库失败1007:数据库已存在,创建数据库失败1008:数据库不存在,删除数据库失败1009:不能删除数据库文件导致删除数据库失败1010:不能删除数据目录导致删除数据库失败1011:删除数据库...2013-09-23
- 这篇文章主要介绍了c#从数据库里取得数据并异步更新ui的方法,大家参考使用吧...2020-06-25
- yii2.0框架是PHP开发的一个比较高效率的框架,集合了作者的大量心血,下面通过用户为例给大家详解yii2使用中的一些基本的增删改查操作。 User::find()->all(); //返回所有用户数据; User::findOne($id); //返回 主键...2015-11-24
- 这篇文章主要介绍了springBoot 项目排除数据库启动方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教...2021-09-10
- 1.用phpmyadmin创建数据库和数据表 创建数据库的时候,请将“整理”设置为:“utf8_general_ci” 或执行语句: 复制代码 代码如下:CREATE DATABASE `dbname` DEFAULT CHARACTER SET utf8 COLLATE utf8_general_ci; 创...2015-10-21
- 这篇文章主要介绍了Linux 下使用shell脚本定时维护数据库,本文通过案例分析给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-07-11
- “主机,用户名,密码”得到连接、“数据库,sql,连接”得到结果,最后是结果的处理显示。当然,数据库连接是扩展库为我们完成的,我们能做的仅仅是处理结果而已。...2013-09-29
- 对数据加密分两种,一种是对数据库本身进行加密,另一种是对数据表中的数据进行加密,下面通过本文给大家介绍C#连接加密的Sqlite数据库的方法,感兴趣的朋友一起看看吧...2020-06-25
- 这篇文章主要介绍了Java连接数据库oracle中文乱码解决方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考下...2020-05-16
- 本篇文章是对C#连接Oracle数据库的连接字符串进行了详细的分析介绍,需要的朋友参考下...2020-06-25
- 今天向MySQL数据库中的一张表添加含有中文的数据,可是老是出异常,检查程序并没有发现错误,无奈呀,后来重新检查这张表发现表的编码方式为latin1并且原想可以插入中文的字段的编码方式也是latin1,然后再次仔细观察控制台输...2014-05-31