php中单元测试安装phpunit(win+linux)

要获取 PHPUnit,最简单的方法是下载 PHPUnit 的 PHP 档案包 (PHAR),它将 PHPUnit 所需要的所有必要组件(以及某些可选组件)捆绑在单个文件中:

要使用 PHP档案包(PHAR)需要有 phar 扩展。

要使用 PHAR 的 --self-update 功能需要有 openssl 扩展。

如果启用了 Suhosin 扩展,需要在 php.ini 中允许执行 PHAR:

suhosin.executor.include.whitelist = phar

如果要全局安装 PHAR:

$ wget https://phar.phpunit.de/phpunit.phar
$ chmod +x phpunit.phar
$ sudo mv phpunit.phar /usr/local/bin/phpunit
$ phpunit --version
PHPUnit x.y.z by Sebastian Bergmann and contributors.

也可以直接使用下载的 PHAR 文件:

$ wget https://phar.phpunit.de/phpunit.phar
$ php phpunit.phar --version
PHPUnit x.y.z by Sebastian Bergmann and contributors.

Windows

整体上说,在 Windows 下安装 PHAR 和手工在 Windows 下安装 Composer 是一样的过程:

  1. 为 PHP 的二进制可执行文件建立一个目录,例如 C:\bin
  2. ;C:\bin 附加到 PATH 环境变量中(相关帮助
  3. 下载 https://phar.phpunit.de/phpunit.phar 并将文件保存到 C:\bin\phpunit.phar
  4. 打开命令行(例如,按 Windows+R » 输入 cmd » ENTER)
  5. 建立外包覆批处理脚本(最后得到 C:\bin\phpunit.cmd):
    C:\Users\username>cd C:\binC:\bin>echo @php "%~dp0phpunit.phar" %* > phpunit.cmdC:\bin>exit
  6. 新开一个命令行窗口,确认一下可以在任意路径下执行 PHPUnit:
    C:\Users\username>phpunit --versionPHPUnit x.y.z by Sebastian Bergmann and contributors.

phpunit官方中文手册

https://phpunit.de/manual/current/zh_cn/installation.html

下载地址:https://phar.phpunit.de/

PHP数组、函数、字符串的常识

php数组排序

sort()根据数组所包含元素进行升序排列

sort()函数是区分大小写。所有大写字母都在小写字母后面。
asort()函数和ksort()函数对关联数组排序

例如:$a=array(‘name’=>100,’user’=>200,’title’=>300);

函数asort()是根据数组$a的每个元素值进行排序。在数组$a中元素值为数字。
函数ksort()是按数组的关键字按字母顺序排列。
数组反向排序

函数rsort()将一个一维数字索引数组按降序排列

函数arsort()将一个一维关联数组按每个元素值的降序排序。

函数krsort()将根据数组元素的关键字将一维数组按照降序排列。
对数组进行重新排序

函数shuffle()将数组各元素进行随机排序。

函数array_reverse()给出一个原来数组的反向排序。
数组中浏览排序

函数prev()将一维数组降序排列。

函数each()在指针前移一个位置之前返回当前元素(即,返回当前元素的同时,输出一个数组)。

函数next()是将指针前移,然后再返回新的当前元素(即,返回当前元素)。

函数array_walk()以相同的方式使用或者修改数组中的每一个元素。
统计元素个数

函数array_count_values()统计每个特定的值在数组中出现过的次数。会返回一个包含频率的关联数组。

函数count()和sizeof()用法相同。
函数extract()可以把一个非数字索引数组,且该数组又有许多关键字值对,便可以转换成一系列的标量变量。
输出函数

echo和print都是将字符串输出到浏览器,但print()有返回值true或false

printf()函数是将一个格式化的字符串输出到浏览器

sprintf()函数是返回一个格式化的字符串。

分割函数

explode()函数根据一个指定的分隔符字符串将字符串本身分割为小块,将分割后的小块返回到一个数组中。

implode()函数(别名join)返回由数组元素组合成的字符串。

strtok()函数是一次只从字符串中取出一些片段。

substr()函数是获取一个字符串给定起点和终点的间字符串。
改变字符串中字母大小写

strtoupper()函数将字符串转换为大写。

strtolower()函数将字符串转换成小写。

ucfirst()函数把字符串第一个字符是字母,就将该字符串第一个字母转换成大写。

ucwords()函数将字符串每个单词的第一个字母转换成大写。
字符串比较

strcmp(str1, str2)函数,如果两个字符串相等就返回0,如果按字典顺序str1在str2后面(大于str2)就返回一个正数,
如果str1小于str2就返回一个负数。

strcasecmp()函数除了不区分大小写,其他和strcmp()一样。

strnatcmp()函数除了不区分大小写,其他和strcmp()一样,当时strnatcmp()函数将按自然排序比较字符串。

strlen()函数检查字符串的长度。
在字符串中查找字符串

strstr()函数是在一个较长的字符串中查找匹配的字符串或字符。

strchr()函数和strstr()函数一样。

stristr()函数和strstr()函数一样,只是不区分字符大小写。

strrchr()函数和strstr()函数一样,但会从最后出现目标关键字的位置的前面返回被搜索字符串。
查找字符串的位置

strpos()函数返回目标关键字子字符串在被搜索字符串中的位置。strpos()函数比strstr()函数运行速度快。

strrpos()函数返回的是被搜索字符串中最后一次出现目标关键字子字符串的位置。

如果不存在返回false
替换字符串

mixed str_replace(mixed needle, mixed new_needle, mixed haystack[, int & count]);把字符串的一部分替换为另一个字符串

neddle需要处理的字符串,new_needle需要插入的字符串,haystack字符串开始位置,起始位置为0,count执行的替换操作次数。

substr_replace()函数用来在给定位置中查找和替换字符串中特定的子字符串。

PHP算法和递归

<?php
header(“Content-Type:text/html;charset=utf-8”);
$arr=array(1,12,53,14,5,16,7,18,91,10,11,120);
//冒泡排序 小数往前放,大数往后放
function getpao($arr)
{
$len=count($arr);
//设置一个空数组 用来接收冒出来的泡
//该层循环控制 需要冒泡的轮数
for($i=1;$i<$len;$i++)
{ //该层循环用来控制每轮 冒出一个数 需要比较的次数
for($k=0;$k<$len-$i;$k++)
{
if($arr[$k]>$arr[$k+1])
{
$tmp=$arr[$k+1];
$arr[$k+1]=$arr[$k];
$arr[$k]=$tmp;
}
}
}
return $arr;
}
//选择排序
/* 每一趟从待排序的数据元素中选出最小(或最大)的一个元素,
顺序放在已排好序的数列的最后,直到全部待排序的数据元素排完。 选择排序是不稳定的排序方法 */
function select_sort($arr){
for($i=0,$len=count($arr);$i<$len-1;$i++){
//假设最小值位置
$p=$i;
//当前都和那些元素比较,$i后面的元素
for($j=$i+1;$j<$len;$j++){
if($arr[$p]>$arr[$j]){
//比较发现更小的,记录最小值位置,并且在在下次比较时
$p=$j;
}
}
//已确定最小值的位置,保存到$p中
if($p != $i){
$tmp=$arr[$p];
$arr[$p]=$arr[$i];
$arr[$i]=$tmp;
}
}
return $arr;
}
//插入排序
/* 从第一个元素开始,该元素可以认为已经被排序
取出下一个元素,在已经排序的元素序列中从后向前扫描
如果该元素(已排序)大于新元素,将该元素移到下一位置
重复步骤3,直到找到已排序的元素小于或者等于新元素的位置
将新元素插入到下一位置中 */
function insert_sort($arr) {
//区分 哪部分是已经排序好的
//哪部分是没有排序的
//找到其中一个需要排序的元素
//这个元素 就是从第二个元素开始,到最后一个元素都是这个需要排序的元素
//利用循环就可以标志出来
//i循环控制 每次需要插入的元素,一旦需要插入的元素控制好了,
//间接已经将数组分成了2部分,下标小于当前的(左边的),是排序好的序列
for($i=1, $len=count($arr); $i<$len; $i++) {
//获得当前需要比较的元素值。
$tmp = $arr[$i];
//内层循环控制 比较 并 插入
for($j=$i-1;$j>=0;$j–) {
//$arr[$i];//需要插入的元素; $arr[$j];//需要比较的元素
if($tmp < $arr[$j]) {
//发现插入的元素要小,交换位置
//将后边的元素与前面的元素互换
$arr[$j+1] = $arr[$j];
//将前面的数设置为 当前需要交换的数
$arr[$j] = $tmp;
} else {
//如果碰到不需要移动的元素
//由于是已经排序好是数组,则前面的就不需要再次比较了。
break;
}
}
}
//将这个元素 插入到已经排序好的序列内。
//返回
return $arr;
}
//快速排序法 对冒泡排序的一种改进
/* 通过一趟排序将要排序的数据分割成独立的两部分,
其中一部分的所有数据都比另外一部分的所有数据都要小,然后再按此方法对这两部分数据分别进行快速排序,
整个排序过程可以递归进行,以此达到整个数据变成有序序列 */
function quick_sort($arr) {
//先判断是否需要继续进行
$length = count($arr);
if($length <= 1) {
return $arr;
}
//如果没有返回,说明数组内的元素个数 多余1个,需要排序
//选择一个标尺
//选择第一个元素
$base_num = $arr[0];
//遍历 除了标尺外的所有元素,按照大小关系放入两个数组内
//初始化两个数组
$left_array = array();//小于标尺的
$right_array = array();//大于标尺的
for($i=1; $i<$length; $i++) {
if($base_num > $arr[$i]) {
//放入左边数组
$left_array[] = $arr[$i];
} else {
//放入右边
$right_array[] = $arr[$i];
}
}
//再分别对 左边 和 右边的数组进行相同的排序处理方式
//递归调用这个函数,并记录结果
$left_array = quick_sort($left_array);
$right_array = quick_sort($right_array);
//合并左边 标尺 右边
return array_merge($left_array, array($base_num), $right_array);
}

print_r($arr);
echo “<br />冒泡”;
print_r(array_reverse($arr));
echo “<br />冒泡排序”;
print_r(getpao($arr));
echo “<br />选择排序”;
print_r(select_sort($arr));
echo “<br />插入排序”;
print_r(insert_sort($arr));
echo “<br />快速排序”;
print_r(quick_sort($arr));
echo “<br />”;

// 递归 函数自身调用自身,但必须在调用自身前有条件判断,否则无限无限调用下去
function test($a=0,&$result=array()){
// global $result;
$a++;
if($a<10){
$result[]=$a;
test($a,$result);
}
return $result;
}
print_r(test());
echo “<br />”;
//递归 利用全局变量
function test($a=0,$result=array()){
global $result;
$a++;
if ($a<10) {
$result[]=$a;
test($a,$result);
}
return $result;
}
//递归 利用静态变量 递归函数间作为“桥梁”的变量利用static进行初始化,每一次递归都会保留”桥梁变量”的值。
function test($a=0){
static $result=array();
$a++;
if ($a<10) {
$result[]=$a;
test($a);
}
return $result;
}

//递归 无限级分类
$area = array(
array(‘id’=>1,’area’=>’北京’,’pid’=>0),
array(‘id’=>2,’area’=>’广西’,’pid’=>0),
array(‘id’=>3,’area’=>’广东’,’pid’=>0),
array(‘id’=>4,’area’=>’福建’,’pid’=>0),
array(‘id’=>11,’area’=>’朝阳区’,’pid’=>1),
array(‘id’=>12,’area’=>’海淀区’,’pid’=>1),
array(‘id’=>21,’area’=>’南宁市’,’pid’=>2),
array(‘id’=>45,’area’=>’福州市’,’pid’=>4),
array(‘id’=>113,’area’=>’亚运村’,’pid’=>11),
array(‘id’=>115,’area’=>’奥运村’,’pid’=>11),
array(‘id’=>234,’area’=>’武鸣县’,’pid’=>21)
);
function t($arr,$pid=0,$lev=0){
static $list=array();
foreach ($arr as $v){
if($v[‘pid’]==$pid){
echo str_repeat(“”,$lev).$v[‘area’].”<br />”;
$list[]=$v;
t($arr,$v[‘id’],$lev+1);
}
}
return $list;
}
$list=t($area);
print_r($area);
echo “<br />”;
print_r($list);
?>

mysql如何应对消息

在使用mysql数据库时,如果是商城那就要考虑到秒杀、抢购、发消息等同一时间访问数据库所带来的堵塞从而压垮数据库。

如何有效的在程序和mysql是做些处理来应对呢。

答案就是:把http请求放入内存的高速队列,然后对队列里的数据按一定的规则进行分流处理。

当一个用户发送一个请求时,我们可以给他延迟2s,依次类推。

如果是发送通知类消息,用户量大,不可能同时发送,那么就是需要列队发送;把发送的消息操作延迟,同时针对活跃用户

优先发送(即异步操作),合理分摊服务器负担。

异步操作优点:部署简单,使用mysql内置存储过程和定时器即可完成大部分调度,服务器部署简单,容易迁移。

缺点:对于大数据量、上千万的消息处理效果不佳。不能应对实时性要求很高的场所。

关于htpp队列,金山有个内部开源HTTPSQL,把队列从mysql移到内存数据库中,并有一个专门的进程负责队列的操作,客户端则通过socket请求进行读写。

另外还有一个轻量级的基于内存的消息队列ZeroMQ,此队列是通过API来实现消息的传输。

mysql瓶颈的应对措施

mysql本身是存在瓶颈的,当数据量达到千万级别以上,无论mysql如何优化,其性能都显著降低(有专门团队开发并改进mysql的除外)。

那么就有以下几种办法解决。

1.增加mysql配置中buffer和cache的数值,增加服务器cpu数量和内存大小。

2.使用第三方引擎或衍生版本。例如:Percona、MariaDB、TokuDB

3.迁移到其他数据库。例如:PostgreSQL、Oracle

mysql数据库如何选择存储引擎

针对不同的业务需求来选择mysql存储引擎。

1.采用MyISAM引擎

  • R/W>100:1且updae相对较少。
  • 并发不高,不需要事务。
  • 表数据量小。
  • 硬件资源有限。

2.采用InnoDB引擎

  • R/W比较小,频繁更新大字段。
  • 表数据量超过1000W,并发高。
  • 安全性和可用性要求高。

3.采用Memory引擎

  • 有足够的内存。
  • 对数据一致性要求不高,如在线人数和Session等应用。
  • 需要定期归档的数据。

 

有关mysql优化的准则

前辈们总结的经验,学习、学习。

1.尽量避免在列上进行运算,这样会导致索引失效。

例如:SELECT * FROM t WHERE YEAR(d) >=2011;

优化为:SELECT * FROM t WHERE d >=’2011-01-01′;

2.使用JOIN时,应该用小结果集驱动大结果集。同时把复杂的JOIN查询拆分成多个QUERY。因为JOIN多个

表时,可能导致更多的锁定和堵塞。

SELECT * FROM a JOIN b ON a.id=b.id

LEFT JOIN c ON c.time=a.date

LEFT JOIN d ON c.pid=d.aid

LEFT JOIN e ON e.cid=a.did

3.LIKE模糊查询的使用,避免%%

例如:SELECT * FROM t WHERE name LIKE ‘%de%’;

优化为:SELECT * FROM t WHERE name >=’de’ AND name<‘df’;

4.仅列出需要查询的字段,这对速度不会有明显影响,主要考虑节省内存。

5.使用批量插入语句节省交互

例如:

INTO t (id,name) VALUES (1,’a’);

INSERT INTO t (id,name) VALUES (2,’b’);

INSERT INTO t (id,name) VALUES (3,’c’);

优化:INSERT INTO t (id,name) VALUES (1,’a’),(2,’b’),(3,’c’);

6.limit的基数比较大时使用between

SELECT * FROM article AS article ORDER BY id LIMIT 100000,10;

优化:SELECT * FROM article AS article WHERE id BETWEEN 100000 AND 100010 ORDER BY id;

7.不要使用rand函数获取多条随机记录

SELECT * FROM table ORDER BY rand() LIMIT 20;

优化:

SELECT * FROM ‘table’ AS t1 JOIN (SELECT ROUND (RAND() * ((SELECT MAX(id) FROM ‘table’)-(SELECT MIN(id) FROM ‘table’ )) + (SELECT MIN(id) FROM ‘table’ )) AS id) AS t2 WHERE t1.id>=t2.id ORDER BY t1.id LIMIT 1;

8.避免使用NULL

9.不要使用count(id),而应该是count(*)

10.不要做无谓的排序,而应尽可能在索引中完成排序。

 

使用Metasploit实现shodan搜索

无意间发现shodan可以搜索任何联网的设备(不多解释,你懂的)。在kali系统中可以配置shodan,也就是说你不用去 https://www.shodan.io/官网上搜索了,在kali终端直接敲命令就可以了。
首先,在shodan注册个免费账户

NO.1

NO.2

NO.3

注册成功后在个人中心获得APIkey

然后在kali终端执行以下命令

可以选择模块并查看该模块下可配置的参数

配置QUERY和SHODAN_APIKEY选项参数(其中SHODAN_APIKEY就是你在shodan注册后个人中给的APIkey,画红线处改成你自己的密匙)

接下来就可以操作命令扫描主机信息

centos安装谷歌浏览器遇到的问题

突然发现centos自带的火狐浏览器好卡,打开网页速度太慢了。就尝试装个谷歌浏览器,结果报错。如下:

http://dl.google.com/linux/rpm/stable/x86_64/repodata/repomd.xml: [Errno 14] curl#7 – “Failed to connect to 2404:6800:4005:800::200e: 网络不可达”

反反复复换了几个地方都不行(网址被封了),干脆把镜像源换了。

命令直接换:

wget -O /etc/yum.repos.d/CentOS-Base.repo http://mirrors.aliyun.com/repo/Centos-7.repo

然后时候生成一下缓存

yum makecache

报错: 正在处理依赖关系 libudev.so.0()(64bit),它被软件包 chromium-31.0.1650.63-2.el6.x86_64 需要

执行:  yum install http://mirror.yandex.ru/fedora/russianfedora/russianfedora/nonfree/el/releases/7/Everything/x86_64/os/opera-developer-24.0.1558.21-3.el7.R.x86_64.rpm

问题解决,这不过是安装个opera浏览器