存档

2020年8月 的存档

nginx重写规则中被重写网址中携带参数如何正确301重定向至新网址中

2020年8月21日 没有评论

比如需要重写的网址是:/news/view.php?itemid=123

我们现在希望自动301到新的网址,并把参数携带过去,我们希望重写后的网址格式是:/news/123.html

那么301重写规则就是:rewrite ^/news/view.php$ /news/$arg_itemid.html? permanent;

解释:$arg_原本参数名称就是获取原本的itemid=123,所以$arg_itemid就是等于123,“$arg_itemid.html?”最后面的问号,就是终止继续携带参数的功能(nginx会自动再携带一遍)如果不加问号,那么301之后就变成了:/news/123.html?itemid=123

nginx重写规则中被重写网址中携带参数如何正确301重定向至新网址中,解决方案暂且记录到这里。

shell脚本实现sh自动删除清理指定过期日期备份功能

2020年8月8日 没有评论

本脚本具体功能,请看脚本中备注的地方,前提条件,比如/backup/mybk下面的目录是年月日格式,比如:20200801(我的备份目录中,还有一个now文件夹也保留),大家可以自行修改为自己的代码,免费拿走。

#!/bin/bash
ROOT_UID=0
E_NOTROOT=67
if [ "$UID" -ne "$ROOT_UID" ]
then
        echo "Must be root to run this script"
        exit $E_NOTROT
fi

#配置需要操作的备份目录
backupDir=/backup/mybk

:<<!
#本脚本可以实现:(假设当前月是202008)
#保留当前备份文件夹now
#保留当前月备份文件夹:202008
#保留当前月后3个月备份文件夹:202007+202006+202005
#保留当前月后9个月备份文件夹中日期最大的一份(删除其他):202004+202003+202002+202001+201912+201911+201910+201909+201908
!


function arrDelete(){
	#把传递过来的数组作为arr
	arr=$1

	#找出数组中的最大值,初始值为0
	MAX=0
	for v in ${arr[@]}
	do
		if [[ $MAX -le $v ]]
		then
		    MAX=$v
		fi
	done

	#再循环一遍,比较大小,找到应该删除的文件夹
	for v in ${arr[@]}
	do
		if [[ $MAX -ne $v ]]
		then
			echo "不是当月最大,删除:"$backupDir"/"$v
			rm -rf $backupDir"/"$v
		fi
	done
}

