PHP 7 - 快速指南


PHP 7 - 简介

PHP 7 是什么?

PHP 7 是 PHP 编程语言的一个主要版本,被认为是开发和交付移动到企业和云的 Web 应用程序方式的一场革命。该版本被认为是继 2004 年 PHP 5 发布之后 PHP 最重要的变化。

新功能

PHP 7 添加了数十个功能,最重要的功能如下 -

  • 改进的性能- 将 PHPNG 代码合并到 PHP7 中,速度是 PHP 5 的两倍。

  • 更低的内存消耗- 优化的 PHP 7 使用更少的资源。

  • 标量类型声明- 现在可以强制执行参数和返回类型。

  • 一致的 64 位支持- 对 64 位架构机器的一致支持。

  • 改进的异常层次结构- 改进了异常层次结构。

  • 许多致命错误转换为异常- 异常范围增加,涵盖许多转换为异常的致命错误。

  • 安全随机数生成器- 添加新的安全随机数生成器 API。

  • 已删除已弃用的 SAPI 和扩展- 从最新版本中删除了各种旧的和不受支持的 SAPI 和扩展。

  • 空合并运算符 (??) - 添加了新的空合并运算符。

  • 返回和标量类型声明- 添加了对返回类型和参数类型的支持。

  • 匿名类- 添加了对匿名的支持。

  • 零成本断言- 添加了对零成本断言的支持。

PHP 7 使用新的 Zend Engine 3.0,与 PHP 5.6 相比,应用程序性能提高了近两倍,内存消耗减少了 50%。它允许为更多并发用户提供服务,而无需任何额外的硬件。PHP 7 的设计和重构考虑了当今的工作负载。

PHP 7 - 性能

根据Zend团队的说法,下图显示了 PHP 7 与 PHP 5.6 和 HHVM 3.7 在流行的基于 PHP 的应用程序上的性能比较。

马真托 1.9

事实证明,在执行 Magento 事务时,PHP 7 的速度是 PHP 5.6 的两倍多。

Magento 交易

德鲁帕尔7

事实证明,在执行 Drupal 事务时,PHP 7 的速度是 PHP 5.6 的两倍多。

Drupal 事务

WordPress 3.6

事实证明,在执行 Wordpress 事务时,PHP 7 的速度是 PHP 5.6 的两倍多。

WordPress 交易

动态语言的比较

曼德尔布罗特交易

PHP 7 - 环境设置

为了开发和运行 PHP 网页,您的计算机系统上需要安装三个重要组件。

  • Web 服务器- PHP 几乎可与所有 Web 服务器软件配合使用,包括 Microsoft 的 Internet 信息服务器 (IIS),但最常用的是 Apache Server。在这里免费下载 Apache - http://httpd.apache.org/download.cgi

  • 数据库- PHP PHP 几乎适用于所有数据库软件,包括 Oracle 和 Sybase,但最常用的是 MySQL 数据库。在这里免费下载 MySQL - http://www.mysql.com/downloads/

  • PHP 解析器- 为了处理 PHP 脚本指令,必须安装解析器来生成可发送到 Web 浏览器的 HTML 输出。本教程将指导您如何在计算机上安装 PHP 解析器。

PHP 解析器安装

在继续之前,请务必确保您的计算机上已设置正确的环境以使用 PHP 开发 Web 程序。将以下 php 文件存储在 Apache 的 htdocs 文件夹中。

phpinfo.php

<?php
   phpinfo();
?>

在浏览器的地址框中输入以下地址。

http://127.0.0.1/phpinfo.php

如果显示的页面显示您的 PHP 安装相关信息,则表示您已正确安装 PHP 和 Web 服务器。否则,您必须按照给定的过程在计算机上安装 PHP。

本节将指导您在以下四个平台上安装和配置 PHP -

阿帕奇配置

如果您使用 Apache 作为 Web 服务器,那么本节将指导您编辑 Apache 配置文件。

