PHP 7.1 方括号数组符号多值复制和指定键值赋值
PHPer 们可能都知道 list 的用法,简单来说就是可以在一个表达试里通过数组对多个变量赋值:
$values = array('value1', 'value2');
$list($v1, $v2) = $values;
感觉是不是很方便呢?在 PHP 7.1 中,还能更省事儿:
[$v1, $v2] = ['foo', 'bar'];
这还不是最给力的,在 PHP 7.1 里我们还可以指定键值来赋值,从而不用关心数组元素的顺序:
list('v1' => $value1, 'v2' => $value2) = array('v1' => 'foo', 'v2' => 'bar', ...);
// or
['v1' => $value1, 'v2' => $value2] = ['v1' => 'foo', 'v2' => 'bar', ...];
其实在 PHP 5 的年代,list 就有一个很不错的用法可能大家都不熟悉:
$arr = [
['x', 'y'],
['x1', 'y2'],
];
foreach ($arr as list($x, $y)) {
echo $x, ' ', $y, PHP_EOL;
}
到了 PHP 7.1,因为可以指定键值赋值,这种用法将更加的灵活,估计也更加常用:
$arr = [
['x' => 1, 'y' => '2'],
['x' => 2, 'y' => '4'],
];
foreach ($arr as ['x' => $x, 'y' => $y)) {
echo $x, ' ', $y, PHP_EOL;
}
再看看一个官网的例子,是不是感觉好像春风拂面一样清爽:
class ElePHPant
{
private $name, $colour, $age, $cuteness;
public function __construct(array $attributes) {
// $this->name = $attributes['name']; // 以前
// 现在
[
"name" => $this->name,
"colour" => $this->colour,
"age" => $this->age,
"cuteness" => $this->cuteness
] = $attributes;
}
// ...
}
值得一提的是:此种赋值方式,是可以嵌套使用的!
[[$a, $b], [$c, $d]] = [[1, 2], [3, 4]];
最后,在 PHP 7.1 的提案里有一个展望,也非常值得期待:
class ElePHPant
{
private $name, $colour, $age, $cuteness;
public function __construct(["name" => string $name, "colour" => \Colour $colour, "age" => int $age, "cuteness" => float $cuteness]) {
$this->name = $name;
$this->colour = $colour;
$this->age = $age;
$this->cuteness = $cuteness;
}
// ...
}
如果 PHP 推出此语法,那么参数列表将不再关心参数顺序,PHP 的小伙伴将不再羡慕 Ruby 的小伙伴啦!
PHP7 就要到来,网上也散布许多零散的相关的消息,PHP7 到底都有些什么改变?我们 PHPer 又将需要做什么改变,本篇博客将尝试一一列举。
PHP7 跟以前不兼容的地方
由于采纳了 AST(Abstract Syntax Tree) 以及 Uniform Variable Syntax,有些代码的意义会有变化,比如:
$obj->$properties['name']
// PHP5.6里等价于
$obj->{$properties['name']}
// 但在PHP7等价于
{$obj->$properties}['name']
为了以后升级 PHP7 的时候避免出现问题,目前的可以通过用大括号把代码写得更明确一些。
性能
由于 phpng 的采纳,性能将得到提升,这应该是 PHP7 聊得最多的话题了,当然,这种对于终端用户仅靠升级 PHP 就可以无痛提升性能的事情,肯定是大家最感兴趣的。除了运行性能的提升以外,内存占用也能得到一定改善,因为数据存储的结构也得到进一步优化。
低版本兼容
有些兼容代码将被取消掉,比如以前的 ASP 风格的开始标签以及 <script language="php"> 开始标签。
另外还有一大波功能或扩展即将被移除,比如 ext-mysql。
有一个有趣的小改变是,在 switch 里将不允许使用多个 default 语句(什么!以前可以吗?)。
新功能(此处应该有掌声)
尿点已过,精彩的部分已经到来。
普通变量的类型限制以及返回类型
话说之前,是否要给普通变量添加类型限制(也就是在函数定义时像 C 一样需要限制普通类型参数是 int,float 等类型)的 RFC 几乎被 PHP 社区全票通过,但是提议的作者却离开了 PHP 开发组,以及撤销了 RFC……结果导致后来又出现多个关于类型限制的 RFC,并且为了具体实现方式而相互掐架……不过最后还是原提案通过了最终决策。
好吧,对于我们终端用户来说,我们现在可以给普通变量添加类型限制了。不过默认情况类型限制并不是严格的,什么意思呢,比如 function foo(int $bar) {} 这个函数,如果第一个参数传入的是字符串 "123",并不会报错,而是被传换成了数字 123 之后,再传递给变量 $bar。
不过,我们可以通过在文件最上方添加代码 declare(strict_types=1) 来改变默认行为,这个时候如果刚才的函数传入的第一个参数还是字符串,那么就会产生 Fatal Error。
另外,PHP7 也支持定义返回类型,并且行为跟参数是类似的:
function isEven(int $number): bool
{
return $number % 2 === 1;
}
组合对比操作符
以前要对比两个数字是 A 大于 B,还是 A 小于 B,还是 A 等于 B,至少得写两个判断:
($a < $b) ? -1 : (($a > $b) ? 1 : 0)
有了组合对比操作符,上面的代码等同于
$a <=> $b
在PHP内核代码里,<=> 操作符叫做“T_SPACESHIP”(太空舰)……叫太空舰操作符或者宇宙飞船操作符还是很霸气的有木有。
Unicode 转义语法
你可以在字符串里使用 \u{xxxx} 来表示一个 unicode 字符。
?? 操作符
类似 ?: 操作符,但等价于 isset($foo) ? $foo : false
// 如果 $foo 不为 null,返回 $foo,否则返回 'default'
$foo ?? 'default'
// ??可以连续调用
$config = $config ?? $this->config ?? static::$defaultConfig;
匿名函数绑定
PHP5.4 的时候已经可以将一个方法绑定在一个对象上,在 PHP7 里实现更加简单:
class HelloWorld
{
private $greeting = "Hello";
}
$closure = function($whom) { echo $this->greeting . ' ' . $whom; }
$obj = new HelloWorld();
$closure->call($obj, 'World'); // Hello World
Use 语句分组
在 PHP7 之前,use 语句只能这么写
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
PHP7 可以这么写了
use Symfony\Componenet\HttpFoundation {
Request;
Response;
}
改进版生成器
在 PHP7 之前,生成器是不能有返回值的,否则会报错。不过 PHP7 里是没有问题的,只需要调用一下getReturn()方法即可。
function gen() {
yield "Hello";
yield " ";
yield "World!";
return "Goodbye Moon!";
}
$gen = gen();
foreach ($gen as $value) {
echo $value;
}
// Outputs "Hello" on iteration 1, " " on iterator 2, and "World!" on iteration 3
echo $gen->getReturn(); // Goodbye Moon!
生成器委托
PHP7 还支持生成器的相互委托,例如:
function hello() {
yield "Hello";
yield " ";
yield "World!";
yield from goodbye();
}
function goodbye() {
yield "Goodbye";
yield " ";
yield "Moon!";
}
$gen = hello();
foreach ($gen as $value) {
echo $value;
}
上面代码在每一次迭代的时候会依次输出 "Hello" " " "World!" "Goodbye" "Moon!",当然,自己委托自己也是可以的,只不过得小心不要死循环了。
更多的 Exception 类型
在 PHP7,内部错误也将采用 Exception 的方式抛出。当然他是单独的类型,叫 \EngineException,以后许多错误都将被 EngineException 代替。
除此之外,eval() 里的代码如果出现错误,将会抛出 \ParseException,如果函数的参数类型发现与传参不匹配,会抛出 \TypeException。如果要同时处理传统的 Exception 和 EngineException,那就得捕获他们共有的基类 \BaseException
好啦,PHP7 的新功能差不多就这些了,期待 PHP7 的到来吧。
新特性每一个版本都会有新特性了,这里我们来看php7.1新特性吧,希望文章能够让各位理解到php7.1新特性基本用法哦。
Allow specifying keys in list()
Square bracket syntax for array destructuring assignment
下面这个支持效果,还是不错的
list($a, $b) = array($b, $a);
[$a, $b] = [$b, $a];
foreach ($points as ["x" => $x, "y" => $y]) {
var_dump($x, $y);
}
这个在遍历的时候会很方便,也很强大
感觉这两个特性会使数组使用便捷一些
Nullable Types
这个就是一个简写的标量或null,用处有,但感觉不大
Generalize support of negative string offsets
这个特性好,可以简化一些简单的字符串处理
Support Class Constant Visibility
暂时想不到太大用处,只是将类常量完善了
Void Return Type
这个限制函数返回值有用
同时希望miexd,number什么的也尽快出来
Catching Multiple Exception Types
多cacth异常感觉没什么用,可能还是不太会用异常吧
剩下的都是比较明显的,没啥好讨论的改进,所以就一块儿说吧
字符串索引可使用负数
$str='abcdef';
var_dump($str[-2]); // => string(1) "e"
$str{-3} = '.';
var_dump($str); // => string(6) "abc.ef"
var_dump(isset($str{-4})); // => bool(true)
var_dump(isset($str{-10})); // => bool(false)
Void 返回类型
如果一个方法被设定成返回 void 类型,那么它将不能返回任何值
function foo(): void
{
return 1; // 报错,不能有返回
}
function foo(): void
{
return; // 正确
}
function foo(): void
{
// 也正确
}
但要注意 null 是不能返回的:
function foo(): void
{
return null; // 这也是不行的!
}
最后,如果子类要覆盖父类的某个返回 void 的方法,返回类型是不可以更改的。
类常量可见性设置
class Token
{
// 默认是 public 属性
const PUBLIC_CONST = 0;
// 可添加可见性设置
private const PRIVATE_CONST = 0;
protected const PROTECTED_CONST = 0;
public const PUBLIC_CONST_TWO = 0;
// 所有常量只能设置一次可见性
// 也可以这么写
private const FOO = 1, BAR = 2;
}
多种 Exception 同时 Catch
try {
// Some code...
} catch (ExceptionType1 | ExceptionType2 $e) {
// 如果有不同的异常想用一种方式来处理的时候,就很有用了
} catch (\Exception $e) {
// ...
}
好啦,PHP 7.1 的新特性就是这些了,大家有没有很期待呢?
超链接下载
如果浏览器支持超链接的方式下载文件,会在点击超链接的时候自动下载文件。
下面我们来测试一下通过超链接下载文件:
<a href="/Uploads/test.zip">通过超链接的方式下载文件</a><br>
当我们点击的时候如下所示:
超链接下载文件
通过超链接下载图片:
我们通过超链接下载图片时,会直接在浏览器打开显示,然后我们需要再存储到指定路径保存下来:
<a href="/Uploads/QC8054R7QPGQ_1000x500.jpg">通过超链接的方式下载图片</a><br>
效果是这样的:
超链接下载图片
通过程序下载
HTML端一行代码
<a href="download.php?filename=QC8054R7QPGQ_1000x500.jpg">通过程序的方式来下载图片</a>
download.php代码
我们是通过Header请求头来发送文件下载信息,指定下载的是附件,下载后的文件名,content-length来指定文件的大小,然后通过readfile函数来读取文件内容而实现文件下载:
<?php
$filename = $_GET['filename'];
header('content-disposition:attachment;filename='. basename($filename));
header('content-length:'. filesize($filename));
readfile($filename);
效果如下:
java里多线程就是一个new thread的事情,php依赖apache靠着linux底层有一个多线程的办法。
今天说说如果你无法操控apache的服务器,如何模拟php并发
<?php
if(function_exists('date_default_timezone_set')) {
date_default_timezone_set('PRC');
}
function a()
{
$time = time();
sleep(3);
$fp = fopen('result_a'.$time.'.log', 'w');
fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");
fclose($fp);
}
function b()
{
$time = time();
sleep(3);
$fp = fopen('result_b'.$time.'.log', 'w');
fputs($fp, 'Set in ' . Date('h:i:s', time()) . (double)microtime() . "rn");
fclose($fp);
}
if(!isset($_GET['act'])) $_GET['act'] = 'a';
if($_GET['act'] == 'a')
{
a();
}
else if($_GET['act'] == 'b') b();
?>
以上代码,在本地写入一个文件。
如果你访问 localhost/a.php 在两个浏览器标签尽可能快的同时打开,发现两个文件创建时间相差为3秒
但是如果你访问localhost/a.php?act=b 另一个访问/a.php?act=a 你发现两个文件创建的时间几乎差不多。
对于apache来说同样的url意味着一个线程(我们或者说是进程),但是不同的URL意味着可以并发。
如果php内部有下载的动作
function runThread()
{
down("http://localhost/test/a.php?act=a");
}
if($_GET['act'] == 'run')
{
echo 'start:';
runThread();
echo ' End';
}
http://localhost/test/a.php?act=run
http://localhost/test/a.php?act=run&s=2
只要主访问的url不同,则认为是不同的进行,意味着并发。文件创建时间不为3秒
本地有Linux服务器的朋友也可以借助linux来进行模拟并发
<?php
for ($i=0;$i<10;$i++) {
echo $i;
sleep(5);
}
?>
上面存成test.php, 然后写一段SHELL代码
#!/bin/bash
for i in 1 2 3 4 5 6 7 8 9 10
do
php -q test.php &
done
相关文章
- 在php中eval是一个函数并且不能直接禁用了,但eval函数又相当的危险了经常会出现一些问题了,今天我们就一起来看看eval函数对数组的操作 例子, <?php $data="array...2016-11-25
- 这篇文章主要介绍了Python 图片转数组,二进制互转操作,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2021-03-09
- 这篇文章主要介绍了C# 中 “$” 符号的作用以及用法,本文给大家介绍的非常详细,对大家的学习或工作具有一定的参考借鉴价值,需要的朋友可以参考下...2020-06-25
- 本文章提供在量的数据中级操作实例有如对键名比较计算数组的差集 计算差集 给指定数组中插入一个元素 反转数组 交集赋值新的数组实例。 //定义回调函数 funct...2016-11-25
- 这篇文章主要介绍了C#二维数组基本用法,以实例形式分析了C#中二维数组的定义、初始化、遍历及打印等用法,具有一定参考借鉴价值,需要的朋友可以参考下...2020-06-25
- Array数组在C#中同样是最基本的数据结构,下面为大家C#数组的常用操作方法小结,皆为细小的代码段,欢迎收看收藏...2020-06-25
- 下面一段代码给大家介绍php curl模拟post请求的示例代码,具体代码如下: <?php$uri = "http://www.cnblogs.com/test.php";//这里换成自己的服务器的地址// 参数数组$data = array ( 'name' => 'tanteng'// 'passwor...2015-11-24
- 某些时候,例如为了搭建一个测试环境,或者克隆一个网站,需要复制一个已存在的mysql数据库。使用以下方法,可以非常简单地实现。假设已经存在的数据库名字叫db1,想要复制一份,命名为newdb。步骤如下:1. 首先创建新的数据库newd...2015-10-21
- 下面小编就为大家带来一篇C# 拷贝数组的几种方法(总结)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧...2020-06-25
- 本文记录的要实现的功能类似于 MySQL 中的 ORDER BY,上个项目中有遇到这样的一个需求。 要求:从两个不同的表中获取各自的4条数据,然后整合(array_merge)成一个数组,再根据数据的创建时间降序排序取前4条。 遇到这个...2014-06-07
- 这篇文章主要介绍了C#实现字符串转换成字节数组的简单实现方法,仅一行代码即可搞定,非常简单实用,需要的朋友可以参考下...2020-06-25
- 这篇文章主要介绍了c#将字节数组转成易读的字符串的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧...2020-06-25
- 这篇文章主要介绍了C#读取文件所有行到数组的方法,涉及C#针对文件及数组的相关操作技巧,需要的朋友可以参考下...2020-06-25
- 如何将下面的二维数组转为一维数组。复制代码 代码如下:$msg = array( array( 'id'=>'45', 'name'=>'jack' ), array( 'id'=>'34', 'name'=>'mary' ), array( 'id...2014-05-31
- 在php中为我们提供了一个函数var_export 他可以直接将php代码入到一个文件中哦。 代码如下 复制代码 var_export($times,true);后面不加tru...2016-11-25
- 本文为代码分享,也是在工作中看到一些“大牛”的代码,做做分享。 具体是这样的,如下一个二维数组,是从库中读取出来的。 代码清单: 复制代码 代码如下: $user = array( 0 => array( 'id' => 1, 'name' => '张三', 'ema...2014-06-07
- 1.前言 昨天碰到一道关于如何解决有序数组的连接问题,这是一个很常见的问题。但是这里要考虑到代码的效率问题,因为要连接的数组都是有序的,这是一个非常重要的前提条件。2.简单但效率不高的算法 我首先想到的是使用...2013-10-04
- 今天小编就为大家分享一篇python 实现将Numpy数组保存为图像,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧...2020-04-27
C#中数组、ArrayList、List、Dictionary的用法与区别浅析(存取数据)
在工作中经常遇到C#数组、ArrayList、List、Dictionary存取数据,但是该选择哪种类型进行存储数据呢?很迷茫,今天小编抽空给大家整理下这方面的内容,需要的朋友参考下吧...2020-06-25- 这篇文章主要介绍了C# 复制与删除文件的实现方法的相关资料,希望通过本文能帮助到大家,让大家理解掌握这部分内容,需要的朋友可以参考下...2020-06-25