function read_dir(){

	monthAgo0=$(date +%Y%m)
	monthAgo1=$(date "-d 1 month ago" +%Y%m)
	monthAgo2=$(date "-d 2 month ago" +%Y%m)
	monthAgo3=$(date "-d 3 month ago" +%Y%m)
	monthAgo4=$(date "-d 4 month ago" +%Y%m)
	monthAgo5=$(date "-d 5 month ago" +%Y%m)
	monthAgo6=$(date "-d 6 month ago" +%Y%m)
	monthAgo7=$(date "-d 7 month ago" +%Y%m)
	monthAgo8=$(date "-d 8 month ago" +%Y%m)
	monthAgo9=$(date "-d 9 month ago" +%Y%m)
	monthAgo10=$(date "-d 10 month ago" +%Y%m)
	monthAgo11=$(date "-d 11 month ago" +%Y%m)
	monthAgo12=$(date "-d 12 month ago" +%Y%m)

	for file in `ls $1` #注意此处这是两个反引号,表示运行系统命令
	do
		if [ -d $1"/"$file ] #注意此处之间一定要加上空格,否则会报错
	then
		if [[ $file == *now* ]]
		then
			echo "now,保留全部:"$1"/"$file
		elif [[ $file == *$monthAgo0* ]]
		then
			echo "当月,保留全部:"$1"/"$file
		elif [[ $file == *$monthAgo1* ]] || [[ $file == *$monthAgo2* ]] || [[ $file == *$monthAgo3* ]]
		then
			echo "最近3个月,保留全部:"$1"/"$file
		elif [[ $file == *$monthAgo4* ]]
		then
			arrmonthAgo4[${#arrmonthAgo4[@]}]=$file
		elif [[ $file == *$monthAgo5* ]]
		then
			arrmonthAgo5[${#arrmonthAgo5[@]}]=$file
		elif [[ $file == *$monthAgo6* ]]
		then
			arrmonthAgo6[${#arrmonthAgo6[@]}]=$file
		elif [[ $file == *$monthAgo7* ]]
		then
			arrmonthAgo7[${#arrmonthAgo7[@]}]=$file
		elif [[ $file == *$monthAgo8* ]]
		then
			arrmonthAgo8[${#arrmonthAgo8[@]}]=$file
		elif [[ $file == *$monthAgo9* ]]
		then
			arrmonthAgo9[${#arrmonthAgo9[@]}]=$file
		elif [[ $file == *$monthAgo10* ]]
		then
			arrmonthAgo10[${#arrmonthAgo10[@]}]=$file
		elif [[ $file == *$monthAgo11* ]]
		then
			arrmonthAgo11[${#arrmonthAgo11[@]}]=$file
		elif [[ $file == *$monthAgo12* ]]
		then
			arrmonthAgo12[${#arrmonthAgo12[@]}]=$file
		else
			echo "超过12个月,删除:"$1"/"$file
			rm -rf $1"/"$file
		fi
	else
		echo "is file,skip:"$1"/"$file
	fi
	done

	#循环各个数组,删除其中不是最大的一个文件夹
	#注意:传递数组为参数,必须要用引号扩起来,否则只能获取到第一个下标
	arrDelete "${arrmonthAgo4[*]}"
	arrDelete "${arrmonthAgo5[*]}"
	arrDelete "${arrmonthAgo6[*]}"
	arrDelete "${arrmonthAgo7[*]}"
	arrDelete "${arrmonthAgo8[*]}"
	arrDelete "${arrmonthAgo9[*]}"
	arrDelete "${arrmonthAgo10[*]}"
	arrDelete "${arrmonthAgo11[*]}"
	arrDelete "${arrmonthAgo12[*]}"
}

#遍历备份目录并操作
read_dir $backupDir

分类: ubuntu高手 标签: , , , , ,

php操作mysql的普通类和pdo类,2者几乎可兼容升级。

2020年8月7日 没有评论

20210119优化版

<?php
/*
普通调用:
require 本类;
$mydb=new myDb($dbname);//$dbname为数据库名称
项目调用:
M()->query();//参考func/global.php中的function M();
*/
class myDb{
	private $Link_ID=0;
	private $PDOStatement;//执行失败时设置为false
	private $Db='';
	private $host=array();
	private $debugMode=false;
	private $debugParams=array();
    private $debugSql='';

	function __construct($db='',$host=array()){
		if(defined('MYSQL_ERROR') && MYSQL_ERROR===true){//判断是否允许debug
			$this->debugMode=true;
		}
		$this->Db=$db;
		$this->host=$host;
		if(count($host)<=0){
			$dbconfig=dirname(dirname(__FILE__)).'/config/global/db.php';
			if(is_file($dbconfig)){
				require_once $dbconfig;
				$this->host=$GLOBALS['dbHost']['default'];
			}
			else {exit('undefind db');}
		}
		//不执行mysql链接,因为考虑到包含文件并不一定需要使用到mysql,由相关方法里面自行执行
		//$this->connect();
	}
	
	function connect(){
		if(!$this->Link_ID){
			try{
				$this->Link_ID=new PDO('mysql:host='.$this->host[0].';dbname='.$this->Db.';charset='.$this->host[3],$this->host[1],$this->host[2]);
				/*
				考虑到我们的app以前客户端都是以字符串进行处理的,所以会造成新版写入缓存的时候是整型,客户端老版api返回后客户端会死掉,在新app的api接口没更换之前,先注释
				查询mysql返回字段int变为String型解决方法
				$this->Link_ID->setAttribute(PDO::ATTR_STRINGIFY_FETCHES,false);
				$this->Link_ID->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);//启用或禁用预处理语句的模拟。默认true.如果设置false,可以在prepare阶段抛出不会终止程序的"Mysql error".
				===说明:
				上方$this->Link_ID->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);注释之后,则为默认值true,会导致$this->debugMode的时候无法抛出"Mysql error"
				可以增加一处设置:$this->Link_ID->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
				PDO::ATTR_ERRMODE的值请参考:https://www.php.net/manual/zh/pdo.setattribute.php
				所以当PDO::ATTR_EMULATE_PREPARES为false,且PDO::ATTR_ERRMODE为PDO::ERRMODE_EXCEPTION的时候,抛PDOException错误(可捕获)
				*/
				//if($this->debugMode){不用这样判断,否则会导致无法获取异常信息,在需要显示异常信息的地方判断即可
					$this->Link_ID->setAttribute(PDO::ATTR_ERRMODE,PDO::ERRMODE_EXCEPTION);
                //}
			}
			catch(PDOException $e){$this->Link_ID=0;die('mysql connect error...');}
			$this->Link_ID && $this->Link_ID->query('set names '.$this->host[3].';');
		}
	}
	
	/**
     * 执行查询
     * @param string $sql
     * @param array $params 参数['column'=>$value,...]
     * @return bool
     */
	function query($sql='',$params=array()){
		if(empty($sql)){return false;}
		$this->connect();
		$queryOK=false;
		if($this->debugMode===true){
			$this->debugSql=$sql;
			$this->debugParams=$params;
		}
		//try catch需要配合`PDO::ATTR_ERRMODE = PDO::ERRMODE_EXCEPTION`使用
        try{
            $PDOStatement=$this->Link_ID->prepare($sql,array(PDO::ATTR_CURSOR=>PDO::CURSOR_SCROLL));//返回 PDOStatement / False
            if($PDOStatement){
                //不能用$PDOStatement->execute($params);如果有int类型会报错
                //应该用PDOStatement::bindValue()去绑定(注意: 不要用bindParam())
                foreach($params as $key=>$value){
                    $PDOStatement->bindValue(':'.$key,$value,$this->getPdoValueType($value));//类型需要判断
                }
				$queryOK=$PDOStatement->execute();//bool
            }
			$this->PDOStatement=$PDOStatement;
        }
		catch(PDOException $e){
			$this->PDOStatement=false;//异常也要设置为false
            if($this->debugMode){
				//explainPDOException会打印原型pdo语句,所以getDebugSql(true)可以打印拼接后的(默认为true打印拼接后的sql)
                exit('<pre>'.implode(PHP_EOL,$this->explainPDOException($e)).'</pre>'.PHP_EOL.'<br />SQL: '.$this->getDebugSql());
            }
        }
		return $queryOK;
	}
	
	/**
     * 单条数据插入 (pdo绑定参数)
     * @param string $table
     * @param array $data 数据['column'=>$value,...]
     * @return bool
     */
	function insert($table,$data){
	    $arr_column=array_keys($data);
        return $this->query('insert into '.$table.'('.implode(',',$arr_column).')values('.(':'.implode(',:',$arr_column)).')',$data);
    }
	
	/**
     * 获取上次插入的id
     * @return int|0
     */
	function insert_id(){
		if(!$this->PDOStatement){return 0;}
		return intval($this->Link_ID->lastInsertId());
	}
	
	/**
     * 单条数据插入并返回自增id (pdo绑定参数)
     * @param string $table
     * @param array $data 数据['column'=>$value,...]
     * @return int|0
     */
	function insert_get_id($table,$data){
	    $this->insert($table,$data);
		return $this->insert_id();
    }
	
	/**
     * 查询多笔记录
     * @param string $sql
     * @param array $params
     * @return array 有结果时返回二维数组, 无则返回空数组 []
     */
	function query_all($sql='',$params=array()){
		if(!$this->query($sql,$params)){return array();}//不能直接return 0;否则当结果为零条的时候前端会出错
		return $this->PDOStatement->fetchAll(PDO::FETCH_ASSOC);
	}

	/**
     * 查询一笔记录
     * @param string $sql
     * @param array $params
     * @return array|false 有记录则返回一维数组, 无则返回 false
     */
	function query_first($sql='',$params=array()){
		if(!$this->query($sql,$params)){return false;}
		return $this->PDOStatement->fetch(PDO::FETCH_ASSOC);
	}

	/**
     * 获取影响的行数
     * @return int|0
     */
	function num_affected_rows(){
		if(!$this->PDOStatement){return 0;}
		return $this->PDOStatement->rowCount();
	}
	
	function beginTransaction(){$this->connect();$this->Link_ID->beginTransaction();}//开启事务
	
	function rollBack(){$this->Link_ID->rollBack();}//回滚事务
	
	function commit(){$this->Link_ID->commit();}//提交事务

	private function getPdoValueType($value){
        if(is_int($value)){return PDO::PARAM_INT;}
		else if(is_bool($value)){return PDO::PARAM_BOOL;}
		else if(is_null($value)){return PDO::PARAM_NULL;}
		else{return PDO::PARAM_STR;}
    }
	
	private function explainPDOException($ex){
        //code, message, file, line, trace
	    $arr=[];
	    $arr[]='PDOException:'.$ex->getCode().':'.$ex->getMessage();
	    $arr[]='File:'.$ex->getFile().':'.$ex->getLine();
	    $i=0;
	    //这里不用$ex->getTraceAsString(), 而是直接获取trace
		//file, line [,class, type], funcion, args[0,1,2,...]
	    foreach($ex->getTrace() as $row){
            $arr2=[];
            $arr2[]=$row['file'].'('.$row['line'].'):';
            if(isset($row['class'])){$arr2[]=$row['class'].$row['type'];}
            $arr2[]=$row['function'];
            if(isset($row['args']) && !empty($row['args'])){//参数 args
                $arr2[]='(';
                $k=0;
                foreach($row['args'] as $arg){
                    if($k>0){$arr2[]=',';}
                    if(is_array($arg)){$arr2[]='['.trim(json_encode($arg,256),'{}').']';}
					elseif(is_scalar($arg)){
                        if(is_string($arg)){$arr2[]='\'' .htmlspecialchars($arg).'\'';}
						else{$arr2[]=htmlspecialchars((string)$arg);}
                    }
					else{}//其他参数类型,暂时忽略
                    $k++;
                }
                $arr2[]=')';
            }
            $arr[]='#'.((string)$i).' '.implode('',$arr2);
            $i++;
        }
	    return $arr;
    }
		
	//打印sql语句($pdoAfter为false时候,打印pdo原型,比如:select * from table where ip=:ip
    function getDebugSql($pdoAfter=true){
		if($this->debugMode===true){
			if(!$pdoAfter){return $this->debugSql;}
			foreach($this->debugParams as $k=>$v){
				$this->debugParams[':'.ltrim($k,':')]=$v;
				unset($this->debugParams[ltrim($k,':')]);
			}
			$debugSql=$this->debugSql;
			$debugParams_vals=array_values($this->debugParams);
			$r=true;
			$index=0;
			while($r){
				$r=stristr($debugSql,'?');
				if(!empty($r)){
					empty($debugParams_vals[$index]) && $debugParams_vals[$index]='NULL';
					if(!is_numeric($debugParams_vals[$index])){$debugParams_vals[$index]=addslashes($debugParams_vals[$index]);}
					$debugSql=preg_replace('/\?/','\''.$debugParams_vals[$index].'\'',$debugSql,1);
					$index++;
				}
			}
			$t=$this->debugParams;//php7可以直接在preg_replace_callback内部使用
			return preg_replace_callback('/:[0-9a-zA-Z_]+/i',function($m) use ($t){
				$v=$t[$m[0]];
				if($v===null){return 'NULL';}
				if(!is_numeric($v)){$v=addslashes($v);}
				return "'{$v}'";
			},$debugSql);
		}
        else {return 'no sql will return if undefind MYSQL_ERROR or MYSQL_ERROR!=true';}
    }
}

先贴上mysql的普通类

<?php
class mydb{
	private $Record=array();
	private $Link_ID=0;
	private $Query_ID=0;
	private $Db;
	function __construct($db){	
		$this->Db=$db;
        $this->Link_ID=0;
	}
	function connect(){
		if(!$this->Link_ID){
			$this->Link_ID=mysql_connect('localhost','root','123456');
			mysql_select_db($this->Db,$this->Link_ID);
			mysql_query("set names 'utf8'",$this->Link_ID);
		}
    }
	function insert_id(){
		$this->connect();
		return mysql_insert_id($this->Link_ID);
	}
	function query($sql){
		$this->connect();
		$this->Query_ID=mysql_query($sql);
		return $this->Query_ID?$this->Query_ID:0;
	}
	function next_record() {
		if(!$this->Query_ID) {return 0;}
		$this->Record=mysql_fetch_assoc($this->Query_ID);
		return is_array($this->Record)?$this->Record:0;
	}
	function query_first($sql){  
		if(!$this->query($sql)) {return 0;}
		$this->Record=mysql_fetch_assoc($this->Query_ID);
		return $this->Record;
	}
	function num_rows() {return mysql_num_rows($this->Query_ID);}
	function num_affected_rows() {return mysql_affected_rows();}
	function f($field) {return $this->Record[$field];}
}
?>

再贴上mysql pdo的类

<?php
/*
普通调用:
require 本类;
$mydb=new myDb($dbname);//$dbname为数据库名称
项目调用:
M()->query();//参考func/global.php中的function M();
*/
class myDb{
	private $Record=array();
	private $Link_ID=0;
	private $Query_ID=0;
	private $Db='';
	private $host=array();
	private $debugMode=false;
	private $debugParams=null;
    private $debugSql='';

	function __construct($db='',$host=array()){
		//判断是否允许debug
		if(defined('MYSQL_ERROR') && MYSQL_ERROR===true){
			$this->debugMode=true;
		}
		
		$this->Db=$db;
		$this->Link_ID=0;
		$this->host=$host;
		
		if(count($host)<=0){
			$configPath=dirname(dirname(__FILE__));
			$dbconfig=$configPath.'/config/global/db.php';
			if(is_file($dbconfig)){
				require_once $dbconfig;
				$this->host=$GLOBALS['dbHost']['default'];
			}
			else exit('undefind db');
		}
	}
	
	function connect(){
		if(!$this->Link_ID){
			try{
				$this->Link_ID=new PDO('mysql:host='.$this->host[0].';dbname='.$this->Db.';charset='.$this->host[3],$this->host[1],$this->host[2]);
				//查询mysql返回字段int变为String型解决方法
				$this->Link_ID->setAttribute(PDO::ATTR_STRINGIFY_FETCHES,false);
				$this->Link_ID->setAttribute(PDO::ATTR_EMULATE_PREPARES,false);
			}
			catch(PDOException $e){$this->Link_ID=0;die('mysql connect error...');}
			$this->Link_ID && $this->Link_ID->query('set names '.$this->host[3].';');
		}
	}
	
	function query($sql='',$params=array()){
		if($sql==''){return false;}
		$queryOK=true;
		$this->connect();
		if($this->debugMode===true){
			$this->debugSql=$sql;
			$this->debugParams=$params;
		}
        $PDOStatement=$this->Link_ID->prepare($sql,array(PDO::ATTR_CURSOR=>PDO::CURSOR_SCROLL));//返回 PDOStatement / False
		if(!$PDOStatement){
			$queryOK=false;
		}
		else {
			if(count($params)>0){
				//不能用$queryOK=$this->Query_ID->execute($params);如果有int类型会报错
                //应该用PDOStatement::bindValue()去绑定(注意: 不要用bindParam())
                foreach($params as $key=>$value){
                    $PDOStatement->bindValue(':'.$key,$value,$this->getPdoValueType($value));//类型需要判断
                }
			}
			$queryOK=$PDOStatement->execute();
		}
		if($queryOK===false && $this->debugMode===true){
			$this->queryError();
		}
        $this->Query_ID=$PDOStatement;
		return $queryOK;
	}
	
	function queryError(){
		$errorInfo=$this->Link_ID->errorInfo();
		if($errorInfo[2]!==null) {
			$debug_backtrace=debug_backtrace();
			$last_error_line=array('file' => __FILE__);
			while(__FILE__==$last_error_line['file']){
				$last_error_line=$debug_backtrace[0];
				array_shift($debug_backtrace);
			}
			echo '<br /><b>Mysql error</b>: '.$errorInfo[2].' <b>in '.$last_error_line['file'].':line '.$last_error_line['line'].'</b><br />';
		}
	}
	
	function getPdoValueType($value){
        if(is_int($value)){return PDO::PARAM_INT;}
        else if(is_null($value)){return PDO::PARAM_NULL;}
		else if(is_bool($value)){return PDO::PARAM_BOOL;}
		else{return PDO::PARAM_STR;}//string
    }
	
	//单条数据插入,$data为数组结构,比如array('title'=>$title,'content'=>$content)
	function insert($table,$data){
	    $arr_column=array_keys($data);
        return $this->query('insert into '.$table.'('.implode(',',$arr_column).')values('.(':'.implode(',:',$arr_column)).')',$data);
    }
	
	//单条数据插入,$data为数组结构,比如array('title'=>$title,'content'=>$content)
	function insert_get_id($table,$data){
	    $this->insert($table,$data);
	    return $this->insert_id();
    }

	function next_record(){
		if(!$this->Query_ID){return 0;}
		$this->Record=$this->Query_ID->fetch(PDO::FETCH_ASSOC, PDO::FETCH_ORI_NEXT);
		return is_array($this->Record)?$this->Record:0;
	}
	
	function query_all($sql='',$params=array()){
		if(!$this->query($sql,$params)){return array();}//不能直接return 0;否则当结果为零条的时候前端会出错
		$this->Record=$this->Query_ID->fetchAll(PDO::FETCH_ASSOC);
		return $this->Record;
	}
	
	function query_first($sql='',$params=array()){
		if(!$this->query($sql,$params)){return 0;}
		$this->Record=$this->Query_ID->fetch(PDO::FETCH_ASSOC);
		return $this->Record;
	}
	
	function insert_id(){$this->connect();return $this->Link_ID->lastInsertId();}

	function num_rows(){return count($this->Query_ID->fetchAll());}
	
	function num_affected_rows(){return $this->Query_ID->rowCount();}
	
	function f($field){return $this->Record[$field];}
	
	function beginTransaction(){$this->connect();$this->Link_ID->beginTransaction();}//开启事务
	
	function rollBack(){$this->connect();$this->Link_ID->rollBack();}//回滚事务
	
	function commit(){$this->connect();$this->Link_ID->commit();}//提交事务

	//打印sql语句($pdoAfter为false时候,打印pdo原型,比如:select * from table where ip=:ip
    function debugSql($pdoAfter=true){
		if($this->debugMode===true){
			if(!$pdoAfter){
				return $this->debugSql;
			}
			foreach($this->debugParams as $k=>$v){
				$this->debugParams[':'.ltrim($k,':')]=$v;
				unset($this->debugParams[ltrim($k,':')]);
			}
			$debugSql=$this->debugSql;
			$debugParams_vals=array_values($this->debugParams);
			$r=true;
			$index=0;
			while($r){
				$r=stristr($debugSql,'?');
				if(!empty($r)){
					empty($debugParams_vals[$index]) && $debugParams_vals[$index]='NULL';
					is_numeric($debugParams_vals[$index]) or $debugParams_vals[$index]=addslashes($debugParams_vals[$index]);
					$debugSql=preg_replace('/\?/','\''.$debugParams_vals[$index].'\'',$debugSql,1);
					$index++;
				}
			}
			$t=$this->debugParams;//php7可以直接在preg_replace_callback内部使用
			return preg_replace_callback('/:[0-9a-zA-Z_]+/i',function($m) use ($t){
				$v=$t[$m[0]];
				if($v===null){
					return 'NULL';
				}
				is_numeric($v) or $v=addslashes($v);
				return "'{$v}'";
			},$debugSql);
		}
        else {return 'no sql will return if undefind MYSQL_ERROR or MYSQL_ERROR!=true';}
    }
}
分类: mysql优化 标签: , ,

php生成不重复的随机字符串

2020年8月6日 没有评论

最近需要实现一个创建不重复订单号的功能,所以书写了一下简单的php代码,基本上可以实现php创建不重复的随机字符串(未考虑多台服务器分布执行,本代码只考虑单台服务器执行),不能保证100%不重复,但是经过实践,1亿条都为出现重复(也没有考虑高并发的情况下),仅供大家参考。

贴出代码:

class createOurOrderNum{
		
		var $dict='0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz*!';
		var $short64='^';//转为64进制后不足指定长度的补足字符串
		
		/*
		1,本class只适合在64位系统+64位php软件环境下进行,否则decb64和b64dec会无法正确互相转换
		2,满足1的条件下,本class只适合转换小于9223372036854775807的数字
		3,不要满足1的条件下,本class只适合转换小于2147483647的数字
		4,本class中的createNum()函数中decb64转换的是12位长度数字(即最大999999999)
		*/
		
		/*
		//将64进制转换为10进制
		function b64dec($b64){
			$dec=0;
			$len=strlen($b64);
			for($i=0;$i<$len;$i++){
				$b=strpos($this->dict,$b64[$i]);
				$j=$len-$i-1;
				$dec+=($j==0?$b:(2<<(6*$j-1))*$b);
			}
			return $dec;
		}
		
		//如何根据已经生成的订单号来解密获得时间戳和微秒
		function getNumberMicrotime($num){
			//将订单号前8位日期获取到
			$ymd=substr($num,0,8);
			//截取订单号最后8位,再将8位中的补足字符串全部替换为空,获得64进制
			$str64=str_replace($this->short64,'',substr($num,strlen($num)-8));
			//将64进制转为10进制
			$str10=$this->b64dec($str64);
			//将$ymd转为时间戳,然后截取前4位,再截取$str10前6位,则为订单号创建的时间戳
			$times[0]=substr(strtotime($ymd),0,4).substr($str10,0,6);
			//截取$str10后6位则为微秒数
			$time[1]=substr($str10,6);
			return $times[0].'.'.$time[1];
		}
		*/
		
		//将10进制转换为64进制
		function decb64($dec){
			$b64='';
			do{
				$b64=$this->dict[($dec%64)].$b64;
				$dec/=64;
			}
			while($dec>=1);
			return $b64;
		}
		function createNum(){
			$time=explode(' ',microtime());
			
			//利用时间戳+毫秒数+随机数,hash加密之后,来通过uniqid创建基本不重复的种子			
			$seed=uniqid(hash('sha1',$time[1].$time[0].mt_rand()),true);
			//再将种子+随机数+随机英文或数组,加密之后,取16位md5值
			$name=substr(md5($seed.mt_rand().substr('0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ',(mt_rand(0,61)),1)),8,16);

			//同一天最大毫秒数为86400,所以时间戳最后6位(86400是5位)不会重复,所以我们可以去除前4位
			//然后加上毫秒来转换为64进制(6+6位返回的是7位长度64进制)
			//最大值应该是decb64('999999999999')='EZKfG==';
			$name64=$this->decb64(substr($time[1],4).sprintf('%06u',substr($time[0],2,6)));

			//12位数字转为64进制之后有可能是8位长度(不排除),所以$name转为64进制之后的不足8位长度要补足(保持长度一致)
			$nameLen=strlen($name64);
			if($nameLen<8){
				$buzu='';
				for($i=0;$i<(8-$nameLen);$i++){$buzu.=$this->short64;}
				$name64=$buzu.$name64;
			}
			else {
				//如果大于8则截取,基本情况不会出现
				$name64=substr($name64,0,8);
			}
			//要以$time[1]为时间戳转换Ymd
			return date('Ymd',$time[1]).$name.$name64;
		}
	}

php调用方法:

$createOurOrderNum=new createOurOrderNum();
$no=$createOurOrderNum->createNum();
echo 'order numer:'.$no;
echo '<br />';
echo 'order number timestamp:'.$createOurOrderNum->getNumberMicrotime($no);

以上就是利用php创建不重复的随机字符串,可以用来用作图片保存(文件名)或者创建订单号。

css.php