centos7 安装php7+mysql5.7+nginx+redis

1.先修改yum源  https://webtatic.com

rpm -Uvh https://dl.fedoraproject.org/pub/epel/epel-release-latest-7.noarch.rpm
rpm -Uvh https://mirror.webtatic.com/yum/el7/webtatic-release.rpm
rpm -Uvh  http://dev.mysql.com/get/mysql57-community-release-el7-9.noarch.rpm

2.安装nginx 继续阅读“centos7 安装php7+mysql5.7+nginx+redis”

PHP 7 编译安装 cannot stat ‘phar.phar’: No such file or directory

PHP 出来了应该尝尝鲜, 结果编译没问题, 安装的时候报了如下错误

cp -pR -f phar.phar /usr/local/php7/bin/phar
cp: cannot stat 'phar.phar': No such file or directory
make: *** [install-pharcmd] Error 1

解决方法很简单:

find . -name 'phar.phar'

找到 phar.phar 文件, 移动或者复制到安装指令执行的目录下就行了.

最后附上, 完成后的执行指令:

php5vsphp7

session和cookie区别,多台WEB服务器如何共享session,禁用COOKIE后SESSION是否可用,为什么?

答:session的运行机制:

用户A访问站点Y,如果站点Y指定了session_start();(以下假设session_start()总是存在)那么会产生一个session_id,这个session_id一般会以COOKIE的形式保存到用户A(我们可以通过在php.ini里设置session.use_only_cookies为1,强制SESSIONID必须以COOKIE专递。)。这时候SESSIONID表现为$_COOKIE[‘PHPSESSID’];(PHPSESSID可用session_name()函数来下修改)

用户A接着访问,这个session id($_COOKID[‘PHPSESSID’])就会在A每次访问Y的时候传送到站点Y。

在站点Y上,会有这么一个目录,是用来保存SESSION的实际数据的。站点Y接收到sessionid,然后通过session id,来获得与SESSION数据的关联,并返回SESSION数据。

答:session与cookie的区别:

SESSION存储在服务器端,用户无法进行修改,相对比较安全,COOKIE存储在客户端,用户通过手段可以进行修改,相对不安全。

Session会在一定时间内保存在服务器上,当访问增多,会比较占用服务器资源。

单个cookie在客户端的限制是3k,就是说一个站点在客户端存放的COOKIE不能超过3k。

答:多台服务器如何共享SESSION:

共享就是每台服务器公用一个,那显然要把这个session专门放到一个地方
比如存数据库,每台服务器都调这个数据库里的session
存memcache 一样的原理

答:可以,但是需要在传值的时候将Session_id写到URL中;因为禁用以后再传递参数的时候会以网址的形式参数接到后面传过去!

PHP语法检查工具

