zoukankan      html  css  js  c++  java
  • php函数的使用技巧

    函数的使用技巧
    
    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
    如果替换 字符串中的 特殊字符:
    ,	 字符串用 双引号
    双引号 和单引号 的区别;
    
    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 一起使用
    这是我们CommonUtilCache.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 = ThinkCache::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 ThinkSessionDriver;
    /**
     * 缓存方式Session驱动
     * 和 ThinkCache.class.php 的缓存方式相结合
     * Class Session
     * @package ThinkSessionDriver
     */
    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 = ThinkCache::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;
        }
    }
  • 相关阅读:
    C++0x standard & features in VC10
    Win32 结构化异常处理(SEH)探秘
    What Every Programmer Should Know About Memory
    Memory leak detector(C++)
    NT's Asynchronous Procedure Call
    服务器应用程序不可用
    不安全代码只会在使用 /unsafe 编译的情况下出现
    关于“因为数据库正在使用,所以无法获得对数据库的独占访问权”的最终解决方案
    让 PowerDesigner 支持 SQLite!
    基于.Net的单点登录(SSO)解决方案
  • 原文地址:https://www.cnblogs.com/yehuisir/p/11191351.html
Copyright © 2011-2022 走看看