函数的使用技巧

1.    do{...}while(false)的用法
作用:使用do{...}while(false)结构可以简化多级判断时代码的嵌套。
例子:
现在要实现一个功能,但需要A、B、C、D四个前提条件,并且这四个前提条件都存在上级依赖,即B依赖于A,C依赖于A和B,D依赖于A、B和C。如果按照一般的写法,是这样:
1. if( A==true )
2. {
3. if( B==true )
4. {
5. if( C==true )
6. {
7. if( D==true )
8. {
9. //实现功能代码
10. }
11. }
12. }
13. }
可能看出来,这样导致多层if语句嵌套,看起来逻辑很不清晰。
一种解决的办法是使用goto语句,当某个条件不成立时,直接跳转到之后的语句段,形如这样:
1. if( A==false )
2. goto tag;
3. if( B==false )
4. goto tag;
5. if( C==false )
6. goto tag;
7. if( D==false )
8. goto tag;
9. //实现功能代码
10.
11. tag:
12. ...
这样看起来风格是好多了,但使用goto语句会有很多隐患,一般是不建议用的。
其实使用do while语句也可以实现类似goto的功能,但代码可读性会比goto风格好很多。代码如下:
1. do
2. {
3. if( A==false )
4. break;
5. if( B==false )
6. break;
7. if( C==false )
8. break;
9. if( D==false )
10. break;
11. //实现功能代码
12. }while(false);
13. ...
在do{...}while(false)中的代码段,可以用break的方式实现类似goto的跳转功能,在实际工程中很有使用价值。 2. 字符串替换函数 str_replace(find, replace,string,count)
find 可以是 array ,string
replace 可以是 array,string
如果替换 字符串中的 特殊字符:\n,\t 字符串用 双引号
双引号 和单引号 的区别; 3. 数组转json字符串
值 有中文 但不转义为unicode 参数:JSON_UNESCAPED_UNICODE
值 有反斜杠 但是不转义反斜杠 参数:JSON_UNESCAPED_SLASHES
json_encode($filter_word,
JSON_UNESCAPED_UNICODE | JSON_UNESCAPED_SLASHES); 4. form表单同一秒内,提交多次的问题:
①在 页面表单 提交按钮做初步限制 如:disabled属性 ajax.unbond事件
②在提交的控制器方法中做规避:memcached缓存add方法的属性
if( ! Cache::add($key, 1, 3)) … 5. 操作数据库数据的“锁”
①“悲观锁” thinkPHP 框架中SQL语句中lock(true),“悲观锁”很容易把表“锁死”。
②“乐观锁” 可以在 数据表中增加 一个版本字段version字段,记录当前update操作的版本。如果先select 其次 update, update中的where包含 主键和版本,如果版本不对就重新select。
③“乐观锁”和缓存memcached 一起使用
这是我们\Common\Util\Cache.class.php文件中的方法
//该方法 可以拿到锁,$callback执行完了,释放锁.
public static function lockTrans($key, \Closure $callback, $expire = 10, $tryTime = 5, $force = false)
{
$lock = self::lock($key, $expire, $tryTime);
if ($lock || $force) $callback();
if ($lock) {
self::unlock($key);
return true;
}
return false;
} 自己亦可以按照 先拿到锁 其次 执行代码 释放锁 这3个步骤来使用 缓存“乐观锁”完成相应的功能
public static function lock($key, $expire = 10, $tryTime = 5, $sleepSec = 0.1)
{
$cnt = 0;
$lock = false;
while (++$cnt <= $tryTime) {
if(!!$lock = self::getInstance()->add('lock_'.$key, 1, $expire)) break;
usleep($sleepSec * 1000000);
}
return $lock;
} public static function unlock($key)
{
return self::rm('lock_'.$key);
} 6. ThinkPHP的自增(setInc)自减(setDec) 做统计功能
public function addActivityNum($data){
if(empty($data)) return false;
if(is_array($data)) $key = implode('_', $data);
if(is_string($data)) $key = md5(trim($data));
//使用缓存保存各个类型中第一条数据
$flag = Cache::getOrSet($key, function ()use($data) {
if($this->db4->table('t_stat_activity_num')->setMasterDB(0)->field('autoid')->where($data)->find()) {
return true;
}
return false;
}, 86400, false); if($flag) {
//采用每60秒数据统一一次自增数据和数量
$up = $this->db4->table('t_stat_activity_num')->where($data)->setInc('num',1,60);
} if(!$flag) {
$data['num'] = 1;
$up = $this->db4->table('t_stat_activity_num')->add($data);
if($up) Cache::rm($key);
} return $up;
} 这样做的好处,操作数据库统计表 不是很频繁,减少 数据库压力。 7. session 存放在缓存服务器中共享session的功能
① 动态修改 ini.php文件中session的配置:
if(extension_loaded('memcache')){
ini_set("session.save_handler", "memcache");
ini_set("session.save_path", "tcp://127.0.0.1:11211");
}
② 切换session的驱动模式
/**
* 打开Session
* @access public
* @param string $savePath
* @param string $sessName
* @return bool
*/
public function open($savePath ='', $sessName ='') {
//session生命周期时间
$this->lifeTime = C('SESSION_EXPIRE') ? C('SESSION_EXPIRE') : $this->lifeTime;
$options = array(
'timeout' => C('SESSION_TIMEOUT') ? C('SESSION_TIMEOUT') : 1,
'persistent' => C('SESSION_PERSISTENT') ? C('SESSION_PERSISTENT') : 0
);
//采用 文件缓存 和memcached缓存 驱动session
$type = C('SESSION_TYPE');
//结合 框架正在使用的 缓存扩展
$this->handle = \Think\Cache::getInstance($type,$options);
return true;
} functions.php /**
* session管理函数
* @param string|array $name session名称 如果为数组则表示进行session设置
* @param mixed $value session值
* @return mixed
*/
function session($name='',$value='') {
$prefix = C('SESSION_PREFIX');
if(is_array($name)) { // session初始化 在session_start 之前调用
if(isset($name['prefix'])) C('SESSION_PREFIX',$name['prefix']);
if(C('VAR_SESSION_ID') && isset($_REQUEST[C('VAR_SESSION_ID')])){
session_id($_REQUEST[C('VAR_SESSION_ID')]);
}elseif(isset($name['id'])) {
session_id($name['id']);
}
if('common' == APP_MODE){ // 其它模式可能不支持
ini_set('session.auto_start', 0);
}
if(isset($name['name'])) session_name($name['name']);
if(isset($name['path'])) session_save_path($name['path']);
if(isset($name['domain'])) ini_set('session.cookie_domain', $name['domain']);
if(isset($name['expire'])) {
ini_set('session.gc_maxlifetime', $name['expire']);
ini_set('session.cookie_lifetime', $name['expire']);
}
if(isset($name['use_trans_sid'])) ini_set('session.use_trans_sid', $name['use_trans_sid']?1:0);
if(isset($name['use_cookies'])) ini_set('session.use_cookies', $name['use_cookies']?1:0);
if(isset($name['cache_limiter'])) session_cache_limiter($name['cache_limiter']);
if(isset($name['cache_expire'])) session_cache_expire($name['cache_expire']);
if(isset($name['type'])) C('SESSION_TYPE',$name['type']);
if(C('SESSION_TYPE')) { // 读取session驱动
$type = C('SESSION_TYPE');
// $class = strpos($type,'\\')? $type : 'Think\\Session\\Driver\\'. ucwords(strtolower($type));
$class = strpos($type,'\\')? $type : 'Think\\Session\\Driver\\'. ucwords(strtolower('Session'));
$hander = new $class();
session_set_save_handler(
array(&$hander,"open"),
array(&$hander,"close"),
array(&$hander,"read"),
array(&$hander,"write"),
array(&$hander,"destroy"),
array(&$hander,"gc"));
}
// 启动session
if(C('SESSION_AUTO_START')) session_start();
}elseif('' === $value){
if(''===$name){
// 获取全部的session
return $prefix ? $_SESSION[$prefix] : $_SESSION;
}elseif(0===strpos($name,'[')) { // session 操作
if('[pause]'==$name){ // 暂停session
session_write_close();
}elseif('[start]'==$name){ // 启动session
session_start();
}elseif('[destroy]'==$name){ // 销毁session
$_SESSION = array();
session_unset();
session_destroy();
}elseif('[regenerate]'==$name){ // 重新生成id
session_regenerate_id();
}
}elseif(0===strpos($name,'?')){ // 检查session
$name = substr($name,1);
if(strpos($name,'.')){ // 支持数组
list($name1,$name2) = explode('.',$name);
return $prefix?isset($_SESSION[$prefix][$name1][$name2]):isset($_SESSION[$name1][$name2]);
}else{
return $prefix?isset($_SESSION[$prefix][$name]):isset($_SESSION[$name]);
}
}elseif(is_null($name)){ // 清空session
if($prefix) {
unset($_SESSION[$prefix]);
}else{
$_SESSION = array();
}
}elseif($prefix){ // 获取session
if(strpos($name,'.')){
list($name1,$name2) = explode('.',$name);
return isset($_SESSION[$prefix][$name1][$name2])?$_SESSION[$prefix][$name1][$name2]:null;
}else{
return isset($_SESSION[$prefix][$name])?$_SESSION[$prefix][$name]:null;
}
}else{
if(strpos($name,'.')){
list($name1,$name2) = explode('.',$name);
return isset($_SESSION[$name1][$name2])?$_SESSION[$name1][$name2]:null;
}else{
return isset($_SESSION[$name])?$_SESSION[$name]:null;
}
}
}elseif(is_null($value)){ // 删除session
if(strpos($name,'.')){
list($name1,$name2) = explode('.',$name);
if($prefix){
unset($_SESSION[$prefix][$name1][$name2]);
}else{
unset($_SESSION[$name1][$name2]);
}
}else{
if($prefix){
unset($_SESSION[$prefix][$name]);
}else{
unset($_SESSION[$name]);
}
}
}else{ // 设置session
if(strpos($name,'.')){
list($name1,$name2) = explode('.',$name);
if($prefix){
$_SESSION[$prefix][$name1][$name2] = $value;
}else{
$_SESSION[$name1][$name2] = $value;
}
}else{
if($prefix){
$_SESSION[$prefix][$name] = $value;
}else{
$_SESSION[$name] = $value;
}
}
}
return null;
} Session.class.php
<?php
namespace Think\Session\Driver;
/**
* 缓存方式Session驱动
* 和 \Think\Cache.class.php 的缓存方式相结合
* Class Session
* @package Think\Session\Driver
*/
class Session {
protected $lifeTime = 1440;
protected $sessionName = '';
protected $handle = null; /**
* 打开Session
* @access public
* @param string $savePath
* @param string $sessName
* @return bool
*/
public function open($savePath ='', $sessName ='') {
$this->lifeTime = C('SESSION_EXPIRE') ? C('SESSION_EXPIRE') : $this->lifeTime;
$options = array(
'timeout' => C('SESSION_TIMEOUT') ? C('SESSION_TIMEOUT') : 1,
'persistent' => C('SESSION_PERSISTENT') ? C('SESSION_PERSISTENT') : 0
);
$type = C('SESSION_TYPE');
$this->handle = \Think\Cache::getInstance($type,$options);
return true;
} /**
* 关闭Session
* @access public
*/
public function close() {
$this->gc(ini_get('session.gc_maxlifetime'));
$this->handle->close();
$this->handle = null;
return true;
} /**
* 读取Session
* @access public
* @param string $sessID
* @return mixed
*/
public function read($sessID = '') {
return $this->handle->get($this->sessionName.$sessID);
} /**
* 写入Session
* @access public
* @param string $sessID
* @param string $sessData
* @return mixed
*/
public function write($sessID = '', $sessData = '') {
return $this->handle->set($this->sessionName.$sessID, $sessData, 0, $this->lifeTime);
} /**
* 删除Session
* @access public
* @param string $sessID
* @return mixed
*/
public function destroy($sessID) {
return $this->handle->delete($this->sessionName.$sessID);
} /**
* Session 垃圾回收
* @access public
* @param string $sessMaxLifeTime
* @return bool
*/
public function gc($sessMaxLifeTime) {
return true;
}
}

