php-library示例 相关代码详见:https://github.com/jjonline/php-library

注:本代码示例需要PHP5.3.0及其以上的PHP环境;当前服务器PHP版本:5.6.40

php-library文件结构

本Demo的自动加载机制

<?php
/**
 * 类自动加载 
 * @param null
 */ 
spl_autoload_register(function ($class) {
   $Dir        =  str_replace('\\', '/', $class).'.class.php';
   $FileName   =  __DIR__.'/'.$Dir;#realpath('./'.$Dir)亦可 但调用了函数肯定会适度加重负担;
   include $FileName;
});
#Function文件夹中的函数方法文件自动加载
$FunctionDir =  __DIR__.'/Function/';
if(is_dir($FunctionDir)) {
   $iterator =  new DirectoryIterator($FunctionDir);
   while($iterator->valid()) {
       if($iterator->isFile()){
         $FileDir =  $FunctionDir.$iterator->getFilename();
         if($iterator->getExtension() == 'php') {
            include $FileDir;
         }
       }
       $iterator->next();
   }
}
?>

Function文件夹中的一些函数方法示例

各函数使用方法和说明详见:Function文件夹中的README.md介绍。

运行结果:

1、password_hash不指定盐值加密密码zheshiyigemima123输出结果:string(60) "$2y$10$6LaKypHhGrHtNI2/l54t6uommbTkDjba7G6GrIZdD0SJ6lW9I2C8C" ;没有通过第三个参数指定固定的盐值(系统会自己添加随机盐值),所以每刷新下结果都会变化的~~~

2、password_verify效验密码zheshiyigemima123和曾经保存过的一个hash串$2y$10$WITh4hNt3PZtWIidd8btEOgQiRhUq15ofxDOZQqIDs3BJD/XnEDAu输出结果:bool(true)

3、password_get_info获取hash串$2y$10$WITh4hNt3PZtWIidd8btEOgQiRhUq15ofxDOZQqIDs3BJD/XnEDAu的信息,输出结果:array(3) { ["algo"]=> int(1) ["algoName"]=> string(6) "bcrypt" ["options"]=> array(1) { ["cost"]=> int(10) } }

4、is_mail_valid检测字符串JJonline@JJonline.Cn是否是一个合法的邮箱格式,输出:bool(true) ;检测字符串JJon-l#?ine@JJonline.Cn是否是一个合法的邮箱格式,输出:bool(false)
Ps1:其实按 RFC822标准JJon-l#?ine@JJonline.Cn是一个合法的邮箱地址,只不过如此反人类的邮箱地址果断不拽它
Ps2:is_mail_valid默认采用正则检测,也可以采用filter_var($mail,FILTER_VALIDATE_EMAIL)方式支持RFC822标准
Ps3:is_mail_valid检测邮箱格式的标准为:用户名部分构成仅能为数字、字母、下划线、加好、减号(中划线)和点,且开头位置仅能为数字或字母;域名部分按域名规则,支持域名中有减号(或者称之为中划线)
   测试支持检测的邮箱格式类型:
      is_mail_valid检测邮箱地址字符串JJonline-Cn@JJonline.Cn的结果bool(true)
      is_mail_valid检测邮箱地址字符串JJonline.Cn@JJonline.Cn的结果bool(true)
      is_mail_valid检测邮箱地址字符串JJonline_Com.Cn@JJonline.Cn的结果bool(true)
      is_mail_valid检测邮箱地址字符串JJonline.Com.Cn@JJonline.Cn的结果bool(true)
      is_mail_valid检测邮箱地址字符串123456@JJonline.Cn的结果bool(true)
      is_mail_valid检测邮箱地址字符串JJonline.Cn@JJonline-Com.Cn的结果bool(true)
      So,符合人类认知的几种邮箱格式检测均已支持~倘若需要支持检测邮箱中域名后缀为特定的,比如.com、.cn的还不支持
