0%

以下两个函数是自己在接触PHP的时候学到的,这里做一下记录只是为了怀念那个时候对于行业的那种陌生感和探索欲望,这两个函数虽然不是很难,但是用的地方不少,比如获取目录树,可以用在对类目的管理、评论等无限级的地方都可以用,话不多说,请看代码。

阅读全文 »

登录到七牛云官网注册一个账号

地址:http://www.qiniu.com

获取对应的七牛云秘钥

位置:个人面板->秘钥管理
获取一对 AccessKey/SecretKey 秘钥

建立存储空间

位置:对象存储
对象存储中可以管理上传的文件、对空间的设置、域名绑定、样式分割符设置及图片样式设定。

阅读全文 »

表述

  • static方法是类中的一个成员方法,属于整个类,即使不用创建任何对象也可以直接调用!
  • 静态方法效率上要比实例化高,静态方法的缺点是不自动进行销毁,而实例化的则可以做销毁
  • 静态方法和静态变量创建后始终使用同一块内存,而使用实例的方式会创建多个内存。
  • C++中,若类的方法前加了static关键字,则该方法称为静态方法,反之为实例方法。静态方法为类所有,可以通过对象来使用,也可以通过类来使用。但一般提倡通过类名来使用,因为静态方法只要定义了类,不必建立类的实例就可使用。静态方法只能用类的静态成员
  • static关键字用来修饰属性、方法,称这些属性、方法为静态属性、静态方法。
  • static关键字声明一个属性或方法是和类相关的,而不是和类的某个特定的实例相关,因此,这类属性或方法也称为“类属性”或“类方法”
  • 如果访问控制权限允许,可不必创建该类对象而直接使用类名加两个冒号“::”调用。
  • static关键字可以用来修饰变量、方法。
  • 不经过实例化,就可以直接访问类中static的属性和static的方法。
  • static 的属性和方法,只能访问static的属性和方法,不能类访问非静态的属性和方法。因为静态属性和方法被创建时,可能还没有任何这个类的实例可以被调用.
  • static的属性,在内存中只有一份,为所有的实例共用
  • 使用self:: 关键字访问当前类的静态成员.
  • 一个类的所有实例,共用类中的静态属性
    阅读全文 »

虽说分享是传统的美德,但我们有时候辛辛苦苦写一些程序只是为了卖点小钱,挣点辛苦费,也防止有些没有道德的人倒卖,所以我们不得不对我们的程序进行加密,以下我们来介绍一下如何通过PHP的自定义函数来加密我们的PHP源代码.

方法一:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<?php  
function encode_file_contents($filename) {
$type=strtolower(substr(strrchr($filename,'.'),1));
if ('php' == $type && is_file($filename) && is_writable($filename)) { // 如果是PHP文件 并且可写 则进行压缩编码
$contents = file_get_contents($filename); // 判断文件是否已经被编码处理
$contents = php_strip_whitespace($filename);

// 去除PHP头部和尾部标识
$headerPos = strpos($contents,'<?php');
$footerPos = strrpos($contents,'?>');
$contents = substr($contents, $headerPos + 5, $footerPos - $headerPos);
$encode = base64_encode(gzdeflate($contents)); // 开始编码
$encode = '<?php'."\n eval(gzinflate(base64_decode("."'".$encode."'".")));\n\n?>";

return file_put_contents($filename, $encode);
}
return false;
}

//调用函数
$filename = 'dam.php';
encode_file_contents($filename);
echo "OK,加密完成!"
?>
阅读全文 »

今天是公司2018年的年会,地点定在渝中区大礼堂,下午1点30开始,上午几乎所有的小伙伴都按捺不住自己内心澎湃的心一心准备参加公司的年会,不知道是不是做程序员做久了,还是说早已习惯了公司的”套路”,不觉得年会有什么新鲜感和吸引我的地方,当然说句实话,年会对我吸引最大的肯定是抽奖环节,据说今年的终极大奖是现金10万;趁着这么还有点时间,更新下自己的博客吧
使用Docker还是蛮久的了,但对于我来时,基本都是针对于开发搭建环境使用,所以也就只会一些基本的使用,要想看深入讲解的,请绕道咯。