检查此处 - Apache 服务器中的 PHP 配置

PHP.INI 文件配置

PHP 配置文件php.ini是影响 PHP 功能的最终且直接的方法。

检查此处 - PHP.INI 文件配置

Windows IIS 配置

要在 Windows 计算机上配置 IIS,您可以参考随 IIS 一起提供的 IIS 参考手册。

PHP 7 - 标量类型声明

PHP 7 中引入了一项新功能,即标量类型声明。标量类型声明有两个选项 -

  • coercive - 强制是默认模式,不需要指定。

  • strict - 严格模式必须明确暗示。

可以使用上述模式强制执行以下函数参数类型 -

  • 整数
  • 漂浮
  • 布尔值
  • 细绳
  • 接口
  • 大批
  • 可调用的

示例 - 强制模式

<?php
   // Coercive mode
   function sum(int ...$ints) {
      return array_sum($ints);
   }
   print(sum(2, '3', 4.1));
?>

它产生以下浏览器输出 -

9

示例 - 严格模式

<?php
   // Strict mode
   declare(strict_types = 1);
   function sum(int ...$ints) {
      return array_sum($ints);
   }
   print(sum(2, '3', 4.1));
?>

它产生以下浏览器输出 -

Fatal error: Uncaught TypeError: Argument 2 passed to sum() must be of the type integer, string given, ...

PHP 7 - 返回类型声明

PHP 7 中引入了一项新功能,即返回类型声明。返回类型声明指定函数应返回的值的类型。可以声明以下类型的返回类型。

  • 整数
  • 漂浮
  • 布尔值
  • 细绳
  • 接口
  • 大批
  • 可调用的

示例 - 有效返回类型

<?php
   declare(strict_types = 1);
   function returnIntValue(int $value): int {
      return $value;
   }
   print(returnIntValue(5));
?>

它产生以下浏览器输出 -

5

示例 - 无效的返回类型

<?php
   declare(strict_types = 1);
   function returnIntValue(int $value): int {
      return $value + 1.0;
   }
   print(returnIntValue(5));
?>

它产生以下浏览器输出 -

Fatal error: Uncaught TypeError: Return value of returnIntValue() must be of the type integer, float returned...

PHP 7 - 空合并运算符

PHP 7 中引入了一项新功能:空合并运算符 (??) 。与isset()函数配合使用,代替三元运算。Null合并运算符返回其第一个操作数(如果存在且不为 NULL)否则返回第二个操作数。

例子

<?php
   // fetch the value of $_GET['user'] and returns 'not passed'
   // if username is not passed
   $username = $_GET['username'] ?? 'not passed';
   print($username);
   print("<br/>");

   // Equivalent code using ternary operator
   $username = isset($_GET['username']) ? $_GET['username'] : 'not passed';
   print($username);
   print("<br/>");
   // Chaining ?? operation
   $username = $_GET['username'] ?? $_POST['username'] ?? 'not passed';
   print($username);
?>

它产生以下浏览器输出 -

not passed
not passed
not passed

PHP 7 - 宇宙飞船操作员

PHP 7 中引入了一个新功能,太空船运算符。它用于比较两个表达式。当第一个表达式分别小于、等于或大于第二个表达式时,它返回 -1、0 或 1。

例子

<?php
   //integer comparison
   print( 1 <=> 1);print("<br/>");
   print( 1 <=> 2);print("<br/>");
   print( 2 <=> 1);print("<br/>");
   print("<br/>");
   //float comparison
   print( 1.5 <=> 1.5);print("<br/>");
   print( 1.5 <=> 2.5);print("<br/>");
   print( 2.5 <=> 1.5);print("<br/>");
   print("<br/>");
   //string comparison
   print( "a" <=> "a");print("<br/>");
   print( "a" <=> "b");print("<br/>");
   print( "b" <=> "a");print("<br/>");
?>

它产生以下浏览器输出 -