Ps4:邮箱地址和网站网站域名一样是不区分大小写滴;那么问题来了Url区分大小写吗?答案是:看情况,因为*nux文件系统区分,而window文件系统特么又不区分~;只能说协议部分和域名部分是不区分大小写滴~

5、is_phone_valid检测存在的天朝手机号15872254727,输出:bool(true) is_phone_valid检测不存在的天朝手机号170123456,输出:bool(false) ;天朝手机号11位,开头为13[0-9]、14[0-9]、15[0-9]、18[0-9]、176、177、178新号段以及虚拟运营商的170[059]

6、is_url_valid检测Urlhttps://www.jjonline.cn:443/UserInfo/index.php?UserId=123456&type=Vip#Node=part1,输出bool(true) ;该方法仅检测http或https打头的Url,包括端口、get变量和锚点支持

7、is_uid_valid检测QQ号77808859,输出:bool(true) ;该方法三个参数,第一个必选参数为需要检测的数字账户id,第二个可选参数指定合法的数字账户最短位数[默认4位],第三个可选参数指定合法的数字账户最长位数[默认11位]。

8、is_password_valid检测密码字符串mima123456,输出bool(true) ;该方法检测的密码字符串必须同时包含字母和数字;该方法三个参数,第一个必选参数为需要检测的密码字符串,第二个可选参数指定合法的密码字符串最短长度[默认8位],第三个可选参数指定合法的密码字符串最长长度[默认16位]。

9、is_citizen_id_valid检测身份证号420521198907031846是否合乎规范,输出:array(6) { ["id"]=> string(18) "420521198907031846" ["location"]=> string(6) "湖北" ["Y"]=> string(4) "1989" ["m"]=> string(2) "07" ["d"]=> string(2) "03" ["sex"]=> int(0) } ;该函数兼容15位老身份证号和18位新身份证号(若传入15位合法的身份证号将返回转换过的18位身份证号),符合规范返回有内容的关联数组(boolean判断为true),不符合规范返回false
      Ps:我都这么卖力的分享了,请给点面子不要拿此身份证号瞎搞

10、time_ago时间友好表示法,写此示例时的时间戳1438852440使用time_ago,输出:string(20) "9年前 (2015-08-06)"

11、Input统一方式获取外部变量或用户提交的变量数据;函数原型:Input('变量类型.变量名/修饰符',['默认值'],['过滤方法'],['额外数据源'])

“变量类型”可选为:

变量类型含义解释
get获取GET变量;此时第四个参数无任何意义
post获取POST变量;此时第四个参数无任何意义
param自动判断请求类型获取GET、POST或者PUT变量;此时第四个参数无任何意义
request获取REQUEST变量;此时第四个参数无任何意义
put获取PUT变量;此时第四个参数无任何意义
session获取$_SESSION变量;建议使用session函数;此时第四个参数无任何意义
cookie获取$_COOKIE变量;建议使用cookie函数;此时第四个参数无任何意义
server获取$_SERVER变量;此时第四个参数无任何意义
globals获取$GLOBALS变量;此时第四个参数无任何意义
data获取其他类型的变量,需要第四个参数['额外数据源']配合

“修饰符”可选为:s、d、b、a、f;表示获取的数据被强制转换的类型,s=>string[字符串]、d=>double[整形]、b=>boolean[布尔值]、a=>array[数组]、f=>float[浮点数];未设置该参数默认为s

“默认值”表示需要获取的指定变量不存在时返回这个默认值,注意变量不存在的含义;假设获取get变量action,也就是说$_GET['action']不存在才会返回默认值;这里存在这种情况:($_GET['action']==='')为true;这就需要对“变量是否存在”的深入理解,直接给答案不解释,这种情况Input返回空字符串并不会返回设置的默认值。