php函数的使用技巧的更多相关文章

  1. SQL Server 聚合函数算法优化技巧

    Sql server聚合函数在实际工作中应对各种需求使用的还是很广泛的,对于聚合函数的优化自然也就成为了一个重点,一个程序优化的好不好直接决定了这个程序的声明周期.Sql server聚合函数对一组值 ...

  2. 探究javascript对象和数组的异同,及函数变量缓存技巧

    javascript中最经典也最受非议的一句话就是:javascript中一切皆是对象.这篇重点要提到的,就是任何jser都不陌生的Object和Array. 有段时间曾经很诧异,到底两种数据类型用来 ...

  3. 总结js常用函数和常用技巧(持续更新)

    学习和工作的过程中总结的干货,包括常用函数.常用js技巧.常用正则表达式.git笔记等.为刚接触前端的童鞋们提供一个简单的查询的途径,也以此来缅怀我的前端学习之路. PS:此文档,我会持续更新. Aj ...

  4. .NET中Main函数使用小技巧

    摘要:任何语言开发出来的程序,都会有一个程序入口函数,可能每个语言所使用的程序入口函数名称不一样,但是它们的作用都是一样的,都是被操作系统去调用.那么本文主要总结.NET中的程序入口函数Main使用的 ...

  5. js常用函数和常用技巧

    学习和工作的过程中总结的干货,包括常用函数.常用js技巧.常用正则表达式.git笔记等.为刚接触前端的童鞋们提供一个简单的查询的途径,也以此来缅怀我的前端学习之路. PS:此文档,我会持续更新. Aj ...

  6. Windbg对过滤驱动DriverEntry函数下断点技巧

    方法1: 1> 先用DeviceTree.exe查看指定的过滤驱动的Load Address(加载地址) 2> 再用LordPE.EXE查看指定过滤驱动文件的入口点地址 3> 计算过 ...

  7. Java中Split函数的用法技巧

    在java.lang包中也有String.split()方法,与.net的类似,都是返回是一个字符型数组,但使用过程中还有一些小技巧.如执行:"2|33|4".split(&quo ...

  8. js函数的一些技巧

    1 函数的引用可以直接通过函数名来调用 bind: function (fn, scope) { return function () { return fn.apply(scope, argumen ...

  9. 算法学习笔记(一)C++排序函数、映射技巧与字典树

    1.头文件algorithm中有函数sort()用于排序,参数为:排序起始地址,排序结束地址,排序规则(返回bool型)例如,要将array[] = {5,7,1,2,9}升序排列,则使用: bool ...

随机推荐

  1. [CSP-S模拟测试]:tree(DP)

    题目传送门(内部题57) 输入格式 第一行包含一个数:$n$表示树的节点数.接下来$n-1$行,每行包含两个数:$u,v$表示无根树的一条边. 输出格式 输出$n$行,第$i$行包含一个浮点数,保留三 ...

  2. [CSP-S模拟测试]:biology(DP)

    题目传送门(内部题23) 输入格式 第一行有$2$个整数$n,m$.接下来有$n$行,每行$m$个整数,表示$a$数组.接下来有$n$行,每行$m$个整数,表示$b$数组. 输出格式 一行一个整数表示 ...

  3. Linux测试端口的连通性的四种方法

    目录 1.telnet 2.ssh 3.crul 4.wget 方法一.telnet telnet为用户提供了在本地计算机上完成远程主机工作的能力,因此可以通过telnet来测试端口的连通性,具体用法 ...

  4. Docker容器数据卷volumes-from

    定义4个终端: 终端host终端container dc01终端container dc02终端container dc03各个容器之间的关系: 1.启动一个父容器dc01启动一个父容器dc01,并在 ...

  5. Linux 下查看操作系统信息

    1.uname -a  可显示电脑以及操作系统的相关信息. 2.输入"cat /proc/version",说明正在运行的内核版本. 3.输入"cat /etc/issu ...

  6. 兼容ie浏览器的方法

    让IE6 IE7 IE8 IE9 IE10 IE11支持Bootstrap的解决方法   最近做一个Web网站,之前一直觉得bootstrap非常好,这次使用了bootstrap3,在chrome,f ...

  7. Java享元模式(Flyweight Pattern)

    享元模式(Flyweight Pattern)主要用于减少创建的对象数量,并减少内存占用并提高性能. 这种类型的设计模式属于结构模式,因为该模式提供了减少对象计数的方法,从而改善应用的对象结构. 享元 ...

  8. 洛谷 P1197 [JSOI2008]星球大战——并查集

    先上一波题目 https://www.luogu.org/problem/P1197 很明显删除的操作并不好处理 那么我们可以考虑把删边变成加边 只需要一波时间倒流就可以解决拉 储存删边顺序倒过来加边 ...

  9. 阿里Druid连接池的坑。。

    Druid的坑 当查询数据库的Clob转换为Oracle Clob类型的时候. java.lang.ClassCastException: com.alibaba.druid.proxy.jdbc.C ...

  10. 插件化框架解读之四大组件调用原理-Activity(三)上篇

    阿里P7移动互联网架构师进阶视频(每日更新中)免费学习请点击:https://space.bilibili.com/474380680 本文通过Activity调用原理来解读Replugin插件化技术 ...