澳门新葡萄京官网首页PHP中动态特性学习笔记

PHP5.3介绍PHP2008魁北克-IliaAlshanetsky.新版本的特性*兼职老版本下的代码*重点主要放在现有的功能的改进*更少的bug*更快的发布周期1.命名空间(Namespaces)*PHP5.3最大的新功能*完全支持名字空间特征*大部分的功能的执行在编译时*简化命名惯例1)更清晰的代码不使用NamespacesfunctionMY_wrapper(){}classMY_DB{}define(”MY_COMM_STR”,””);MY_wrapper();newMY_DB();MY_COMM_STR;2)使用NamespacesnamespaceMY;functionwrapper(){}classDB{}constCONN_STR=””;useMYASMY;wrapper();newDB();CONN_STR;3)一个文件中多个名字空间namespaceLIB;classMYSQL{}classSQLite{}$b=newSQLite(;namespaceLIB_EXTRA;classMScrypt{}$anewMScrypt();var_dump(get_class($a),get_class($b)};//result://string(18)LIB_EXTRA::MScrypt//string(11)LIB::SQLite4)名字空间的层级namespacefoo;functionstrlen($foo){returnhtmlspecialchars($foo);}echostrlen(test);//testecho::strlen(test)//4echonamespace::strlen(test);//test*function,class和constant引用在一个名字空间中首先指向这个名字空间,其次才是一个全局的范围5)名字空间自动引入function__autoload($var){var_dump($var);}//LIB::foorequire./ns.php;/**?phpnamespaceLIB;newfoo();?*/*__autoload()将处理为和名字空间的类名一起。*autoload仅在class不在名字空间和全局范围内存在时触发。*__autoload()声明在一个名字空间中将不别调用!6)其他的名字空间的语法技巧namespacereally::long::pointlessly::verbose::ns;__NAMESPACE__;//当前的名字空间名称classa{}get_class(newa());//really::long::pointlessly::verbose::ns::absusereally::long::pointlessly::verbose::ns::aASb;//从一个名字空间引用class2.改进的性能*md5()速度提高了大概10-15%*引擎中更好的堆栈实现*常量移到只读内存区*改进Exception处理(更简单更少的代码)*调用(require/include)_once去掉了使用open(2)(linux下的c函数)*使用gcc4编译的二进制更小更快整体性能提高5-15%3.新的语言特性1)__DIR__*引入__DIR__magic常量定位脚本的目录echodirname(__FILE__);//PHP5.3/*vs*/echo__DIR__;//=5.32)?:操作符*允许从2个值的or/and表达式快速的获取一个非空的值$a=true?:false;//true;$a=false?:true;//true;$a=?:1;//1$a=0?:2;//2$a=array()?:array(1);//array(1);$a=strlen()?:strlen(a);//13)__callStatic()*等价于__call(),但它是为调用静态方法准备的classhelper{staticfunction__callStatic($name,$args){echo$name.”(”.implode(”,”$args).”)”;}}helper::test(foo,bar);//test(foo,bar);//动态的函数/方法调用有点慢…4)动态的调用静态方法*php现在允许动态的调用静态的方法classhelper{staticfunctionfoo(){echo__METHOD__;`}}$a=helper;$b=foo;$a::$b();//helper::foo//动态的函数/方法调用有点慢…5)延迟静态绑定*静态处理从编译时延迟到执行时classA{publicstaticfunctionwhoami(){echo__CLASS__;}publicstaticfunctionidentity(){self::whoami();}}classBextendsA{publicstaticfunctionwhoami(){echo__CLASS__;}}B::identity();//A–php5.3classA{publicstaticfunctionwhoami(){echo__CLASS__;}publicstaticfunctionidentity(){static::whoami();}}classBextendsA{publicstaticfunctionwhoami(){echo__CLASS__;}}B::identity();//B–php=5.3*小心使用操作码缓存,没有向后兼容6)MySQLInd*特殊的,高速的专门为PHP设计的MySQL调用库接口*更好的性能*内存的使用优化*内置的驱动(不是适应性的再次扩展)*ManyfutureoptionsduetotightintegrationwithPHP*目前还没有PDO_MySQL支持mysql(i)onlyfornow7)INIMagic*CGI/FastCGI支持.htaccess形式的INI控制*用户可以自己设定每个目录的INI在php.ini中通过[PATH=/var/]设定*优化错误处理*允许用户使用INI变量和常量任何定义的INI文件中*其他几个小的优化用户自定义的php.ini(.htaccess)文件名.默认为.user.iniuser_ini.filename=.user.ini禁止这个特性设置这个选项为空值用户自定义php.ini的缓存失效期(time-to-live)秒数.默认is300s(5分钟)user_ini.cache_ttl=300s[PATH=/var/]variables_order=GPCsafe_mode=1[myvaribles]somevar=1234anothervar=${somevar};anothervar==somevar[iniarrays]foo[bar]=1foo[123]=2foo[]=38)扩展的OpenSSL函数*使用OpenSSLDigest函数foreach(openssl_get_md_methods()as$d){//MD4,MD5,SHA512…(12allinall)echo$d.-.openssl_digest(foo,md5);//acbd18db4cc2f85cedef654fccc4a4d8}*使用OpenSSL加密函数//BF-CBC,AES-256CFB1…(54allinall)foreach(openssl_get_cipher_methods()as$v){$val=openssl_encrypt(value,$v,secret);openssl_decrypt($val,$v,secret);//value}*扩展的openssl_pkey_new()和openssl_pkey_get_details()函数允许访问内部的DSA,RSA和DH密匙.其目标在PHP中实现一个简单的OpenId9)SPL(StandardPHPLibrary)优化*优化嵌套的目录迭代次数由文件系统迭代*引入GlobIterator*各种各样的数据结构类:双链表,堆栈,队列,堆,小型堆,大型堆,优先级队列*其他的很绕口的一些特征10)时间处理进行扩展了和添加*可控制的strtotime()由date_create_from_format()实现$date=strtotime(08-01-0700:00:00);var_dump(date(Y-m-d,$date));//string(10)2008-01-07$date=date_create_from_format(m-d-y,08-01-07);var_dump($date-format(”Y-m-d”));//string(10)2007-08-01*添加了date_get_last_errors(),并且返回时间语法分析的错误和警告array(4){[warning_count]=int(0)[warnings]=array(0){}[error_count]=int(2)[errors]=array(2){[2]=string(40)Theseparationsymbolcouldnotbefound[6]=string(13)Trailingdata}}11)getopt()优化*影响Windows平台*本地的执行不依赖于本地getopt()实现.*跨平台支持长选项(–option)//input:–a=foo–b–cvar_dump(getopt(,array(a:,b::,c)));/*output:array(3){[a]=string(3)foo[b]=bool(false)[c]=bool(false)}*/12)XSLTProfiling*引入XsltProfiling通过setProfiling()实现$xslt=newxsltprocessor();$xslt-importStylesheet($xml);$xslt-setProfiling(/tmp/profile.txt);$xslt-transformToXml($dom);ResultingIn:numbermatchnamemodeCallsTot100usAvg0date55811Total55813)E_DEPRECATED标记*怎么样将一个php发行为一个没有错误的模式?废弃*E_DEPRECATED用来指定废弃的功能,或许未来的版本中会消除。14)垃圾回收器*为复杂和长时间运行脚本的执行结束周期释放内存的清理gc_enable();//允许垃圾回收var_dump(gc_enabled());//truevar_dump(gc_collect_cycles());//某个元素的清理gc_disable();//禁止垃圾回收15)NOWDOC*一个HEREDOC不再进行转译HEREDOC$foo=ONEthisis$fubarONE;/*string(10)thisis*/NOWDOC$bar=TWOthisis$fubarTWO;/*string(16)thisis$fubar*/4.其他优化*SQLite升级到3.5.6*40多个bug被修复*CGI/FastCGISAPI优化*各种流的优化*未来更多的优化<

本文主要总结给对PHP 特性不了解的新手看的,因此演示代码占比较多的篇幅。
大家看还缺哪些给补充吧。欢迎来邮件或在PHPChina
的《PHPer》杂志版块纠正错误。
动态语言就是能够在运行时改变程序结构和变量类型的语言。例如:新的类和对
象可以被加载和创建,新的函数或方法可以加入和去除等等,比如Smalltalk、Ruby、
Python、PHP、Lua、Perl、Groovy
等。反之则是静态语言,比如C/C++、Java、C#等。
动态语言的动态特性决定它开发的时候需要更少的代码,有更高的灵活性。PHP
的动态特性奠定了它存在的价值,熟悉PHP 的动态特性让我们更能活用PHP。
1 弱类型变量
动态语言都被设计成弱类型,也就是说变量被赋值以后才能确定它的数据类型,
当代码在实际执行时,才会检测变量是否被非法使用。
PHP 变量是弱类型变量就意味着,我们不需要声明变量的类型,在运行时自动检
测变量的类型,并且可以认为改动变量的类型。
2、PHP动态特性:
特性1、弱类型变量
PHP变量是弱类型变量就意味着,我们不需要声明变量的类型,在运行时自动检测变量的类型,并且可以认为改动变量的类型。

Buid-in web server内置了一个简单的Web服务器

 代码如下

把当前目录作为Root Document只需要这条命令即可:
php -S localhost:3300

// PHP弱类型变量例子
$test = 1;
print gettype($test) . “: $testn”;
$test = 1.23456789;
print gettype($test) . “: $testn”;
$test = ‘test’;  // 变量自动改变类型
print gettype($test) . “: $testn”;
$test = array(‘t’=>’HI,I m from an array!’);
settype($test, ‘object’);  // 改变变量的类型
print gettype($test) . “: {$test->t}n”;
// 测试变量类型
if(is_object($test)) {
    print “Test Type: My Type Is object.n”;
} else {
    print gettype($test);
}

也可以指定其它路径
php -S localhost:3300 -t /path/to/root

弱类型并不意味着代码不安全,或者不健壮。极限编程已经给成为一种软件开发方法。这个方法侧重测试,使用全面的单元测试方案来驱动开发过程。通过不同环境
下执行所编写的代码,就可以保证代码的安全性和健壮性。经验证明,在弱类型语言中,综合运用弱类型和单元测试通常比传统系统编程语言的类型检查更好(请参
 特性2、可变变量
一个变量的变量名可以动态的设置和使用

还可以指定路由
php -S localhost:3300 router.php

 代码如下

命名空间(php5.3)
命名空间的分隔符为反斜杆
namespace foxlanmpsTable; class Select {}

// 可变变量例子
$var = ‘hi’;
$$var = ‘hello’;
print $var;
print $$var;
print $hi;  // 等价于上一行

获取完整类别名称
PHP5.3
中引入命名空间的别名类和命名空间短版本的功能。虽然这并不适用于字符串类名称
use SomeDeeplyNestedNamespaceFooBar; // does not work, because
this will try to use the global FooBar class $reflection = new
ReflectionClass(‘FooBar’); echo FooBar::class;

特性3、变量函数
这意味着如果一个变量名后有圆括号,PHP
将寻找与变量的值同名的函数,并且将尝试执行它。除了别的事情以外,这个可以被用于实现回调函数,函数表等等。

为了解决这个问题采用新的FooBar::class语法,它返回类的完整类别名称
命名空间 use 操作符开始支持函数和常量的导入
namespace NameSpace { const FOO = 42; function f() { echo
FUNCTION.”n”; } } namespace { use const NameSpaceFOO; use
function NameSpacef; echo FOO.”n”; f(); }

 代码如下

输出 42 NameSpacef
Group use declarations
从同一 namespace 导入的类、函数和常量现在可以通过单个 use 语句
一次性导入了。
//PHP7之前use somenamespaceClassA;use somenamespaceClassB;use
somenamespaceClassC as C;use function somenamespacefn_a;use
function somenamespacefn_b;use function somenamespacefn_c;use
const somenamespaceConstA;use const somenamespaceConstB;use
const somenamespaceConstC;// PHP7之后use somenamespace{ClassA,
ClassB, ClassC as C};use function somenamespace{fn_a, fn_b,
fn_c};use const somenamespace{ConstA, ConstB, ConstC};

// 变量函数例子
// 无参数函数
function a(){
    print “i’m an”;
}
// 有参数函数
function b($param) {
    print “i’m b, param: $paramn”;
}
$x = ‘a’;
$x();
$x = ‘b’;
$x(‘xxxxxxxxxxx’);

支持延迟静态绑定
static关键字来引用当前类,即实现了延迟静态绑定
class A { public static function who() { echo CLASS; } public static
function test() { static::who(); // 这里实现了延迟的静态绑定 } } class B
extends A { public static function who() { echo CLASS; } }B::test();

特性4、可变长度参数列表
调用函数的时候,函数的参数个数可以不一样

输出结果: B
支持goto语句
多数计算机程序设计语言中都支持无条件转向语句goto,当程序执行到goto语句时,即转向由goto语句中的标号指出的程序位置继续执行。尽管goto语句有可能会导致程序流程不清晰,可读性减弱,但在某些情况下具有其独特的方便之处,例如中断深度嵌套的循环和
if 语句。
goto a; echo ‘Foo’; a: echo ‘Bar’; for($i=0,$j=50; $i<100; $i++) {
while($j–) { if($j==17) goto end; } } echo “i = $i”; end: echo ‘j hit
17’;

 代码如下

支持闭包、Lambda/Anonymous函数
闭包(Closure)函数和Lambda函数的概念来自于函数编程领域。例如JavaScript
是支持闭包和 lambda 函数的最常见语言之一。
在PHP中,我们也可以通过create_function()在代码运行时创建函数。但有一个问题:创建的函数仅在运行时才被编译,而不与其它代码同时被编译成执行码,因此我们无法使用类似APC这样的执行码缓存来提高代码执行效率。
在PHP5.3中,我们可以使用Lambda/匿名函数来定义一些临时使用(即用即弃型)的函数,以作为array_map()/array_walk()等函数的回调函数。
echo preg_replace_callback(‘-([a-z])‘, function ($match)
{ return strtoupper($match[1]); }, ‘hello-world’); // 输出 helloWorld
$greet = function($name) { printf(“Hello %srn”, $name); };
$greet(‘World’); $greet(‘PHP’); //…在某个类中 $callback = function
($quantity, $product) use ($tax, &$total) { $pricePerItem =
constant(CLASS . “::PRICE_” . strtoupper($product)); $total +=
($pricePerItem * $quantity) * ($tax + 1.0); };

function foo() {
   $numargs = func_num_args();
   print “Number of arguments: $numargsn”;
   print “the third argument: ” . func_get_arg(2) . “n”;
}
foo(1, 2, ‘…@…’);
foo(1, 2, ‘############’, 4);

魔术方法__callStatic()和__invoke()
PHP中原本有一个魔术方法__call(),当代码调用对象的某个不存在的方法时该魔术方法会被自动调用。新增的__callStatic()方法则只用于静态类方法。当尝试调用类中不存在的静态方法时,__callStatic()魔术方法将被自动调用。
class MethodTest { public function __call($name, $arguments) { // 参数
$name 大小写敏感 echo “调用对象方法 ‘$name’ ” . implode(‘ — ‘,
$arguments). “n”; } /** PHP 5.3.0 以上版本中本类方法有效 */ public
static function __callStatic($name, $arguments) { // 参数 $name
大小写敏感 echo “调用静态方法 ‘$name’ ” . implode(‘ — ‘, $arguments).
“n”; } } $obj = new MethodTest; $obj->runTest(‘通过对象调用’);
MethodTest::runTest(‘静态调用’); // As of PHP 5.3.0

 

以上代码执行后输出如下: 调用对象方法’runTest’ –-
通过对象调用调用静态方法’runTest’ –- 静态调用
以函数形式来调用对象时,__invoke()方法将被自动调用。
class MethodTest { public function __call($name, $arguments) { // 参数
$name 大小写敏感 echo “Calling object method ‘$name’ ” . implode(‘, ‘,
$arguments). “n”; } /** PHP 5.3.0 以上版本中本类方法有效 */ public
static function __callStatic($name, $arguments) { // 参数 $name
大小写敏感 echo “Calling static method ‘$name’ ” . implode(‘, ‘,
$arguments). “n”; } } $obj = new MethodTest; $obj->runTest(‘in
object context’); MethodTest::runTest(‘in static context’); // As of PHP
5.3.0

特性5,从数组中导出变量
把数组中的数据复制出变量,将键名当作变量名,值作为变量的值。

Nowdoc语法
用法和Heredoc类似,但使用单引号。Heredoc则需要通过使用双引号来声明。
Nowdoc中不会做任何变量解析,非常适合于传递一段PHP代码。
// Nowdoc 单引号 PHP 5.3之后支持 $name = ‘MyName’; echo
<<<‘EOT’ My name is “$name”. EOT; //上面代码输出 My name is
“$name”. ((其中变量不被解析) // Heredoc不加引号 echo <<<FOOBAR
Hello World! FOOBAR; //或者 双引号 PHP 5.3之后支持 echo
<<<“FOOBAR” Hello World! FOOBAR;

 

支持通过Heredoc来初始化静态变量、类成员和类常量。
// 静态变量 function foo() { static $bar = <<<LABEL Nothing in
here… LABEL; } // 类成员、常量 class foo { const BAR =
<<<FOOBAR Constant example FOOBAR; public $baz =
<<<FOOBAR Property example FOOBAR; }

 代码如下

在类外也可使用const来定义常量
//PHP中定义常量通常是用这种方式 define(“CONSTANT”, “Hello world.”);
//并且新增了一种常量定义方式 const CONSTANT = ‘Hello World’;

// 例1
$a = array(‘x’ => 100, ‘y’=> 200, ‘z’ => 300);
// 从数组中将变量导入到当前的符号表
extract($a); // 和extract相反的函数是compact()
print “$x $y $z”;

三元运算符增加了一个快捷书写方式
原本格式为是(expr1) ? (expr2) : (expr3)
如果expr1结果为True,则返回expr2的结果。
新增一种书写方式,可以省略中间部分,书写为expr1 ?: expr3
如果expr1结果为True,则返回expr1的结果
$expr1=1;$expr2=2;//原格式 $expr=$expr1?$expr1:$expr2 //新格式
$expr=$expr1?:$expr2

// 例2
$a = array(100, 200, 300);
list($x, , $z) = $a;
print “$x $z”;

输出结果: 1 1
空合并运算符(??)
简化判断
$param = $_GET[‘param’] ?? 1;

特性6,用一个数组的值作为其键名,另一个数组的值作为其值,创建一个数组

相当于:
$param = isset($_GET[‘param’]) ? $_GET[‘param’] : 1;

 代码如下

Json更懂中文(JSON_UNESCAPED_UNICODE)
echo json_encode(“中文”, JSON_UNESCAPED_UNICODE); //输出:”中文”

$a = array(‘green’, ‘red’, ‘yellow’);
$b = array(‘avocado’, ‘apple’, ‘banana’);
$c = array_combine($a, $b);
print_r($c);

二进制
$bin = 0b1101; echo $bin; //13

特性7,动态创建函数

Unicode codepoint 转译语法
这接受一个以16进制形式的 Unicode
codepoint,并打印出一个双引号或heredoc包围的 UTF-8 编码格式的字符串。
可以接受任何有效的 codepoint,并且开头的 0 是可以省略的。
echo “u{9876}”

 代码如下

旧版输出:u{9876} 新版输入:顶
使用 ** 进行幂运算
加入右连接运算符 ** 来进行幂运算。 同时还支持简写的 **=
运算符,表示进行幂运算并赋值。
printf(“2 ** 3 == %dn”, 2 ** 3);printf(“2 ** 3 ** 2 == %dn”,
2 ** 3 ** 2);$a = 2;$a **= 3;printf(“a == %dn”, $a);

// lambda函数
$newfunc = create_function(‘$a,$b’, ‘return “$a + $b = ” . $a + $b;’); 
// 创建了一个匿名函数
print “nNew anonymous function: $newfuncn”;
print $newfunc(2, 4);
print “n”;
// 效果类似于
function test($a,$b){
    return “$a + $b = ” . $a + $b;
}
print test(2, 4);

输出 2 ** 3 == 8 2 ** 3 ** 2 == 512 a == 8
太空船操作符(组合比较符)
太空船操作符用于比较两个表达式。当 a大于、等于或小于b 时它分别返回 -1 、
0 或 1 。 比较的原则是沿用 PHP 的常规比较规则进行的。
// Integersecho 1 <=> 1; // 0echo 1 <=> 2; // -1echo 2
<=> 1; // 1// Floatsecho 1.5 <=> 1.5; // 0echo 1.5 <=>
2.5; // -1echo 2.5 <=> 1.5; // 1// Stringsecho “a” <=> “a”;
// 0echo “a” <=> “b”; // -1echo “b” <=> “a”; // 1

特性8、自动加载对象
可以定义一个 __autoload 函数,它会在试图使用尚未被定义的类时自动调用。

Traits
Traits提供了一种灵活的代码重用机制,即不像interface一样只能定义方法但不能实现,又不能像class一样只能单继承。至于在实践中怎样使用,还需要深入思考。
魔术常量为TRAIT
官网的一个例子: trait SayWorld { public function sayHello() {
parent::sayHello(); echo “World!n”; echo ‘ID:’ . $this->id . “n”;
} } class Base { public function sayHello() { echo ‘Hello ‘; } } class
MyHelloWorld extends Base { private $id; public function __construct()
{ $this->id = 123456; } use SayWorld; } $o = new MyHelloWorld();
$o->sayHello(); /*will output: Hello World! ID:123456 */

 代码如下

array 数组简写语法
$arr = [1,’james’,
‘james@fwso.cn’];
$array = [   ”foo” => “bar”,   ”bar” => “foo”   ];

// ClassA.php, 这段代码写在ClassA.php
class A {
    function __construct() {
        print ‘yeah!’;
    }
}

array 数组中某个索引值简写
function myfunc() { return array(1,’james’,
‘james@fwso.cn’);
}echo myfunc()[1]; $name = explode(“,”, “Laruence,male”)[0];
explode(“,”, “Laruence,male”)[3] = “phper”;

5
function __autoload($className) {
   require_once $className . ‘.php’;
}
// 这段代码写在b.php
new A();  //
程序运行到这里的时候,A类未定义,将自动调用__autoload()函数
特性9、__get和__set代替所有对属性变量数组的访问

非变量array和string也能支持下标获取了
echo array(1, 2, 3)[0]; echo [1, 2, 3][0]; echo “foobar”[2];

class Setter{
   public $n;
   private $x = array(“a” => 1, “b” => 2, “c” => 3);
   private function __get($nm) {
       echo “Getting [$nm]n”;
       if (isset($this->x[$nm])) {
           $r = $this->x[$nm];
           print “Returning: $rn”;
           return $r;
       } else {
           echo “Nothing!n”;
       }
   }
   private function __set($nm, $val) {
       echo “Setting [$nm] to $valn”;
       if (isset($this->x[$nm])) {
           $this->x[$nm] = $val;
           echo “OK!n”;
       } else {
           echo “Not OK!n”;
       }
   }
   private function __isset($nm) {
       echo “Checking if $nm is setn”;
       return isset($this->x[$nm]);
   }
   private function __unset($nm) {
       echo “Unsetting $nmn”;
       unset($this->x[$nm]);
   }
}
$foo = new Setter();
$foo->n = 1;
$foo->a = 100;
$foo->a++;
$foo->z++;
var_dump(isset($foo->a)); //true
unset($foo->a);
var_dump(isset($foo->a)); //false
// this doesn’t pass through the __isset() method
// because ‘n’ is a public property
var_dump(isset($foo->n));
var_dump($foo);

支持为负的字符串偏移量
现在所有接偏移量的内置的基于字符串的函数都支持接受负数作为偏移量,包括数组解引用操作符([]).
var_dump(“abcdef”[-2]);var_dump(strpos(“aabbcc”, “b”, -3));

 

以上例程会输出:
string (1) “e”int(3)

特性10、自定义未定义的方法
你调用未定义方法时,方法名和方法接收的参数将会传给__call方法

常量引用
“常量引用”意味着数组可以直接操作字符串和数组字面值。举两个例子:
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 }

 代码如下

常量增强
允许常量计算,允许使用包含数字、字符串字面值和常量的标量表达式
const A = 2; const B = A + 1; class C { const STR = “hello”; const STR2
= self::STR + “, world”; }

class Caller {
   private $x = array(1, 2, 3);
   private function __call($m, $a) {
       print “Method $m called:n”;
       print_r($a);
       return $this->x;
   }
}
$foo = new Caller();
$a = $foo->test(1, “2”, 3.4, true);
print_r($a);

允许常量作为函数参数默认
function test($arg = C::STR2)

特性11、自定义错误、异常处理
设置使用自定义错误或异常处理函数后,当发生错误或异常时将调用自定义的处理函数代替系统错误处理函数。

类常量可见性 现在起支持设置类常量的可见性。
class ConstDemo{ const PUBLIC_CONST_A = 1; public const
PUBLIC_CONST_B = 2; protected const PROTECTED_CONST = 3; private
const PRIVATE_CONST = 4;}

 代码如下

通过define()定义常量数组
define(‘ANIMALS’, [‘dog’, ‘cat’, ‘bird’]);echo ANIMALS[1]; //
outputs “cat”

set_error_handler(‘error_handler’);  //
设置错误时调用的自定义处理错误函数,设置自定义异常处理函数为set_exception_handler()
print $a/0;  // 这里逻辑错了,调用error_handler()报错
function error_handler($errno, $message, $filename, $line) {
  if ($errno & (E_ALL ^ E_NOTICE)) {
    $types = array(
        1 =>     ‘error’,
        2 =>     ‘warning’,
        4 =>     ‘parse error’,
        8 =>     ‘notice’,
        16 =>    ‘core error’,
        32 =>    ‘core warning’,
        64 =>    ‘compile error’,
        128 =>   ‘compile warning’,
        256 =>   ‘user error’,
        512 =>   ‘user warning’,
        1024 =>  ‘user notice’,
        2048 =>  ‘strict warning’
    );
    print
“n~~~~~~~~~~~~~~n”;
    print $types[$errno] .’: ‘. $message .’ in ‘. $filename .’ on line
‘. $line .’.’;
    print
“n
~~~~~~~~~~~~~~n”;
    exit;  
  }
}

函数变量类型声明
两种模式 : 强制 ( 默认 ) 和 严格模式
类型:array,object(对象),string、int、float和 bool
class bar { function foo(bar $foo) { }
//其中函数foo中的参数规定了传入的参数必须为bar类的实例,否则系统会判断出错。同样对于数组来说,也可以进行判断,比如:
function foo(array $foo) { } }   foo(array(1, 2, 3)); //
正确,因为传入的是数组   foo(123); // 不正确,传入的不是数组function
add(int $a) { return 1+$a; } var_dump(add(2));function foo(int $i) {
… } 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

特性12、高可配置性
可修改范围为
PHP_INI_USER 的 配置选项可在用户的PHP脚本或Windows注册表中设置
PHP_INI_PERDIR 的 配置选项可在 php.ini, .htaccess 或 httpd.conf
中设置
PHP_INI_SYSTEM 的 配置选项可在 php.ini or httpd.conf 中设置
PHP_INI_ALL 的 配置选项可在各处设置
我们要熟悉在php.ini中修改php的配置,还会经常在php脚本中修改脚本中可修改的配置项。
可以使用
ini_set()函数或专门修改运行时配置的函数来改变可修改范围为PHP_INI_ALL

参数跳跃
如果你有一个函数接受多个可选的参数,目前没有办法只改变最后一个参数,而让其他所有参数为默认值。
RFC上的例子,如果你有一个函数如下:
function create_query($where, $order_by, $join_type=”, $execute =
false, $report_errors = true) { … }

// 修改php的配置参数
ini_set(‘session.save_path’, ‘D:/temp’);  //
修改配置让脚本把session文件保存到D:/temp目录

那么有没有办法设置$report_errors=false,而其他两个为默认值。为了解决这个跳跃参数的问题而提出:
create_query(“deleted=0”, “name”, default, default, false);

特性13、代码中执行php脚本
特性14、php的工作模型
(这个特性详细的在)
作为一种纯解释型语言,PHP脚本在每次被解释时进行初始化,在解释完毕后终止运行。这种运行是互相独立的,每一次请求都会创建一个单独的进程或线程,来解释相应的页面文件。页面创建的变量和其他对象,都只在当前的页面内部可见,无法跨越页面访问旧电脑回收。
在终止运行后,页面中申请的、没有被代码显式释放的外部资源,包括内存、数据库连接、文件句柄、Socket连接等,都会被强行释放。
  也就是说,PHP无法在语言级别直接访问跨越页面的变量,也无法创建驻留内存的对象。
PHP这种独特的工作模型的优势在于,基本上解决了令人头疼的资源泄漏问题。Web应用的特点是大量的、短时间的并发处理,对各种资源的申请和释放工作非常频繁,很容易导致泄漏。
但是,这种机制的缺点也非常明显。最直接的后果是,PHP在语言级别无法实现跨页面的缓冲机制。
补充一点,对象克隆
PHP对象赋值到变量是传引用的,需要复制对象需要用clone。

可变函数参数
代替 func_get_args()
function add(…$args) { $result = 0; foreach($args as $arg) $result +=
$arg; return $result; }

可为空(Nullable)类型
类型现在允许为空,当启用这个特性时,传入的参数或者函数返回的结果要么是给定的类型,要么是
null 。可以通过在类型前面加上一个问号来使之成为可为空的。
function test(?string $name){ var_dump($name);}

以上例程会输出:
string(5) “tpunt”NULLUncaught Error: Too few arguments to function
test(), 0 passed in…

Void 函数
在PHP 7 中引入的其他返回值类型的基础上,一个新的返回值类型void被引入。
返回值声明为 void 类型的方法要么干脆省去 return 语句,要么使用一个空的
return 语句。 对于 void 函数来说,null 不是一个合法的返回值。
function swap(&$left, &$right) : void{ if ($left === $right) { return; }
$tmp = $left; $left = $right; $right = $tmp;}$a = 1;$b =
2;var_dump(swap($a, $b), $a, $b);

以上例程会输出:
nullint(2)int(1)

试图去获取一个 void 方法的返回值会得到 null
,并且不会产生任何警告。这么做的原因是不想影响更高层次的方法。
返回值类型声明
函数和匿名函数都可以指定返回值的类型
function show(): array { return [1,2,3,4]; }function arraysSum(array
…$arrays): array{return array_map(function(array $array): int {return
array_sum($array);}, $arrays);}

参数解包功能
在调用函数的时候,通过 …
操作符可以把数组或者可遍历对象解包到参数列表,这和Ruby等语言中的扩张(splat)操作符类似
function add($a, $b, $c) { return $a + $b + $c; } $arr = [2, 3];
add(1, …$arr);

实例化类
class test{ function show(){ return ‘test’; } } echo (new
test())->show();

支持 Class::{expr}() 语法
foreach ([new Human(“Gonzalo”), new Human(“Peter”)] as $human) { echo
$human->{‘hello’}(); }

Callable typehint
function foo(callable $callback) { }


foo(“false”); //错误,因为false不是callable类型   foo(“printf”);
//正确   foo(function(){}); //正确 class A {   static function
show() { } }   foo(array(“A”, “show”)); //正确

Getter 和 Setter
如果你从不喜欢写这些getXYZ()和setXYZ($value)方法,那么这应该是你最受欢迎的改变。提议添加一个新的语法来定义一个属性的设置/读取:
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)