PHP Mess Detector(http://phpmd.org/)

PHP项目体检工具,根据你设定的标准(如单一文件代码体积,未使用的参数个数,未使用的方法数)检查PHP代码,超出设定的标准时报警。

PHP Copy Paste Detector(https://github.com/sebastianbergmann/…)

顾名思义,检查冗余代码的

PHP Dead Code Detector(https://github.com/sebastianbergmann/…)

看名字就知道了,检查从未被调用过的方法

PHP Code Sniffer(http://pear.php.net/package/PHP_CodeS…)

老牌代码格式化工具,PHP写的,Pear包,可自己hack,可集成到命令行里。我一直用的PHP Code Beautifier,只有Windows GUI,Windows CMD很难用,已经打算跳槽到PHP CS了

你还可以用jenkins把上述工具以plugins形式整合起来,做持续集成:http://jenkins-php.org/

你还可以用xinc+phing跟上述工具集成起来做持续集成后的自动化打包发布:http://code.google.com/p/xinc/

 

https://segmentfault.com/q/1010000000119048

PHP抽奖概率算法


/*
* 不同概率的抽奖原理就是把0到*(比重总数)的区间分块
* 分块的依据是物品占整个的比重,再根据随机数种子来产生0-* 中的某个数
* 判断这个数是落在哪个区间上,区间对应的就是抽到的那个物品。
* 随机数理论上是概率均等的,那么相应的区间所含数的多少就体现了抽奖物品概率的不同。
*/
function get_rand($proArr)
{
$result = array();
foreach ($proArr as $key => $val) {
$arr[$key] = $val['v'];
}
$proSum = array_sum($arr); // 计算总权重
$randNum = mt_rand(1, $proSum);
$d1 = 0;
$d2 = 0;
for ($i=0; $i < count($arr); $i++) { $d2 += $arr[$i]; if($i==0) { $d1 = 0; } else { $d1 += $arr[$i-1]; } if($randNum >= $d1 && $randNum <= $d2) { $result = $proArr[$i]; } } unset ($arr); return $result; } /* * 使用较多的为这个方法 */ function get_rand1($proArr) { $result = array(); foreach ($proArr as $key => $val) {
$arr[$key] = $val['v'];
}
// 概率数组的总概率
$proSum = array_sum($arr);
asort($arr);
// 概率数组循环
foreach ($arr as $k => $v) {
$randNum = mt_rand(1, $proSum);
if ($randNum <= $v) { $result = $proArr[$k]; break; } else { $proSum -= $v; } } return $result; } /* * 奖项数组 * 奖品id,名称,比重 */ $arr = array( array('id'=>1,'name'=>'特等奖','v'=>1),
array('id'=>2,'name'=>'一等奖','v'=>5),
array('id'=>3,'name'=>'二等奖','v'=>10),
array('id'=>4,'name'=>'三等奖','v'=>12),
array('id'=>5,'name'=>'四等奖','v'=>22),
array('id'=>6,'name'=>'没中奖','v'=>50)
);

测试结果(10000次):
get_rand():
count_1:0 count_2:490 count_3:1021 count_4:1172 count_5:2172 count_6:5145
特等奖中奖率全为:0
get_rand1():
count_1:92 count_2:477 count_3:1017 count_4:1195 count_5:2264 count_6:4955
总体感觉 get_rand1() 更准确些……

5分钟快速实现一个哈希表(Clang)

哈希表(Hash table,也叫散列表),是根据键(Key)而直接访问在内存存储位置的数据结构。 也就是说,它通过计算一个关于键值的函数,将所需查询的数据映射到表中一个位置来访问记录,这加快了查找速度。 这个映射函数称做散列函数,存放记录的数组称做散列表。 ————维基百科

在一些合理的假设下,在哈希表中的所有操作的时间复杂度可以简单看作O(1) 。它通过计算一个键的哈希值来快速定位键值在哈希表的位置。 实现一个好的哈希表的关键是一个好的哈希算法与一个处理哈希冲突的方法 。常见的简单哈希算法有BKDRHash,APHash,DJBHash,JSHash,RSHash.较复杂有MD5和SHA1之流。哈希算法的好坏直接影响哈希表存取的效率。 而处理哈希冲突的办法有开放寻址法与拉链法。下面示例使用的是拉链法

BKDRHash哈希算法

上述多个哈希算法中 BKDRHash在效率,平衡,均匀分布方面表现突出,并且它的实现也是最容易理解与记忆的。实现如下:

/**  * BKDR hash function in clang * @param key char* 字符串 * @return int hashed value, we will get a int value */int bkdrHash( char *key ){    uint seed = 131;//i can be 13, 131, 1313,131313 etc    uint hash = 0;    while( *key != ‘\n’ && *key != 0 )    {            hash = hash * seed + ( *key++ );    }    return ( hash & 0x7FFFFFFF );}

哈希表(拉链法处理冲突)

示意图:(图片来源:http://blog.csdn.net/v_JULY_v/article/details/6256463)

上图中,左则是一个数组,保存的是每个单向链表的头指针。实际的值就存储在链表中

单向链表中的节点的数据结构与数组定义代码

/** 单向链表的节点的结构体 */typedef struct _htItem{        struct _htItem  *next;        char *key_string;        uint fid;} htItem;/** 取得Key在数组中的映射位置 */uint htIndex( char *key, htItem **ht ){        uint hashedKey = bkdrHash( key );        uint length = (ht[0]->fid-1);        return (uint)hashedKey % length+1;}/** 定义数组 */htItem *item[21]; //为方便后台实现,在定义在数组的时候,我们给多一个长度,第一个数据不存储数据,只存放数组长度,剩余的元素空间

初始化数组元素

/** 有必要对数组元素进行一次0 初始化 */void htInit( htItem **ht, uint length ){         int i;         for( i=0; i<length; i++ ){                 ht[i] = (htItem*)malloc(sizeof(htItem));                  memset( ht[i], 0, sizeof(htItem) );         }         ht[0]->fid = length;}

数据的插入和更新

首先通过哈希函数找到Key对应在数组中的位置,再遍历链表,如果在链表中查到相同的key,就直接把该节点的数据更新,否则malloC一个节点,并把节点放到链表末尾。

/** set hashTable element */uint htSet( char *key, uint fid,  htItem **ht ){         uint i = htIndex( key, ht );         htItem *item = ht[i];         while( item->next )         {                  if( strcmp(key, item->next->key_string) == 0 ){                          item->next->fid = fid;                          return 0;                 }else{                          item = item->next;                 }         }         item->next = (htItem*)malloc(sizeof(htItem));         item->next->fid = fid;         item->next->key_string = key;         return 0;}

获取数据

首先通过哈希函数定位KEY在数组中的位置,再依次对比KEY值,如果命中就返回相应的值,否则返回空值

/** get hashTable elements */htItem* htGet( char *key, htItem **ht ){        uint i = htIndex( key, ht);        htItem *item = ht[i]->next;         htItem *tmp = (htItem*)malloc(sizeof(htItem));         memset(tmp, 0, sizeof(htItem));        while( item )        {                if( strcmp(key, item->key_string) == 0 ){                          printf(“hiting %s\n”, key);                          tmp->fid = item->fid;                          tmp->key_string = item->key_string;                        return tmp;                }                 item = item->next;        }        return;}

删除数据

/** delete one element of hashtable */int htDel(char *key, htItem **ht){        uint i = htIndex(key, ht);        htItem *item = ht[i];        while(item->next){                if(strcmp(key, item->next->key_string) == 0 ){                        htItem *tmp = item->next;                        item->next = tmp->next;                        free(tmp);                        return 0;                }                item = item->next;        }        return -1;}

打印完整hashtable中的元素

void print_hashTable( htItem **ht ){        uint length = ht[0]->fid;        uint i;        htItem *item;        for( i = 1; i < length; i++ )        {                item = ht[i]->next;                while(item)                {                        printf(“%s => %d\n”,item->key_string, item->fid);                        item = item->next;                }        }}

简单几个方法就实现了哈希表的增删查改。

使用示例

/** 定义与初始化 */    htItem *item[101];          htInit(item, 101);                  /** 添加元素 */         htSet(“longmon”,100,item);          htSet(“natalie”, 1000,item);         htSet(“xiaoqiong”,99, item);                  /** 打印 */         print_hashTable(item);                  /** 删除一个元素 */         htDel(“natalie”, item);                  /** 打印 */         print_hashTable(item);                  /** 获取keylongmon的值 */         htItem *tmpitem = htGet(“longmon”, item);                   /** 打印 */         printf(“key: %s => val:%d\n”, tmpitem->key_string, tmpitem->fid);

输出结果

#打印 xiaoqiong => 99natalie => 1000longmon => 100#打印 xiaoqiong => 99longmon => 100#打印 Key: longmon => val: 100

完整代码 https://github.com/longmon/hashTable_in_c

哈希表是PHP内核的基石。

PHP内核中的哈希表是十分重要的数据结构,PHP的大部分的语言特性都是基于哈希表实现的, 例如:变量的作用域、函数表、类的属性、方法等,Zend引擎内部的很多数据都是保存在哈希表中的。而PHP内核中的哈希表处理冲突使用的也是拉链法。

扩展阅读:

centOS和unbutu下安装php-ssh2扩展

centOS和unbutu下安装php-ssh2扩展的方法大致相同,但要繁琐一些。

1.安装支持的库文件

命令:yum install  php-devel php-pear libssh2 libssh2-devel

2.建立ssh2扩展

命令:pecl install -f ssh2

之后会显示安装的日志,需要选择时直接按回车键就好

3.安装成功后,需要修改ssh2.ini

[root@wcc etc]# touch /etc/php.d/ssh2.ini

[root@wcc etc]# echo extension=ssh2.so > /etc/php.d/ssh2.ini

可以用vim打开/etc/php.d/ssh2.ini 确认是否已经包含extension=ssh2.so

4.验证是否安装成功

php -m | grep ssh2

显示ssh2则表示安装成功