0
-1
1

0
-1
1

0
-1
1

PHP 7 - 常量数组

现在可以使用Define()函数定义数组常量。在 PHP 5.6 中,只能使用const关键字定义它们。

例子

<?php
   //define a array using define function
   define('animals', [
      'dog',
      'cat',
      'bird'
   ]);
   print(animals[1]);
?>

它产生以下浏览器输出 -

cat

PHP 7 - 匿名类

现在可以使用新类来定义匿名类。可以使用匿名类来代替完整的类定义。

例子

<?php
   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) {
         print($msg);
      }
   });

   $app->getLogger()->log("My first Log Message");
?>

它产生以下浏览器输出 -

My first Log Message

PHP 7 - 闭包::call()

添加Closure::call()方法作为临时将对象范围绑定到闭包并调用它的简写方式。与 PHP 5.6 的bindTo相比,它的性能要快得多。

示例 - PHP 7 之前的版本

<?php
   class A {
      private $x = 1;
   }

   // Define a closure Pre PHP 7 code
   $getValue = function() {
      return $this->x;
   };

   // Bind a clousure
   $value = $getValue->bindTo(new A, 'A'); 

   print($value());
?>

它产生以下浏览器输出 -

1

示例 - PHP 7+

<?php
   class A {
      private $x = 1;
   }

   // PHP 7+ code, Define
   $value = function() {
      return $this->x;
   };

   print($value->call(new A));
?>

它产生以下浏览器输出 -

1

PHP 7 - 过滤反序列化()

PHP 7 引入了 Filtered unserialize()函数,以便在反序列化不可信数据上的对象时提供更好的安全性。它可以防止可能的代码注入,并使开发人员能够将可以反序列化的类列入白名单。

例子

<?php
   class MyClass1 { 
      public $obj1prop;   
   }
   class MyClass2 {
      public $obj2prop;
   }

   $obj1 = new MyClass1();
   $obj1->obj1prop = 1;
   $obj2 = new MyClass2();
   $obj2->obj2prop = 2;

   $serializedObj1 = serialize($obj1);
   $serializedObj2 = serialize($obj2);

   // default behaviour that accepts all classes
   // second argument can be ommited.
   // if allowed_classes is passed as false, unserialize converts all objects into __PHP_Incomplete_Class object
   $data = unserialize($serializedObj1 , ["allowed_classes" => true]);

   // converts all objects into __PHP_Incomplete_Class object except those of MyClass1 and MyClass2
   $data2 = unserialize($serializedObj2 , ["allowed_classes" => ["MyClass1", "MyClass2"]]);

   print($data->obj1prop);
   print("<br/>");
   print($data2->obj2prop);
?>

它产生以下浏览器输出 -

1
2

PHP 7 - 国际字符

在 PHP7 中,添加了一个新的IntlChar类,该类旨在公开额外的 ICU 功能。此类定义了许多静态方法和常量,可用于操作 unicode 字符。在使用此类之前,您需要安装Intl扩展。

例子

<?php
   printf('%x', IntlChar::CODEPOINT_MAX);
   print (IntlChar::charName('@'));
   print(IntlChar::ispunct('!'));
?>

它产生以下浏览器输出 -

10ffff
COMMERCIAL AT
true

PHP 7 - CSPRNG

在 PHP 7 中,引入了以下两个新函数,用于以跨平台方式生成加密安全的整数和字符串。

  • random_bytes() - 生成加密安全的伪随机字节。

  • random_int() - 生成加密安全的伪随机整数。

随机字节()

random_bytes() 生成适合加密使用的任意长度的加密随机字节字符串,例如在生成盐、密钥或初始化向量时。

句法

string random_bytes ( int $length )

参数

  • length - 应返回的随机字符串的长度(以字节为单位)。

返回值

  • 返回一个字符串,其中包含请求的加密安全随机字节数。

