邢栋博客

邢栋博客,Action博客,记录工作和生活中的点点滴滴

关于php的JIT

关于php的JIT
php是解释执行的,它的编译过程是属于动态编译,也就是在运行的时候进行编译,与之相对的事运行前编译的静态编译。动态编译与静态编译除了编译时机的不同,还有一个不同之的地方,那就是静态编译是将代码编译成了机器指令,而动态编译并没有编译为机器指令,而是编译成了解释器可识别的指令。即时编译,即just-in-time complication,简称JIT。JIT是动态编译中的一种技术,简单的讲,就是在某段代码第一次执行前进行编译,所以称为即时编译。


与解释执行不同的事,JIT是将源代码编译为机器指令执行,但JIT又与静态编译不同,它是在运行时实时进行的编译,而且JIT并不会把所有代码全部编译为机器码,它只会编译频繁执行的代码。说JIT比解释快,其实说的是"执行编译后的代码"比"解释器解释执行"要快,并不是说编译比解释的过程快,而且JIT编译通常比解释执行要慢一些,如果对执行一次的代码进行即时编译,其效率反而要比解释执行慢,JIT之所以快是因为多次执行抵消了编译所占的世界,显得平均效果高而已。

php的mcrypt加密类
<?php
    class McryptModel
    {
        protected $td = '';
        protected $iv = '';
        protected $key = '';
        private static $instance = null;

        private function __construct($cipher,$mode,$key)
        {
            $this->cipher = $cipher;
            $this->mode = $mode;
            $this->key = $key;
        }

        public static function getInstance($cipher=MCRYPT_RIJNDAEL_128,$mode=MCRYPT_MODE_CBC,$key='xingdong365')
        {
            if(self::$instance === null){
                self::$instance = new self($cipher,$mode,$key);
            }
            return self::$instance;
        }

        public function encrypt($str)
        {
            $td = mcrypt_module_open($this->cipher,'',$this->mode,'');//打开算法模块
            $this->td = $td;
            $iv_size = mcrypt_enc_get_iv_size($td);//获取向量大小
            $iv = mcrypt_create_iv($iv_size,MCRYPT_RAND);//初始化向量
            $this->iv = $iv;
            $num = mcrypt_generic_init($td,$this->key,$iv);//初始化加密空间
            $encrypt = mcrypt_generic($td,$str);//执行加密
            mcrypt_generic_deinit($td);//结束加密,执行清理工作
            return base64_encode($encrypt);
        }

        public function decrypt($str)
        {
            $str = base64_decode($str);
            $td = $this->td;
            mcrypt_generic_init($td,$this->key,$this->iv);
            $decrypt = mdecrypt_generic($td,$str);
            mcrypt_generic_deinit($td);
            mcrypt_module_close($td);//关闭算法模块
            return $decrypt;
        }
    }

    $m = McryptModel::getInstance();
    echo $e = $m->encrypt('hello');
    echo "<hr>";
    echo $m->decrypt($e);

    //des加密
    function des_encrypt($encrypt, $key='xingdong365'){
        $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_DES,MCRYPT_MODE_ECB),MCRYPT_RAND);
        $passcrypt = mcrypt_encrypt(MCRYPT_DES ,$key, $encrypt, MCRYPT_MODE_ECB, $iv);
        $resturn = base64_encode($passcrypt);
        return $resturn;
    }

    //des解密
    function des_decrypt($decrypt, $key='xingdong365'){
        $decoded = base64_decode($decrypt);
        $iv = mcrypt_create_iv(mcrypt_get_iv_size(MCRYPT_DES,MCRYPT_MODE_ECB),MCRYPT_RAND);
        $resturn = mcrypt_decrypt(MCRYPT_DES ,$key, $decoded, MCRYPT_MODE_ECB, $iv);
        return $resturn;
    }
php使用redis替换文件存储session(session_set_save_handler)
<?php
class MySessionHandler implements SessionHandlerInterface
{
    private $redis;
    private $sessionsavepath;
    private $sessionname;
    public function __construct()
    {
        $this->redis = new Redis();
        $this->redis->connect('127.0.0.1',6379);
    }
    public function close()
    {
        return true;
    }
    public function destroy($session_id)
    {
        if($this->redis->delete($session_id)){
            return true;
        }
        return false;
    }
    public function gc($maxlifetime)
    {
        return true;
    }
    public function open($sessionsavepath, $name)
    {
        return true;
    }
    public function read($session_id)
    {
        if($value = $this->redis->get($session_id)){
            return $value;
        }else{
            return false;
        }
    }
    public function write($session_id, $session_data)
    {
        if($this->redis->set($session_id,$session_data,60)){
            return true;
        }else{
            return false;
        }
    }

}

$handler = new MySessionHandler();
session_set_save_handler($handler, true);
session_start();

//$_SESSION['sess_name'] = 'xd';
var_dump($_SESSION);
php生成随机验证码
<?php
    function getVerifyCode($num){
        $content = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
        $content = str_shuffle($content);
        return substr($content,-$num);
    }

    echo getVerifyCode(4);
php运行机制和原理

php由内核Zend引擎和扩展成组成,php内核负责处理请求、完成文件流错误处理等操作,Zend引擎可以将php程序文件转换成可以在虚拟机上运行的机器语言,扩展层提供一些应用层操作需要的函数类库等,比如数组和mysql数据库的操作等。