迭代器 yield
目前,自定义迭代器很少使用,因为它们的实现,需要大量的样板代码。生成器解决这个问题,并提供了一种简单的样板代码来创建迭代器。
例如,你可以定义一个范围函数作为迭代器:
function *xrange($start, $end, $step = 1) { for ($i = $start; $i <
$end; $i += $step) { yield $i; } } foreach (xrange(10, 20) as $i) { //
… }

上述xrange函数具有与内建函数相同的行为,但有一点区别:不是返回一个数组的所有值,而是返回一个迭代器动态生成的值。
列表解析和生成器表达式
列表解析提供一个简单的方法对数组进行小规模操作:
$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];

生成器表达式也很类似,但是返回一个迭代器(用于动态生成值)而不是一个数组。
生成器的返回值
在PHP5.5引入生成器的概念。生成器函数每执行一次就得到一个yield标识的值。在PHP7中,当生成器迭代完成后,可以获取该生成器函数的返回值。通过Generator::getReturn()得到。
function generator(){ yield 1; yield 2; yield 3; return
“a”;}$generatorClass = (“generator”)();foreach ($generatorClass as $val)
{ echo $val .” “;}echo $generatorClass->getReturn();

输出为:1 2 3 a
生成器中引入其他生成器
在生成器中可以引入另一个或几个生成器,只需要写yield from functionName1
function generator1(){ yield 1; yield 2; yield from generator2(); yield
from generator3();}function generator2(){ yield 3; yield 4;}function
generator3(){ yield 5; yield 6;}foreach (generator1() as $val) { echo
$val, ” “;}