Docker简介

Docker

Docker是一个开源平台,用于自动化部署应用,以通过快捷的途径在称之为容器的轻量级软件层下打包、发布和运行这些应用。它使得应用平台独立,因为它扮演了Linux上一个额外的操作系统级虚拟化的自动化抽象层。它通过其组件cgroups和命名空间利用Linux内核的资源分离特性,达到避免虚拟机开销的目的。它使得用于部署和扩展web应用、数据库和后端服务的大规模构建组件无需依赖于特定的堆栈或供应者。

阅读全文 »

场景:

某天程序员A加班加点完成了本次微信项目的迭代工作,在使用全身解数之后终于盼来了上线的等待,当然,后面也是成功上线了,但是项目经理在看过线上项目之后,才发现程序员A在微信后台修改的操作菜单并没有生效,当然程序员A也知道,这个生效要等一小时左右,但是项目经理急了,’我马上要给客户看,怎么能等待生效’。

这是一个线上执行的单文件,如有需要拆分成各个板块形成方法,可以自行去改。
直接执行以下代码能即时修改微信菜单,比微信后台修改操作快很多。

阅读全文 »

安全培训中提到可以通过referer判断安全性,hackbar中也有一个enable referer的选项,则,这个referer到底是个什么角色?

在http请求的Headers部分可见Referer.

1
Referer http://www.baidu.com/s?tn=98835442_hao_pg&ie=utf-8&f=3&wd=126.com&oq=126.&bs=126.com&rsv_bp=1&inputT=5799&rsp=0

Http协议头中的Referer主要用来让服务器判断来源页面, 即用户是从哪个页面来的,通常被网站用来统计用户来源,是从搜索页面来的,还是从其他网站链接过来,或是从书签等访问,以便网站合理定位.

Referer有时也被用作防盗链, 即下载时判断来源地址是不是在网站域名之内, 否则就不能下载或显示,很多网站,如天涯就是通过Referer页面来判断用户是否能够下载图片

阅读全文 »

《维和步兵营》看完之后给我给我的感触和启发都颇深,脑子里久久都回荡着里面的每一个场景,不得不说是一部好的电视剧,从《士兵突击》到《我是特种兵》系列到《维和步兵营》不得不让我爱上那种军人气概、军人气节、军人情怀。天气转凉,蜷缩在被窝里,写点观后感,一部电视剧也是一种经历,记录下此刻的心境。

阅读全文 »

基础语法

数组

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
array_chunk($array, $size): 将数组按size大小分为多个数组
array_diff($a, $b): 比较数组的不同,可以用来判断两个数组是否相等,需要注意的是这里返回的是在array1中但是不在array2中的值,而不是两个的交集
array_key_exists("key",$a) # 查看key是否存在于某个字典
array_intersect($array1, $array2[,$array $...]) # 返回一个数组,该数组包含了所有在array1同时也出现在其他参数数组中的值
array_merge() # 合并数组,相同的key直接覆盖
array_merge_recursive() # 合并数组,相同的key不覆盖
array_push($source, "red", "gree") # 给数组添加元素
array_search(): 搜索一个key的索引,如果是二维的数组,那么就是通过value搜索key
array_search(strtolower($search), array_map('strtolower', $array)): array_search忽略大小写
array_slice($arr, 0, 1) # 数组分片
array_sum($arr): 计算数组中所有值的和
array_values($arr): 获取数组所有的value值
<!--more-->