Zend引擎是用C语言实现的,将php代码通过词法语法解析成可执行的Opcode并实现相应的处理方法和基本的数据结构进行内存分配和管理等,对外提供相应的可供调用的API方法。Zend引擎是php的核心,所有的外围功能都是围绕他实现的。扩展层通过组件的方式提供各种基础服务、内置函数,标准库都是通过它来实现的。用户也可以编写自己的扩展来实现特定的需求。服务端应用编写接口(Server Application Programming Interface,SAPI),通过一系列钩子函数使得php可以和外围交互数据。我们平时编写的php程序就是通过不同的SAPI方式得到不同的应用模式,如通过WebServer实现的Web应用和在命令行下运行的脚本等。

一段php程序被执行的时候会被解析成opcode命令,然后在虚拟机中按照顺序执行,由于php本身是C语言开发的,所以在执行的时候调用的都是C的函数。Opcode是php程序执行的基本单位。


thinkphp的nginx重写兼容配置
 if (!-e $request_filename) {
 rewrite ^/index.php(.*)$ /index.php?s=$1 last;
 rewrite ^(.*)$ /index.php?s=$1 last;
 break;
 }
php利用二叉堆算法来实现 TopK

利用二叉堆算法来实现 TopK
实现流程是:
1、先读取10个或100个数到数组里面,这就是我们的topK数.
2、调用生成小顶堆函数,把这个数组生成一个小顶堆结构,这个时候堆顶一定是最小的.
3、从文件或者数组依次遍历剩余的所有数.
4、每遍历出来一个则跟堆顶的元素进行大小比较,如果小于堆顶元素则抛弃,如果大于堆顶元素则替换之.
5、跟堆顶元素替换完毕之后,在调用生成小顶堆函数继续生成小顶堆,因为需要再找出来一个最小的.
6、重复以上4~5步骤,这样当全部遍历完毕之后,我们这个小顶堆里面的就是最大的topK,因为我们的小顶堆永远都是排除最小的留下最大的,而且这个调整小顶堆速度也很快,只是相对调整下,只要保证根节点小于左右节点就可以.
7、算法复杂度的话按top10最坏的情况下,就是每遍历一个数,如果跟堆顶进行替换,需要调整10次的情况,也要比排序速度快,而且也不是把所有的内容全部读入内存,可以理解成就是一次线性遍历.


<?php
	//为了测试运行内存调大一点
	ini_set('memory_limit', '2024M');
	//生成小顶堆函数
	function Heap(&$arr,$idx){
	    $left  = ($idx << 1) + 1;
	    $right = ($idx << 1) + 2;

	    if (!isset($arr[$left])){
	        return;
	    }
	    if(isset($arr[$right]) && $arr[$right] < $arr[$left]){
	        $l = $right;
	    }else{
	        $l = $left;
	    }

	    if ($arr[$idx] > $arr[$l]){
	         $tmp = $arr[$idx]; 
	         $arr[$idx] = $arr[$l];
	         $arr[$l] = $tmp;
	         Heap($arr,$l);
	    }
	}

	/*
	  当然这个数据集并不一定全放在内存,也可以在
	  文件里面,因为我们并不是全部加载到内存去进
	  行排序
	*/
	for($i=0;$i<500000;$i++){
	    $numArr[] = $i;    
	}
	//打乱它们
	shuffle($numArr);
	//先取出10个到数组
	$topArr = array_slice($numArr,0,10);
	//获取最后一个有子节点的索引位置
	//因为在构造小顶堆的时候是从最后一个有左或右节点的位置
	//开始从下往上不断的进行移动构造(具体可看上面的图去理解)
	$idx = floor(count($topArr) / 2) - 1;
	//生成小顶堆
	for($i=$idx;$i>=0;$i--){
	    Heap($topArr,$i);
	}

	echo time()."<hr/>";
	//这里可以看到,就是开始遍历剩下的所有元素
	for($i = count($topArr); $i < count($numArr); $i++){
	    //每遍历一个则跟堆顶元素进行比较大小
	    if ($numArr[$i] > $topArr[0]){
	        //如果大于堆顶元素则替换
	        $topArr[0] = $numArr[$i];
	        /*
	          重新调用生成小顶堆函数进行维护,只不过这次是从堆顶
	          的索引位置开始自上往下进行维护,因为我们只是把堆顶
	          的元素给替换掉了而其余的还是按照根节点小于左右节点
	          的顺序摆放这也就是我们上面说的,只是相对调整下,并
	          不是全部调整一遍
	        */
	        Heap($topArr,0);
	    }
	}
	echo "<hr/>";
	var_dump($topArr);
	echo "<hr/>".time()."<hr>";


源文链接:简书  http://www.jianshu.com/p/df71c71cdc57 

php使用openssl_random_pseudo_bytes生成安全的随机数

需要安装openssl扩展,openssl_random_pseudo_bytes


function getRandomString($length = 6)
{
        /*
         * Use OpenSSL (if available)
         */
        if (function_exists('openssl_random_pseudo_bytes')) {
            $bytes = openssl_random_pseudo_bytes($length * 2);

            if ($bytes === false)
                throw new RuntimeException('Unable to generate a random string');

            return substr(str_replace(['/', '+', '='], '', base64_encode($bytes)), 0, $length);
        }

        $pool = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';

        return substr(str_shuffle(str_repeat($pool, 5)), 0, $length);
}



优惠券
广告位-淘宝
最新微语