在php5.6官方文档的不兼容页(http://php.net/manual/zh/migration56.incompatible.php)中提到了几个与以前版本不兼容的情况,其中提到了为类定义数组属性时,不兼容的情况,原文及示例如下:

在 PHP 5.6 之前的版本中,为类定义数组类型的属性时, 如果数组中同时使用了显式数组键和隐式数组键,并且显式的键和隐式的序列键相同, 那么数组的键将被覆盖。例如:

 <?php
class C {
const ONE = 1;
public $array = [
self::ONE => 'foo',
'bar',
'quux',
];
} var_dump((new C)->array);
?>

以上示例在PHP 5.5中输出:

 array(2) {
[0]=>
string(3) "bar"
[1]=>
string(4) "quux"
}

在PHP 5.6中输出:

array(3) {
[1]=>
string(3) "foo"
[2]=>
string(3) "bar"
[3]=>
string(4) "quux"
}
以上的例子,其实是非常特例的情况,其出现的前提条件有几条:
1. 必须是为类定义数组属性,并且是在类变量定义时初始化该属性的情况;
2. 一定是显式数组键在前,隐式数组键在后,隐式数组键对与自身位置相同的显示数组键的值的覆盖的情况;如果隐式数组键在前,显式数组键定义在后,则覆盖是一定会发生的,与版本无关;
3. 显式数组键必须是常量(包括类常量)方式,如果是字面量常量,则无论什么版本,在以上情况下,都不会出现隐式数组键覆盖显式数组键;
考察以下示例在PHP 5.5中的输出:
1.1 非类数组成员定义:
 $array = [
ONE=>'foo',
'bar',
'quux'
];
var_dump($array);

输出:

array(3) {
[1] =>
string(3) "foo"
[2] =>
string(3) "bar"
[3] =>
string(4) "quux"
}

1.2 非初始化时赋值:

 define('ONE', 1);
class C {
public $array;
}
$c = new C;
$c->array = [ONE=>'foo','bar','quux'];
var_dump($c->array);

输出:

array(3) {
[1] =>
string(3) "foo"
[2] =>
string(3) "bar"
[3] =>
string(4) "quux"
}
 define('ONE', 1);
class C {
const ONE = 1;
public $array;
public function __construct() {
$this->array = array(
'bar',
ONE => 'foo',
'quux',
);
}
}
$c = new C;
var_dump($c->array);

输出:

array(3) {
[0] =>
string(3) "bar"
[1] =>
string(3) "foo"
[2] =>
string(4) "quux"
}

2. 显式键对隐式键的覆盖:

 define('ONE', 1);
class C {
const ONE = 1;
public $array = array(
'bar',
'quux',
ONE => 'foo',
'guru'
);
}
$c = new C;
var_dump((new C)->array);

输出:

array(3) {
[0] =>
string(3) "bar"
[1] =>
string(3) "foo"
[2] =>
string(4) "guru"
}

3. 字面量常量作为显式键名:

 class C {
public $array = array(
'bar',
'quux',
1 => 'foo',
'guru'
);
}
$c = new C;
var_dump((new C)->array);

输出:

array(3) {
[0] =>
string(3) "bar"
[1] =>
string(3) "foo"
[2] =>
string(4) "guru"
}
 class C {
public $array = array(
1 => 'foo',
'bar',
'quux',
);
}
$c = new C;
var_dump((new C)->array);

输出:

array(3) {
[1] =>
string(3) "foo"
[2] =>
string(3) "bar"
[3] =>
string(4) "quux"
}
其实本质上,这是一个隐藏的很深的小bug。
在数组的定义中,如果有部分单元指定了数字键名,其后的隐式键名会延续此前最大数字(包括隐式或显式)键名,而不应产生隐式键名覆盖显式数字键名情况,无论显式键名是字面量常量还是符号常量。
见官方手册数组一节:http://php.net/manual/zh/language.types.array.php:
 <?php
$array = array(
"a",
"b",
6 => "c",
"d",
);
var_dump($array);
?>

以上例程会输出:

array(4) {
[0]=>
string(1) "a"
[1]=>
string(1) "b"
[6]=>
string(1) "c"
[7]=>
string(1) "d"
}
只不过,5.6之前的版本在实现为类初始化数组成员时,用符号常量作数字键,对部分单元进行命名,出现了与数组语义定义不符的情况。
鉴于此种情况极其少见,故其影响较小,但一旦出现,则由此引起的bug极其难查。

php 5.6 与之前版本不兼容中的数组属性定义辨析的更多相关文章

  1. 解决Selenium与firefox浏览器版本不兼容问题

    因为在用java打开firefox浏览器的时候报错 org.openqa.selenium.firefox.NotConnectedException: Unable to connect to ho ...

  2. Selenium2学习-007-WebUI自动化实战实例-005-解决 Firefox 版本不兼容:org.openqa.selenium.WebDriverException: Failed to connect to binary FirefoxBinary

    此文主要讲述 Java 运行 Selenium 脚本时,因 Friefox 浏览器版本与 selenium-server-standalone-x.xx.x.jar 不兼容引起的 org.openqa ...

  3. cuda和gcc版本不兼容

    gcc8.1和cuda9.0版本不兼容,比较坑. 下面是各版本cuda支持的gcc: 从CUDA 4.1版本开始,现在支持gcc 4.5.gcc 4.6和4.7不受支持. 从CUDA 5.0版本开始, ...

  4. Gradle 'MYasprj' project refresh failed Error:CreateProcess error=216, 该版本的 %1 与您运行的 Windows 版本不兼容

    Gradle ‘MYasprj’ project refresh failed Error:CreateProcess error=216, 该版本的 %1 与您运行的 Windows 版本不兼容.请 ...

  5. 模块XXXX可能与您正在运行的Windows版本不兼容。检查该模块是否与regsvr32.exe的x86(32位)x64(64位)版本兼容。

    最近自己在编写ActiveX控件.遇到的麻烦事不少. 今天遇到了这个问题“模块XXXX可能与您正在运行的Windows版本不兼容.检查该模块是否与regsvr32.exe的x86(32位)x64(64 ...

  6. ubuntu下python安装pandas和numpy等依赖库版本不兼容的问题RuntimeWarning: numpy.dtype size changed

    习惯了linux下用pip install numpy及pip install pandas命令了.折腾了好久了. 上来先在python3中pip3 install numpy装了numpy,然后再p ...

  7. 【我的Android进阶之旅】解决 Error:CreateProcess error=216, 该版本的 %1 与您运行的 Windows 版本不兼容。请查看计算机的系统信息,了解是否需要 x86

    一.错误描述 刚刚打开Android Studio新建一个项目,然后就编译不了,报了如下所示的错误: 错误描述为: Error:CreateProcess error=216, 该版本的 %1 与您运 ...

  8. 解决selenium与firefox版本不兼容问题

    Python环境下类比 个人使用 32位环境 Python 2.7.12 Selenium 2.53.6 Firefox 47.01 安装selenium可用pip选择对应版本,参考另一教程. 因为在 ...

  9. idea2019版与maven3.6.2版本不兼容引发的血案

    昨天遇到了点问题解决浪费了一些时间(导致更新内容较少)回顾下问题 项目出现Unable to import maven project: See logs for details 翻了好多博客 莫名的 ...

随机推荐

  1. ehcache配置:使用Spring+SpringMVC+Mybatis或者有shiro

    SSM框架的搭建就不在叙述了 本文主要是讲解在SSM基础上再加上ehcache 1:首先:pom.xml需要的jar <dependency> <groupId>org.myb ...

  2. POJ 2777-题解

    一.题意 给你一排N个格子,M种颜色,P个操作.有两种操作:(1)C A B D:把[A, B]区间内的所有格子涂成颜色D.(2)P A B:输出[A, B]区间内的颜色的种类数.注意,初始颜色为1. ...

  3. 测试工具-PICT-微软基于数据项多个取值的正交法用例生成工具

    下载 http://download.microsoft.com/download/f/5/5/f55484df-8494-48fa-8dbd-8c6f76cc014b/pict33.msi 这里使用 ...

  4. VB.NET 指针

    在.NET中,对指针指向数据的存储函数都封装在marshal类中,主要的函数包括:Copy.PtrToStringUni .PtrToStructure .OffsetOf.WriteXXX,Rrea ...

  5. #region 常量和静态变量静态类readonly

    #region 常量和静态变量静态类readonly //---------------------------------------------------------------------- ...

  6. Jmeter Http接口性能测试

    Jmeter Http接口性能测试 1.      启动Jmeter Jmeter下载解压即可使用,Jmeter启动,点击D:\ProgramFiles\jmeter\apache-jmeter-2. ...

  7. LevelDB Cache机制

    [LevelDB Cache机制] 对于levelDb来说,读取操作如果没有在内存的memtable中找到记录,要多次进行磁盘访问操作.假设最优情况,即第一次就在level 0中最新的文件中找到了这个 ...

  8. 学习 java 编程语言两个月来的感受

    今天是我接触java编程的第81天, 现在的感受是觉得非常快乐, 每次看着自己的写的代码能成功运行的时候那种喜悦是无法言表的, 最初接触电脑还是在小学, 后来到了初中觉得电脑无非就是点点鼠标, 按按键 ...

  9. 聊一下Python的线程 & GIL

    再来聊一下Python的线程 参考这篇文章 https://www.zhihu.com/question/23474039/answer/24695447 简单地说就是作为可能是仅有的支持多线程的解释 ...

  10. jquery中的属性和样式设置

    添加属性 $target.attr({"title":"one piece","name":"solgan"}); 为目 ...