输出:1 2 3 4 5 6
finally关键字
这个和Java中的finally一样,经典的try
… catch … finally 三段式异常处理。
多异常捕获处理
一个catch语句块现在可以通过管道字符(|)来实现多个异常的捕获。
这对于需要同时处理来自不同类的不同异常时很有用。
try { // some code} catch (FirstException | SecondException $e) { //
handle first and second exceptions} catch (Exception $e) { // …}
finally{//}

foreach 支持list()
对于“数组的数组”进行迭代,之前需要使用两个foreach,现在只需要使用foreach
+
list了,但是这个数组的数组中的每个数组的个数需要一样。看文档的例子一看就明白了。
$array = [ [1, 2], [3, 4], ]; foreach ($array as list($a, $b)) {
echo “A: $a; B: $bn”; }

短数组语法 Symmetric array destructuring
短数组语法([])现在可以用于将数组的值赋给一些变量(包括在foreach中)。
这种方式使从数组中提取值变得更为容易。
$data = [ [‘id’ => 1, ‘name’ => ‘Tom’], [‘id’ => 2, ‘name’
=> ‘Fred’],];while ([‘id’ => $id, ‘name’ => $name] = $data)
{ // logic here with $id and $name}

list()现在支持键名
现在list()支持在它内部去指定键名。这意味着它可以将任意类型的数组
都赋值给一些变量(与短数组语法类似)
$data = [ [‘id’ => 1, ‘name’ => ‘Tom’], [‘id’ => 2, ‘name’
=> ‘Fred’],];while (list(‘id’ => $id, ‘name’ => $name) =
$data) { // logic here with $id and $name}

iterable 伪类
现在引入了一个新的被称为iterable的伪类 (与callable类似)。
这可以被用在参数或者返回值类型中,它代表接受数组或者实现了Traversable接口的对象。
至于子类,当用作参数时,子类可以收紧父类的iterable类型到array
或一个实现了Traversable的对象。对于返回值,子类可以拓宽父类的
array或对象返回值类型到iterable。
function iterator(iterable $iter){ foreach ($iter as $val) { // }}

ext/openssl 支持 AEAD
通过给openssl_encrypt()和openssl_decrypt()
添加额外参数,现在支持了AEAD (模式 GCM and CCM)。 通过
Closure::fromCallable() 将callables转为闭包
Closure新增了一个静态方法,用于将callable快速地 转为一个Closure 对象。
class Test{ public function exposeFunction() { return
Closure::fromCallable([$this, ‘privateFunction’]); } private function
privateFunction($param) { var_dump($param); }}$privFunc = (new
Test)->exposeFunction();$privFunc(‘some value’);

以上例程会输出:
string(10) “some value”

匿名类
现在支持通过 new class
来实例化一个匿名类,这可以用来替代一些“用后即焚”的完整类定义。
interface Logger{ public function log(string $msg);}class Application{
private $logger; public function getLogger(): Logger { return
$this->logger; } public function setLogger(Logger $logger) {
$this->logger = $logger; }}$app = new
Application;$app->setLogger(new class implements Logger{ public
function log(string $msg) { echo $msg;
}});var_dump($app->getLogger());

Closure::call()
Closure::call()
现在有着更好的性能,简短干练的暂时绑定一个方法到对象上闭包并调用它。
class Test{ public $name = “lixuan”;}//PHP7和PHP5.6都可以$getNameFunc =
function () { return $this->name;};$name =
$getNameFunc->bindTo(new Test, ‘Test’);echo
$name();//PHP7可以,PHP5.6报错$getX = function () { return
$this->name;};echo $getX->call(new Test);

为unserialize()提供过滤
这个特性旨在提供更安全的方式解包不可靠的数据。它通过白名单的方式来防止潜在的代码注入。
//将所有对象分为__PHP_Incomplete_Class对象$data = unserialize($foo,
[“allowed_classes” =>
false]);//将所有对象分为__PHP_Incomplete_Class 对象
除了ClassName1和ClassName2$data = unserialize($foo, [“allowed_classes”
=> [“ClassName1”, “ClassName2”]);//默认行为,和
unserialize($foo)相同$data = unserialize($foo, [“allowed_classes”
=> true]);

IntlChar
新增加的 IntlChar 类旨在暴露出更多的 ICU
功能。这个类自身定义了许多静态方法用于操作多字符集的 unicode
字符。Intl是Pecl扩展,使用前需要编译进PHP中,也可apt-get/yum/port
install php5-intl
printf(‘%x’, IntlChar::CODEPOINT_MAX);echo
IntlChar::charName(‘@’);var_dump(IntlChar::ispunct(‘!’));

以上例程会输出: 10ffff COMMERCIAL AT bool(true)
预期
预期是向后兼用并增强之前的 assert() 的方法。
它使得在生产环境中启用断言为零成本,并且提供当断言失败时抛出特定异常的能力。
老版本的API出于兼容目的将继续被维护,assert()现在是一个语言结构,它允许第一个参数是一个表达式,而不仅仅是一个待计算的
string或一个待测试的boolean。
ini_set(‘assert.exception’, 1);class CustomError extends AssertionError
{}assert(false, new CustomError(‘Some error message’));

以上例程会输出: Fatal error: Uncaught CustomError: Some error message
intdiv()
接收两个参数作为被除数和除数,返回他们相除结果的整数部分。
var_dump(intdiv(7, 2));

输出int(3)
CSPRNG
新增两个函数: random_bytes() and
random_int().可以加密的生产被保护的整数和字符串。总之随机数变得安全了。
random_bytes — 加密生存被保护的伪随机字符串 random_int
—加密生存被保护的伪随机整数
preg_replace_callback_array()
新增了一个函数preg_replace_callback_array(),使用该函数可以使得在使用preg_replace_callback()函数时代码变得更加优雅。在PHP7之前,回调函数会调用每一个正则表达式,回调函数在部分分支上是被污染了。
Session options
现在,session_start()函数可以接收一个数组作为参数,可以覆盖php.ini中session的配置项。
比如,把cache_limiter设置为私有的,同时在阅读完session后立即关闭。
session_start([‘cache_limiter’ => ‘private’, ‘read_and_close’
=> true,]);

$_SERVER[“REQUEST_TIME_FLOAT”]
这个是用来统计服务请求时间的,并用ms(毫秒)来表示
echo “脚本执行时间 “, round(microtime(true) –
$_SERVER[“REQUEST_TIME_FLOAT”], 2), “s”;

empty() 支持任意表达式
empty() 现在支持传入一个任意表达式,而不仅是一个变量
function always_false() { return false;}if (empty(always_false())) {
echo ‘This will be printed.’;}if (empty(true)) { echo ‘This will not be
printed.’;}

输出 This will be printed.
php://input 可以被复用
php://input
开始支持多次打开和读取,这给处理POST数据的模块的内存占用带来了极大的改善。
Upload progress 文件上传
Session提供了上传进度支持,通过$_SESSION[“upload_progress_name”]就可以获得当前文件上传的进度信息,结合Ajax就能很容易实现上传进度条了。
详细的看http://www.laruence.com/2011/10/10/2217.html
大文件上传支持
可以上传超过2G的大文件。
GMP支持操作符重载
GMP 对象支持操作符重载和转换为标量,改善了代码的可读性,如:
$a = gmp_init(42); $b = gmp_init(17); // Pre-5.6 code:
var_dump(gmp_add($a, $b)); var_dump(gmp_add($a, 17));
var_dump(gmp_add(42, $b)); // New code: var_dump($a + $b);
var_dump($a + 17); var_dump(42 + $b);

JSON 序列化对象
实现了JsonSerializable接口的类的实例在json_encode序列化的之前会调用jsonSerialize方法,而不是直接序列化对象的属性。
参考http://www.laruence.com/2011/10/10/2204.html
HTTP状态码在200-399范围内均被认为访问成功
支持动态调用静态方法
class Test{ public static function testgo() { echo “gogo!”; } } $class =
‘Test’; $action = ‘testgo’; $class::$action(); //输出 “gogo!”

弃用e修饰符
e修饰符是指示preg_replace函数用来评估替换字符串作为PHP代码,而不只是仅仅做一个简单的字符串替换。不出所料,这种行为会源源不断的出现安全问题。这就是为什么在PHP5.5
中使用这个修饰符将抛出一个弃用警告。作为替代,你应该使用preg_replace_callback函数。你可以从RFC找到更多关于这个变化相应的信息。
新增函数 boolval
PHP已经实现了strval、intval和floatval的函数。为了达到一致性将添加boolval函数。它完全可以作为一个布尔值计算,也可以作为一个回调函数。
新增函数hash_pbkdf2
PBKDF2全称“Password-Based Key Derivation Function
2”,正如它的名字一样,是一种从密码派生出加密密钥的算法。这就需要加密算法,也可以用于对密码哈希。更广泛的说明和用法示例
array_column
//从数据库获取一列,但返回是数组。 $userNames = []; foreach ($users as
$user) { $userNames[] = $user[‘name’]; }
//以前获取数组某列值,现在如下 $userNames = array_column($users,
‘name’);

一个简单的密码散列API
$password = “foo”; // creating the hash $hash =
password_hash($password, PASSWORD_BCRYPT); // verifying a password if
(password_verify($password, $hash)) { // password correct! } else { //
password wrong! }

异步信号处理 Asynchronous signal handling
A new function called pcntl_async_signals() has been introduced to
enable asynchronous signal handling without using ticks (which introduce
a lot of overhead). 增加了一个新函数
pcntl_async_signals()来处理异步信号,不需要再使用ticks(它会增加占用资源)
pcntl_async_signals(true); // turn on async
signalspcntl_signal(SIGHUP, function($sig) { echo
“SIGHUPn”;});posix_kill(posix_getpid(), SIGHUP);

以上例程会输出:
SIGHUP

HTTP/2 服务器推送支持 ext/curl
Support for server push has been added to the CURL extension (requires
version 7.46 and above). This can be leveraged through the
curl_multi_setopt() function with the new CURLMOPT_PUSHFUNCTION
constant. The constants CURL_PUST_OK and CURL_PUSH_DENY have also
been added so that the execution of the server push callback can either
be approved or denied. 蹩脚英语:
对于服务器推送支持添加到curl扩展(需要7.46及以上版本)。
可以通过用新的CURLMOPT_PUSHFUNCTION常量
让curl_multi_setopt()函数使用。
也增加了常量CURL_PUST_OK和CURL_PUSH_DENY,可以批准或拒绝
服务器推送回调的执行
php.ini中可使用变量
PHP default_charset 默认字符集 为UTF-8
ext/phar、ext/intl、ext/fileinfo、ext/sqlite3和ext/enchant等扩展默认随PHP绑定发布。其中Phar可用于打包PHP程序,类似于Java中的jar机制
PHP7.1不兼容性
1.当传递参数过少时将抛出错误
在过去如果我们调用一个用户定义的函数时,提供的参数不足,那么将会产生一个警告(warning)。
现在,这个警告被提升为一个错误异常(Error
exception)。这个变更仅对用户定义的函数生效, 并不包含内置函数。例如:
function test($param){}test();

输出:
Uncaught Error: Too few arguments to function test(), 0 passed in %s on
line %d and exactly 1 expected in %s:%d

2.禁止动态调用函数
禁止动态调用函数如下 assert() – with a string as the first argument
compact() extract() func_get_args() func_get_arg() func_num_args()
get_defined_vars() mb_parse_str() – with one arg parse_str() – with
one arg
(function () { ‘func_num_args'();})();

输出
Warning: Cannot call func_num_args() dynamically in %s on line %d

3.无效的类,接口,trait名称命名
以下名称不能用于 类,接口或trait 名称命名: void iterable
4.Numerical string conversions now respect scientific notation
Integer operations and conversions on numerical strings now respect
scientific notation. This also includes the (int) cast operation, and
the following functions: intval() (where the base is 10), settype(),
decbin(), decoct(), and dechex().
5.mt_rand 算法修复
mt_rand() will now default to using the fixed version of the Mersenne
Twister algorithm. If deterministic output from mt_srand() was relied
upon, then the MT_RAND_PHP with the ability to preserve the old
(incorrect) implementation via an additional optional second parameter
to mt_srand().
6.rand() 别名 mt_rand() 和 srand() 别名 mt_srand()
rand() and srand() have now been made aliases to mt_rand() and
mt_srand(), respectively. This means that the output for the following
functions have changes: rand(), shuffle(), str_shuffle(), and
array_rand().
7.Disallow the ASCII delete control character in identifiers
The ASCII delete control character (0x7F) can no longer be used in
identifiers that are not quoted.
8.error_log changes with syslog value
If the error_log ini setting is set to syslog, the PHP error levels are
mapped to the syslog error levels. This brings finer differentiation in
the error logs in contrary to the previous approach where all the errors
are logged with the notice level only.
9.在不完整的对象上不再调用析构方法
析构方法在一个不完整的对象(例如在构造方法中抛出一个异常)上将不再会被调用
10.call_user_func()不再支持对传址的函数的调用
call_user_func() 现在在调用一个以引用作为参数的函数时将始终失败。
11.字符串不再支持空索引操作符 The empty index operator is not supported
for strings anymore
对字符串使用一个空索引操作符(例如str[]=x)将会抛出一个致命错误,
而不是静默地将其转为一个数组
12.ini配置项移除
下列ini配置项已经被移除: session.entropy_file session.entropy_length
session.hash_function session.hash_bits_per_character
PHP7.0 不兼容性
1、foreach不再改变内部数组指针
在PHP7之前,当数组通过 foreach
迭代时,数组指针会移动。现在开始,不再如此,见下面代码。
$array = [0, 1, 2];foreach ($array as &$val) {
var_dump(current($array));}

PHP5输出: int(1) int(2) bool(false) PHP7输出: int(0) int(0)
int(0)
2、foreach通过引用遍历时,有更好的迭代特性
当使用引用遍历数组时,现在 foreach
在迭代中能更好的跟踪变化。例如,在迭代中添加一个迭代值到数组中,参考下面的代码:
$array = [0];foreach ($array as &$val) { var_dump($val); $array[1]
= 1;}

PHP5输出: int(0) PHP7输出: int(0) int(1)
3、十六进制字符串不再被认为是数字
含十六进制字符串不再被认为是数字
var_dump(“0x123” ==
“291”);var_dump(is_numeric(“0x123”));var_dump(“0xe” +
“0x1”);var_dump(substr(“foo”, “0x1”));

PHP5输出: bool(true) bool(true) int(15) string(2) “oo” PHP7输出
bool(false) bool(false) int(0) Notice: A non well formed numeric value
encountered in /tmp/test.php on line 5 string(3) “foo”
4、PHP7中被移除的函数
被移除的函数列表如下: call_user_func() 和
call_user_func_array()从PHP 4.1.0开始被废弃。 已废弃的
mcrypt_generic_end()
函数已被移除,请使用mcrypt_generic_deinit()代替。 已废弃的
mcrypt_ecb(), mcrypt_cbc(), mcrypt_cfb() 和 mcrypt_ofb()
函数已被移除。 set_magic_quotes_runtime(), 和它的别名
magic_quotes_runtime()已被移除. 它们在PHP 5.3.0中已经被废弃,并且 在in
PHP 5.4.0也由于魔术引号的废弃而失去功能。 已废弃的
set_socket_blocking()
函数已被移除,请使用stream_set_blocking()代替。 dl()在 PHP-FPM
不再可用,在 CLI 和 embed SAPIs 中仍可用。
GD库中下列函数被移除:imagepsbbox()、imagepsencodefont()、imagepsextendfont()、imagepsfreefont()、imagepsloadfont()、imagepsslantfont()、imagepstext()
在配置文件php.ini中,always_populate_raw_post_data、asp_tags、xsl.security_prefs被移除了。
5、new 操作符创建的对象不能以引用方式赋值给变量
new 操作符创建的对象不能以引用方式赋值给变量
class C {}$c =& new C;

PHP5输出: Deprecated: Assigning the return value of new by reference is
deprecated in /tmp/test.php on line 3 PHP7输出: Parse error: syntax
error, unexpected ‘new’ (T_NEW) in /tmp/test.php on line 3
6、移除了 ASP 和 script PHP 标签
使用类似 ASP 的标签,以及 script 标签来区分 PHP 代码的方式被移除。
受到影响的标签有:<% %>、<%= %>、
7、从不匹配的上下文发起调用
在不匹配的上下文中以静态方式调用非静态方法, 在 PHP 5.6 中已经废弃,
但是在 PHP 7.0 中, 会导致被调用方法中未定义 $this
变量,以及此行为已经废弃的警告。
class A { public function test() { var_dump($this); }}//
注意:并没有从类 A 继承class B { public function
callNonStaticMethodOfA() { A::test(); }}(new
B)->callNonStaticMethodOfA();

PHP5输出: Deprecated: Non-static method A::test() should not be called
statically, assuming $this from incompatible context in /tmp/test.php on
line 8 object(B)#1 (0) { } PHP7输出: Deprecated: Non-static method
A::test() should not be called statically in /tmp/test.php on line 8
Notice: Undefined variable: this in /tmp/test.php on line 3 NULL
8、在数值溢出的时候,内部函数将会失败
将浮点数转换为整数的时候,如果浮点数值太大,导致无法以整数表达的情况下,
在之前的版本中,内部函数会直接将整数截断,并不会引发错误。 在 PHP 7.0
中,如果发生这种情况,会引发 E_WARNING 错误,并且返回 NULL。
9、JSON 扩展已经被 JSOND 取代
JSON 扩展已经被 JSOND 扩展取代。 对于数值的处理,有以下两点需要注意的:
第一,数值不能以点号(.)结束 (例如,数值 34. 必须写作 34.0 或 34)。
第二,如果使用科学计数法表示数值,e 前面必须不是点号(.) (例如,3.e3
必须写作 3.0e3 或 3e3)。
10、INI 文件中 # 注释格式被移除
在配置文件INI文件中,不再支持以 # 开始的注释行, 请使用
;(分号)来表示注释。 此变更适用于 php.ini 以及用 parse_ini_file() 和
parse_ini_string() 函数来处理的文件。
11、$HTTP_RAW_POST_DATA 被移除
不再提供 $HTTP_RAW_POST_DATA 变量。 请使用
php://input 作为替代。
12、yield 变更为右联接运算符
在使用 yield 关键字的时候,不再需要括号,
并且它变更为右联接操作符,其运算符优先级介于 print 和 => 之间。
这可能导致现有代码的行为发生改变。可以通过使用括号来消除歧义。
echo yield -1;// 在之前版本中会被解释为:echo (yield) – 1;//
现在,它将被解释为:echo yield (-1);yield $foo or die;//
在之前版本中会被解释为:yield ($foo or die);//
现在,它将被解释为:(yield $foo) or die;

PHP 7.1.x 中废弃的特性
1.ext/mcrypt
mcrypt 扩展已经过时了大约10年,并且用起来很复杂。因此它被废弃并且被
OpenSSL 所取代。 从PHP 7.2起它将被从核心代码中移除并且移到PECL中。
2.mb_ereg_replace()和mb_eregi_replace()的Eval选项
对于mb_ereg_replace()和mb_eregi_replace()的
e模式修饰符现在已被废弃
弃用或废除
下面是被弃用或废除的 INI 指令列表. 使用下面任何指令都将导致 错误.
define_syslog_variables register_globals register_long_arrays
safe_mode magic_quotes_gpc magic_quotes_runtime
magic_quotes_sybase 弃用 INI 文件中以 ‘#’ 开头的注释. 弃用函数:
call_user_method() (使用 call_user_func() 替代)
call_user_method_array() (使用 call_user_func_array() 替代)
define_syslog_variables() dl() ereg() (使用 preg_match() 替代)
ereg_replace() (使用 preg_replace() 替代) eregi() (使用 preg_match()
配合 ‘i’ 修正符替代) eregi_replace() (使用 preg_replace() 配合 ‘i’
修正符替代) set_magic_quotes_runtime() 以及它的别名函数
magic_quotes_runtime() session_register() (使用
SESSION超全部变量替代)sessionunregister()(使用_SESSION 超全部变量替代)
session_is_registered() (使用 $SESSION 超全部变量替代)
set_socket_blocking() (使用 stream_set_blocking() 替代) split()
(使用 preg_split() 替代) spliti() (使用 preg_split() 配合 ‘i’
修正符替代) sql_regcase() mysql_db_query() (使用 mysql_select_db()
和 mysql_query() 替代) mysql_escape_string() (使用
mysql_real_escape_string() 替代) 废弃以字符串传递区域设置名称. 使用
LC
* 系列常量替代. mktime() 的 is_dst 参数. 使用新的时区处理函数替代.
弃用的功能: 弃用通过引用分配 new 的返回值. 调用时传递引用被弃用.
已弃用的多个特性
allow_call_time_pass_reference、define_syslog_variables、highlight.bg、register_globals、register_long_arrays、magic_quotes、safe_mode、zend.ze1_compatibility_mode、session.bug_compat42、session.bug_compat_warn
以及 y2k_compliance。

发表评论

电子邮件地址不会被公开。 必填项已用*标注