目录
0x01 类的自动加载
在编写OOP程序时,很多开发者为每一个类新建一个PHP文件。这会带来一个烦恼:每个脚本的开头,都需要包含(include)一个长长的列表(每个类都有个文件)
1.__autoload($classname)
当实例化类的时候会先自动调用__autoload函数(类名会自动赋值给$classname),然后再自动调用该类的构造函数
注意:类文件的名称 必须是 类名
__autoload是系统注册好的函数,直接重载即可。
<?php
//require_once './libary/CheckCode.php';
//require_once './libary/Db.php';
//require_once './libary/Page.php';
function __autoload($classname){
require_once "./libary/$classname.php";
}
$config = ['host'=>'localhost','dbname'=>'gaokao','user'=>'root','password'=>'root'];
$db1 = Db::getInstance($config);
$data = ['name'=>'卢克韦林','pwd'=>md5('lukeweiling'),'fee'=>100000];
$db1->insertData('user',$data);
$str = 'abcdefghjkmnpqrstuvwxyz23456789ABCDEFGHJKMNPQRSTUVWXYZ';
$cc = new CheckCode(200,50,$str,4);
$cc->draw();
$p = new Page(100,5,1);
$p->showPage();
?>
2.spl__autoload_register($function_name) 注册自动加载函数的系统内置函数
例如:有多个不同库文件在不同的文件夹中的时候,就可以用该函数注册多个自动加载函数
0x02 PSR规范
PSR-4自动加载规范
术语class是指 classes,interfaces,traits 以及其他类似的结构
一个完全合乎规范的类名格式如下:
\<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>
1.有一个顶级的命名空间名称,和类文件所在的顶级文件夹对应
2.有一个或者多个二级命名空间,和类文件所在的二级文件夹对应
3.以类名作为类文件名
0x04 composer
用来管理 库文件(类文件) 的工具
0x05 openssl
openssl是一个动态库。
windows下使用该函数需要先配置一个环境变量,OPENSSL_CONF=openssl.cnf路径
1.$resource openssl_pkey_new([array $config]);
生成一个新的私钥;
可以将对秘钥的设置封装在该变量$config中,然后传给该函数;
$config=['private_key_bits'=>4096,'private_key_type'=>OPENSSL_KEYTYPE_RSA]
其中private_key_bits 设置私钥的长度 默认为2048
private_key_type设置私钥的类型 默认为RSA,非对称加密,即私钥可以生成公钥,私钥加密的文件,必须公钥解密,公钥加密的信息,必须私钥解密
2.openssl_pkey_export ( mixed $key
, string &$out
[, string $passphrase
[, array $configargs
]] ) : bool
将一个密钥的可输出表示转换为字符串
3.openssl_pkey_export_to_file(mixed $key,string 文件名)
将秘钥导出到文件中
4.openssl_pkey_get_details ( resource $key
) : array
@成功,返回包含密钥详情的数组,失败返回 FALSE
.
@返回的数组中包含了如下索引:
- bits (位数),
- key (表示公钥的字符串)
- type (如下密钥类型之一:
OPENSSL_KEYTYPE_RSA
,OPENSSL_KEYTYPE_DSA
,OPENSSL_KEYTYPE_DH
,OPENSSL_KEYTYPE_EC
或者 未知类型返回1).
公私钥加密解密
resource openssl_pkey_get_public(公钥的字符串) 返回表示公钥的句柄
bool openssl_public_encrypt(要加密的信息,加密后存在哪个变量,公钥的句柄);用公钥对数据进行加密。
$string base64_encode($data) 对二进制数据进行base64编码成字符串格式
base64_decode()将字符串还原成二进制编码
<html>
<head>
<meta charset='utf-8'>
</head>
<body>
<?php
//生成公私钥
function genKey(){
$config = ['private_key_bits'=>4096];
$res = openssl_pkey_new($config);//生成私钥,返回句柄
openssl_pkey_export($res,$priKey);//将私钥转化为字符串存在一个变量中
//var_dump($priKey);
openssl_pkey_export_to_file($res,'pri.key');//将生成的私钥保存到pri.key中
file_put_contents('pub.key',openssl_pkey_get_details($res)['key']);//将生成的公钥保存到pub.key
}
//公钥加密数据
function pub_encData($data){
//得到公钥
$pubKey =openssl_pkey_get_public(file_get_contents('pub.key'));
//用公钥加密
openssl_public_encrypt($data,$after,$pubKey);
//加密后的信息默认是二进制格式,用base64_encode()可以编码成字符串格式
$after = base64_encode($after);
return $after;
}
//私钥加密数据
function pri_encData($data){
//得到私钥
$priKey = openssl_pkey_get_private(file_get_contents('pri.key'));
//用私钥加密
openssl_private_encrypt($data,$after,$priKey);
$after = base64_encode($after);
return $after;
}
//公钥解密数据
// $data为base64编码的加密数据
function pub_decData($data){
//1.解码data
$data = base64_decode($data);
//2.从key文件中生成公钥句柄
$pubKey = openssl_pkey_get_public(file_get_contents('pub.key'));
//3,解密
openssl_public_decrypt($data,$after,$pubKey);
return $after;
}
// 私钥解密数据
function pri_decData($data){
$priKey=openssl_pkey_get_private(file_get_contents('pri.key'));
openssl_private_decrypt(base64_decode($data),$after,$priKey);
return $after;
}
//签名私钥加密的数据
function pri_sign($data){
$data = base64_decode($data);
$priKey=openssl_pkey_get_private(file_get_contents('pri.key'));
openssl_sign($data,$sign,$priKey);
//传入的sign的引用,所以,签名后的字符串可以存在sign中返回
// 因为sign中存的是二进制形式,所以需要base64_encode一下
return base64_encode($sign);
}
//签名公钥加密的数据
function pub_sign($data){
$data = base64_decode($data);
$pubKey=openssl_pkey_get_public(file_get_contents('pub.key'));
openssl_sign($data,$sign,$pubKey);
//传入的sign的引用,所以,签名后的字符串可以存在sign中返回
// 因为sign中存的是二进制形式,所以需要base64_encode一下
return base64_encode($sign);
}
//用公钥验签私钥加密并签名的数据
// data 是经过base64编码后的 没有签名的加密数据
// sign 是经过base64编码后的 有签名的加密数据
function checkSign($data,$sign){
$data = base64_decode($data);
$sign = base64_decode($sign);
$pubKey=openssl_pkey_get_public(file_get_contents('pub.key'));
$is_succeed = openssl_verify($data,$sign,$pubKey);
return $is_succeed;
}
//生成证书
function genCert(){
$dn=[
"countryName"=>"China",
"stateOrProvinceName"=>"ShanXi",
"University"=>"XDU"
];
$priKey = openssl_pkey_get_private(file_get_contents('pri.key'));
//生成csr
$csr = openssl_csr_new($dn,$priKey);
//生成证书句柄
$cacert = openssl_csr_sign($csr,null,$priKey,30);
//导出证书
openssl_x509_export_to_file($cacert,'pub.pem');
}
// 1.生成公钥和私钥
genKey();
$data = "hello world";
// 2.私钥加密数据
$data = pri_encData($data);
// 3.在数据上签名
$signed_data = pri_sign($data);
//4.验签
$ret = checkSign($data,$signed_data);
if($ret){
echo pub_decData($data);
}
?>
</body>
</html>
签名以及验签:
1.bool openssl_sign(加密后的数据,签名后返回的字符串,私钥句柄) 返回值为签名是否成功
2.bool openssl_verify($data,$sign)
用公钥(私钥)验签私钥(公钥)加密并签名的数据
data 是经过base64编码后的 没有签名的加密数据
sign 是经过base64编码后的 有签名的加密数据
生成证书:
- openssl_csr_new(array $dn,resource &$prikey)
- 根据
dn
提供的信息生成新的CSR(证书签名请求) - prikey为私钥句柄
- 根据
- openssl_csr_sign(CSR句柄,null,私钥句柄,证书有效期)
- 给定CSR生成一个x509证书句柄
- openssl_x509_export_to_file(证书句柄,文件名)
- 导出证书到一个文件中