错误/异常

  • 如果找不到适当的随机源,则会抛出异常。

  • 如果给定的参数无效,则会抛出TypeError 。

  • 如果给出的字节长度无效,则会抛出错误。

例子

<?php
   $bytes = random_bytes(5);
   print(bin2hex($bytes));
?>

它产生以下浏览器输出 -

54cc305593

random_int()

random_int()生成加密随机整数,适合在无偏结果至关重要的情况下使用。

句法

int random_int ( int $min , int $max )

参数

  • min - 要返回的最小值,必须是PHP_INT_MIN或更高。

  • max - 要返回的最高值,必须小于或等于PHP_INT_MAX

返回值

  • 返回从最小值到最大值(含)范围内的加密安全随机整数。

错误/异常

  • 如果找不到适当的随机源,则会抛出异常。

  • 如果给定的参数无效,则会抛出TypeError 。

  • 如果 max 小于 min,则会抛出错误。

例子

<?php
   print(random_int(100, 999));
   print("");
   print(random_int(-1000, 0));
?>

它产生以下浏览器输出 -

614
-882

PHP 7 - 期望

期望是对旧的assert() 函数的向后兼容增强。Expectation 允许在生产代码中进行零成本断言,并提供在断言失败时抛出自定义异常的能力。assert() 现在是一种语言构造,其中第一个参数是一个表达式,而不是要测试的字符串或布尔值。

assert() 的配置指令

指示 默认值 可能的值
zend.断言 1

1 - 生成并执行代码(开发模式)

0 - 生成代码但在运行时跳过它

-1 - 不生成代码(生产模式)

断言异常 0

1 - 当断言失败时,通过抛出作为异常提供的对象或通过抛出新的AssertionError对象(如果未提供异常)来抛出。

0 - 如上所述使用或生成 Throwable,但仅根据该对象生成警告而不是抛出它(与 PHP 5 Behave兼容)

参数

  • 断言- 断言。在 PHP 5 中,这必须是要计算的字符串或要测试的布尔值。在 PHP 7 中,这也可以是任何返回值的表达式,该表达式将被执行,结果用于指示断言是成功还是失败。

  • 描述- 如果断言失败,将包含在失败消息中的可选描述。

  • 异常- 在 PHP 7 中,第二个参数可以是Throwable对象而不是描述性字符串,在这种情况下,如果断言失败并且启用了assert.exception配置指令,则这是将抛出的对象。

返回值

如果断言为假,则为 FALSE,否则为TRUE

例子

<?php
   ini_set('assert.exception', 1);

   class CustomError extends AssertionError {}

   assert(false, new CustomError('Custom Error Message!'));
?>

它产生以下浏览器输出 -

Fatal error: Uncaught CustomError: Custom Error Message! in...

PHP 7 - use 语句

从 PHP7 开始,单个 use 语句可用于从同一命名空间导入类、函数和常量,而不是多个 use 语句。

例子

<?php
   // Before PHP 7
   use com\tutorialspoint\ClassA;
   use com\tutorialspoint\ClassB;
   use com\tutorialspoint\ClassC as C;

   use function com\tutorialspoint\fn_a;
   use function com\tutorialspoint\fn_b;
   use function com\tutorialspoint\fn_c;

   use const com\tutorialspoint\ConstA;
   use const com\tutorialspoint\ConstB;
   use const com\tutorialspoint\ConstC;

   // PHP 7+ code
   use com\tutorialspoint\{ClassA, ClassB, ClassC as C};
   use function com\tutorialspoint\{fn_a, fn_b, fn_c};
   use const com\tutorialspoint\{ConstA, ConstB, ConstC};

?>

PHP 7 - 错误处理

从 PHP 7 开始,错误处理和报告已发生变化。现在大多数错误不是通过 PHP 5 使用的传统错误报告机制来报告错误,而是通过抛出 Error 异常来处理。与异常类似,这些 Error 异常会冒泡,直到到达第一个匹配的 catch 块。如果没有匹配的块,则将调用使用set_exception_handler()安装的默认异常处理程序。如果没有默认的异常处理程序,则异常将转换为致命错误,并像传统错误一样进行处理。