count()函数:输出数组的长度
empty()函数:判断数组是否为空
end() // 返回当前数组的最后一个值,需要注意的是这个函数不仅仅是返回最后一个值,还会把数组当前的指针指向最后一个数据
explode(',', $str) # 将字符串分割为数组
implode(',', $arr) # 将数组拼接成字符串
in_array('a', $a) # 查看数组是否存在某个元素
json_encode($arr) # 数组转换城字符串
list($a, $b) = [1, 2] # 分别赋值
rsort(): 以降序对数组排序
sort(); # 排序,可以给数组排序,会修改原来数组的值
uasort($array, $cmp_function) # 定义对比函数进行排序
unset(arr[1]): 删除数组元素
# 数组遍历
foreach($array as $value): 数组遍历
foreach($array as $key => $value): 数组(字典)遍历

# 数组用于函数
func(*list): 将数组作为函数的输入

# 在数组里面添加数组元素,在不确定key的情况下
$arr = [];
$arr['a'][] = 'a';
$arr['a'][] = 'b';

字符串

PHP里面单引号和双引号确实有些地方的用法是不同的,比如匹配换行符的时候

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
json_decode(string, $assoc=false)	# 将字符串转换为json对象,$assoc=true时返回array而不是object
lcfirst($str) # 将字符串首字母转换为小写
mb_strlen($str, 'utf-8') # 求中文字符串长度
mb_substr($str, $start, $length, 'utf-8'): 字符串分割,可以分割中文哟,如果要获得所有右边的,那么$length不用填或者填上NULL,如果版本不行那就是用功能弱一点的substr
nl2br() # 将字符串中的\n转换成网页的换行符<br>
sprintf() # 字符串格式化,需要注意的是,它不是用\转义,而是用的%来转义
strlen() # 求字符串长度
strpos('abc', 'a'); # 在字符串中查找第一次出现位置,没找到返回false
str_repeat('abc', n) # 将字符串重复n次
str_replace(搜索值,替换值,目标) # 字符串替换
str_replace("\n", "", $content); # 去除换行符
substr_count($haystack, $needle, [$offset, $length]); # 计算子字符串needle在字符串haystack中出现的次数
trim($string); # 去除字符串前后的空白字符,如果要去除所有的字符只能使用preg_replace('/\s+/', '', $string),这是stackoverflow上面给出的答案
$a . $b . 'abc':字符串连接直接用点号
explode(',', $str, [$limit]) # 字符串分割,第三个参数大于0表示限制分组数量,limit规定所返回的数组元素的个数,小于0时,返回包含除了最后的-limit个元素以外的所有元素的数组;0表示返回包含一个元素的数组
array_map('strrev', explode('-', strrev($a), 2)) # 字符串分割,逆向
iconv('utf-8', 'GBK', $data): 将字符编码从utf-8转换为GBK
join("&", $arr) # 拼接字符串
parse_str('name=wang&age=18'): 从查询字符串中解析到变量,可以得到$name$age两个变量
parse_url($url): 解析url成数组,与http_build_query()功能相反
preg_replace('/user_id=\d+&name=/', 'user_id=' . 1048 . '&name=', $code): 正则替换
preg_replace_callback('//', function($matches){return strtolower($matchs[0])}: 执行一个正则表达式搜索并且使用一个回调函数进行替换
preg_match('/Chongqing(?<right>.*)/', $string, $matches): 正则匹配,pattern参数前后必须加斜杠
sprintf("sahgoiahg%s", $a): 格式化输出
strtolower($str)/strtoupper($str): 大小写字符串
ucfirst($str): 将字符串首字母大写
ucwords($str): 将字符串每个单词首字母大写

str_replace(' ', '', lcfirst(ucwords(str_replace(['-', '_'], ' ', $str)))); # 字符串转换为驼峰命名法

数字

1
2
3
4
5
6
7
ceil()函数:向上取整
rand(min, max):产生随机数,不需要给初始值了现在
intval($val): 字符串转整数,如果不是数字型字符串,那么转换会失败,失败后返回0,没错是0,mmp
int ip2long(string $ip_address):IP转换成整数值
string long2ip(string $proper_address):整数值转换成IP
number_format(float $number) // 以千位分隔符方式格式化一个数字,返回字符串
sprintf('%04d', 2) // 数字前补零

时间

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
time(): 获取当前时间戳
strtotime(''): 字符串转换为时间戳
gmdate("Y-m-d\TH:i:s\Z"): 获取GMT时区的时间
$beginToday=mktime(0,0,0,date('m'),date('d'),date('Y')):获取今天开始时的时间戳
$endToday=mktime(0,0,0,date('m'),date('d')+1,date('Y'))-1:获取今天结束时的时间戳
$beginYesterday=mktime(0,0,0,date('m'),date('d')-1,date('Y')):获取昨天开始时的时间戳
$endYesterday=mktime(0,0,0,date('m'),date('d'),date('Y'))-1:获取昨天结束时的时间戳
$beginLastweek=mktime(0,0,0,date('m'),date('d')-date('w')+1-7,date('Y')):获取上周开始时的时间戳
$endLastweek=mktime(23,59,59,date('m'),date('d')-date('w')+7-7,date('Y')):获取上周结束时的时间戳
$beginThismonth=mktime(0,0,0,date('m'),1,date('Y')):获取本月开始时的时间戳
$endThismonth=mktime(23,59,59,date('m'),date('t'),date('Y')):获取本月结束时的时间戳
# 单独获取当前的年、月、日、时、分、秒等
date('Y-m-d H:i:s'); // 如果要单独获取或者修改格式,那么直接按照里面的格式修改即可
# 输出指定格式
date('Y-m-d H:i', time())
# 时间的表示
d: 月份中的第几天,有前导零的2位数字,0131
D: 星期中的第几天,文本表示,3个字母,Mon 到 Sun
j: 月份中的第几天,没有前导零,131
l:(“L”的小写字母),星期几,完整的文本格式 Sunday 到 Saturday
N: ISO-8601 格式数字表示的星期中的第几天(PHP 5.1.0 新加),1(表示星期一)到 7(表示星期天)
S: 每月天数后面的英文后缀,2 个字符,st,nd,rd 或者 th。可以和 j 一起用
w: 星期中的第几天,数字表示 0(表示星期天)到 6(表示星期六)
z: 年份中的第几天 0365
星期 --- ---
W ISO-8601 格式年份中的第几周,每周从星期一开始(PHP 4.1.0 新加的) 例如:42(当年的第 42 周)
月 --- ---
F 月份,完整的文本格式,例如 January 或者 March January 到 December
m 数字表示的月份,有前导零 0112
M 三个字母缩写表示的月份 Jan 到 Dec
n 数字表示的月份,没有前导零 112
t 指定的月份有几天 2831
年 --- ---
L 是否为闰年 如果是闰年为 1,否则为 0
o ISO-8601 格式年份数字。这和 Y 的值相同,只除了如果 ISO 的星期数(W)属于前一年或下一年,则用那一年。(PHP 5.1.0 新加) Examples: 1999 or 2003
Y 4 位数字完整表示的年份 例如:19992003
y 2 位数字表示的年份 例如:9903
时间 --- ---
a 小写的上午和下午值 am 或 pm
A 大写的上午和下午值 AM 或 PM
B Swatch Internet 标准时 000999
g 小时,12 小时格式,没有前导零 112
G 小时,24 小时格式,没有前导零 023
h 小时,12 小时格式,有前导零 0112
H 小时,24 小时格式,有前导零 0023
i 有前导零的分钟数 0059>
s 秒数,有前导零 0059>
u 毫秒 (PHP 5.2.2 新加)。需要注意的是 date() 函数总是返回 000000 因为它只接受 integer 参数, 而 DateTime::format() 才支持毫秒。 示例: 654321
时区 --- ---
e 时区标识(PHP 5.1.0 新加) 例如:UTC,GMT,Atlantic/Azores
I 是否为夏令时 如果是夏令时为 1,否则为 0
O 与格林威治时间相差的小时数 例如:+0200
P 与格林威治时间(GMT)的差别,小时和分钟之间有冒号分隔(PHP 5.1.3 新加) 例如:+02:00
T 本机所在的时区 例如:EST,MDT(【译者注】在 Windows 下为完整文本格式,例如“Eastern Standard Time”,中文版会显示“中国标准时间”)。
Z 时差偏移量的秒数。UTC 西边的时区偏移量总是负的,UTC 东边的时区偏移量总是正的。 -4320043200
完整的日期/时间 --- ---
c ISO 8601 格式的日期(PHP 5 新加) 2004-02-12T15:19:21+00:00
r RFC 822 格式的日期 例如:Thu, 21 Dec 2000 16:01:07 +0200
U 从 Unix 纪元(January 1 1970 00:00:00 GMT)开始至今的秒数 参见 time()

Carbon时间处理第三方库

1
Carbon::parse('2017-08-25 18:18:18');	# 不用指定格式即可将时间字符串自动转换为Carbon对象

文件操作

1
2
3
4
5
6
7
8
$fp = fopen("test", "r") or die("Unable to open file!");	# 打开文件
$fp = fopen('test', 'w') # 写入
fread($fp,filesize("webdictionary.txt")); # 读取指定大小的内容
fgetc($fp) # 读取一个字符
fgets($fp) # 读取一行
feof($fp) # 判断指针是否指向文件尾了
fwrite($fp, 'haofly') # 写入字符串到文件
fclose($fp); # 关闭文件

函数/类/对象

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
# public, private, projtected的区别:
public # 权限最多,可以内部调用,实例调用
protected # 受保护类型,用于本类和继承类调用
private # 私有类型,只有在本类中使用

# 对象的序列化和反序列化
serialize()
unserialize()

# 一些自省(反射)方法
func_get_args() # 获取当前方法所有的参数
get_class(className) # 取得当前语句所在的类名
get_class_methods(className) # 取得相应class所包含的所有的方法名
get_class_vars(clasName) # 取得相应class所包含的所有的变量名
get_object_vars($object) # 获取类或者对象的属性,返回数组
property_exists($object, $key) # 类或者对象是否存在某个属性
setAttribute($name, $value) # 设置函数的属性或者直接设置函数的内部变量
$this->{$key} = $value # 给类动态添加属性
$this->{$key} # 返回对象指定的属性
# 根据类名知道类的定义文件
$reflector = new ReflectionClass('className');
echo $reflector->getFileName();
# 标准嘞StdClass
$obj->value # 直接获取其内部的变量

# trait: 一种代码复用机制,从基类继承的成员会被trait插入的成员所覆盖,优先顺序是来自当前类的成员覆盖了trait的方法,而trait则覆盖了被继承的方法。这是为了弥补PHP单继承的局限
# 例如可以写一个单例:
trait SingleInstance
{
static private $instance = null;
static public function getInstance(){
if (!self::$instance) {
self::$instance = new static();
}
return self::$instance;
}
}
# 在其他类里面只需要use SingleInstance就行了。再比如,文档里面的例子
<?php
class Base {
public function sayHello() {
echo 'Hello ';
}
}
trait SayWorld {
public function sayHello() {
parent::sayHello();
echo 'World!';
}
}
class MyHelloWorld extends Base {
use SayWorld;
}
$o = new MyHelloWorld();
$o->sayHello(); // 输出的是Hello World
?>

发送CURL请求

注意:使用CURL之前一定要先确定服务器是否已经安装php的curl扩展,如果没有,可能会报奇怪的错误,安装完扩展后记得重启php进程。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
$ch = curl_init();								// 初始化curl
curl_setopt(); // 设置参数
curl_setopt($ch, CURLOPT_URL, 'url'); // 设置URL
curl_setop($ch, CURLOPT_POST, true); // 发送POST请求
curl_setop($ch, CURL_POSTFIELDS, $data); // POST的数据
curl_setop($ch, CURLOPT_RETURNTRANSFER, true); // 获取返回结果,如果不加这个,那么$result=true
$result = curl_exec($ch); // 执行curl请求
curl_getinfo($ch, CURLINFO_HTTP_CODE) // 获取http_code

curl_setopt($curlHandle, CURLOPT_HTTPHEADER, ['Accept: application/json']); // 添加HTTP头
curl_close($ch); // 关闭连接
# 如果要通过CURL 上传文件,那么需要这样对$data进行处理
if (function_exists('curl_file_create')) { // php 5.6+
$cFile = curl_file_create($scriptPath);
} else { //
$cFile = '@' . realpath($scriptPath);
}
$data = ['file' => $cFile];
# 获取curl所有参数所代表的常量值
$arr = get_defined_constants(true);
var_dump($arr['curl']);

WEB程序

1
2
3
4
5
6
7
8
9
10
11
$_SERVER['REQUEST_METHOD']    # 返回数据提交的方式,GET、POST等
$_SERVER["SERVER_PORT"] # 获取端口
$_SERVER['HTTP_HOST'] # 获取域名或主机地址
$_SERVER['SERVER_NAME'] # 获取域名或主机名
$_SERVER["REQUEST_URI"] # 获取域名后的详细地址
$_SERVER['PHP_SELF'] # 获取PHP文件名
$_SERVER["QUERY_STRING"] # 获取网址后的参数
$_SERVER['HTTP_REFERER'] # 获取来源url
parse_str(file_get_contents("php://input"),$post_vars); # 获取PUT数据
getallheaders # 获取请求头
error_log('message') # 把错误信息发送到web服务器的错误日志,或者到一个文件里,有长度限制

异常处理

1
2
3
4
5
try{
throw new Exception('soahg');
}catch(Exception $e){
echo $e->getMessage();
}

帮助函数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
gettype(): 获取变量类型
$obj instanceof A # 判断对象是否属于某个类,不过判断是不是数组只能用is_array() # 判断是否是数组
is_string() # 判断是否是字符串
is_object() # 判断是否是object
is_bool() # 是否是布尔值
is_int() # 是否是整数
is_integer()# 是否是整数
is_float() # 是否是浮点数
is_real() # 是否是实数
is_numeric # 是否是数字或者数字字符串
interface_exists() # 检查接口是否已经定义
class_exists() # 检查类是否已经定义

PHP_INT_MAX # 最大整数
PHP_INT_MIN # 最小整数
min($value1, $value2...) # 选出最小值,最大值max同理
min([$value1, $value2,...]) # 选出最小值,最大值max同理

hash_hmac(算法名, 明文, 盐) # hash加密函数,可以选定加密算法,例如hash_hmac('sha1', 'mingwen', 'salt')

composer包管理

require是指在生产环境中必须的包,而require-dev则是开发的时候要用而生产环境无需用的包,常用命令:

1
2
3
4
5
6
7
8
9
composer config --list	# 列出当前所有的配置
composer show # 获取所有安装的包的列表
composer require package_name --dev # 安装包,并将其写入composer.json的require-dev中去
composer remove package_name # 移除包
composer config -g repo.packagist composer https://packagist.phpcomposer.com # 更换为国内的源
# 忽略ssl证书验证
composer config --global disable-tls true
composer config --global secure-http false
"package/ppkg": "2.7.*@beta" # 安装beta版

autoload

autoload,可以预加载类,自动索引所有的类,能够加快依赖的索引速度。但是autoload并不是实时更新的,如果发现vendor/composer/autoload_classmap.php中的类与你预想的有冲突,那么就需要更新一下了:composer dump-autoload。
在composer.json中有四种自动加载类型:

  • classmap: development相关的:
    1
    2
    3
    {
    "classmap": ["src/"] # 这样composer就会读取这个文件夹下所有的文件,然后再vendor/composer/autoload_classmap.php中将所有的class的namespace+classname生成一个key=>value的数组
    }
  • psr-0: 已经被弃用
  • psr-4: 一般用于项目代码的自动加载
  • files: helper相关的