“过滤方法”参数,可以是数据处理或过滤的函数名字符串(自定义函数亦可,留意过滤函数方法体的合理性),多个函数使用逗号分隔函数名成字符串或用索引数组;也可以是一个正则表达式,使用正则来过滤数据(此时表达式分隔符必须是左划线[正划线];使用正则倘若匹配失败则不会返回原值,而是会返回设置的默认值或者null);同时也可以是int型常量或变量用于filter_var的第二个参数,并使用filter_var进行过滤。若传递的函数并不存在,此时将尝试将该参数理解成filter_var过滤方法的第二个参数(int型)并用filter_var函数对数据过滤。

“额外数据源”可以使用Input处理该函数第一个参数中的“变量类型”所不支持的数据类型(主要指那些超全局变量);Input函数仅用于获取(并不进行数据设置),使用“额外数据源”参数则需要“变量类型”必须设置为data,继而“默认值”参数、“过滤方法”参数相互配合,用更少的代码完成更多的事情。该参数类型可以是数组也可以是字符串。

注意:Input默认Sql注入的安全过滤需要针对特定业务场景,有需要进一步过滤请完善./Function/UsefullFunction.php中的Input_filter函数;该函数默认过滤掉纯粹的特定Sql语句中的关键词,若数据中包含这些Sql关键词是不会被过滤的!

Input是一个很强大的函数,用法举例:

12、session函数用于统一设置、获取session

13、cookie函数用于统一设置、获取cookie;函数原型cookie('COOKIE名',['COOKIE值'],['COOKIE配置项']);注意此函数有默认配置项,可以按需定制(修改函数体开始的$config数组即可),亦可通过'COOKIE配置项'参数覆盖默认配置。

'COOKIE名':用于获取或设置指定名称的COOKIE,若'COOKIE名'传入null则表示删除指定前缀的所有cookie,此时若cookie名前缀为空将不做任何处理即不删除任何cookie;作为php标准,当并未按需指定默认配置时可以通过'COOKIE配置项'参数传入cookie前缀,写法为:cookie(null,null,array('prefix'=>'J_'));函数体也做了变通处理还可以这么写cookie(null,'J_'),此时第二个参数将被理解成要删除的cookie前缀。

'COOKIE值':用于设置cookie的值,或当'COOKIE名'为null并且'COOKIE值'不为null,此时'COOKIE值'表示传入cookie前缀,以用于快速删除该cookie前缀的所有cookie。

'COOKIE配置项'参数形式:

'COOKIE配置项'允许三种类型变量参数:int、string(int)以及array,可以理解为两种,多数情况下允许传入数组;仅进行cooke设置时'COOKIE配置项'参数方可允许为数值型参数(无论是int还是int型的字符串);此时的数值表示为该设置的cookie设置一个过期时间,例如cookie('J_cookie','required',3600),表示设置一个名为J_cookie,值为required,过期时间为3600秒的cookie。当'COOKIE配置项'为数组时,该关联数组的结构为:array('prefix'=>string,'expire'=>int,'path'=>path string,domain'=>string,'httponly'=>boolean),其中索引不区分大小写,prefix为设置该cookie的前缀(设置前缀也可以通过默认值配置或者直接将'COOKIE名'设置为完整的cookie名称)、设置的cookie过期时间(默认浏览器关闭cookie失效)、以及cookie的作用目录(默认/)、作用域名(默认当前域名)、以及该cookie是否httponly;除prefix外,其余几个索引键与setcookie(string $name [, string $value [, int $expire = 0 [, string $path [, string $domain [, bool $secure = false [, bool $httponly = false ]]]]]])函数对应;仅需留意的是expire索引键的值通过cookie函数仅需指定多少秒后过期即可,而无需再加上time(),比如使用setcookie函数设置一个1个小时后过期的cookie,expire参数为time()+3600,而使用cookie函数,expire仅需要传入3600即可。

cookie是一个很强大的函数,用法举例:

不再详细介绍的函数:format_bytes

1、Hashids类:加密数字型id成字符串hash并可反向解密hash成数字id

应用场景:url中不便于直接显示成数字的id加密成唯一性的字符串(hash);php脚本接收到该hash后又可以很方便的还原成数字id。也可以将多个数字型的参数一次性加密后作为一个GET变量附加在url中。

<?php
   #三个可选参数,
   #参数1为加密盐值
   #参数2为指定加密后的hash串最小长度
   #参数3为手动指定hash串中允许出现的字符
   $obj =  new Library\Hashids\Hashids('http://blog.jjonline.cn',16);
   #加密数字1成为字符串 此处可以传递多个数字一起加密 或者一个value全部为数字的索引数组
   var_dump($obj->encode(1));# 可能的字符串输出:1nZVNL5Eq5793Jyg
   #解密hash字符串为数字原型
   $restult = $obj->decode('1nZVNL5Eq5793Jyg');
   #注意解密后成为数组
   var_dump($restult);
   #加密多个数字型索引数组
   var_dump($obj->encode(1,2,3));#可能的字符串输出:K8aO5d4Uos45b2dr
   #或者写法为var_dump($obj->encode([1,2,3]));
   #此类还提供加密16进制数的方法 不再介绍 原理一致  只不过方法名变化:encode_hex和decode_hex
?>

运行结果:

数字1加密后的hash字符串为:string(16) "1nZVNL5Eq5793Jyg"

hash串1nZVNL5Eq5793Jyg解密后的数字原型为:int(1)

数组[1,2,3]加密后的hash字符串为:string(16) "K8aO5d4Uos45b2dr"

数组型hash串K8aO5d4Uos45b2dr解密后的数字原型数组为:array(3) { [0]=> int(1) [1]=> int(2) [2]=> int(3) }

2、PasswordHash类:不可逆的密码加密和密码对比,开源原始名:phpass

应用场景:加密密码字符串成为不可逆的hash字符串,此加密方式一个明文密码对应无数个hash串;通过保存的hash串和密码明文进行对比,又可以效验明文密码的正确性。[该加密类被WordPress、emlog等许多开源程序使用]

<?php
   #两个参数,第一个参数指定加密深度 int 取值范围5-30 第二个参数指定该加密是否可以移植指定false,更换运行环境后解密将出现问题
   $PasswordHash  =  new Library\PasswordHash\PasswordHash(8,true);
   #加密密码 zheshiyigemima123 可以发现每一次刷新结果都不一样 保留一个结果:$P$BPae94jMsALnSwBm5fnKiMBpLuxZfN1 用于下方密码效验试验
   var_dump($PasswordHash->HashPassword('zheshiyigemima123'));
   #对比数据库保存的密码hash串:$P$BPae94jMsALnSwBm5fnKiMBpLuxZfN1是否为明文密码:zheshiyigemima123的一个hash;换种方式描述:核对用户密码是否正确
   #第一个参数为需要核对的明文密码 第二个参数为曾经加密获得并保存的hash串 
   #该方法返回boolean值 true效验成功  false的话.....说多了都显得愚蠢了
   var_dump($PasswordHash->CheckPassword('zheshiyigemima123','$P$BPae94jMsALnSwBm5fnKiMBpLuxZfN1'));
   #继续试验  将密码明文换下 zheshiyigemima321
   var_dump($PasswordHash->CheckPassword('zheshiyigemima321','$P$BPae94jMsALnSwBm5fnKiMBpLuxZfN1'));
?>	

运行结果:

密码zheshiyigemima123加密后的hash字符串为:string(34) "$P$BtKOUlmgfwdO.LWeAzSIuKTa.hr/HA." ;每刷新下结果都会变化的~~~

用曾经保存过的一个hash串$P$BPae94jMsALnSwBm5fnKiMBpLuxZfN1来核对密码zheshiyigemima123(正确的密码)是否正确:bool(true)

用曾经保存过的一个hash串$P$BPae94jMsALnSwBm5fnKiMBpLuxZfN1来核对密码zheshiyigemima321(错误的密码)是否正确:bool(false)

更多...待添加,或您提pull request