由于 Error 层次结构不是从 Exception 扩展而来的,因此在 PHP 5 中使用 catch (Exception $e) { ... } 块来处理未捕获异常的代码将不会处理此类错误。需要使用catch (Error $e) { ... } 块或set_exception_handler()处理程序来处理致命错误。

异常层次结构

例子

<?php
   class MathOperations {
      protected $n = 10;

      // Try to get the Division by Zero error object and display as Exception
      public function doOperation(): string {
         try {
            $value = $this->n % 0;
            return $value;
         } catch (DivisionByZeroError $e) {
            return $e->getMessage();
         }
      }
   }

   $mathOperationsObj = new MathOperations();
   print($mathOperationsObj->doOperation());
?>

它产生以下浏览器输出 -

Modulo by zero

PHP 7 - 整数除法

PHP 7 引入了一个新函数intdiv(),它执行其操作数的整数除法并将除法返回为 int。

例子

<?php
   $value = intdiv(10,3);
   var_dump($value);
   print(" ");
   print($value);
?>

它产生以下浏览器输出 -

int(3) 
3

PHP 7 - 会话选项

从 PHP7+ 开始,session_start()函数接受一组选项来覆盖php.ini中设置的会话配置指令。这些选项支持session.lazy_write,默认情况下该选项处于打开状态,并且如果会话数据已更改,则会导致 PHP 覆盖任何会话文件。

添加的另一个选项是read_and_close,它指示应读取会话数据,然后应立即关闭会话而不更改。例如,使用以下代码片段将session.cache_limiter设置为 private 并设置标志以在读取会话后立即关闭会话。

<?php
   session_start([
      'cache_limiter' => 'private',
      'read_and_close' => true,
   ]);
?>

PHP 7 - 已弃用的功能

以下功能已被弃用,并且可能会从 PHP 的未来版本中删除。

PHP 4 风格的构造函数

PHP 4 风格的构造函数是与定义它们的类同名的方法,现在已弃用,并将在将来删除。如果 PHP 4 构造函数是类中定义的唯一构造函数,PHP 7 将发出 E_DEPRECATED。实现 __construct() 方法的类不受影响。

例子

<?php
   class A {
      function A() {
         print('Style Constructor');
      }
   }
?>

它产生以下浏览器输出 -

Deprecated: Methods with the same name as their class will not be constructors 
in a future version of PHP; A has a deprecated constructor in...

对非静态方法的静态调用

对非静态方法的静态调用已被弃用,并且将来可能会被删除。

例子

<?php
   class A {
      function b() {
         print('Non-static call');
      }
   }
   A::b();
?>

它产生以下浏览器输出 -

Deprecated: Non-static method A::b() should not be called statically in...
Non-static call

password_hash() 盐选项

password_hash()函数的 salt 选项已被弃用,以便开发人员不会生成自己的(通常不安全的)盐。当开发人员未提供盐时,该函数本身会生成加密安全的盐 - 因此不再需要自定义盐生成。

capture_session_meta SSL 上下文选项

capture_session_meta SSL 上下文选项已被弃用SSL 元数据现在通过stream_get_meta_data()函数使用。

PHP 7 - 删除的扩展和 SAPI

以下扩展已从 PHP 7 开始删除 -

  • 埃雷格
  • 数据库管理系统
  • mysql
  • sybase_ct

从 PHP 7 开始,以下 SAPI 已被删除 -

  • 在线服务器
  • 阿帕奇
  • apache_hooks
  • apache2过滤器
  • 连续性
  • 伊萨皮
  • 米尔特
  • 纳萨皮
  • phttpd
  • pi3web
  • 罗克森
  • thttpd
  • 无尾礼服
  • 网络詹姆斯