欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  网络运营

PHP 5.5新的加密函数-password_hash()

程序员文章站 2022-03-16 16:29:21
PHP 5.4刚刚发布4个月,现在来谈论下一个版本的PHP,可能为时过早,但是在PHP的内部邮件列表中,这个话题现在很火。 PHP 5.5目前还处于早期发展阶段,最终他会成什么样子,现在没人...
PHP 5.4刚刚发布4个月,现在来谈论下一个版本的PHP,可能为时过早,但是在PHP的内部邮件列表中,这个话题现在很火。
PHP 5.5目前还处于早期发展阶段,最终他会成什么样子,现在没人会知道,下面 只是总结人们对PHP 5.5的期望,但是PHP 5.5并不会包含下面所有的内容。
简单的来说,有4个比较重要的功能点:
一个简单的密码hash函数
类型约束检测(Scalar typehinting)
Getters and seters (属性)
生成器(Generators)
其他的很多细节:
不支持Windows XP和2003
PHP 5.5将不再支持Windows XP和2003系统,这些系统太老了。
/e修饰符定义为过时的
/e修饰符被设置之后preg_replace()在进行了对替换字符串的后向引用替换之后, 将替换后的字符串作为php代码评估执行(eval函数方式), 并使用执行结果作为实际 参与替换的字符串. 单引号, 双引号, 反斜线(\)和NULL字符在 后向引用替换时会 被用反斜线转义。
这将会导致安全问题,作为替代,应该使用preg_replace_callback函数。
boolval()
PHP已经实现了strval, intval, floatval函数,转换为bool类型的boolval函数将会被添加。 他和(bool)的转换是一样的,但是他可以作为回调函数使用。
array_column()
array_colume或者array_pluch函数将会表现如下:
<?php
 
$userNames = array_column($users, 'name');
// 等同于下面代码
$userNames = [];
foreach ($users as $user) {
    $userNames[] = $user['name'];
}
一个简单的密码hash函数
最近很多大型网站泄漏密码(注意这个的泄漏密码不是国内的各种密码门,老外才不关心国内呢,在国外也 有很多类是国内的密码泄漏事件),对于密码我们一直提倡使用bcrypt进行加密,但还是有很多人使用不 安全的sha1哈希。(国内、外的密码泄漏,虽然都是泄漏,但国外泄漏是被哈希过的密码,而国内直接是 明文)
我估计这可能是使用crypt函数太困难的(sha1, md5的确很简单),因为我们需要一个简单而且安全的密码 哈希函数:
<?php
 
$password = "foo";
 
// 创建一个密码哈希
$hash = password_hash($password, PASSWORD_BCRYPT);
 
// 验证一个密码
if (password_verify($password, $hash)) {
    // 密码正确!
} else {
    // 密码错误!
}
新的密码哈希有更多的更能,这里是RFC 概述。
常量引用(Constant dereferencing)
“Constant dereferencing” 是指可以直接用操作数组的方式来操作字符串,看下面2个例子:
<?php
 
function randomHexString($length) {
    $str = '';
    for ($i = 0; $i < $length; ++$i) {
        $str .= "0123456789abcdef"[mt_rand(0, 15)]; // direct dereference of string
    }
}
 
function randomBool() {
    return [false, true][mt_rand(0, 1)]; // direct dereference of array
}
我不认为应该使用该特性,但他让语言语法多了一点。查看RFC
empty()函数将支持参数是一个函数调用(和其他表达式)
目前的empty()函数的参数只能是一个变量,PHP 5.5中将支持emtpy($this->getFriends())这样使用,在之前的版本 这将会抛出一个错误。查看RFC
获取完整的类名
PHP 5.3中增加了命名空间的特性。就导致下面代码的问题:
<?php
 
use Some\Deeply\Nested\Namespace\FooBar;
 
// 这个代码不能工作,因为他会在全局中查找FooBar类,显然这是找不到的
$reflection = new ReflectionClass('FooBar');
为了解决这个问题引入一个新的语法FooBar::class返回完整的类名
use Some\Deeply\Nested\Namespace\FooBar;
 
// this works because FooBar::class is resolved to "Some\\Deeply\\Nested\\Namespace\\FooBar"
$reflection = new ReflectionClass(FooBar::class);
更多示例查看RFC
函数参数可以跳过(Parameter skipping)
如果你有一个函数接受多个可选参数,目前你没有办法使用中间参数的默认值,新增的default可以做到使用某些参数的默认值, 而不是在调用函数的地方再定义一遍值。
下面是RFC 中的一个例子:
function create_query($where, $order_by, $join_type='', $execute = false, $report_errors = true) { ... }
如果我们要设置$report_errors = false 而不需要设置$join_type和$execute参数,我们就可以使用下面代码:
create_query("deleted=0", "name", default, default, false);
类型约束检测
检测类型约束原本是要包含中PHP 5.4中的,但是由于未达成共识,他没有被包含进PHP 5.4。
现在PHP 5.5又开始讨论提议他了。查看RFC
function foo(int $i) { ... }
 www.2cto.com
foo(1);      // $i = 1
foo(1.0);    // $i = 1
foo("1");    // $i = 1
foo("1abc"); // not yet clear, maybe $i = 1 with notice
foo(1.5);    // not yet clear, maybe $i = 1 with notice
foo([]);     // error
foo("abc");  // error
新的Getters和Setters语法
如果你是getXYZ()和setXYZ()写法的粉丝,那么这是一个可喜的变化。PHP 5.5中提议增加一个对于直接属性读写的 语法:
<?php
 
class TimePeriod {
    public $seconds;
 
    public $hours {
        get { return $this->seconds / 3600; }
        set { $this->seconds = $value * 3600; }
    }
}
 
$timePeriod = new TimePeriod;
$timePeriod->hours = 10;
 
var_dump($timePeriod->seconds); // int(36000)
var_dump($timePeriod->hours);   // int(10)
也有一些其他的特性,例如只读的属性,更多内容可以参考RFC
生成器
目前自定义的迭代器很少被使用,因为使用他太麻烦了,需要很多其他无关的代码(被称为模板代码),生成器提供一个方便 使用迭代器的方法来解决这个问题。
例如,这是一个自定义范围的函数,但他也可以被当迭代器使用:
<?php
 
function *xrange($start, $end, $step = 1) {
    for ($i = $start; $i < $end; $i += $step) {
        yield $i;
    }
}
 
foreach (xrange(10, 20) as $i) {
    // ...
}
上面xrange函数具有同内置的range函数相同的功能,唯一不同的是他返回的不是一个包含了所有值的数组,而是一个迭代器 生成的动态值。
更多的功能可以参考RFC
列表内涵和生成器表达式
列表内涵提供一个简单的访问数组的方式:
$firstNames = [foreach ($users as $user) yield $user->firstName];
上面类表内涵等同于下面代码:
$firstNames = [];
foreach ($users as $user) {
    $firstNames[] = $user->firstName;
}
他也可以过滤数组:
$underageUsers = [foreach ($users as $user) if ($user->age < 18) yield $user];
生成器表达式类是,但他返回的是一个迭代器动态生成的值,而不是一个数组。