Php 简明教程

PHP - Quick Guide

PHP - Introduction

PHP 最初是一个小型开源项目,随着越来越多的人发现其用处,它不断发展。Rasmus Lerdorf 早在 1994 年就发布了 PHP 的第一个版本。最初,PHP 被认为是“个人主页”的缩写,但现在它代表递归首字母缩略词“PHP:超文本预处理器”。

Lerdorf 于 1993 年开始使用 C 编写几个通用网关接口 (CGI) 程序,他用这些程序来维护他的个人主页,由此开始了 PHP 的开发。后来,他将它们扩展到与 Web 表单配合使用并与数据库进行通信。PHP 的这种实现是“个人主页/表单解释器”或 PHP/FI。

当代,PHP 是世界上最流行的服务器端编程语言,用于构建 Web 应用程序。多年来,它经历了多次修订和版本更新。

PHP Versions

PHP 是由拉斯姆斯·勒多夫于 1994 年开发的,是一套用 C 语言编写的简单的 CGI 二进制文件。他将这套脚本称为“个人主页工具”。它可以看作是 PHP 1.0 版本。

  1. 1996 年 4 月,拉斯姆斯推出了 PHP/FI。它加入了对 DBM、mSQL 和 Postgres95 数据库、Cookie 和用户自定义函数的支持。PHP/FI 被赋予了 version 2.0 状态。

  2. PHP:超文本预处理器 – PHP 3.0 版本是由泽夫·苏拉斯基和安迪·古特曼在重写 PHP 解析器后推出的,并采用了如今的缩写形式。它为多个数据库、协议和 API 提供了成熟的接口,支持面向对象编程,并实现了语言语法的统一。

  3. PHP 4.0 在 2000 年 5 月发布,由 Zend 引擎提供支持。它支持多种 Web 服务器、HTTP 会话、输出缓冲、处理用户输入的安全方式以及多种新语言结构。

  4. PHP 5.0 于 2004 年 7 月发布。它主要由其核心技术 Zend Engine 2.0 和十几项新特性驱动。PHP 的开发团队包括几十名开发人员,还有其他人员在从事与 PHP 相关的和支持其的项目,如 PEAR、PECL 和文档编撰。

  5. PHP 7.0 于 2015 年 12 月发布。它最初被称为 PHP 下一代 (phpng)。开发者们重新编写了 Zend 引擎,并称其为 Zend 引擎 3。PHP 7 的一些重要特性包括其性能提升、内存用量降低、返回和标量类型声明以及匿名类。

  6. PHP 8.0 于 2020 年 11 月 26 日发布。这是一个主版本,包含了相对于前期版本的大量的重大改进。其中一个突出特性是即时 (JIT) 编译,它可以提供大幅的性能提升。PHP 的最新版本是 8.2.8,它于 2023 年 7 月 4 日发布。

PHP Application Areas

PHP 是网络上使用最为广泛的语言之一。以下是 PHP 的一些应用领域:

  1. PHP 是一种服务器端脚本语言,它嵌入在 HTML 中。它用于管理动态内容、数据库、会话跟踪,甚至可以构建完整的电子商务网站。尽管它特别适用于 Web 开发,但你还可以构建桌面独立应用程序,因为 PHP 也有命令行界面。你可以使用 PHP-GTK 扩展来在 PHP 中构建 GUI 应用程序。

  2. PHP 被广泛用于构建 Web 应用程序,但你不限于仅输出 HTML。PHP 的输出能力包括丰富的文件类型,如图像或 PDF 文件、加密数据和发送电子邮件。你还可以轻松地输出任何文本,如 JSON 或 XML。

  3. PHP 是一个跨平台语言,它可以在所有主流的操作系统平台上运行,并与大多数 Web 服务器程序(如 Apache、IIS、lighttpd 和 nginx)兼容。PHP 还通过 LDAP、IMAP、SNMP、NNTP、POP3、HTTP、COM 等协议支持其他服务。

以下是 PHP 的更多一些重要特性:

  1. PHP 执行系统功能。它可以创建、打开、读取、写入和关闭文件。

  2. PHP 可以处理表单。它可以从文件中收集数据、通过电子邮件发送数据、通过电子邮件保存数据到文件、将数据返回给用户。

  3. 你可以通过 PHP 在你的数据库中添加、删除和修改元素。

  4. 访问 Cookie 变量并设置 Cookie。

  5. 使用 PHP,你可以限制用户访问网站的某些页面。

  6. It can encrypt data.

PHP 提供大量的可重复使用的类,并且可以在“PEAR”和“Composer”中找到库。“PEAR”(PHP 扩展和应用程序存储库) 是可重复使用的 PHP 库或类的仓库。“Composer”是 PHP 中的依赖管理工具。

PHP - Installation

你可以在互联网上免费获取任何一个 PHP 在线编译器来学习 PHP 编程的基本知识。这有助于熟悉 PHP 的特性,而无需在电脑上安装 PHP。之后,在本地计算机上安装一个成熟的 PHP 环境。

Tutorialpoint 的 “Coding Ground for Developers” 提供了一个这样的在线 PHP 编译器。访问 https://www.tutorialspoint.com/codingground.htm ,输入 PHP 脚本并执行。

php installation 1

不过,要能够学习 PHP 的高级特性,特别是与服务器变量、使用后端数据库等网络概念相关的特性,你需要在本地计算机上安装 PHP 环境。

为了开发并运行 PHP 网页,你需要在你的计算机系统上安装三个至关重要的组成部分。

  1. Web Server - PHP 几乎可以与所有网络服务器软件配合使用,包括微软的 Internet Information Server (IIS)、NGNIX 或 Lighttpd 等。最常用的网络服务器软件是免费的 Apache Server。此处免费下载 Apache: https://httpd.apache.org/download.cgi

  2. Database - PHP 几乎可以与所有数据库软件配合使用,包括 Oracle 和 Sybase,但最常用的数据库是免费的 MySQL 数据库。此处免费下载 MySQL: [role="bare"]https://www.mysql.com/downloads/

  3. PHP Parser - 必须安装解析器才能处理 PHP 脚本指令以生成可发送到网络浏览器的 HTML 输出。

虽然可以单独安装这三个组成部分并正确配置安装,但这是一个有点复杂的过程,特别是对于初学者来说。相反,使用包含预编译的 Apache、MySQL 和 PHP 二进制文件的所有一体化打包分发版更为方便。

XAMPP Installation

有许多已预先编译的包在开源和专有发行版中可用。来自 Apache Friends ( https://www.apachefriends.org/ ) 的 XAMPP 是最流行的 PHP 启用 Web 服务器包之一。我们将在本教程中使用 XAMPP。

XAMPP 是一个易于安装的 Apache 发行版,它包含 A*pache, *M*ariaDB, *P*HP and *P*erl. The letter *X 缩写表示它是一项跨平台软件,可在 Windows、Linux 和 OS X 上使用。请注意,XAMPP 包含 MariaDB,它是 MySQL 的一个派生,但功能没有区别。

要下载适用于你操作系统的安装程序,请访问 https://www.apachefriends.org/download.html ,并下载以下之一:

  1. Windows − link:https://sourceforge.net/projects/xampp/files/XAMPP%20Windows/8.0.28/xampp-windows-x64-8.0.28-0-VS16-installer.exe [[role="bare"]https://sourceforge.net/projects/]

  2. Linuxhttps://sourceforge.net/projects/

  3. OS X − 链接:https://sourceforge.net/projects/xampp/files/XAMPP%20Mac%20OS%20X/8.0.28/xampp-osx-8.0.28-0-installer.dmg [[role="bare"] [role="bare"]https://sourceforge.net/projects/ ]

在 Windows 上使用安装程序是一个完全基于向导的安装。你需要提供的是管理员访问权限和安装目录的位置,默认为“c:\xampp”。

要在 Linux 上安装 XAMPP,请使用以下步骤:

Step 1 - 更改安装程序的权限:

chmod 755 xampp-linux-*-installer.run

运行安装程序:

sudo ./xampp-linux-*-installer.run

XAMPP 现在安装在“/opt/lamp”目录下面。

Step 2 - 要启动 XAMPP,只需调用此命令:

sudo /opt/lampp/lampp start

你现在应该在屏幕上看到类似此内容的内容:

Starting XAMPP ...
LAMPP: Starting Apache...
LAMPP: Starting MySQL...
LAMPP started.
Ready. Apache and MySQL are running.

你还可以使用图形工具轻松管理服务器。你可以使用以下命令来启动此工具:

cd /opt/lampp
sudo ./manager-linux.run (or manager-linux-x64.run)

Step 3 - 要停止 XAMPP,只需调用此命令:

sudo /opt/lampp/lampp stop

你现在应该在屏幕上看到类似此内容的内容:

Stopping XAMPP ...
LAMPP: Stopping Apache...
LAMPP: Stopping MySQL...
LAMPP stopped.

此外,请注意,有一个可以轻松启动/停止服务器的图形工具。你可以使用以下命令来启动此工具:

cd /opt/lampp
sudo ./manager-linux.run (or manager-linux-x64.run)

如果你使用的是 OS X,请按照以下步骤操作:

  1. 要开始安装,请打开 DMG 映像并双击映像以启动安装过程。

  2. 要启动 XAMPP,只需打开 XAMPP 控制并启动 Apache、MySQL 和 ProFTPD。XAMPP 控制的名称是“manager-osx”。

  3. 要停止 XAMPP,只需打开 XAMPP 控制并停止服务器。XAMPP 控制的名称是“manager-osx”。

  4. XAMPP 控制面板是一个 GUI 工具,可以轻松从中启动和停止 Apache 服务器和 MySQL。

php installation 2

启动 Apache 模块后按下 Admin 按钮。XAMPP 主页会像下面这样显示−

php installation 3

PHP Parser Installation

在你继续之前,务必确保在你的机器上设置了适当的环境,以便使用 PHP 开发你的网络程序。

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

http://127.0.0.1/info.php

如果显示一个显示你的 PHP 安装相关的信息的页面,则意味着你的 PHP 和网络服务安装正确。否则,你必须遵循以下步骤在你的电脑上安装 PHP。

本部分将指导您在以下四个平台上安装和配置 PHP −

  1. @ {s0}

  2. @ {s1}

  3. @ {s2}

  4. @ {s3}

Apache Configuration

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

只需在此处检查− @ {s4}

PHP.INI File Configuration

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

只需在此处检查− @ {s5}

Windows IIS Configuration

要配置你 Windows 机器上的 IIS,你可以参阅随 IIS 一起提供的 IIS 参考手册。

现在,你的本地机器上有一个完整的 PHP 开发环境。

PHP - History

PHP 最初是一个小型开源项目,随着越来越多人发现它的用处,逐渐演变。Rasmus Lerdorf 在 1994 年发布了 PHP 的第一个版本。当时,PHP 的意思是个人主页,因为他用它来维护自己的个人主页。后来,他添加了数据库支持,并称之为“个人主页/Forms 解译器”或 PHP/FI,可以用来构建简单的动态 Web 应用程序。

  1. Zeev Suraski 和 Andi Gutmans 在 1997 年重写了解析器,并形成了 PHP 3 的基础。PHP 的语言名称也更改为递归缩写 PHP:超文本预处理器。他们还编写了 Zend Engine,这是 PHP 的编译器和运行时环境。搭载 Zend Engine 的 PHP 4 于 2000 年 5 月发布。

  2. PHP 5 于 2004 年发布,其中包含许多新功能,例如面向对象编程支持、PHP 数据对象 (PDO) 和众多性能增强。

  3. PHP 7 ,是 2015 年开发的一个新的主要 PHP 版本。它包含了新的语言功能,其中最值得注意的是针对函数的返回类型声明,它补充了现有的参数类型声明,以及在参数和返回类型声明中支持标量类型(整数、浮点数、字符串和布尔值)。

New Features in PHP 8

PHP 8 是最新的主要版本,于 2020 年 11 月发布。一些新功能和值得注意的更改包括:

Just-in-time (JIT) Compilation

PHP 8 的 JIT 编译器为数学类型操作提供了相比普通 Web 开发用例而言显著的性能提升。JIT 编译器提供了将来将某些代码从 C 迁移至 PHP 的潜力。

The "match: Expression

新引入的“match”表达式比 switch 语句更简洁。由于 match 是一个表达式,它的结果可以分配给变量或从函数中返回。

PHP 8 – Type Changes and Additions

PHP 8 引入了联合类型、一个新的静态返回类型和一个新的混合类型。PHP 8 还提供了属性(类似于其他编程语言中的“注释”),用于向 PHP 类添加元数据。

此外,对 PHP 标准库做出了多项更改和补充。PHP 8.2.9 是可用的最新稳定版本。

PHP 发布历史中的重要里程碑总结在以下表格中 −

Version

Description

Version 1.0 (8 June 1995)

正式名称为“个人主页工具 (PHP Tools)”。这是第一次使用名称“PHP”。

Version 2.0 (1 November 1997)

正式名称为“PHP/FI 2.0”。这是可以实际表征为 PHP 的第一个版本,成为一种独立语言,具有许多沿用至今的功能。

Version 3.0 (6 June 1998)

开发人员从一个人变为多个人。Zeev Suraski 和 Andi Gutmans 为此版本重写了基础。

Version 4.0 (22 May 2000)

添加了称为 Zend Engine 的更高级的两个阶段解析/执行标记解析系统。

Version 5.0 (13 July 2004)

Zend Engine II 具有新的对象模型。

Version 5.1 (24 November 2005)

通过在重新设计的 PHP Engine 中引入编译器变量提升性能。添加了 PHP 数据对象 (PDO) 作为访问数据库的一致接口。

Version 6.x Not released

放弃了计划包括原生 Unicode 支持的 PHP 版本。

Version 7.0 (3 December 2015)

Zend Engine 3,统一变量语法,添加了 Closure:call()、??(空值合并)运算符、返回类型声明、标量类型声明、<⇒“飞船”三路比较运算符、匿名类

Version 7.3 (6 December 2018)

灵活的 Heredoc 和 Nowdoc 语法

Version 8.0 (26 November 2020)

即时 (JIT) 编译、以负索引开始的数组、无效的算术/位运算符上的 TypeError、变量语法调整、属性、具名参数、匹配表达式、联合类型、混合类型、静态返回类型

PHP - Features

PHP(超文本预处理程序)是一种开源服务端脚本语言,主要用于 Web 开发。PHP 可以嵌入 HTML 代码中。

PHP 主要用于服务端脚本编写,它在 Web 服务器上运行脚本,然后将处理后的 HTML 转发给客户端上的 Web 浏览器。这使得程序员可以设计可管理会话、处理表单、与数据库通信并执行各种其他必要的在线应用程序任务的动态网页。

Features of PHP

多年来,PHP 结合了许多特性。它不断通过新特性和代码修订进行升级。在本章中,让我们重点介绍 PHP 的一些关键特性:

php features

PHP is Simple and Easy to Learn

与 C、Java 和 Perl 相比,PHP 的语法较为简单,开发人员很容易理解,特别是那些已经熟悉其他编程语言的开发人员。由于有丰富的预定义函数,可以快速开发 Web 应用程序。

PHP is Open Source

PHP 是免费且开源的,意味着我们可以免费下载它,任何人都可以使用、修改和分发它。这鼓励了一个庞大且充满活力的开发人员社区,他们使用论坛、教程和文档来支持和促进其开发。

PHP is Cross-Platform Compatible

PHP 与多种操作系统兼容,包括 Windows、Linux、macOS 和 UNIX;以及不同的数据库,如 MongoDB、PostgreSQL、MySQL。

由于具有跨平台互操作性,基于 PHP 的应用程序可以在多种环境中运行,无需进行任何修改。

Server-Side Scripting in PHP

PHP 主要用于服务端脚本编写,它在 Web 服务器上运行脚本,然后将处理后的 HTML 转发给客户端上的 Web 浏览器。它帮助开发人员在多个请求中处理表单提交和用户会话管理。

PHP Supports Easy Integration with Databases

PHP 为各种 DBMS 提供强大的数据库交互支持。它提供多种内置函数来实现数据库连接。

PHP 还包括数据库抽象层,它集成了应用程序与数据库之间的通信。这使得开发人员可以轻松设计基于数据库的 Web 应用程序。

PHP Provides Extensive Library Support

PHP 为多种功能提供了丰富的库,例如图像处理、加密、PDF 生成、解析 XML 和 JSON、处理会话和 Cookie 等。

Security Features in PHP

PHP 为数据加密提供了大量内置函数。开发人员还可以利用第三方应用程序来保障安全性。

PHP 采用 Sha1MD5 等安全算法来加密字符串。此外,诸如 filter_varstrip_tags 等函数有助于为用户维护一个安全的环境。PHP 还支持 HTTPS 等安全通信协议。

Efficient Memory and Session Management in PHP

PHP 是一款可靠的语言,因为它具有高效的内存管理和会话管理。它避免了不必要的内存分配。

PHP 代码在其自己的内存空间中运行,与其他脚本语言相比速度更快,使其更高效。在 PHP 中,数据库连接也很快。

PHP Has Active Community and Support

由于 PHP 是一个开源平台,它拥有一个充满活力的开发人员社区,他们积极为其发展做出贡献、分享知识、提供支持并创建第三方工具和框架。

由于这个活跃的社区支持,PHP 保持最新状态,开发人员可以轻松地在编写 PHP 代码时遇到任何错误或异常时从其他社区成员那里寻求帮助。

PHP - Syntax

PHP 的语法规则与 C 语言非常相似。PHP 是一种服务器端脚本语言。PHP 代码存储为扩展名为“php”的文本文件。PHP 文件本质上是一个网页,内容是穿插在 HTML 脚本中的一个或多个 PHP 代码块。但是,它必须在浏览器中使用 HTTP 协议 URL 打开。也就是说,如果您双击 PHP 文件图标,它将使用文件协议在本地打开。例如,如果您在 Apache 服务器的文档根目录中打开“index.php”文件,它可能只显示 PHP 代码文本。但是,如果您启动 Apache 服务器并打开 URL http://localhost/index.php ,它将显示 Apache 主页。

“php”文件可能包含 HTML、CSS 和 JavaScript 代码块以及 PHP 代码。因此,PHP 解析器必须区分出 PHP 代码和其他元素。当在网络浏览器中打开“php”文件时,HTML 引擎会呈现 HTML/CSS/JavaScript 部分,并在遇到包含在 PHP 标记内的语句时即退出 HTML 块。PHP 解析器解释器处理此块并向浏览器返回响应。

php syntax

PHP 定义了使用标记来让 PHP 代码脱离 HTML 的两种方法。标准 PHP 标记和短标记(SGML 样式)。

Canonical PHP Tags

通用最有效的 PHP 标记样式为 −

<?php
   One or more PHP statements
?>

如果您使用此样式,则可以确信您的标记将始终被正确解释。

Short-open (SGML-style) Tags

短标记或短开标记看起来像这样 −

<?php
	One or more PHP statements
?>

顾名思义,短标记是最短的选项。您必须执行两件事之一,以使 PHP 能够识别标记 −

  1. 在构建 PHP 时选择“--enable-short-tags”配置选项。

  2. 将 php.ini 文件中的“short_open_tag”设置设为打开。

short_open_tag=on

必须禁用此选项才能使用 PHP 解析 XML,因为 XML 标记使用相同的语法。

ASP-style tags

<%...%>

HTML script tags

<script language = "PHP">...</script>

的使用已被停止。

Escaping from HTML

PHP 解析器忽略开闭标记对之外的所有内容。因此,PHP 文件可以具有混合内容。这允许在 HTML 文档中嵌入 PHP −

<p>This is a HTML statement</p>
<?php echo This is a PHP statement.'; ?>
<p>This is another HTML statement.</p>

下面展示了使用条件脱离的稍高阶示例 −

<?php if ($expression == true): ?>
   This HTML statement will be rendered.
<?php else: ?>
   Otherwise this HTML statement will be rendered.
<?php endif; ?>

PHP 跳过不满足条件的块,即使它们在 PHP 打开/关闭标记之外。

对于输出大块文本,退出 PHP 解析模式通常比通过 echo 或 print 发送所有文本更有效率。

Basic Syntax of PHP

PHP 的基本语法与 C 和 C++ 的语法非常相似。

Statements are Expressions Terminated by Semicolons

PHP 中的语句是后面紧跟一个分号 (;) 的任何表达式。任何被 PHP 标记括起来的有效 PHP 语句序列都是有效的 PHP 程序。

以下是在 PHP 中一个典型的语句,在这个案例中它给一个叫做 “$greeting” 的变量分配一个字符串 −

$greeting = "Welcome to PHP!";

文本编辑器中的一个物理行在 PHP 代码中没有任何意义。一行中可能会包含多个以分号结尾的语句。另一方面,如果需要的话,一个 PHP 语句可以溢出到多行。

Expressions are Combinations of Tokens

PHP 最小的构建块是不可分割的标记,诸如数字 (3.14159)、字符串 (“two”)、变量 ($two)、常量 (TRUE) 以及构成 PHP 自身语法的特殊单词,诸如 “if”、“else”、“while”、“for” 等。

Braces Make Blocks

尽管不能将语句像表达式那样组合,但你总可以通过将它们括在一对花括号中,将语句序列放在任何可以放置语句的位置。

这里,以下两个语句是等价的 −

if (3 == 2 + 1)
   print("Good - I haven't totally lost my mind.");
if (3 == 2 + 1) {
   print("Good - I haven't totally");
   print("lost my mind.");
}

PHP is Case Sensitive

PHP 是一种大小写敏感的语言。各种 PHP 标识符的名称(诸如变量、函数、类等)都是大小写敏感的。结果是变量 “$age” 不同于 “$Age”。同样,一个名为 “myfunction()” 的函数不同于另一个名为 “MyFunction()” 的函数。

PHP - Hello World

通常,学习者在学习一门新语言或框架时,会作为其第一个程序编写一个“Hello World”程序。其目的是验证要使用的软件是否已正确安装并且按预期工作。要在 PHP 中运行一个 Hello World 程序,你应该在使用的操作系统上安装了 Apache 服务器以及 PHP 模块。

PHP 是一种服务端编程语言。PHP 代码必须位于 Web 服务器的文档根目录中。Web 服务器文档根目录是你系统上运行的 Web 服务器的根目录。此根目录下的文档可供连接到 Web 服务器的任何系统(提供用户有权限)访问。如果一个文件不在此根目录下,则无法通过 Web 服务器访问它。

在此教程中,我们使用 XAMPP 服务器软件编写 PHP 代码。默认文档根目录通常在 Windows 上为“C:\xampp\htdocs\”,在 Linux 上为“/opt/lamp/htdocs/”。但是,你可以通过修改 Apache 服务器的配置文件“httpd.conf”中的 DocumentRoot 设置来更改默认文档根目录。

在 Windows 操作系统上,从 XAMPP 控制面板启动 Apache 服务器。

php hello world

浏览到“htdocs”目录。将以下脚本另存为其中的“hello.php”。

<?php
   echo "Hello World!";
?>

在浏览器中打开一个新选项卡,并输入 http://localhost/hello.php 作为 URL。你应该在浏览器窗口中看到“Hello World”消息。

PHP 脚本可能包含 HTML 和 PHP 代码的混合。

<!DOCTYPE html>
<html>
<body>
   <h1>My PHP Website</h1>
   <?php
      echo "Hello World!";
   ?>
</body>
</html>

“Hello World”消息将呈现为纯文本。但是,你可以将 HTML 标签放在“Hello World”字符串中。浏览器将相应地解释这些标签。

在以下代码中,“echo”语句渲染了“Hello World”,使其处于页面中心对齐的 <h1> 标题中。

<?php
   echo "<h1 align='center'>Hello World!</h1>";
?>

PHP Script from Command Prompt

你可以从命令提示符运行你的 PHP 脚本。假设你的“hello.php”文件中有以下内容。

<?php
   echo "Hello PHP!!!!!";
?>

将 PHP 可执行文件的路径添加到你的操作系统的路径环境变量中。例如,在 Windows 上的典型 XAMPP 安装中,PHP 可执行文件“php.exe”位于“c:\xampp\php”目录中。在此路径环境变量字符串中添加此目录。

现在以命令提示符运行此脚本 −

C:\xampp\htdocs>php hello.php

你将获得以下输出 -

Hello PHP!!!!!

PHP - Comments

任何计算机程序(如 PHP 程序)中的注释都是一种特定的解释性文本,语言编译器/解释器会忽略它。其目的是帮助用户理解程序算法中使用的逻辑。

尽管在代码中放置注释并不是必须的,但这是强烈推荐的做法。注释也可以作为程序文档。在需要调试和修改代码时,注释也非常有用。

PHP 有两种注释格式 -

  1. Single-line Comments

  2. Multi-line Comments

Single-line Comments

它们通常用于短说明或与本地代码相关的注释。PHP 使用两种符号在程序中插入单行注释。

Single-line Comments Using "

以“#”符号开头的 PHP 代码中的行被视为单行注释。

<?php
   # Single line comment starting with # symbol
   echo 'Hello World';
?>

Single-line Comments Using "//"

PHP 还支持以“//”符号为单行注释的 C 样式。以双斜线符号开头的行被视为注释。

<?php
   // Single line comment starting with // symbol
   echo 'Hello World';
?>

以符号 “#”或 “//”开头的注释不需要关闭。这些符号的作用持续到物理行的末尾。

换句话说,PHP 解析器会将下一行作为 PHP 语句对待,而不是注释,即使没有注释结束标记。

Multi-line Comments

多行注释通常用于在必要时提供伪代码算法和更详细的说明。

多行注释的样式与 C 中相同。嵌入在符号 “/ " and " /”内的行或多行被视为注释。

Example of Multi-line Comment in PHP

这是一个多行注释的示例。

<?php

   /* This is a multiline comment example
   program to add two numbers
   Variables used - $x for first number,
   $y for second number */

   $x=10;
   $y=20;
   print "Total = ". $x+$y;
?>

请注意,您甚至可以将单行放在程序中的 “/* .. /" symbols. However, if there is a "/ " 符号内,它必须有一个注释结束标记 “*/”。如果没有,将显示以下错误 -

PHP Parse error:  Unterminated comment starting line 3 in /home/cg/root/65ded9eeb52fc/main.php on line 3

PHP - Variables

PHP 中的变量是一个命名内存位置,它保存属于某种数据类型的数据。

  1. PHP 使用美元符号 ($) 前缀变量名称的惯例。

  2. PHP 中的变量名称区分大小写。

  3. 变量名称遵循与 PHP 中其他标签相同的规则。有效的变量名称以字母或下划线开头,后面跟任意数量的字母、数字或下划线。

  4. 根据命名约定,“$name”、“$rate_of_int”、“$Age”、“$mark1”是 PHP 中的 valid variable names 示例。

  5. Invalid variable names: “name”(没有$前缀)、“$rate of int”(不允许空格)、“$Age#1”(无效字符#)、“$11”(名称不是以字母开头)。

变量使用“=”运算符赋值,左侧是变量,右侧是要计算的表达式。

No Need to Specify the Type of a Variable

PHP 是一种动态类型语言。不需要指定变量的类型。相反,变量的类型由分配给它的值决定。变量的值是其最近赋值的值。

看看下面的 example

<?php
   $x = 10;
   echo "Data type of x: " . gettype($x) . "\n";

   $x = 10.55;
   echo "Data type of x now: " . gettype($x) . "";
?>

它将生成以下 output

Data type of x: integer
Data type of x now: double

Automatic Type Conversion of Variables

当有必要时,PHP 会很好地自动将类型从一种转换为另一种类型。在下面的代码中,PHP 将字符串变量“y”转换为“int”,对另一个整数变量执行加法,并将结果打印为 30。

看看下面的 example

<?php
   $x = 10;
   $y = "20";

   echo "x + y is: ", $x+$y;
?>

它将生成以下 output

x + y is: 30

Variables are Assigned by Value

在 PHP 中,变量始终按值分配。如果将表达式分配给变量,则原始表达式的值将被复制到其中。如果分配后表达式中任何变量的值发生变化,它不会对分配的值产生任何影响。

<?php
   $x = 10;
   $y = 20;
   $z = $x+$y;
   echo "(before) z = ". $z . "\n";

   $y=5;
   echo "(after) z = ". $z . "";
?>

它将生成以下 output

(before) z = 30
(after) z = 30

Assigning Values to PHP Variables by Reference

您还可以通过引用方式将值分配给 PHP 变量。在这种情况下,新变量仅引用或成为原始变量的别名或指向原始变量。新变量的更改会影响原始变量,反之亦然。

要按引用分配,只需在正在分配的变量(源变量)的开头添加一个和号 (&)。

看看下面的 example

<?php
   $x = 10;
   $y = &$x;
   $z = $x+$y;
   echo "x=". $x . " y=" . $y . " z = ". $z . "\n";

   $y=20;
   $z = $x+$y;
   echo "x=". $x . " y=" . $y . " z = ". $z . "";
?>

它将生成以下 output

x=10 y=10 z = 20
x=20 y=20 z = 40

Variable Scope

作用域可以定义为变量在其中声明的程序中可用性的范围。PHP 变量可以是四种作用域类型之一−

Variable Naming

命名变量的规则是−

  1. 变量名必须以字母或下划线字符开头。

  2. 变量名可以包含数字、字母、下划线,但不能使用 +、-、%、(、)、& 等字符。

变量没有大小限制。

PHP - Echo/Print

在 PHP 中, echoprint 语句都用于在浏览器或 PHP 控制台上呈现输出。它们两个都不是函数,而是语言结构。因此,不应在其中任何一个中使用括号。

The "echo" Statement in PHP

echo 语句与以下 syntax 搭配使用 −

echo(string ...$expressions): void

echo 语句输出一个或多个表达式,没有额外的换行符或空格。

Example

以下是 echo 语句在 PHP 中工作方式的一个示例 −

<?php
   $name = "Rajesh";
   echo "Hello " . $name . " How are you?"
?>

它将生成以下 output

Hello Rajesh How are you?

由于双引号字符串在 PHP 中类似于单引号字符串,因此以下语句会产生相同输出。

echo 'Hello ' . $name . ' How are you?';

Example

双引号字符串输出变量的值。因此,以下语句在打印输出之前插入“$name”变量的值。

<?php
   $name = "Rajesh";
   echo "Hello $name How are you?";
?>

它将生成以下 output

Hello Rajesh How are you?

Example

但是,单引号字符串将按原样输出“$name”。

<?php
   $name = "Rajesh";
   echo 'Hello $name How are you?';
?>

它将生成以下 output

Hello $name How are you?

传递给 echo 语句的字符串可以逐个作为多个参数传递,也可以连接在一起作为单个参数传递。因此,以下两个语句都是有效的 −

echo 'Hello ', 'how ', 'are ', 'you?', "\n";
echo 'Hello ' . 'how ' . 'are ' . 'you?' . "\n";

Example

请注意,如果不使用换行字符,两个连续 echo 语句的输出将在同一行中呈现。请看以下示例 −

<?php
   echo "hello";
   echo "world";
?>

它将生成以下 output

helloworld

The "print" Statement in PHP

print 语句类似于 echo,但它输出表达式。

print(string $expression): int

与 echo 一样,print 也是一种语言结构。它的参数是一个表达式,但它不会放在括号中。

主要区别在于 PHP 中的 print 语句只接受一个参数,并且总是返回 1。

Example

看看下面的 example

<?php
   $name = "Rajesh";

   print "Hello " . $name . " How are you?\n";
   print "Hello $name How are you?";
?>

它将生成以下 output

Hello Rajesh How are you?
Hello Rajesh How are you?

Output Multiline Strings Using Print/Echo

echo 和 print 语句都可以输出跨越编辑器中多行内容的多行字符串。请看以下示例 −

<?php
   print "
   Multi-line
   string can be output
   by echo as well as
   print statement in PHP
   ";
?>

它将生成以下 output

Multi-line
string can be output
by echo as well as
print statement in PHP

如果把 print 替换成 echo ,输出会保持不变。

PHP var_dump() Function

PHP 中的内置函数之一是 var_dump() 函数。此函数显示结构化信息,例如类型和作为此函数的参数给出的一个或多个表达式的值。

var_dump(mixed $value, mixed ...$values): void

此函数返回输出中对象的全部 public、private 和 protected 属性。数组和对象的转储信息缩进得当,显示递归结构。

对于内置整数、浮点数和布尔变量,var_dump() 函数显示参数变量的类型和值。

Example 1

例如,这是一个整数变量 −

<?php
   $x = 10;
   var_dump ($x);
?>

转储信息如下 −

int(10)

Example 2

让我们看看它对浮点数变量的行为 −

<?php
   $x = 10.25;
   var_dump ($x);
?>

var_dump() 函数返回以下 output

float(10.25)

Example 3

如果表达式是布尔值 −

<?php
   $x = true;
   var_dump ($x);
?>

它将生成以下 output

bool(true)

Example 4

对于字符串变量,var_dump() 函数还返回字符串的长度。

<?php
   $x = "Hello World";
   var_dump ($x);
?>

它将生成以下 output

string(11) "Hello World"

这里我们可以使用 <pre> HTML 标记,它显示预格式化文本。<pre> 元素中的文本以固定宽度的字体显示,并且文本保留空格和换行符。

<?php
   echo "<pre>";
   $x = "Hello World";
   var_dump ($x);
   echo "</pre>"
?>

它将生成以下 output

string(11) "Hello World"

Example 5 - Studying the Array Structure Using var_dump()

var_dump() 函数对于研究数组结构非常有用。在以下示例中,我们有一个数组,其中数组的一个元素是另一个数组。换句话说,我们有嵌套数组的情况。

<?php
   $x = array("Hello", false, 99.99, array(10, 20,30));
   var_dump ($x);
?>

它将生成以下 output

array(4) {
  [0]=>
  string(5) "Hello"
  [1]=>
  bool(false)
  [2]=>
  float(99.99)
  [3]=>
  array(3) {
    [0]=>
    int(10)
    [1]=>
    int(20)
    [2]=>
    int(30)
  }
}

Example 6

由于在前面的示例中“$x”是一个 indexed array ,所以从“0”开始的索引及其值将被转储。如果数组是 associate array ,则会转储键值对信息。

<?php
   $x = array(
      "Hello", false, 99.99,
      array(1=>10, 2=>20,3=>30)
   );
   var_dump($x);
?>

在这里,你会得到以下 output

array(4) {
  [0]=>
  string(5) "Hello"
  [1]=>
  bool(false)
  [2]=>
  float(99.99)
  [3]=>
  array(3) {
    [1]=>
    int(10)
    [2]=>
    int(20)
    [3]=>
    int(30)
  }
}

当你使用 var_dump() 来显示数组值时,不需要使用结束标记“ </pre> ”。

Example 7

var_dump() 函数还可以显示表示类的对象的特性。在下面的示例中,我们声明了一个 Point 类,其中包含两个私有特性“x”和“y”。该类的构造函数使用传递给它的参数初始化对象“p”。

var_dump() 函数提供有关对象特性及其对应值的信息。

<?php
   class Point {
      private int $x;
      private int $y;

      public function __construct(int $x, int $y = 0) {
         $this->x = $x;
         $this->y = $y;
      }
   }

   $p = new Point(4, 5);
   var_dump($p)
?>

它将生成以下 output

object(Point)#1 (2) {
  ["x":"Point":private]=>
  int(4)
  ["y":"Point":private]=>
  int(5)
}

PHP 中有一个类似的内置函数,用于生成转储,名为 get_defined_vars()

var_dump(get_defined_vars());

它会将所有已定义的变量转储到浏览器中。

PHP - $ and $$ Variables

我们知道 PHP 使用“$”符号作为变量名前缀的惯例。PHP 还可以通过在名称之前添加两个美元符号 ($$) 来声明动态变量。变量变量(或动态变量)可以动态设置和使用。

普通变量的声明如下 −

$a = 'good';

动态变量取正常变量的值并将其作为变量的名称。在上面的示例中,“good”可以使用两个美元符号“$$”作为变量名 −

$$a = 'morning';

我们现在有两个变量:“$a”内容为“good”和“$$a”内容为“morning”。因此,以下 echo 语句将产生相同输出 −

echo "$a {$$a}";
echo "$a $good";

两者都产生相同的输出 −

good morning

Example 1

看看下面的 example

<?php
   $a = 'good';
   $$a = 'morning';

   echo "$a {$$a}\n";
   echo "$a $good";
?>

它将生成以下 output

good morning
good morning

Example 2

我们来看另一个示例 −

<?php
   $x = "foo";
   $$x = "bar";
   echo "Value of x = " .$x . "\n";
   echo 'Value of $$x = ' . $$x . "\n";
   echo 'Value of foo = ' . $foo;
?>

在这里,你会得到以下 output

Value of x = foo
Value of $$x = bar
Value of foo = bar

Using Multiple "$" Symbols

请注意,美元符号“$”的使用并不限于两个。可以添加任意数量的美元符号作为前缀。

假设有一个变量“$x”其值为“a”。接下来,我们定义 x='as',那么“x”和“$a”将具有相同的值。同样,语句 $$$x='and' 实际上声明了一个“$as”变量,其值为’and'。

Example

这是一个完整的示例,展示了多个“$”符号的使用。

<?php
   $php = "a";
   $lang = "php";
   $World = "lang";
   $Hello = "World";
   $a = "Hello";
   echo '$a= ' . $a;
   echo "\n";
   echo '$$a= ' . $$a;
   echo "\n";
   echo '$$$a= ' . $$$a;
   echo "\n";
   echo '$$$$a= ' . $$$$a;
   echo "\n";
   echo '$$$$$a= ' . $$$$$a;
?>

当您运行此代码时,它将生成以下 output

$a= Hello
$$a= World
$$$a= lang
$$$$a= php
$$$$$a= a

Using Dynamic Variables with Arrays

将动态变量与数组一起使用可能会导致某些歧义的情况。对于数组“a”,如果你写 a[1],那么解析器需要知道你是否正在引用“$a[1]”作为变量,或者你希望“a”作为变量,然后从该变量中获取 [1] 索引。

若要解决此歧义,请对第一种情况使用 ${$a[1]},对第二种情况使用 ${$a}[1]。

Example

请看以下示例:

<?php
   $vars = array("hw", "os", "lang");
   $var_hw="Intel";
   $var_lang="PHP";
   $var_os="Linux";

   foreach ($vars as $var)
      echo ${"var_$var"} . "\n";

   print "$var_hw\n$var_os\n$var_lang";
?>

它将生成以下 output

Intel
Linux
PHP
Intel
Linux
PHP

需要注意的是,这个技术不能在函数或类方法中与 PHP 的超全局数组(PHP 中的几个预定义变量是“超全局”,这意味着它们在整个脚本中的所有作用域中都可用)一起使用。变量“$this”是 PHP 中的一个特殊变量,不能动态引用。

PHP - Constants

PHP 中的常量是简单值的一个名称或标识符。常量值在 PHP 脚本执行期间不能更改。

  1. 默认情况下,PHP 常量区分大小写。

  2. 根据惯例,常量标识符始终为大写。

  3. 常量名称以字母或下划线开头,后面跟任意数量的字母、数字或下划线。

  4. 不必在常量之前写美元符号($),但必须在变量之前使用美元符号。

Examples of Valid and Invalid Constant Names in PHP

以下是 PHP 中有效和无效常量名称的一些示例 -

// Valid constant names
define("ONE",     "first thing");
define("TWO2",    "second thing");
define("THREE_3", "third thing");
define("__THREE__", "third value");

// Invalid constant names
define("2TWO",    "second thing");

Difference between Constants and Variables in PHP

  1. 不能通过简单赋值定义常量;只能使用 define() 函数定义常量。

  2. 可以定义和访问常量,而无需考虑变量作用域规则。

  3. 一旦常量设置好之后,就不能重新定义或取消定义。

Defining a Named Constant

PHP 函数库中的 define() 函数用于在运行时定义一个命名常量。

define(string $const_name, mixed $value, bool $case = false): bool

Parameters

  1. const_name − 常量的名称。

  2. value − 常量的值。它可以是一个标量值(int、float、string、bool 或 null),也可以接受数组值。

  3. case − 如果设置为 true,常量将被定义为不区分大小写。默认的行为是区分大小写,例如,CONSTANT 和 Constant 代表不同的值。

define() 函数在成功时返回 "true",失败时返回 "false"。

Example 1

以下示例演示了 define() 函数的工作原理:

<?php
   define("CONSTANT", "Hello world.");

   echo CONSTANT;
   // echo Constant;
?>

第一条 echo 语句输出 CONSTANT 的值。您将获得以下 output

Hello world.

但是,当您取消对第二条 echo 语句的注释时,它将显示以下错误:

Fatal error: Uncaught Error: Undefined constant "Constant" in hello.php: on line 5

如果将 case 参数设置为 False,PHP 不区分大小写常量。

Example 2

您还可以将数组用作常量的值。查看以下示例:

<?php
   define(
      $name="LANGS",
      $value=array('PHP', 'Java', 'Python')
   );
   var_dump(LANGS);
?>

它将生成以下 output

array(3) {
  [0]=>
  string(3) "PHP"
  [1]=>
  string(4) "Java"
  [2]=>
  string(6) "Python"
}

Using the constant() Function

echo 语句输出已定义常量的值。您还可以使用 constant() 函数。它返回 name 指示的常量的值。

constant(string $name): mixed

如果您需要检索常量的值,但不知道其名称,constant() 函数非常有用。即,它存储在变量中或由函数返回。

<?php
   define("MINSIZE", 50);

   echo MINSIZE;
   echo PHP_EOL;
   echo constant("MINSIZE");	// same thing as the previous line
?>

它将生成以下 output

50
50

Using the defined() Function

PHP 函数库提供了一个 defined() 函数,用于检查是否给定一个已命名的常量存在。查看以下示例:

<?php
   define('MAX', 100);

   if (defined('MAX')) {
      echo MAX;
   }
?>

它将生成以下 output

100

PHP 还有一个名为 "get_defined_constants()" 的函数,它返回一个包含所有已定义常量及其值在内的关联数组。

PHP - Magic Constants

PHP 中的魔术常量是预定义常量。它们可以供在上面运行的任何脚本使用,并且它们会根据使用位置而改变。与在运行时解决的常规常量不同,所有这些“魔术”常量均在编译时解决。

PHP 中有九个魔术常量。这些特殊常量不区分大小写。

LINE

它返回文件中的当前行号。以下 example 展示了如何使用此魔术常量。

<?php
   $x="Hello World";
   echo "$x. The current Line number is " . __LINE__ . ".";
?>

它将生成以下 output

Hello World. The current Line number is 5.

FILE

此魔术常量返回文件的完整路径和文件名。如果在 include 内使用,则返回已包括文件的名字。请看以下 example

<?php
   $x="Hello World";
   echo "$x. Current PHP script name is " . __FILE__ . ".";
?>

它将生成以下 output

Hello World. Current PHP script name is C:\xampp\htdocs\hello.php.

DIR

此魔术常量返回文件的目录。如果在 include 内使用,则返回已包括文件的目录。这相当于“dirname( FILE )”。此目录名称没有尾随斜杠,除非它是根目录。见以下 example

<?php
   $x="Hello World";
   echo "$x. Directory of the Current PHP script name is " . __DIR__ . ".";
?>

它将在浏览器上显示以下 output

Hello World. Directory of the Current PHP script name is C:\xampp\htdocs.

FUNCTION

此魔术常量返回使用常量的功能名称,或匿名功能的 {closure}。以下 example 展示了它是如何工作的 −

<?php
   function hello(){
      $x="Hello World";
      echo "$x. The function name is ". __FUNCTION__ . "";
   }
   hello();
?>

它将生成以下 output

Hello World. The function name is hello

如果此魔术常量在功能之外使用,那么它将给空白输出。

CLASS

此常量返回类名称。类名称包含它声明的命名空间。见以下 example

<?php
   class myclass {
      public function __construct() {
         echo "Inside the constructor of ". __CLASS__ . PHP_EOL;
      }
      function getClassName(){
         echo "from an instance method of " . __CLASS__ . "";
      }
   }
   $obj = new myclass;
   $obj->getClassName();
?>

它将生成以下 output

Inside the constructor of myclass
from an instance method of myclass

METHOD

METHOD 常量返回类方法名称。以下 example 展示了它是如何工作的 −

<?php
   class myclass {
      public function __construct() {
         echo "Calling " . __METHOD__ . " of " . __CLASS__ ."<br>";
      }
      function mymethod(){
         echo "Calling " . __METHOD__ . " of " . __CLASS__ ."";
      }
   }
   $obj = new myclass;
   $obj->mymethod();
?>

它将生成以下 output

Calling myclass::__construct of myclass
Calling myclass::mymethod of myclass

TRAIT

返回性状名称。性状名称包含它声明的命名空间。在 PHP 中,性状是重新使用代码的机制。性状类似于类,但只准备以精细且一致的方式对功能分组。无法在它自己上实例化这种性状。

看看以下 example

<?php
   trait mytrait {
      public function hello() {
         echo "Hello World from " . __TRAIT__ ."";
      }
   }
   class myclass {
      use mytrait;
   }
   $obj = new myclass();
   $obj->hello();
?>

它将生成以下 output

Hello World from mytrait

NAMESPACE

此常量返回当前命名空间的名称。在 PHP 中,通过命名空间,我们能够使用名称相同的类 / 功能 / 常量在不同的环境中,无需任何冲突,从而封装这些项目。命名空间是类 / 功能的逻辑组合,根据它们的相关性。

以下 example 展示了如何使用此魔术常量 −

<?php
   namespace myspace;
   class myclass {
      public function __construct() {
         echo "Name of the class: " . __CLASS__ . " in " . __NAMESPACE__ . "";
      }
   }
   $class_name = __NAMESPACE__ . '\myclass';
   $a = new $class_name;
?>

它将生成以下 output

Name of the class: myspace\myclass in myspace

ClassName::class

与其他魔术常量不同,这个魔术常量不以双下划线 (__ ) 开头或结尾。它返回完全限定的类名。

以下 example 展示了如何使用此魔术常量 −

<?php
   namespace myspace;
   class myclass {
      public function __construct() {
         echo "Name of the class: " . myclass::class ;
      }
   }
   use myspace;
   $a = new myclass;
?>

它将生成以下 output

Name of the class: myspace\myclass

PHP – Data Types

“数据类型”一词是指将数据分类到不同类别中。PHP 共有八种数据类型,我们使用这些数据类型构造变量−

  1. Integers − 无小数点的整数,例如 4195。

  2. Doubles − 浮点数,例如 3.14159 或 49.1。

  3. Booleans - 只有两种可能的值,即真或假。

  4. NULL - 仅有一个值 NULL 的特殊类型。

  5. Strings - 字符序列,例如“PHP 支持字符串操作”。

  6. Arrays - 其他值的命名和索引集合。

  7. Objects - 程序员定义的类的实例,既可以封装其他类型的值,也可以封装特定于该类的函数。

  8. Resources - 保存对 PHP 外部资源(例如数据库连接)的引用的特殊变量。

前五个是简单类型,后两个(数组和对象)是复合类型。复合类型可以打包任意类型的其他任意值,而简单类型则不能。

在本章中,让我们详细讨论 PHP 的这些内置数据类型。

Integer Data Type in PHP

没有小数点(例如 4195)的整数在 PHP 中为 int 类型。整型数据类型是最简单的类型。它们对应于简单的整数,包括正数和负数。

  1. int 是集合 Z = {…​, -2, -1, 0, 1, 2, …​} 中的数字。

  2. int 可以用十进制(基数 10)、十六进制(基数 16)、八进制(基数 8)或二进制(基数 2)记法表示。

要使用八进制记法,数字应加上前缀“0o”或“0O”。要使用十六进制记法,数字应加上前缀“0x”。要使用二进制记法,数字应加上前缀“0b”。

下面给出一些 examples -

  1. Decimal Integer - 201、4195、-15

  2. Octal Integer - 0010、0O12、-0O21

  3. Hexadecimal Integer - 0x10、-0x100

  4. Binary Integer - 0b10101、-0b100

可以将整数分配给变量,也可以在表达式中使用它们,如下所示 -

$int_var = 12345;
$another_int = -12345 + 12345;

Double Data Type in PHP

双变量表示浮点数(也称为“浮点数”、“双精度数”或“实数”),即带分数部分的数字。分数部分跟在整数部分后面,中间用小数符号 (.) 分隔。

Note − 双精度变量可以为正、负或零。

$var1 = 1.55
$var2 =-123.0

Scientific Float Notation

PHP还允许使用科学计数法表示小数点后具有更多位数的浮点数。符号“E”或“e”用于分隔整数部分和小数部分。

− 1.2e3, 2.33e-4, 7E-10, 1.0E5

默认情况下,双精度打印时使用所需的小数位数。查看以下 example

<?php
   $many = 2.2888800;
   $many_2 = 2.2111200;
   $few = $many + $many_2;

   print("$many + $many_2 = $few");
?>

它生成下列内容 output

2.28888 + 2.21112 = 4.5

Boolean Data Type in PHP

bool 类型只有两个值;它可以为真或假。 bool 类型用于表示真值。

$bool1 = true;
$bool2 = false;

你也可以使用整数值“1”和“0”来表示真和假布尔值 −

$bool3 = 1;
$bool4 = 0;

通常,返回布尔值的运算符的结果将传递给诸如 if, whiledo-while 之类的控制结构。例如,

if (TRUE)
   print("This will always print.");

else
   print("This will never print.");

Interpreting Other Data Types as Booleans

这里有一组规则,你可以使用它来将其他数据类型解释为布尔值 −

  1. 如果该值是一个数字,则只有当该值等于零时它才为假,否则该值为真。

  2. 如果该值是一个字符串,则当该字符串为空(没有字符)或该字符串为“0”时它为假,否则为真。

  3. NULL类型的变量总为假。

  4. 如果该值是一个数组,则当它不包含其他值时它为假;否则为真。对于一个对象,包含一个值意味着有一个已经赋值的成员变量。

  5. 有效的资源为真(虽然一些在成功时返回资源的函数在不成功时将返回FALSE)。

Note − 不要将双精度用于布尔值。

当在布尔上下文中使用这些变量中的每一个时,这些变量中每一个都有其名称中嵌入的真值。

$true_num = 3 + 0.14159;
$true_str = "Tried and true"
$true_array[49] = "An array element";
$false_array = array();
$false_null = NULL;
$false_num = 999 - 999;
$false_str = "";

String Data Type in PHP

字符串是一系列字符,例如’PHP支持字符串操作'。

在PHP中,一个字符和一个字节相同。它意味着PHP仅支持256个字符集,因此不提供本机Unicode支持。

PHP支持单引号和双引号字符串的构建。以下两种表示在PHP中均有效 −

$string_1 = "This is a string in double quotes";
$string_2 = 'This is a somewhat longer, singly quoted string';

以下是字符串类型的其他一些示例 −

$string_39 = "This string has thirty-nine characters";
$string_0 = "";		// a string with zero characters

单引号字符串几乎按原样对待,而双引号字符串用其值替换变量,并特别解释某些字符序列。

<?php
   $variable = "name";
   $literally = 'My $variable will not print!';

   print($literally);
   print "\n";

   $literally = "My $variable will print!";
   print($literally);
?>

当您运行此代码时,它将生成以下 output

My $variable will not print!
My name will print

字符串长度没有限制。在可用内存范围内,您可以创建任意长的字符串。

由双引号分隔的字符串(如“this”)将在 PHP 中通过以下两种方式进行预处理:

  1. 以反斜杠 (\) 开头的某些字符序列将替换为特殊字符。

  2. 变量名(以 $ 开头)将替换为其值的字符串表示形式。

转义序列替换如下:

  1. \n 被换行符替换

  2. \r 被回车符替换

  3. \t 被制表符替换

  4. \$ 被美元符号本身 ($) 替换

  5. \" 被单个双引号 (") 替换

  6. \\ 被单个反斜杠 (\) 替换

PHP 也有字符串数据类型的 HeredocNowdoc 表示法。

Heredoc Representation of String Data Type

您可以使用 heredoc 将多行分配给单个字符串变量:

<?php
   $channel =<<<_XML_

   <channel>
      <title>What's For Dinner</title>
      <link>http://menu.example.com/ </link>
      <description>Choose what to eat tonight.</description>
   </channel>
   _XML_;

   echo <<< END
      This uses the "here document" syntax to output multiple lines with
	  variable interpolation. Note that the here document terminator must
	  appear on a line with just a semicolon. no extra whitespace!
   END;

   print $channel;
?>

当你运行这段代码时,它将产生以下输出:

This uses the "here document" syntax to output
multiple lines with variable interpolation. Note
that the here document terminator must appear on a
line with just a semicolon. no extra whitespace!

<channel>
   <title>What's For Dinner</title>
   <link>http://menu.example.com/ </link>
   <description>Choose what to eat tonight.</description>
</channel>

Nowdoc Representation of String Data Type

heredoc 标识符的所有规则也适用于 nowdoc 标识符。 nowdoc 的指定方式与 heredoc 相同,但 nowdoc 中不进行解析。您可以使用 nowdoc 构造来嵌入大块文本,而无需使用任何转义字符。

nowdoc 使用与 heredoc 相同的 <<< 序列进行标识,但标识符用单引号括起来,例如 <<<'EOT'。Nowdoc 用于单引号字符串,就像 heredoc 用于双引号字符串一样。

请看以下示例:

<?php
   echo <<<'IDENTIFIER'
   As the cat cleared its throat with a refined "Meow",
   the squirrel chirped excitedly about its latest
   discovery of a hidden stash of peanut treasure!
   IDENTIFIER;
?>

运行代码并检查其输出:

As the cat cleared its throat with a refined "Meow",
the squirrel chirped excitedly about its latest
discovery of a hidden stash of peanut treasure!

Null Data Type in PHP

在 PHP 中,null 表示一个特殊类型,它只有一个值:NULL。未定义和 unset() 变量将变为值“null”。

程序员通常在 PHP 中使用 Null 数据类型来初始化变量或指示某个值缺失。

若要给变量赋值为 NULL,只需像这样赋值:

$my_var = NULL;

根据惯例,特殊常量 NULL 为大写,但实际上它就是 case insensitive; 你也可以直接输入 −

$my_var = null;

已分配了 NULL 的变量具有以下属性 −

  1. 在布尔语境中,它被评估为 FALSE。

  2. 使用 IsSet() 函数测试时,它会返回 FALSE。

Note − PHP 中变量的数据类型在运行时根据赋值给它们的 值来确定。

Array Data Type in PHP

PHP 中的一个数组是一个有序映射,一个键与一个或多个值相关联。PHP 数组使用 array() 函数定义,或使用将数据放入方括号中的简短表示法进行定义。

请看以下 associative arrays 示例 −

Using the array() Function

$arr = array(
   "foo" => "bar",
   "bar" => "foo",
);

Using the Short Notation

$arr = [
   "foo" => "bar",
   "bar" => "foo",
];

PHP 中的数组也可以使用“键 - 值对”语法定义。它被称为 indexed array

$arr = array("foo", "bar", "hello", "world");

multi-dimensional array 中,主数组中的每个元素也可以是一个数组。而且,子数组中的每个元素也可以是一个数组,依此类推。使用多重索引访问多维数组中的值。

Note − 在 PHP 中,复合数据类型用于存储数据集合,包括数组和对象。

Object Data Type in PHP

对象类型是一个由程序员定义的类的实例,它可以将其他类型的值和特定于该类的函数打包在一起。

要创建一个新对象,请使用 new statement 实例化一个类 −

class foo {
   function bar() {
      echo "Hello World.";
   }
}
$obj = new foo;
$obj->bar();

Resource Data Type in PHP

资源是保存对 PHP 外部资源(如文件流或数据库连接)的引用的特殊变量。

以下是一个 file resource 示例 −

$fp = fopen("foo.txt", "w");

属于以上任何类型的的数据都存储在一个变量中。但是,由于 PHP 是一种动态类型语言,因此无需指定变量的类型,因为这将在运行时确定。

Example: The gettype() Function

gettype() 函数有助于找出存储在变量中的数据类型 −

<?php
   $x = 10;
   echo gettype($x) . "\n";

   $y = 10.55;
   echo gettype($y) . "\n";

   $z = [1,2,3,4,5];
   echo gettype($z);
?>

当您运行此代码时,它将生成以下 output

integer
double
array

PHP - Type Casting

术语 "类型转换" 指的是将一种类型的数据转换为另一种类型。由于 PHP 是弱类型语言,解析器在执行某些操作时会将某些数据类型强制转换为其他类型。例如,如果一个带有数字的字符串是加法运算中涉及的运算符之一,则它将转换为整数。

Implicit Type Casting

下面是一个强制或隐式类型转换的示例:

<?php
   $a = 10;
   $b = '20';
   $c = $a+$b;
   echo "c = " . $c;
?>

在这种情况下,$b 是一个字符串变量,被转换为整数以启用加法。它将生成以下 output

c = 30

我们再来看另一个示例。这里,整数变量 $a 被转换为一个字符串,以便与一个字符串变量连接。

<?php
   $a = 10;
   $b = '20';
   $c = $a.$b;
   echo "c = " . $c;
?>

它将生成以下 output

c = 1020

除了此类强制类型转换之外,还有其他方法可将一种类型的数据显式转换为另一种类型。为此,您可以使用 PHP 的类型转换运算符或类型转换函数。

Type Casting Operators

若要将一个类型的表达式转换为另一个类型,您需要在表达式前面的括号中放入后一个类型的数据类型。

$var = (type)expr;

PHP 中的某些类型转换运算符为 −

  1. (int) 或 (integer) 转换为整数

  2. (bool) 或 (boolean) 转换为布尔

  3. (float) 或 (double) 或 (real) 转换为浮点数

  4. (string) 转换为字符串

  5. (array) 转换为数组

  6. (object) 转换为对象

Casting to Integer

您可以轻松地将浮点值转换为整数。看看以下 example

<?php
   $a = 9.99;
   $b = (int)$a;
   var_dump($b);
?>

它将生成以下 output

int(9)

请注意,浮点值不会四舍五入到最接近的整数;它只会返回整数部分。

String to Integer Conversion

(int) 运算符还会将字符串转换为整数。如果字符串仅由数字组成,则转换非常简单。

<?php
   $a = "99";
   $b = (int)$a;
   var_dump($b);
?>

在这里,你会得到以下 output

int(99)

即使字符串包含浮点数,(int) 运算符也会仅返回整数部分。

现在我们再举一个例子来理解一个特殊情况。 If the string is alphanumeric, casting with (int) works differently

  1. 如果字符串以数字开头,后面跟着非数字字符,则只会考虑初始数字。

  2. 如果字符串以非数字字符开头,并且数字位于中间,则强转运算符返回“0”。

看看以下 example

<?php
   $a = "10 Rs.";
   $b = (int)$a;
   var_dump($b);

   $a = "$100";
   $b = (int)$a;
   var_dump($b);
?>

它将生成以下 output

int(10)
int(0)

Casting to Float Type

您可以使用 (float) 或 (double) 强转运算符将变量或表达式显式转换为浮点数。

<?php
   $a = 100;
   $b = (double)$a;
   var_dump($b);
?>

它将生成以下 output

float(100)

包含任何有效数字表示的字符串都可以使用强转运算符转换为浮点类型。

<?php
   $a = "100";
   $b = (double)$a;
   var_dump($b);

   $a = "9.99";
   $b = (float)$a;
   var_dump($b);
?>

在这里,你会得到以下 output

float(100)
float(9.99)

即使字符串嵌入了浮点的科学计数法,该字符串也会转换为浮点。看看下面的例子 −

<?php
   $a = "1.23E01";
   $b = (double)$a;
   var_dump($b);
   $a = "5.5E-5";
   $b = (float)$a;
   var_dump($b);
?>

它将生成以下 output

float(12.3)
float(5.5E-5)

所有浮点数后边的非数字字符均被忽略。类似的,如果字符串以任何一个非数字字符开头,则会转换为“0”。见以下的 example

<?php
   $a = "295.95 only";
   $b = (double)$a;
   var_dump($b);

   $a = "$2.50";
   $b = (float)$a;
   var_dump($b);
?>

它将生成以下 output

float(295.95)
float(0)

Casting to String Type

通过使用一个强制类型转换操作符,任何求值为一个浮点数或整数的表达式都可以强制转换为一个字符串类型。下面给出几个示例−

<?php
   $a = 100;
   $b = (string)$a;
   var_dump($b);

   $x = 55.50;
   $y = (string)$x;
   var_dump($y);
?>

您将获得以下内容 output

string(3) "100"
string(4) "55.5"

Casting to Bool Type

任何非零数字(可以是整数或浮点数)使用 (bool) 操作符强制转换为 true。求值为“0”的表达式返回 false。字符串始终强制转换为 true。

看看以下 example

<?php
   $a = 100;
   $b = (bool)$a;

   $x = 0;
   $y = (bool)$x;

   $m = "Hello";
   $n = (bool)$m;

   var_dump($b);
   var_dump($y);
   var_dump($n);
?>

它将生成以下 output

bool(true)
bool(false)
bool(true)

Type Casting Functions

PHP 包含用于执行类型强制转换的以下内置函数−

  1. intval()

  2. floatval()

  3. strval()

让我们详细讨论这些内置函数。

The intval() Function

这个函数获取一个变量的整数值。

intval(mixed $value, int $base = 10): int

$base 参数默认为 10,这意味着该值转换为十进制数。

  1. 如果值为一个浮点数,则 intval() 函数返回一个整数,抛弃小数部分。

  2. 一个数字的字符串表示返回一个对应的整数,抛弃小数部分(如果存在的话)。

  3. 如果值为一个带有有效八进制数的字符串,并且基数为 8,则 intval() 函数返回一个对应的八进制数。

When the base is "0" ,值的转换基于字符前缀。

  1. 如果值以 0X 或 0x 开头,则返回一个十六进制数。

  2. 如果值以 0B 或 0b 开头,则返回一个二进制数

  3. 如果值以 0 开头,则该函数返回一个八进制数。

intval() 函数对于 true,返回 1,对于 false 布尔值,返回 0。

Example

下面的示例展示了 intval() 函数的工作方式−

<?php
   echo intval(42). PHP_EOL;
   echo intval(4.2). PHP_EOL;
   echo intval('42') . PHP_EOL;

   echo intval(042) . PHP_EOL;         # 0ctal number
   echo intval('042', 0) . PHP_EOL;    # 0ctal number
   echo intval('42', 8) . PHP_EOL;     # octal

   echo intval(0x1A) . PHP_EOL;        # Hexadecimal
   echo intval('0x1A', 16) . PHP_EOL;  # Hexadecimal
   echo intval('0x1A', 0) . PHP_EOL;   # Hexadecimal

   echo intval(false) . PHP_EOL;
   echo intval(true) . PHP_EOL;
?>

它将生成以下 output

42
4
42
34
34
34
26
26
26
0
1

The floatval() Function

floatval() 函数获取一个表达式的浮点值。

floatval(mixed $value): float

该值可能是一个任意的标量变量。带有非数字字符的字符串返回“0”。带有数字表示或带有一个数字表示起始子串的字符串返回对应的数字。下面的 example 展示了 floatval() 函数的工作方式 −

<?php
   echo floatval(42). PHP_EOL;
   echo floatval(4.2). PHP_EOL;
   echo floatval('42') . PHP_EOL;

   echo floatval('99.90 Rs') . PHP_EOL;
   echo floatval('$100.50') . PHP_EOL;
   echo floatval('ABC123!@#') . PHP_EOL;

   echo (true) . PHP_EOL; ;
   echo (false) . PHP_EOL;
?>

它将生成以下 output

42
4.2
42
99.9
0
0
1

doubleval() 函数是 floatval() 函数的一个别名,因此返回类似的结果。

The strval() Function

strval() 函数获取变量的字符串值。此函数不对返回的值执行任何格式化。

strval(mixed $value): string

正在转换为字符串的值可以是任何标量类型、null 值或实现了 __toString() 方法的对象。查看以下内容:

<?php
   echo strval(42). PHP_EOL;
   echo strval(4.2). PHP_EOL;
   echo strval(4.2E5) . PHP_EOL;

   echo strval(NULL) . PHP_EOL;

   echo (true) . PHP_EOL;
   echo (false) . PHP_EOL;
?>

它将生成以下 output

42
4.2
420000

1

以下内容定义了一个实现了 __toString() 方法的类:

<?php
   class myclass {
      public function __toString() {
         return __CLASS__;
      }
   }
   echo strval(new myclass);
?>

在这里,你会得到以下 output

myclass

PHP - Type Juggling

PHP 被称为动态类型语言。PHP 中变量的类型会动态更改。此特性在 PHP 中称为“类型转换”。

在 C、C++ 和 Java 中,您需要在随后代码中使用变量之前声明该变量及其类型。该变量只能取与声明的类型相匹配的值。

在 PHP 中既不需要显式类型声明变量,也不支持显式类型声明。因此,PHP 变量的类型由分配给它的值决定,反之亦然。此外,当变量被分配了不同类型的值时,其类型也会更改。

Example 1

了解 PHP 中的以下变量赋值。

<?php
   $var = "Hello";
   echo "The variable \$var is of " . gettype($var) . " type" .PHP_EOL;

   $var = 10;
   echo "The variable \$var is of " . gettype($var) . " type" .PHP_EOL;

   $var = true;
   echo "The variable \$var is of " . gettype($var) . " type" .PHP_EOL;

   $var = [1,2,3,4];
   echo "The variable \$var is of " . gettype($var) . " type" .PHP_EOL;
?>

它将生成以下 output

The variable $var is of string type
The variable $var is of integer type
The variable $var is of boolean type
The variable $var is of array type

你会看到,“$var” 的类型会根据分配给它的值动态改变。PHP 的这一特性被称为“类型混用”。

Example 2

在计算表达式时也会进行类型混用。在这个示例中,包含数字的字符串变量会自动转换为整数以评估加法表达式。

<?php
   $var1=100;
   $var2="100";
   $var3=$var1+$var2;
   var_dump($var3);
?>

以下是它的 @{s0}

int(200)

Example 3

如果一个字符串以数字开头,在执行计算时会忽略后面的非数字字符(如果有)。然而,PHP 解析器会发出如下所示的通知 −

<?php
   $var1=100;
   $var2="100 days";
   $var3=$var1+$var2;
   var_dump($var3);
?>

您将获得以下内容 output

int(200)

PHP Warning:  A non-numeric value encountered in /home/cg/root/53040/main.php on line 4

Type Casting vs Type Juggling

注意,PHP 中的“类型转换”与“类型混用”略有不同。

  1. 在类型混用中,当必要时 PHP 会自动将类型从一个转换到另一个。例如,如果将一个整数值分配给变量,它会变成一个整数。

  2. 另一方面,类型转换发生在用户显式定义他们想要转换的数据类型时。

Example

类型转换强制将变量用作某种类型。以下脚本展示了不同的类型转换运算符示例 −

<?php
   $var1=100;
   $var2=(boolean)$var1;
   $var3=(string)$var1;
   $var4=(array)$var1;
   $var5=(object)$var1;
   var_dump($var2, $var3, $var4, $var5);
?>

它将生成以下 output

bool(true)
string(3) "100"
array(1) {
  [0]=>
  int(100)
}
object(stdClass)#1 (1) {
  ["scalar"]=>
  int(100)
}

Example

还可以通过用双引号字符串括起来的方式将变量转换为字符串 −

<?php
   $var1=100.50;
   $var2=(string)$var1;
   $var3="$var1";
   var_dump($var2, $var3);
?>

在这里,你会得到以下 output

string(5) "100.5"
string(5) "100.5"

PHP - Strings

字符串是一系列字符,如“PHP 支持字符串操作”。PHP 中的字符串是一个字节数组和一个指示缓冲区长度的整数。在 PHP 中,字符与字节相同。这意味着 PHP 仅支持 256 个字符集,因此不提供本机的 Unicode 支持。

PHP 支持单引号和双引号的字符串格式。两种格式“this is a simple string”和“this is a simple string”均有效。PHP 还有 Heredoc 和 Nowdoc 形式的字符串数据类型。

Single-Quoted String

用单引号(字符“'”)引起来的一系列字符是一个字符串。

$str = 'this is a simple string';

Example

如果要包含一个文字单引号,请用反斜杠(\)对其进行转义。

<?php
   $str = 'This is a \'simple\' string';
   echo $str;
?>

它将给出以下内容:

This is a 'simple' string

Example

要指定一个文字反斜杠,请将其加倍(\\)。

<?php
   $str = 'The command C:\\*.* will delete all files.';
   echo $str;
?>

以下是它的 @{s0}

The command C:\*.* will delete all files.

Example

诸如“\r”或“\n”之类的转义序列将被视为文本,并且不会解释它们的特殊含义。如果变量出现在单引号字符串中,它们也不会扩展。

<?php
   $str = 'This will not expand: \n a newline';
   echo $str . PHP_EOL;
   $x=100;
   $str = 'Value of x = $x';
   echo $str;
?>

它将生成以下 output

This will not expand: \n a newline
Value of x = $x

Double-Quoted String

用双引号(“"”)引起来的一系列字符是另一种字符串表示形式。

$str = "this is a simple string";

单引号和双引号字符串是等效的,除了它们对转义序列的处理不同。PHP 会解释特殊字符的某些转义序列。例如,“\r”和“\n”。

Sequence

Meaning

\n

换行符(LF 或 ASCII 中的 0x0A (10))

\r

回车符(CR 或 ASCII 中的 0x0D (13))

\t

水平制表符(HT 或 ASCII 中的 0x09 (9))

\v

垂直制表符(VT 或 ASCII 中的 0x0B (11))

\e

转义符(ESC 或 ASCII 中的 0x1B (27))

\f

换页符(FF 或 ASCII 中的 0x0C (12))

|backslash

\$

dollar sign

\"

How to Escape Octal and Hexademical Characters in PHP?

PHP 支持将八进制和十六进制数字转义为其 ASCII 字符。例如,字符 P 的 ASCII 字符为十进制中的 80。十进制中的 80 对应八进制中的 120。同样,十进制中的 80 对应十六进制中的 50。

要转义八进制字符,使用“\”前缀;要转义十六进制字符,使用“\x”前缀。

<?php
   $str = "\120\110\120";
   echo "PHP with Octal: ". $str;
   echo PHP_EOL;

   $str = "\x50\x48\x50";
   echo "PHP with Hexadecimal: ". $str;
?>

检查 output

PHP with Octal: PHP
PHP with Hexadecimal: PHP

与单引号串一样,转义任何其他字符也将导致反斜杠被打印。双引号串最重要的特征是变量名将被展开。

Example

PHP 中的双引号串展开变量名(PHP 变量用 $ 符号作为前缀)。如要在 PHP 串中实际表示 “$” 符号,用 “\” 字符进行转义。

<?php
   $price = 200;
   echo "Price = \$ $price";
?>

您将获得以下内容 output

Price = $ 200

String Concatenation Operator

要将两个字符串变量连接在一起,PHP 使用点 (.) 运算符 −

<?php
   $string1="Hello World";
   $string2="1234";

   echo $string1 . " " . $string2;
?>

在这里,你会得到以下 output

Hello World 1234

在上述示例中,我们使用了连接运算符两次。这是因为我们必须插入第三个串。在两个字符串变量之间,我们添加了一个包含单个字符(一个空格)的串,以分隔这两个变量。

PHP 的标准库包括很多用于字符串处理的函数。它们可以在 PHP 的官方文档中找到 ( https://www.php.net/manual/en/ref.strings.php )。

The strlen() Function

strlen() 函数用于找到一个字符串的长度。

Example

让我们找到字符串 “Hello world!” 的长度 −

<?php
   echo strlen("Hello world!");
?>

它将生成以下 output

12

字符串的长度通常用于循环或其他函数中,这些时候了解字符串何时结束非常重要(也就是说,在循环中,我们希望在字符串中的最后一个字符后面停止循环)。

The strpos() Function

strpos() 函数用于在字符串内搜索字符串或字符。

  1. 如果在字符串中找到匹配项,此函数将返回第一个匹配项的位置。

  2. 如果没有找到匹配项,它将返回 FALSE。

Example

让我们看看能否在我们的字符串中找到字符串 “world” −

<?php
   echo strpos("Hello world!","world");
?>

它将生成以下 output

6

如你所见,字符串 “world” 在我们字符串中的位置是 “6”。这个位置是 “6” 而不是 “7” 的原因是字符串中的第一个位置是 “0”,而不是 “1”。

PHP - Boolean

在 PHP 中,“bool” 是内置标量数据类型之一。它用于表示真值,可以是 True 或 False。布尔值常量使用 PHP 常量 True 或 False。这些常量不区分大小写,即 true、TRUE 或 True 是同义词。

你可以如下声明 bool 类型的变量 −

$a = true;

Example

逻辑运算符 (<, >, ==, != 等)返回布尔值。

<?php
   $gender="Male";
   var_dump ($gender=="Male");
?>

它将生成以下 output

bool(true)

Boolean Values in Control Statements

布尔值用于构造控制语句,如 if, while, forforeach 。这些语句的行为取决于布尔运算符返回的 true/false 值。

以下条件语句使用在 if 关键字之前的括号中表达式返回的布尔值 −

$mark=60;

if ($mark>50)
   echo "pass";
else
   echo "fail";

Converting a Value to Boolean

使用 (bool) 转换运算符将一个值转换为 bool。当一个值在逻辑上下文中使用时,它将自动解释为类型为 bool 的值。

非零数字被认为是真,只有 0(+0.0 或 -0.0)是假。非空字符串表示真,空字符串 “” 等同于假。同样,一个空数组返回假。

Example

请查看以下示例:

<?php
   $a = 10;
   echo "$a: ";
   var_dump((bool)$a);

   $a = 0;
   echo "$a: ";
   var_dump((bool)$a);

   $a = "Hello";
   echo "$a: ";
   var_dump((bool)$a);

   $a = "";
   echo "$a: ";
   var_dump((bool)$a);

   $a = array();
   echo "$a: ";
   var_dump((bool)$a);
?>

它将生成以下 output

10: bool(true)
0: bool(false)
Hello: bool(true)
: bool(false)
Array: bool(false)

Integer 是 PHP 中内置标量类型之一。在字面量中没有小数点的整数在 PHP 中为“int”类型。整数可以用十进制(基数 10)、十六进制(基数 16)、八进制(基数 8)或二进制(基数 2)记法表示。

要使用八进制记法,数字之前加上“0o”或“0O”(PHP 8.1.0 及更早版本)。从 PHP 8.1.0 开始,以“0”为前缀且没有小数点的数字为八进制数字。

要使用十六进制记法,数字之前加上“0x”。要使用二进制记法,数字之前加上“0b”。

Example

请看以下示例:

<?php
   $a = 1234;
   echo "1234 is an Integer in decimal notation: $a\n";

   $b = 0123;
   echo "0o123 is an integer in Octal notation: $b\n";

   $c = 0x1A;
   echo "0xaA is an integer in Hexadecimal notation: $c\n";

   $d = 0b1111;
   echo "0b1111 is an integer in binary notation: $d\n";
?>

它将生成以下 output

1234 is an Integer in decimal notation: 1234
0o123 is an integer in Octal notation: 83
0xaA is an integer in Hexadecimal notation: 26
0b1111 is an integer in binary notation: 15

从 PHP 7.4.0 开始,整数字面量可能包含下划线 (_) 作为数字之间的分隔符,以提高字面量的可读性。这些下划线由 PHP 的扫描器移除。

Example

请看以下示例:

<?php
   $a = 1_234_567;
   echo "1_234_567 is an Integer with _ as separator: $a\n";
?>

它将生成以下 output

1_234_567 is an Integer with _ as separator: 1234567

PHP does not support unsigned intsint 的大小依赖于平台。在 32 位系统上,最大值约为二十亿。64 位平台的最大值通常约为 9E18。

int 大小可以用常量 PHP_INT_SIZE 确定,最大值可以用常量 PHP_INT_MAX 确定,最小值可以用常量 PHP_INT_MIN 确定。

如果整数恰好超出了 int 类型的边界,或任何操作导致数字超出了 int 类型的边界,它将被解释为浮点数。

Example

请看以下示例:

<?php
   $x = 1000000;
   $y =  50000000000000 * $x;
   var_dump($y);
?>

它将生成以下 output

float(5.0E+19)

PHP 没有用于整数除法的运算符。因此,整数和浮点数之间的除法运算总是导致浮点数。要获得整数除法,可以使用 intval() 内置函数。

Example

请看以下示例:

<?php
   $x = 10;
   $y = 3.5;
   $z = $x/$y;
   var_dump ($z);
   $z = intdiv($x, $y);
   var_dump ($z);
?>

它将生成以下 output

float(2.857142857142857)
int(3)

PHP - Integers

Integer 是 PHP 中内置标量类型之一。在字面量中没有小数点的整数在 PHP 中为“int”类型。整数可以用十进制(基数 10)、十六进制(基数 16)、八进制(基数 8)或二进制(基数 2)记法表示。

要使用八进制记法,数字之前加上“0o”或“0O”(PHP 8.1.0 及更早版本)。从 PHP 8.1.0 开始,以“0”为前缀且没有小数点的数字为八进制数字。

要使用十六进制记法,数字之前加上“0x”。要使用二进制记法,数字之前加上“0b”。

Example

请查看以下示例:

<?php
   $a = 1234;
   echo "1234 is an Integer in decimal notation: $a\n";

   $b = 0123;
   echo "0o123 is an integer in Octal notation: $b\n";

   $c = 0x1A;
   echo "0xaA is an integer in Hexadecimal notation: $c\n";

   $d = 0b1111;
   echo "0b1111 is an integer in binary notation: $d";
?>

它将生成以下 output

1234 is an Integer in decimal notation: 1234
0o123 is an integer in Octal notation: 83
0xaA is an integer in Hexadecimal notation: 26
0b1111 is an integer in binary notation: 15

从 PHP 7.4.0 开始,整数字面量可能包含下划线 (_) 作为数字之间的分隔符,以提高字面量的可读性。这些下划线由 PHP 的扫描器移除。

Example

请查看以下示例:

<?php
   $a = 1_234_567;
   echo "1_234_567 is an Integer with _ as separator: $a";
?>

它将生成以下 output

1_234_567 is an Integer with _ as separator: 1234567

PHP does not support unsigned intsint 的大小依赖于平台。在 32 位系统上,最大值约为二十亿。64 位平台的最大值通常约为 9E18。

int 大小可以用常量 PHP_INT_SIZE 确定,最大值可以用常量 PHP_INT_MAX 确定,最小值可以用常量 PHP_INT_MIN 确定。

如果整数恰好超出了 int 类型的边界,或任何操作导致数字超出了 int 类型的边界,它将被解释为浮点数。

Example

请查看以下示例:

<?php
   $x = 1000000;
   $y =  50000000000000 * $x;
   var_dump($y);
?>

它将生成以下 output

float(5.0E+19)

PHP 没有用于整数除法的运算符。因此,整数和浮点数之间的除法运算总是导致浮点数。要获得整数除法,可以使用 intval() 内置函数。

Example

请查看以下示例:

<?php
   $x = 10;
   $y = 3.5;
   $z = $x/$y;
   var_dump ($z);
   $z = intdiv($x, $y);
   var_dump ($z);
?>

它将生成以下 output

float(2.857142857142857)
int(3)

PHP - Files & I/O

本章将说明与文件相关的以下函数 −

  1. Opening a File

  2. Reading a File

  3. Writing a File

  4. Closing a File

Opening and Closing Files

PHP fopen() 函数用于打开一个文件。它需要两个参数,首先是文件名,然后是操作模式。

文件模式可以指定为此表中的六个选项之一。

Sr.No

Mode & Purpose

1

r 仅打开文件用于读取。将文件指针放在文件开头。

2

r+ 打开一个文件用于读写。将文件指针放在文件开头。

3

w 仅打开文件用于写入。将文件指针放在文件开头。并将文件截断为零长度。如果文件不存在,它将尝试创建一个文件。

4

w+ 仅打开文件用于读写。将文件指针放在文件开头。并将文件截断为零长度。如果文件不存在,它将尝试创建一个文件。

5

a 仅打开文件用于写入。将文件指针放在文件结尾。如果文件不存在,它将尝试创建一个文件。

6

a+ 仅打开文件用于读写。将文件指针放在文件结尾。如果文件不存在,它将尝试创建一个文件。

如果打开文件失败,则 fopen 返回 false 的值,否则它返回一个 file pointer ,用于进一步读取或写入该文件。

在对打开的文件进行更改后,使用 fclose() 函数将其关闭非常重要。 fclose() 函数需要一个文件指针作为其参数,然后在关闭成功时返回 true ,或者在关闭失败时返回 false

Reading a File

一旦使用 fopen() 函数打开一个文件,就可以用称为 fread() 的函数读取它。此函数需要两个参数。它们必须是文件指针和文件长度(以字节表示)。

可以使用 filesize() 函数找到文件长度,它以文件名作为其参数并返回文件的大小(以字节表示)。

所以,以下是使用 PHP 读取文件所需的步骤。

  1. 使用 fopen() 函数打开一个文件。

  2. 使用 filesize() 函数获取文件的长度。

  3. 通过 fread() 函数读取文件内容。

  4. 通过 fclose() 函数关闭文件。

Example

以下示例将文本文件的内容分配给一个变量,然后在网页上显示该内容。

<html>
<head>
   <title>Reading a file using PHP</title>
</head>
<body>
   <?php
      $filename = "tmp.txt";
      $file = fopen( $filename, "r" );

      if( $file == false ) {
         echo ( "Error in opening file" );
         exit();
      }

      $filesize = filesize( $filename );
      $filetext = fread( $file, $filesize );
      fclose( $file );

      echo ( "File size : $filesize bytes" );
      echo ( "<pre>$filetext</pre>" );
   ?>
</body>
</html>

它将产生以下结果 −

reading file

Writing a File

可以使用 PHP fwrite() 函数编写新文件或在现有文件中附加文本。该函数需要两个指定 file pointer 和要写入的数据字符串的参数。还可以选择包含第三个整数参数以指定要写入的数据的长度。如果包含第三个参数,则在达到指定长度后写入将停止。

Example

以下示例创建一个新文本文件,然后在其中写一个简短的文本标题。关闭此文件后,使用 file_exist() 函数确认其存在,该函数将文件名作为参数

<?php
   $filename = "/home/user/guest/newfile.txt";
   $file = fopen( $filename, "w" );

   if( $file == false ) {
      echo ( "Error in opening new file" );
      exit();
   }
   fwrite( $file, "This is  a simple test\n" );
   fclose( $file );
?>
<html>
<head>
   <title>Writing a file using PHP</title>
</head>
<body>
   <?php
      $filename = "newfile.txt";
      $file = fopen( $filename, "r" );

      if( $file == false ) {
         echo ( "Error in opening file" );
         exit();
      }

      $filesize = filesize( $filename );
      $filetext = fread( $file, $filesize );

      fclose( $file );

      echo ( "File size : $filesize bytes" );
      echo ( "$filetext" );
      echo("file name: $filename");
   ?>
</body>
</html>

它将产生以下结果 −

writing file

我们已介绍了有关 PHP File System Function 章节中文件输入和输出的所有函数。

PHP - Maths Functions

为启用数学运算,PHP 具有数学(算术)运算符和许多数学函数。在本章中,将通过示例说明以下数学函数。

PHP abs() Function

abs() 函数是 PHP 解释器的内置函数。此函数接受任意数字作为参数并返回一个正值,而不考虑其符号。任何数字的绝对值始终为正。

abs( mixed $num)

PHP abs() 函数返回 num 的绝对值。如果 num 的数据类型是浮点数,它的返回类型也将是浮点数。对于整数参数,返回类型为整数。

Example

请查看以下示例:

<?php
   $num=-9.99;
   echo "negative float number: " . $num . "\n";
   echo "absolute value : " . abs($num) . "\n";

   $num=25.55;
   echo "positive float number: " . $num . "\n";
   echo "absolute value : " . abs($num). "\n";

   $num=-45;
   echo "negative integer number: " . $num . "\n";
   echo "absolute value : " . abs($num) . "\n";

   $num=25;
   echo "positive integer number: " . $num . "\n";
   echo "absolute value : " . abs($num);
?>

它将生成以下 output

negative float number: -9.99
absolute value : 9.99
positive float number: 25.55
absolute value : 25.55
negative integer number: -45
absolute value : 45
positive integer number: 25
absolute value : 25

PHP ceil() Function

ceil() 函数是 PHP 解释器的内置函数。此函数接受任意浮点数作为参数并将其四舍五入到下一个最高整数。此函数始终返回一个浮点数,因为浮点数的范围大于整数范围。

ceil ( float $num ) : float

PHP ceil() 函数返回大于或等于给定参数的最小整数值。

Example 1

以下代码将 5.78 四舍五入到其下一个最高整数 6

<?php
   $arg=5.78;
   $val=ceil($arg);
   echo "ceil(" . $arg .  ") = " . $val;
?>

它将生成以下 output

ceil(5.78) = 6

Example 2

以下示例演示了如何查找 15.05 的下一个最高整数。

<?php
   $arg=15.05;
   $val=ceil($arg);
   echo "ceil(" . $arg .  ") = " . $val;
?>

它将生成以下 output

ceil(15.05) = 16

Example 3

对于负数,它会四舍五入到 0。

<?php
   $arg=-3.95;
   $val=ceil($arg);
   echo "ceil(" . $arg .  ") = " . $val;
?>

它将生成以下 output

ceil(-3.95) = -3

PHP exp() Function

exp() 函数计算欧拉数 e 的指数。PHP 有一个预定义常量 M_E,表示欧拉数,等于 2.7182818284590452354。因此,exp(x) 返回 2.7182818284590452354x

此函数始终返回一个浮点数。

exp ( float $arg ) : float

PHP exp() 函数返回提升到给定 arg. 的欧拉数 e。请注意, e 是自然算法的底数。exp() 函数是自然对数的逆函数。

Example 1

PHP 中的一个预定义常量是 M_LN2 ,它表示 loge2,等于 0.69314718055994530942。因此,此值的 exp() 将返回 2。

<?php
   echo "exp(" . M_LN2 . ") = " . exp(M_LN2);
?>

它将生成以下 output

exp(0.69314718055995) = 2

Example 2

M_LN10 是表示 loge10 的另一个预定义常量。此程序计算 exp(M_LN10) 并返回 10。

<?php
   echo "exp(" . M_LN10 . ") = " . exp(M_LN10);
?>

它将生成以下 output

exp(2.302585092994) = 10

PHP floor() Function

floor() 函数是 PHP 解释器中的另一个内置函数。此函数接受任意浮点数字作为参数,并根据其向下取整到最接近的整数。此函数始终返回浮点数,因为浮点值的范围大于整数值的范围。

floor ( float $num ) : float

PHP floor() 函数返回不小于给定参数的最大整数。

Example 1

以下示例展示了如何将 15.05 舍入至下一个最大整数,即 15

<?php
   $arg=15.05;
   $val=floor($arg);
   echo "floor(" . $arg .  ") = " . $val;
?>

它将生成以下 output

floor(15.05) = 15

Example 2

以下示例展示了如何找出 5.78 的下一个最小整数。

<?php
   $arg=5.78;
   $val=floor($arg);
   echo "floor(" . $arg .  ") = " . $val;
?>

它将生成以下 output

floor(5.78) = 5

Example 3

负数从 0 中舍去。

<?php
   $arg=-3.95;
   $val=floor($arg);
   echo "floor(" . $arg .  ") = " . $val;
?>

它将生成以下 output

floor(-3.95) = -4

PHP intdiv() Function

intdiv() 函数返回两个整型参数的整数商。如果 x/y 除法结果为“i”,余数为“r”,则为 −

x = y*i+r

在这种情况下,intdiv(x,y) 返回“i”

intdiv ( int $x , int $y ) : int

“x”参数是除法表达式的分子部分,而“y”参数是除法表达式的分母部分。

PHP intdiv() 函数返回“x”除以“y”的整数商。如果两个参数都是正数或都是负数,则返回值为正数。

Example 1

以下示例表明,如果分子小于分母,则 intdiv() 函数返回 0。

<?php
   $x=10;
   $y=3;
   $r=intdiv($x, $y);
   echo "intdiv(" . $x . "," . $y . ") = " . $r . "\n";
   $r=intdiv($y, $x);
   echo "intdiv(" . $y . "," . $x . ") = " . $r;
?>

它将生成以下 output

intdiv(10,3) = 3
intdiv(3,10) = 0

Example 2

在以下示例中,intdiv() 函数返回负数,因为分子或分母是负数。

<?php
   $x=10;
   $y=3;
   $r=intdiv($x, $y);
   echo "intdiv(" . $x . "," . $y . ") = " . $r . "\n";

   $x=10;
   $y=-3;
   $r=intdiv($x, $y);
   echo "intdiv(" . $x . "," . $y . ") = " . $r . "\n";

   $x=-10;
   $y=3;
   $r=intdiv($x, $y);
   echo "intdiv(" . $x . "," . $y . ") = " . $r . "\n";

   $x=-10;
   $y=-3;
   $r=intdiv($x, $y);
   echo "intdiv(" . $x . "," . $y . ") = " . $r ;
?>

它将生成以下 output

intdiv(10,3) = 3
intdiv(10,-3) = -3
intdiv(-10,3) = -3
intdiv(-10,-3) = 3

Example 3

在以下示例中,分母为 0。它导致 DivisionByZeroError 异常。

<?php
   $x=10;
   $y=0;
   $r=intdiv($x, $y);
   echo "intdiv(" . $x . "," . $y . ") = " . $r . "\n";
?>

它将生成以下 output

PHP Fatal error:  Uncaught DivisionByZeroError: Division by zero

Example 4

两个参数中的小数部分都会被忽略。PHP intdiv() 函数仅适用于整数部分。

<?php
   $x=2.90;
   $y=1.90;
   $r=intdiv($x, $y);
   echo "intdiv(" . $x . "," . $y . ") = " . $r . "";
?>

它将生成以下 output

intdiv(2.9,1.9) = 2

PHP log10() Function

log10 () 函数计算某个数字的以 10 为底的对数。以 10 为底的对数也称为 commonstandard algorithm 。log10(x) 函数计算 log10x。它与自然算法之间的关系由以下等式表示 −

log10x=logex/loge10 ; So that
log10100=loge100/loge10 = 2

在 PHP 中, log10log10() 函数表示

log10 ( float $arg ) : float

PHP log10() 函数返回 arg 的以 10 为底的对数。

Example 1

以下代码计算 100 的以 10 为底的对数

<?php
   $arg=100;
   echo "log10(" . $arg. ")=" . log10($arg) . "";
?>

它将生成以下 output

log10(100)=2

Example 2

以下代码计算欧拉数 M_E 的以 10 为底的对数。结果等于预定义的常数 M_LOG10E

<?php
   $arg=M_E;
   echo "log10(" . $arg. ")=" . log10($arg) . "\n";
   echo "predefined constant M_LOG10E=" . M_LOG10E;
?>

它将生成以下 output

log10(2.718281828459)=0.43429448190325
predefined constant M_LOG10E=0.43429448190325

Example 3

以下代码计算 log100 并返回 -∞。

<?php
   $arg=0;
   echo "log10(" . $arg. ")=" . log10($arg) . "";
?>

它将生成以下 output

log10(0)=-INF

Example 4

平方根(-1)的结果也是 NaN。所以它的 log10() 也返回 NaN。

<?php
   $arg=sqrt(-1);
   echo "log10(" . $arg. ")=" . log10($arg) . "";
?>

它将生成以下 output

log10(NAN)=NAN

PHP max() Function

max() 函数返回数组中最大的元素,或者返回两个或两个以上逗号分隔参数中最大的参数。

max ( array $values ) : mixed

或者,

max ( mixed $value1 [, mixed $... ] ) : mixed
  1. 如果只给出了一个参数,则它应该是可能具有相同或不同类型的值的数组。

  2. 如果给出了两个或更多参数,则它们应该是具有相同或不同类型的任何可比较值。

PHP max() 函数返回数组参数或值序列中的最大值。标准比较运算符适用。如果不同类型的值有多个被评估为相等(例如 0 和’PHP'),则将返回函数的第一个参数。

Example 1

下面的代码返回数字数组中的最大值。

<?php
   $arg=array(23, 5.55, 142, 56, 99);
   echo "array=";
   foreach ($arg as $i) echo $i . ",";
   echo "\n";
   echo "max = " . max($arg);
?>

它将生成以下 output

array=23,5.55,142,56,99,
max = 142

Example 2

下面的代码返回字符串数组中的 max()。

<?php
   $arg=array("Java", "Angular", "PHP", "C", "Kotlin");
   echo "array=";
   foreach ($arg as $i) echo $i . ",";
   echo "\n";
   echo "max = " . max($arg);
?>

它将生成以下 output

array=Java,Angular,PHP,C,Kotlin,
max = PHP

Example 3

在下面的示例中,向 max() 函数提供了一系列字符串值。让我们看看它如何表现 −

<?php
   $val1="Java";
   $val2="Angular";
   $val3="PHP";
   $val4="C";
   $val5="Kotlin";
   echo "values=" . $val1 . "," . $val2 . "," . $val3 . "," . 	$val4 . "," . $val5 . "\n";
   echo "max = " . max($val1, $val2, $val3,$val4,$val5);
?>

它将生成以下 output

values=Java,Angular,PHP,C,Kotlin
max = PHP

Example 4

在此示例中,给定的数组是混合数据类型的集合。

<?php
   $arg=array(23, "Java", 142, 1e2, 99);
   echo "array=";
   foreach ($arg as $i) echo $i . ",";
   echo "\n";
   echo "max = " . max($arg);
?>

它将生成以下 output

array=23,Java,142,100,99,
max = 142

PHP min() Function

min() 函数返回数组中最小的元素,或者返回两个或两个以上逗号分隔参数中最小的参数。

min ( array $values ) : mixed

或者,

min ( mixed $value1 [, mixed $... ] ) : mixed
  1. 如果只给出了一个参数,则它应该是可能具有相同或不同类型的值的数组

  2. 如果给出了两个或更多参数,则它们应该是具有相同或不同类型的任何可比较值

PHP min() 函数返回数组参数或值序列中的最小值。标准比较运算符适用。如果不同类型的值有多个被评估为相等(例如 0 和’PHP'),则将返回函数的第一个参数

Example 1

下面的代码返回数字数组中的最小值。

<?php
   $arg=array(23, 5.55, 142, 56, 99);
   echo "array=";
   foreach ($arg as $i) echo $i . ",";
   echo "\n";
   echo "min = " . min($arg);
?>

它将生成以下 output

array=23,5.55,142,56,99,
min = 5.55

Example 2

下面的代码返回字符串数组中的 min()。

<?php
   $arg=array("Java", "Angular", "PHP", "C", "Kotlin");
   echo "array=";
   foreach ($arg as $i) echo $i . ",";
   echo "\n";
   echo "min = " . min($arg);
?>

它将生成以下 output

array=Java,Angular,PHP,C,Kotlin,
min = Angular

Example 3

此示例中,向 min() 函数提供了一系列字符串值。

<?php
   $val1="Java";
   $val2="Angular";
   $val3="PHP";
   $val4="C";
   $val5="Kotlin";
   echo "values=" . $val1 . "," . $val2 . "," . $val3 . "," . 	$val4 . "," . $val5 . "\n";
   echo "min = " . min($val1, $val2, $val3,$val4,$val5);
?>

它将生成以下 output

values=Java,Angular,PHP,C,Kotlin
min = Angular

Example 4

在此示例中,给定的数组是混合数据类型的集合。

<?php
   $arg=array(23, "Java", 142, 1e2, 99);
   echo "array=";
   foreach ($arg as $i) echo $i . ",";
   echo "\n";
   echo "min = " . min($arg);
?>

它将生成以下 output

array=23,Java,142,100,99,
min = 23

PHP pow() Function

pow () 函数用于计算某个数的幂。它返回 xy 计算,也称为将 x 提升到 y。PHP 还提供了“**”作为指数运算符。

因此,pow(x,y) 返回 xy,与 x**y 相同。

pow ( number $base , number $exp ) : number

第一个参数是要提升的底数。第二个参数是需要将底数提升到的幂。

PHP pow() 函数返回以 exp 的幂次升高的基数。如果两个参数都是非负整数,则结果将以整数形式返回,否则以浮点数形式返回。

Example 1

以下示例使用 pow() 函数计算 102:

<?php
   echo "pow(10,2) = " . pow(10,2);
   echo " using ** operator " . 10**2;
?>

它将生成以下 output

pow(10,2) = 100 using ** operator 100

Example 2

将任何数字升至 0 次方得到的结果都是 1。以下示例对此进行了验证:

<?php
   $x=10;
   $y=0;
   echo "pow(" . $x, "," . $y . ")=". pow($x,$y);
?>

它将生成以下 output

pow(10,0)=1

Example 3

以下示例展示了如何使用 pow() 函数计算 100 的平方根:

<?php
   $x=100;
   $y=0.5;
   echo "pow(" . $x, "," . $y . ")=". pow($x,$y) . "\n";
   echo "using sqrt() function : ". sqrt(100);
?>

它将生成以下 output

pow(100,0.5)=10
using sqrt() function : 10

Example 4

本示例展示了如何使用 pow() 函数计算圆的面积。

<?php
   $radius=5;
   echo "radius = " . $radius . " area = " . M_PI*pow(5,2);
?>

它将生成以下 output

radius = 5 area = 78.539816339745

PHP round() Function

round() 函数可用于将任意浮点数四舍五入到所需精度级别。正精度参数使数字在小数点后四舍五入;而负精度导致数字在小数点前四舍五入。精度默认为“0”。

例如,round(10.6) 返回 11,round(10.2) 返回 10。此函数始终返回浮点数。

该函数还有另一个可选参数,称为 mode ,它采用稍后描述的重新定义的常量之一。

round ( float $value , int $precision , int $mode ) : float

Parameters

  1. Value - 要舍入的浮点数。

  2. Precision - 要舍入为几位小数。默认为 0。正精度在小数点后舍入给定的数字。负精度在小数点前舍入给定的数字。

  3. Mode - 下列预定义常量之一。

Sr.No

Constant & Description

1

PHP_ROUND_HALF_UP 当数字达到一半时,舍入为远离 0。因此,1.5 变为 2,-1.5 变为 -2

2

PHP_ROUND_HALF_DOWN 当数字达到一半时,舍入为靠近 0。因此 1.5 变为 1,-1.5 变为 -1

3

PHP_ROUND_HALF_EVEN 将数字舍入到最接近的偶数值

4

PHP_ROUND_HALF_ODD 将数字舍入到最接近的奇数值

PHP round() 函数返回一个浮点数,方法是将该值四舍五入到所需的精度。

Example 1

以下代码将给定数字舍入到正精度值:

<?php
   $arg=1234.567;
   echo "round(" . $arg . ") = " . round($arg) . "\n";
   echo "round(" . $arg . ",1) = " . round($arg,1) . "\n";
   echo "round(" . $arg . ",2) = " . round($arg,2) . "";
?>

它将生成以下 output

round(1234.567) = 1235
round(1234.567,1) = 1234.6
round(1234.567,2) = 1234.57

Example 2

以下代码将数字舍入到负精度值:

<?php
   $arg=1234.567;
   echo "round(" . $arg . ") = " . round($arg) . "\n";
   echo "round(" . $arg . ",-1) = " . round($arg,-1) . "\n";
   echo "round(" . $arg . ",-2) = " . round($arg,-2) . "";
?>

它将生成以下 output

round(1234.567) = 1235
round(1234.567,-1) = 1230
round(1234.567,-2) = 1200

Example 3

以下代码针对舍入使用 UP 和 DOWN 模式常量:

<?php
   echo "round(3.45,HALF_UP) = " . round(3.45,0, PHP_ROUND_HALF_UP) . "\n";
   echo "round(3.75 HALF_UP) = " . round(3.75, 1, PHP_ROUND_HALF_DOWN) . "";
?>

它将生成以下 output

round(3.45,HALF_UP) = 3
round(3.75 HALF_UP) = 3.7

Example 4

以下代码使用 ODD 和 EVEN 模式进行舍入 −

<?php
   echo "round( 3.45,HALF_ODD) = " . round(3.45,0, PHP_ROUND_HALF_ODD) . "\n";
   echo "round(3.78 HALF_EVEN) = " . round(3.78, 0, PHP_ROUND_HALF_EVEN) . "";
?>

它将生成以下 output

round(3.45,HALF_ODD) = 3
round(3.78, HALF_EVEN) = 4

PHP sqrt() Function

sqrt() 函数返回正浮点数的平方根。由于负数的平方根未定义,因此它返回 NAN。这是最常用的函数之一。此函数始终返回浮点数。

sqrt (float $arg) : float

PHP sqrt() 函数返回给定 arg 数字的平方根。对于负数,该函数返回 NAN。

Example 1

以下代码计算 100 的平方根 −

<?php
   $arg = 100;
   echo "Square root of " . $arg . "=" . sqrt($arg) . "";
?>

它将生成以下 output

Square root of 100=10

Example 2

对于 sqrt(2)、1/sqrt(2) 和 sqrt(3),PHP 分别有特殊预定义常量 M_SQRT2、M_SQRT1_2 和 M_SQRT3。

<?php
   echo "sqrt(2) = " . sqrt(2) . "\n";
   echo "M_SQRT2 = " . M_SQRT2. "\n";
   echo "sqrt(3) = " . sqrt(3) . "\n";
   echo "M_SQRT3 = " . M_SQRT3 . "\n";
   echo "1/sqrt(2)) = " . 1/sqrt(2) . "\n";
   echo "M_SQRT1_2 = " . M_SQRT1_2 . "";
?>

它将生成以下 output

sqrt(2) = 1.4142135623731
M_SQRT2 = 1.4142135623731
sqrt(3) = 1.7320508075689
M_SQRT3 = 1.7320508075689
1/sqrt(2)) = 0.70710678118655
M_SQRT1_2 = 0.70710678118655

Example 3

数学常量 M_SQRTPI 和 M_2_SQRTPI 分别表示 sqrt(Π) 和 2/sqrt(Π) 的值。

<?php
   echo "sqrt(pi) = " . sqrt(M_PI) . "\n";
   echo "M_SQRTPI = " . M_SQRTPI. "\n";
   echo "2/sqrt(pi) = " . 2/sqrt(M_PI) . "\n";
   echo "M_2_SQRTPI = " . M_2_SQRTPI . "";
?>

它将生成以下 output

sqrt(pi) = 1.7724538509055
M_SQRTPI = 1.7724538509055
2/sqrt(pi) = 1.1283791670955
M_2_SQRTPI = 1.1283791670955

Example 4

sqrt(-1) 未定义,因此它返回 NAN。

<?php
   echo "sqrt(-1) = " . sqrt(-1) . "";
?>

它将生成以下 output

sqrt(-1) = NAN

Predefined Mathematical Constants

除了上述数学函数外,PHP 还有以下预定义数学常量 −

Constant

Value

Description

M_PI

3.14159265358979323846

Pi

M_E

2.7182818284590452354

Euler Number e

M_LOG2E

1.4426950408889634074

log2 e

M_LOG10E

0.43429448190325182765

log10 e

M_LN2

0.69314718055994530942

loge 2

M_LN10

M_LN10 2.30258509299404568402 loge 10

loge 10

M_PI_2

1.57079632679489661923

pi/2

M_PI_4

0.78539816339744830962

pi/4

M_1_PI

0.31830988618379067154

1/pi

M_2_PI

0.63661977236758134308

2/pi

M_SQRTPI

1.77245385090551602729

sqrt(pi)

M_2_SQRTPI

1.12837916709551257390

2/sqrt(pi)

M_SQRT2

1.41421356237309504880

sqrt(2)

M_SQRT3

1.73205080756887729352

sqrt(3)

M_SQRT1_2

0.70710678118654752440

1/sqrt(2)

M_LNPI

1.14472988584940017414

loge(pi)

M_EULER

0.57721566490153286061

Euler constant

PHP_ROUND_HALF_UP

1

Round halves up

PHP_ROUND_HALF_DOWN

2

Round halves down

PHP_ROUND_HALF_EVEN

3

将一半舍入到偶数

PHP_ROUND_HALF_ODD

4

将一半舍入到奇数

NAN

NAN

Not A Number

INF

INF

Infinity

PHP - Heredoc & Nowdoc

PHP 提供了两种替代方法,可以使用 heredocnewdoc 语法来声明单引号或双引号字符串。

  1. 单引号字符串不会解释转义字符,也不会展开变量。

  2. 另一方面,如果您声明一个双引号字符串,而该字符串本身包含双引号字符,则需要使用 "\" 符号对其进行转义。 heredoc 语法提供了一种便捷的方法。

Heredoc Strings in PHP

PHP 中的 heredoc 字符串非常像双引号字符串,但没有双引号。这意味着它们不需要转义引号和展开变量。

Heredoc Syntax

$str = <<<IDENTIFIER
place a string here
it can span multiple lines
and include single quote ' and double quotes "
IDENTIFIER;

首先,从 "<<<" 运算符开始。在此运算符之后,提供一个标识符,然后换行。字符串本身紧随其后,然后再次使用相同的标识符来结束引号。该字符串可以跨越多行,并包括单引号 (') 或双引号 (")。

结尾标识符可以通过空格或制表符缩进,在这种情况下,缩进将从文档字符串中的所有行中删除。

Example

该标识符只能包含字母数字字符和下划线,并且以下划线或非数字字符开头。结尾标识符不应包含分号 (;) 以外的任何其他字符。此外,结尾标识符前后必须只能是换行符。

请看以下示例:

<?php
   $str1 = <<<STRING
   Hello World
      PHP Tutorial
         by TutorialsPoint
   STRING;

   echo $str1;
?>

它将生成以下 output

Hello World
    PHP Tutorial
        by TutorialsPoint

Example

结尾标识符在编辑器的第一列之后可能包含缩进,也可能不包含缩进。如果有缩进,它将被删除。但是,结尾标识符的缩进不能比正文中的任何行更深。否则,将引发 ParseError。请看以下示例及其输出 −

<?php
   $str1 = <<<STRING
   Hello World
      PHP Tutorial
   by TutorialsPoint
         STRING;

   echo $str1;
?>

它将生成以下 output

PHP Parse error:  Invalid body indentation level
(expecting an indentation level of at least 16) in hello.php on line 3

Example

heredoc 中的引号不需要转义,但仍可以使用 PHP 转义序列。Heredoc 语法还会展开变量。

<?php
   $lang="PHP";
   echo <<<EOS
   Heredoc strings in $lang expand vriables.
   The escape sequences are also interpreted.
   Here, the hexdecimal ASCII characters produce \x50\x48\x50
   EOS;
?>

它将生成以下 output

Heredoc strings in PHP expand vriables.
The escape sequences are also interpreted.
Here, the hexdecimal ASCII characters produce PHP

Nowdoc Strings in PHP

PHP 中的 Nowdoc 字符串与 Hereodoc 字符串类似,不同之处在于它不扩展变量,也不解释转义序列。

<?php
   $lang="PHP";

   $str = <<<'IDENTIFIER'
   This is an example of Nowdoc string.
   it can span multiple lines
   and include single quote ' and double quotes "
   IT doesn't expand the value of $lang variable
   IDENTIFIER;

   echo $str;
?>

它将生成以下 output

This is an example of Nowdoc string.
it can span multiple lines
and include single quote ' and double quotes "
IT doesn't expand the value of $lang variable

Nowdoc 的语法类似于 Hereodoc 的语法,不同之处在于,遵循 "<<<" 运算符的标识符需要用单引号引起来。Nowdoc 的标识符也遵循 Hereodoc 标识符的规则。

Heredoc 字符串类似于不带转义的双引号字符串。Nowdoc 字符串类似于不带转义的单引号字符串。

PHP - Compound Types

PHP 中的数据类型可以是“标量类型”或“复合类型”。整数、浮点数、布尔值和字符串类型为标量类型,而数组和对象类型归类为复合类型。复合类型中的单个变量可以存储多种类型的值。

在 PHP 中,对象和数组是两种复合数据类型。

  1. 数组是有序集合,其中包含其他数据类型的元素,这些元素不一定相同。

  2. 对象是内置类或用户定义类的实例,由属性和方法组成。

Arrays in PHP

数组是一种数据结构,其中一个变量存储了一个或多个数据值。PHP 中的数组是有序映射,它将值与键关联。

  1. PHP 中有两种声明数组的方法。一种是使用内置的 array() 函数,另一种是将数组元素置于方括号内。

  2. 仅包含值集合的数组称为 indexed array 。每个值由从 0 开始的位置索引标识。

  3. 如果数组是键值对集合,则称为 associative array 。该对的关键组成部分可以是数字或字符串,而值部分可以是任何类型。

The array() Function in PHP

内置 array() 函数使用提供给它的参数并返回数组类型对象。一个或多个以逗号分隔的参数是数组中的元素。

array(mixed ...$values): array

括号中的每个值可以是单个值(可能是数字、字符串、任何对象,甚至另一个数组),或键值对。键与其值之间的关联由“⇒”符号表示。

Example

请查看以下示例:

$arr1 = array(10, "asd", 1.55, true);

$arr2 = array("one"=>1, "two"=>2, "three"=>3);

$arr3 = array(
   array(10, 20, 30),
   array("Ten", "Twenty", "Thirty"),
   array("physics"=>70, "chemistry"=>80, "maths"=>90)
);

Using Square Brackets [ ]

除了 array() 函数之外,还可以将以逗号分隔的数组元素置于方括号内以声明数组对象。在这种情况下,元素也可以是单个值、字符串或另一个数组。

$arr1 = [10, "asd", 1.55, true];

$arr2 = ["one"=>1, "two"=>2, "three"=>3];

$arr3 = [
   [10, 20, 30],
   ["Ten", "Twenty", "Thirty"],
   ["physics"=>70, "chemistry"=>80, "maths"=>90]
];

Accessing Array Elements

要从给定数组访问任何元素,可以使用 array[key] 语法。对于索引数组,将索引置于方括号内,因为索引本身就是键。

<?php
   $arr1 = [10, 20, 30];
   $arr2 = array("one"=>1, "two"=>2, "three"=>3);

   var_dump($arr1[1]);
   var_dump($arr2["two"]);
?>

它将生成以下 output

int(20)
int(2)

Array Traversal in PHP

还可以使用 foreach 循环来迭代索引数组。

<?php
   $arr1 = [10, 20, 30, 40, 50];
   foreach ($arr1 as $val){
      echo "$val\n";
   }
?>

它将生成以下 output

10
20
30
40
50

请注意,PHP 在内部将索引数组视为关联数组,其中索引被视为键。此事实可以通过数组的 var_dump() 输出得到验证。

我们可以使用 foreach 语法将索引数组的每个元素解包为键和值变量 −

<?php
   $arr1 = [10, 20, 30, 40, 50];
   foreach ($arr1 as $key => $val){
      echo "arr1[$key] = $val" . "\n";
   }
?>

它将生成以下 output

arr1[0] = 10
arr1[1] = 20
arr1[2] = 30
arr1[3] = 40
arr1[4] = 50

foreach 循环还用于遍历关联数组,尽管任何其他类型的循环也可以通过某种操作使用。

让我们看一下 foreach 循环实现,每个 k-v 对在两个变量中解包。

<?php
   $capitals = array(
      "Maharashtra"=>"Mumbai",
      "Telangana"=>"Hyderabad",
      "UP"=>"Lucknow",
      "Tamilnadu"=>"Chennai"
   );

   foreach ($capitals as $k=>$v) {
      echo "Capital of $k is $v" . "\n";
   }
?>

它将生成以下 output

Capital of Maharashtra is Mumbai
Capital of Telangana is Hyderabad
Capital of UP is Lucknow
Capital of Tamilnadu is Chennai

Objects in PHP

在 PHP 中,对象是一种复合数据类型。它是内置或用户定义类的实例。下面是一个简单的 PHP 类 −

class SayHello {
   function hello() {
      echo "Hello World";
   }
}

要声明类的对象,我们需要使用 new 操作符。

$obj=new SayHello;

我们现在可以调用它的方法 −

<?php
   class SayHello {
      function hello() {
         echo "Hello World". PHP_EOL;
      }
   }

   $obj=new SayHello;
   var_dump(gettype($obj));
   $obj->hello();
?>

它将生成以下 output

string(6) "object"
Hello World

stdClass

PHP 提供 stdClass 作为一个通用的空类,它可用于动态添加属性和转换。stdClass 的对象开始时为 null。我们可以动态地向其中添加属性。

<?php
   $obj=new stdClass;
   $obj->name="Deepak";
   $obj->age=21;
   $obj->marks=75;

   print_r($obj);
?>

它将生成以下 output

stdClass Object (
   [name] => Deepak
   [age] => 21
   [marks] => 75
)

Array to Object Conversion in PHP

PHP 中的数组可以按如下方式强制转换成对象 −

<?php
   $arr=array("name"=>"Deepak", "age"=>21, "marks"=>75);
   $obj=(object)$arr;

   print_r($obj);
?>

它将生成以下 output

stdClass Object (
   [name] => Deepak
   [age] => 21
   [marks] => 75
)

Object to Array Conversion in PHP

相反,对象可以强制转换成数组。请看以下示例 −

<?php
   $obj=new stdClass;
   $obj->name="Deepak";
   $obj->age=21;
   $obj->marks=75;

   $arr=(array)$obj;
   print_r($arr);
?>

它将生成以下 output

Array
(
   [name] => Deepak
   [age] => 21
   [marks] => 75
)

Scalar Type to Object Type Conversion in PHP

任何标量类型的变量也可以通过类型转换转换成对象。标量变量的值将成为对象标量属性的值。

<?php
   $name="Deepak";
   $age=21;
   $percent=75.50;

   $obj1=(object)$name;
   print_r($obj1);

   $obj2=(object)$age;
   print_r($obj2);

   $obj3=(object)$percent;
   print_r($obj3);
?>

它将生成以下 output

stdClass Object
(
   [scalar] => Deepak
)
stdClass Object
(
   [scalar] => 21
)
stdClass Object
(
   [scalar] => 75.5
)

PHP - File Include

PHP 中的 include statement 类似于 Java 或 Python 中的 import statement 、C/C++ 中的 #include directive 。但是,在 PHP 中包含语句工作方式上略有不同。

Java/Python 中的导入或 C/C++ 中的 #include 只将一个或多个语言结构(例如函数或类)从一个文件中加载到当前文件中。相比之下,PHP 中的 include 语句将另一个文件中的一切引入现有 PHP 脚本。它可能是 PHP 代码、文本文件、HTML 标记等。

The "include" Statement in PHP

以下是 PHP 中 include 语句如何工作的一个典型示例:

myfile.php

<?php
   # some PHP code
?>

test.php

<?php
   include 'myfile.php';
   # PHP script in test.php
?>

PHP 中的 include 关键字非常方便,尤其当你需要在项目中跨多个 PHP 脚本使用相同的 PHP 代码(函数或类)或 HTML 标记时。一个典型的例子是创建应出现在 Web 应用程序所有页面中的菜单。

假设你想为网站创建一个通用菜单。然后,创建一个名为“menu.php”的文件,其内容如下。

<a href="http://www.tutorialspoint.com/index.htm">Home</a> -
<a href="http://www.tutorialspoint.com/ebxml">ebXML</a> -
<a href="http://www.tutorialspoint.com/ajax">AJAX</a> -
<a href="http://www.tutorialspoint.com/perl">PERL</a> <br />

现在创建任意多页面并包含此文件以创建头部。例如,现在你的“test.php”文件可以具有以下内容:

<html>
   <body>
      <?php include("menu.php"); ?>
      <p>This is an example to show how to include PHP file!</p>
   </body>
</html>

这两个文件假定存在于 XAMPP 服务器的文档根目录中。访问 http://localhost/test.php URL。它将生成以下内容 output

php file include

当 PHP 解析器遇到 include 关键字时,它会尝试在当前脚本正在执行的同一目录中找到指定文件。如果未找到,则搜索“php.ini”的“include_path”设置中的目录。

当包含一个文件时,它包含的代码会继承包含所在行可变的范围。呼叫文件中该行可用的任何变量都将在从该点开始的呼叫文件中可用。但是,在包含文件中定义的所有函数和类都具有全局范围。

Example

在以下示例中,我们有一个“myname.php”脚本,其中声明了两个变量。它包含在另一个脚本 test.php 中。变量以全局范围加载。

myname.php

<?php
   $color = 'green';
   $fruit = 'apple';
?>

test.php

<?php
   include "myname.php";
   echo "<h2>$fname $lname</h2>";
?>

当浏览器访问 http://localhost/test.php 时,它显示:

Ravi Teja

然而,如果文件包含在函数内部,则变量仅成为函数局部范围的一部分。

myname.php

<?php
   $color = 'green';
   $fruit = 'apple';
?>

test.php

<?php
   function showname() {
      include "myname.php";
   }
   echo "<h2>$fname $lname</h2>";
?>

现在当浏览器访问 http://localhost/test.php 时,它显示未定义的变量警告:

Warning: Undefined variable $fname in C:\xampp\htdocs\test.php on line 7
Warning: Undefined variable $lname in C:\xampp\htdocs\test.php on line 7

include_once statement

include 一样,PHP 也有“ include_once ”关键字。唯一的区别在于,如果已包含来自文件中的代码,则不会再次包含,且 “include_once” 返回 true。正如名称所建议的,文件将只包含一次。

“include_once” 可能在以下情况下使用:同一文件可能在脚本的特定执行过程中包含并评估多次,因此它可以帮助避免重新定义函数、重新赋值变量值等问题。

PHP – Include vs Require

PHP 中的 require 关键字与 include 关键字非常相似。两者的区别在于,失败后 require 会产生致命的 E_COMPILE_ERROR 级别的错误。

换句话说, require 会停止脚本,而 include 只会发出警告(E_WARNING),允许脚本继续运行。

require_once keyword

“require_once”关键字与 require 类似,但也有细微差别。如果您使用“require_once”,那么 PHP 将检查文件是否已包含,如果是,则不会再包含相同的文件。

PHP - Date & Time

PHP 的内置函数库具有广泛的函数,可帮助以编程方式处理和操作日期和时间信息。可以使用日期/时间信息的字符串形式或者从当前系统的时间创建 PHP 中的 Date 和 Time 对象。

PHP 提供定义了许多方法的 DateTime 类。在本章中,我们将会详细了解 PHP 中提供的各种与日期和时间相关的。

PHP 中的日期/时间功能实现了 ISO 8601 日历,它实现了在格里高利历之前通用的现行的闰年规则。日期和时间信息内部存储为 64 位数字。

Getting the Time Stamp with time()

PHP 的 time() 函数提供了有关当前日期和时间的所需的所有信息。它不需要参数,但返回一个整数。

time(): int

time() 返回的整数表示自 1970 年 1 月 1 日格林尼治标准时间午夜以来的经过的秒数。这个时刻称为 UNIX 紀元,并且从那时起经过的秒数称为时间戳。

<?php
   print time();
?>

它将生成以下 output

1699421347

我们可以将时间戳转换为人类容易理解的形式。

Converting a Time Stamp with getdate()

该函数 getdate() 可以选择接受一个时间戳,并返回一个包含有关日期信息的关联数组。如果您省略时间戳,它会使用 time() 返回的当前时间戳。

下表列出了 getdate() 返回的数组中包含的元素。

Sr.No

Key & Description

Example

1

seconds 秒(0-59)

20

2

minutes 分(0 - 59)

29

3

hours 时(0 - 23)

22

4

mday 日(1 - 31)

11

5

wday 星期(0 - 6)

4

6

mon 月(1 - 12)

7

7

year Year (4 digits)

1997

8

yday 一年中的天(0 - 365)

19

9

weekday Day of the week

Thursday

10

month Month of the year

January

11

0 Timestamp

948370048

现在您可以完全控制日期和时间。您可以按照想要的任何格式格式化此日期和时间。

Example

看看下面的 example

<?php
   $date_array = getdate();

   foreach ( $date_array as $key => $val ){
      print "$key = $val\n";
   }
   $formated_date  = "Today's date: ";
   $formated_date .= $date_array['mday'] . "-";
   $formated_date .= $date_array['mon'] . "-";
   $formated_date .= $date_array['year'];

   print $formated_date;
?>

它将生成以下 output

seconds = 0
minutes = 38
hours = 6
mday = 8
wday = 3
mon = 11
year = 2023
yday = 311
weekday = Wednesday
month = November
0 = 1699421880
Today's date: 8-11-2023

Converting a Time Stamp with date()

date() 函数返回一个表示日期的格式化字符串。通过要传递给它的字符串参数,可以对 date() 返回的格式进行大量的控制。

date(string $format, ?int $timestamp = null): string

date() 可选择接受时间戳,如果省略则使用当前日期和时间。包含在传递给 date() 的格式化字符串中的任何其他数据都将包含在返回值中。

下表列出了格式化字符串可以包含的代码:

Sr.No

Format & Description

Example

1

a 'am' or 'pm' lowercase

pm

2

A 'AM' or 'PM' uppercase

PM

3

d 月份中的天,带前导零的数字

20

4

D 星期中的天(三个字母)

Thu

5

F Month name

January

6

h 小时(12 小时制,前导零)

12

7

H 小时(24 小时制,前导零)

22

8

g 小时(12 小时制,无前导零)

12

9

G 小时(24 小时制,无前导零)

22

10

i 分钟(0-59)

23

11

j 当月的第幾天(無前導零)

20

12

l (Lower 'L') 星期中的天

Thursday

13

L 閏年(‘1’ 表示是,‘0’ 表示否)

1

14

m 年份中的月份(数字,前导零)

1

15

M 年份中的月份(三个字母)

Jan

16

r 以 RFC 2822 格式化日期

Thu, 21 Dec 2000 16:01:07 +0200

17

n 年份中的月份(数字,无前导零)

2

18

s Seconds of hour

20

19

U Time stamp

948372444

20

y Year (two digits)

06

21

Y Year (four digits)

2006

22

z 一年中的第幾天(0-365)

206

23

Z 格林威治时间的秒偏移量

+5

Example

看看下面的 example

<?php
   print date("m/d/y G.i:s \n", time()) . PHP_EOL;
   print "Today is ";
   print date("j of F Y, \a\\t g.i a", time());
?>

它将生成以下 output

11/08/23 11.23:08

Today is 8 2023f November 2023, at 11.23 am

希望您对如何根据您的要求格式化日期和时间的了解很好。供您参考,所有日期和时间函数的完整列表中给出了 PHP Date & Time Functions

PHP - Scalar Type Declarations

提供类型提示的功能自 5.0 版本起已内置于 PHP 中。 Type hinting 指在函数定义中提供参数数据类型的方法。在 PHP 7 之前,在函数中只能对数组、可调用和类使用类型提示。从 PHP 7 起,您还可以对标量数据类型(如 int、string、bool 等)的参数插入类型提示。

PHP 是一种动态(且弱)类型语言。因此,在定义函数时不需要声明参数类型,这是静态类型语言(如 C 或 Java)所必需的。

PHP 中函数的典型定义如下 −

function addition($x, $y) {
   echo "First number: $x Second number: $y Addition: " . $x+$y;
}

在此,我们假设参数 $x 和 $y 是数字的。但是,即使传递给函数的值不是数字,PHP 解析器仍会尽最大程度地尝试将变量强制转换为兼容的类型。

如果传递的值之一是数字的字符串表示,而第二个是数字变量,PHP 会将字符串变量强制转换为数字以执行加法操作。

Example

请查看以下示例:

<?php
   function addition($x, $y) {
      echo "First number: " . $x;
      echo "\nSecond number: " . $y;
      echo "\nAddition: " . $x+$y;
   }

   $x="10";
   $y=20;
   addition($x, $y);
?>

它将生成以下 output

First number: 10
Second number: 20
Addition: 30

但是,如果上述示例中的 $x 是不包含有效数字表示的字符串,则会遇到错误。

<?php
   function addition($x, $y) {
      echo "First number: " . $x;
      echo "\nSecond number: " . $y;
      echo "\nAddition: " . $x+$y;
   }

   $x="Hello";
   $y=20;
   addition($x, $y);
?>

运行此代码并查看它如何显示 error

Scalar Type Declarations in PHP 7

PHP 7 版本引入的一项新功能允许定义一个函数,其参数的数据类型可以在括号中指定。

PHP 7 引入了以下标量类型声明 −

  1. Int

  2. Float

  3. Bool

  4. String

  5. Interfaces

  6. Array

  7. Callable

旧版本的 PHP 只允许使用数组、可调用和类类型作为类型提示。此外,在旧版本的 PHP(PHP 5)中,致命错误为可恢复错误,而新版本(PHP 7)返回可抛出错误。

标量类型声明以两种模式实现 −

  1. Coercive Mode − 强制是默认模式,无需指定。

  2. Strict Mode − 必须显式提示严格模式。

Coercive Mode

前面示例中定义的 addition() 函数现在可以重新编写,方法是合并类型声明,如下所示:

function addition(int $x, int $y) {
   echo "First number: $x Second number: $y Addition: " . $x+$y;
}

注意,如果字符串包含一个整数,解析器仍会将不兼容的类型(即字符串)强制转换为 int,就像以前一样。

Example

请查看以下示例:

<?php
   function addition(int $x, int $y) {
      echo "First number: " . $x;
      echo "\nSecond number: " . $y;
      echo "\nAddition: " . $x+$y;
   }

   $x="10";
   $y=20;
   echo addition($x, $y);
?>

它将生成以下 output

First number: 10
Second number: 20
Addition: 30

很明显,这是因为 PHP 是一种弱类型语言,因为 PHP 尝试将字符串类型的变量强制转换为整数。PHP 7 引入了解决此问题的严格模式功能。

Strict Mode

为了应对 PHP 的弱类型检查,已引入严格模式。此模式启用一个 declare statement

declare (strict_types=1);

您应将此声明放在 PHP 脚本的开头(通常就在 PHP 标签的下方)。这意味着标量的类型严格程度是按文件配置的。

在弱模式中,strict_types 标记为 0。将其设为 1 会强制 PHP 解析器检查传递的参数和值的兼容性。在以上代码中添加此声明并检查结果。它将显示以下错误信息:

Fatal error: Uncaught TypeError: addition():
Argument #1 ($x) must be of type int, string given,
called in add.php on line 12 and defined in add.php:4

Stack trace:
#0 add.php(12): addition('10', 20)
#1 {main}
   thrown in add.php on line 4

Example

以下是函数定义中标量类型声明的另一个示例。启用严格模式后,如果将不兼容的类型作为参数传递,则会引发致命错误。

<?php

   // Strict mode
   // declare(strict_types = 1);
   function sum(int ...$ints) {
      return array_sum($ints);
   }

   print(sum(2, '3', 4.1));
?>

取消对该代码开头的 declare 声明的注释并运行它。现在,它将生成一个 error

Fatal error: Uncaught TypeError:
sum(): Argument #2 must be of type int, string given,
called in add.php on line 9 and defined in add.php:4
Stack trace:
#0 add.php(9): sum(2, '3', 4.1)
#1 {main}
   thrown in add.php on line 4

类型提示功能主要由 IDE 用于提示用户有关函数声明中使用的参数的预期类型的信息。以下屏幕截图显示了键入时 VS Code 编辑器弹出函数原型。

php scalar type declarations

PHP - Return Type Declarations

PHP 版本 7 将标量类型声明功能扩展到了函数的返回值。根据此新规定,返回类型声明指定函数应返回的值的类型。我们可以为返回类型声明以下类型:

  1. int

  2. float

  3. bool

  4. string

  5. interfaces

  6. array

  7. callable

为了实现返回类型声明,函数被定义为:

function myfunction(type $par1, type $param2): type {
   # function body
   return $val;
}

PHP 解析器默认是强制类型。您需要声明 “strict_types=1” 来强制更严格地验证要返回的变量的类型与定义中使用的类型。

Example

在以下示例中,division() 函数被定义为返回类型为 int。

<?php
   function division(int $x, int $y): int {
      $z = $x/$y;
      return $z;
   }

   $x=20.5;
   $y=10;

   echo "First number: " . $x;
   echo "\nSecond number: " . $y;
   echo "\nDivision: " . division($x, $y);
?>

因为类型检查没有被设为 strict_types=1,所以即使其中一个参数是非整数,也会进行除法。

First number: 20.5
Second number: 10
Division: 2

然而,一旦您在脚本开头添加了 strict_types 声明,程序就会引发致命错误消息。

Fatal error: Uncaught TypeError: division(): Argument #1 ($x) must be of type int, float given, called in div.php on line 12 and defined in div.php:3
Stack trace:
#0 div.php(12): division(20.5, 10)
#1 {main}
   thrown in div.php on line 3

VS Code 会在运行代码之前警告错误,方法是在错误位置显示错误行:

php return type declarations

Example

要使 division() 函数返回 float 而不是 int,将分子转换为 float,看看 PHP 如何引发致命错误:

<?php
   // declare(strict_types=1);
   function division(int $x, int $y): int {
      $z = (float)$x/$y;
      return $z;
   }

   $x=20;
   $y=10;

   echo "First number: " . $x;
   echo "\nSecond number: " . $y;
   echo "\nDivision: " . division($x, $y);
?>

取消对开头 declare 声明的注释,然后在此运行此代码来检查它的输出。它将显示一条错误:

First number: 20
Second number: 10PHP Fatal error:  Uncaught TypeError: division(): Return value must be of type int, float returned in /home/cg/root/14246/main.php:5
Stack trace:
#0 /home/cg/root/14246/main.php(13): division()
#1 {main}
  thrown in /home/cg/root/14246/main.php on line 5

PHP - Operators Types

What are Operators in PHP?

与任何编程语言一样,PHP 也有运算符,它们是符号(有时 keywords ),被预先定义来对一个或多个操作数执行某些通常需要的操作。

例如,使用表达式“4 + 5”等于 9。此处“4”和“5”称为 operands ,而“+”称为 operator

我们在 PHP 中具有以下类型的运算符 −

  1. Arithmetic Operators

  2. Comparison Operators

  3. Logical Operators

  4. Assignment Operators

  5. String Operators

  6. Array Operators

  7. Conditional (or Ternary Operators)

本章将概述如何在 PHP 中使用这些运算符。在后续章节中,我们将仔细了解每个运算符及其工作原理。

Arithmetic Operators in PHP

我们使用算术运算符对给定的操作数执行加法、减法、乘法、除法等数学运算。算术运算符(不包括增量和减量运算符)始终对两个操作数起作用,但是这些操作数的类型应该相同。

下表高亮显示了 PHP 支持的算术运算符。假设变量“$a”保存了 42,而变量“$b”保存了 20 −

Operator

Description

Example

+

Adds two operands

$a + $b = 62

-

从第一个操作数中减去第二个操作数

$a - $b = 22

*

Multiply both operands

$a * $b = 840

/

Divide numerator by de-numerator

$a / $b = 2.1

%

模运算符,整数除法后的余数

$a % $b = 2

++

自增运算符,将整数加一

$a ++ = 43

 — 

自减运算符,将整数减一

$a — = 42

Comparison Operators in PHP

您将使用比较运算符来比较两个操作数并找出它们之间的关系。根据比较结果,它们返回一个布尔值(真或假)。

下表突出显示了 PHP 支持的比较运算符。假定变量 $a 存储 10,变量 $b 存储 20,则−

Operator

Description

Example

==

检查两个操作数的值是否相等,如果相等,则条件变为真。

($a == $b) 不是真

!=

检查两个操作数的值是否相等,如果不相等,则条件变为真。

($a != $b) 是真

>

检查左操作数的值是否大于右操作数的值,如果大于,则条件变为真。

($a > $b) 是假

<

检查左操作数的值是否小于右操作数的值,如果小于,则条件变为真。

($a < $b) 是真

>=

检查左操作数的值是否大于或等于右操作数的值,如果大于或等于,则条件变为真。

($a >= $b) 为 false

检查左操作数的值是否小于或等于右操作数的值,如果小于或等于,则条件变为真。

($a ⇐ $b) 为 true

Logical Operators in PHP

您可以在 PHP 中使用逻辑运算符对多个表达式一起执行逻辑运算。逻辑运算符始终返回布尔值,无论是真还是假。

逻辑运算符通常与条件语句和循环一起使用,以根据布尔条件返回决策。在处理复杂表达式时,您还可以将它们组合起来,以操作布尔值。

下表重点介绍了 PHP 支持的逻辑运算符。

假设变量 $a 保存 10,变量 $b 保存 20,则 -

Operator

Description

Example

and

名为逻辑 AND 运算符。如果两个操作数都为真,则条件变为真。

(A and B) 为真

or

称为逻辑或运算符。如果两个操作数中的任何一个非零,条件变为真。

(A 或 B) 为真

&&

称为逻辑 AND 运算符。如果两个操作数都是非零,则条件变为真。

(A && B) 为真

称为逻辑或运算符。如果两个操作数中的任何一个非零,条件变为真。

(A

B) is true

!

称为逻辑 NOT 运算符。用于反转操作数的逻辑状态。如果条件为 true,则逻辑 NOT 运算符会将其变为 false。

Assignment Operators in PHP

您可以在 PHP 中使用赋值运算符为给定变量分配或更新新值。赋值运算符的右侧保存值,而赋值运算符的左侧是将值分配到的变量。

双方的数据类型应该相同,否则您将收到一个错误。赋值运算符的结合性是从右向左。PHP 支持两种类型的赋值运算符 −

  1. Simple Assignment Operator − 它是使用最广泛的运算符。它用于为变量或常量赋值。

  2. Compound Assignment Operators − 将赋值运算符 (=) 与其他运算符(例如 +、*、/ 等)组合。

下表高亮显示了 PHP 支持的赋值运算符 −

Operator

Description

Example

=

简单的赋值运算符,将右侧操作数的值赋给左侧操作数

C = A + B 将 A + B 的值赋给 C

+=

加法和赋值运算符,它将右侧操作数加到左侧操作数并将其结果赋给左侧操作数

C += A 等效于 C = C + A

-=

减法和赋值运算符,它从左侧操作数中减去右侧操作数并将结果赋给左侧操作数

C -= A 等效于 C = C - A

*=

乘法和赋值运算符,它用右侧操作数乘以左侧操作数并将结果赋给左侧操作数

C *= A 等效于 C = C * A

/=

除法和赋值运算符,它将左侧操作数除以右侧操作数并将结果赋给左侧操作数

C /= A 等效于 C = C / A

%=

模数和赋值运算符,它使用两个操作数进行模数运算,并将结果分配给左操作数

C %= A 等效于 C = C % A

String Operators in PHP

PHP 中有两个运算符用于处理字符串数据类型 −

  1. "."(点)运算符是 PHP 的连接运算符。它连接两个字符串操作数(将右手字符串的字符追加到左手字符串),并返回一个新字符串。

  2. PHP 还有一个“.=”运算符,可以称之为连接赋值运算符。它通过追加右手操作数的字符来更新在其左边的字符串。

$third = $first . $second;
$leftstring .= $rightstring;

Array Operators in PHP

PHP 定义了以下一组符号,用作数组数据类型的运算符−

Symbol

Example

Name

Result

+

$a + $b

Union

$a 和 $b 的并集。

==

$a == $b

Equality

如果 $a 和 $b 具有相同的键值对,则为 TRUE。

===

$a === $b

Identity

如果 $a 和 $b 在相同顺序中具有相同的键值对且具有相同的类型,则为 TRUE。

!=

$a != $b

Inequality

如果 $a 不等于 $b,则为 TRUE。

<>

$a <> $b

Inequality

如果 $a 不等于 $b,则为 TRUE。

!==

$a !== $b

Non identity

如果 $a 与 $b 不是同一对象,则为 TRUE。

Conditional Operators in PHP

PHP 中还有一个运算符称为条件运算符。它也被称为三元运算符。它首先为真或假值求值一个表达式,然后根据求值结果执行两个给定语句中的一个。

Operator

Description

Example

? :

Conditional Expression

如果条件为真?然后值为 X:否则值为 Y

Operator Categories in PHP

我们在上面讨论的所有运算符可以归类为以下几类−

  1. 单目前缀运算符,它位于单个操作数之前。

  2. 二元运算符,它取两个操作数并执行各种算术和逻辑运算。

  3. 条件运算符(三元运算符),它取三个操作数并根据第一个表达式的求值结果求值第二个或第三个表达式。

  4. 赋值运算符,它将值分配给变量。

Operator Precedence in PHP

运算符的优先级决定了表达式中运算符执行的顺序。例如,在“2+6/3”中,6/3 的除法先执行,然后“2+2”的加法执行,因为除法运算符“/”的优先级高于加法运算符“+”。

要强制在其他运算符之前调用某个运算符,应使用括号。在此示例中,(2+6)/3 首先执行加法,然后执行除法。

某些运算符可能具有相同优先级。在这种情况下,关联顺序(左或右)决定运算顺序。具有相同优先级但非关联的运算符不能并列使用。

下表按运算符的优先级降序列出了 PHP 运算符 −

Operators

Purpose

clone new

clone and new

**

exponentiation

++ — 

increment/decrement

~(int) (float) (string) (array) (object) (bool)

casting

instanceof

types

!

logical

* /

multiplication/division

%

modulo

+ - .

arithmetic and string

<< >>

bitwise shift

< ⇐ > >=

comparison

= != === !== <> ≤== != === !== <> ≤

comparison

&

bitwise and/references

^

bitwise XOR

bitwise OR

&&

logical and

logical or

??

null coalescing

? :

ternary

= += -= = * = /= .= %= &=

= ^= ≤ >>= ??=

assignment operators

yield from

yield from

yield

yield

print

print

and

logical

xor

logical

or

logical

PHP - Arithmetic Operators Examples

在 PHP 中,算术运算符用于对数字值执行数学运算。下表重点介绍了 PHP 支持的算术运算符。假设变量“$a”的值为 42,而变量“$b”的值为 20 −

Operator

Description

Example

+

Adds two operands

$a + $b = 62

-

从第一个操作数中减去第二个操作数

$a - $b = 22

*

Multiply both the operands

$a * $b = 840

/

将分子除以分母

$a / $b = 2.1

%

模运算符,整数除法后的余数

$a % $b = 2

++

自增运算符,将整数加一

$a ++ = 43

 — 

自减运算符,将整数减一

$a — = 42

Example

以下示例说明了如何在 PHP 中使用这些算术运算符 −

<?php
   $a = 42;
   $b = 20;

   $c = $a + $b;
   echo "Addtion Operation Result: $c \n";

   $c = $a - $b;
   echo "Substraction Operation Result: $c \n";

   $c = $a * $b;
   echo "Multiplication Operation Result: $c \n";

   $c = $a / $b;
   echo "Division Operation Result: $c \n";

   $c = $a % $b;
   echo "Modulus Operation Result: $c \n";

   $c = $a++;
   echo "Increment Operation Result: $c \n";

   $c = $a--;
   echo "Decrement Operation Result: $c";
?>

它将生成以下 output

Addtion Operation Result: 62
Substraction Operation Result: 22
Multiplication Operation Result: 840
Division Operation Result: 2.1
Modulus Operation Result: 2
Increment Operation Result: 42
Decrement Operation Result: 43

PHP - Comparison Operators Examples

在 PHP 中,比较运算符用于比较两个值并确定它们之间的关系。这些运算符基于比较结果返回布尔值,即 True 或 False。

下表突出显示了 PHP 支持的比较运算符。假定变量 $a 存储 10,变量 $b 存储 20,则−

Operator

Description

Example

==

检查两个操作数的值是否相等,如果相等,则条件变为真。

($a == $b) 不是真

!=

检查两个操作数的值是否相等,如果不相等,则条件变为真。

($a != $b) 是真

>

检查左操作数的值是否大于右操作数的值,如果大于,则条件变为真。

($a > $b) 是假

<

检查左操作数的值是否小于右操作数的值,如果小于,则条件变为真。

($a < $b) 是真

>=

检查左操作数的值是否大于或等于右操作数的值,如果大于或等于,则条件变为真。

($a >= $b) 为 false

检查左操作数的值是否小于或等于右操作数的值,如果小于或等于,则条件变为真。

($a ⇐ $b) 为 true

此外,这些运算符还可以与逻辑运算符(&&、||、!)结合使用,以在 PHP 程序的决策制定中形成复杂的条件。

Example

以下示例展示了如何在 PHP 中使用这些比较运算符:

<?php
   $a = 42;
   $b = 20;

   if ($a == $b) {
      echo "TEST1 : a is equal to b \n";
   } else {
      echo "TEST1 : a is not equal to b \n";
   }

   if ($a > $b) {
      echo "TEST2 : a is greater than  b \n";
   } else {
      echo "TEST2 : a is not greater than b \n";
   }

   if ($a < $b) {
      echo "TEST3 : a is less than  b \n";
   } else {
      echo "TEST3 : a is not less than b \n";
   }

   if ($a != $b) {
      echo "TEST4 : a is not equal to b \n";
   } else {
      echo "TEST4 : a is equal to b \n";
   }

   if ($a >= $b) {
      echo "TEST5 : a is either greater than or equal to b \n";
   } else {
      echo "TEST5 : a is neither greater than nor equal to b \n";
   }
   if ($a <= $b) {
      echo "TEST6 : a is either less than or equal to b \n";
   } else {
      echo "TEST6 : a is neither less than nor equal to b";
   }
?>

它将生成以下 output

TEST1 : a is not equal to b
TEST2 : a is greater than b
TEST3 : a is not less than b
TEST4 : a is not equal to b
TEST5 : a is either greater than or equal to b
TEST6 : a is neither less than nor equal to b

PHP - Logical Operators Examples

在 PHP 中,逻辑运算符用于组合条件语句。这些运算符允许你通过将多个条件组合在一起创建更复杂的条件。

逻辑运算符通常用在 if, while 等条件语句中,以及 for 循环中,用以根据特定条件控制程序执行的流程。

下表重点介绍了 PHP 支持的逻辑运算符。

假设变量 $a 保存 10,变量 $b 保存 20,则 -

Operator

Description

Example

and

名为逻辑 AND 运算符。如果两个操作数都为真,则条件变为真。

(A and B) 为真

or

称为逻辑或运算符。如果两个操作数中的任何一个非零,条件变为真。

(A 或 B) 为真

&&

称为逻辑与运算符。如果左右运算数均为真,则与运算符返回真。

(A && B) 为真

称为逻辑或运算符。如果两个操作数中的任何一个非零,条件变为真。

(A

B) is true

!

称为逻辑 NOT 运算符。用于反转操作数的逻辑状态。如果条件为 true,则逻辑 NOT 运算符会将其变为 false。

Example

以下示例演示如何在 PHP 中使用这些逻辑运算符 -

<?php
   $a = 42;
   $b = 0;

   if ($a && $b) {
      echo "TEST1 : Both a and b are true \n";
   } else {
      echo "TEST1 : Either a or b is false \n";
   }

   if ($a and $b) {
      echo "TEST2 : Both a and b are true \n";
   } else {
      echo "TEST2 : Either a or b is false \n";
   }

   if ($a || $b) {
      echo "TEST3 : Either a or b is true \n";
   } else {
      echo "TEST3 : Both a and b are false \n";
   }

   if ($a or $b) {
      echo "TEST4 : Either a or b is true \n";
   } else {
      echo "TEST4 : Both a and b are false \n";
   }

   $a = 10;
   $b = 20;

   if ($a) {
      echo "TEST5 : a is true \n";
   } else {
      echo "TEST5 : a is false \n";
   }

   if ($b) {
      echo "TEST6 : b is true \n";
   } else {
      echo "TEST6 : b is false \n";
   }

   if (!$a) {
      echo "TEST7 : a is true \n";
   } else {
      echo "TEST7 : a is false \n";
   }

   if (!$b) {
      echo "TEST8 : b is true \n";
   } else {
      echo "TEST8 : b is false";
   }
?>

它将生成以下 output

TEST1 : Either a or b is false
TEST2 : Either a or b is false
TEST3 : Either a or b is true
TEST4 : Either a or b is true
TEST5 : a is true
TEST6 : b is true
TEST7 : a is false
TEST8 : b is false

PHP - Assignment Operators Examples

您可以在 PHP 中使用赋值运算符将值赋给变量。赋值运算符是执行算术或其他操作的速记符号,同时将值赋给变量。例如,“=”运算符将右侧的值赋给左侧变量。

此外,还有组合赋值运算符,如 +=、-=、*=、/= 和 %=,这些运算符将算术运算与赋值结合在一起。例如,“$x += 5” 是 “$x = $x + 5” 的速记形式,它将 $x 的值增加 5。赋值运算符提供了一种简洁的方法来根据变量当前的值更新变量。

下表高亮显示了 PHP 支持的赋值运算符 −

Operator

Description

Example

=

简单的赋值运算符。将右侧操作数的值赋值给左侧操作数

C = A + B 将 A + B 的值赋给 C

+=

增加且赋值运算符。 它将右操作数添加到左操作数,并将其结果赋予左操作数

C += A 等效于 C = C + A

-=

减去且赋值运算符。 它从左操作数中减去右操作数,并将其结果赋予左操作数

C -= A 等效于 C = C - A

*=

乘以且赋值运算符。 它将右操作数乘以左操作数,并将其结果赋予左操作数

C *= A 等效于 C = C * A

/=

除以且赋值运算符。 它用右操作数除以左操作数,并将其结果赋予左操作数

C /= A 等效于 C = C / A

%=

取余且赋值运算符。 它用两个操作数取模,并将其结果赋予左操作数

C %= A 等效于 C = C % A

Example

以下示例展示了如何在 PHP 中使用这些赋值运算符:

<?php
   $a = 42;
   $b = 20;

   $c = $a + $b;
   echo "Addition Operation Result: $c \n";

   $c += $a;
   echo "Add AND Assignment Operation Result: $c \n";

   $c -= $a;
   echo "Subtract AND Assignment Operation Result: $c \n";

   $c *= $a;
   echo "Multiply AND Assignment Operation Result: $c \n";

   $c /= $a;
   echo "Division AND Assignment Operation Result: $c \n";

   $c %= $a;
   echo "Modulus AND Assignment Operation Result: $c";
?>

它将生成以下 output

Addition Operation Result: 62
Add AND Assignment Operation Result: 104
Subtract AND Assignment Operation Result: 62
Multiply AND Assignment Operation Result: 2604
Division AND Assignment Operation Result: 62
Modulus AND Assignment Operation Result: 20

PHP – String Operators

PHP 中有两个用于处理字符串数据类型的运算符:连接运算符 (".") 和连接赋值运算符 (".="). 阅读本章以了解这些运算符如何在 PHP 中工作。

Concatenation Operator in PHP

点运算符 (".") 是 PHP 的连接运算符。它将两个字符串操作数(右手字符串的字符追加到左手字符串)连接起来并返回一个新字符串。

$third = $first . $second;

Example

以下示例展示了如何在 PHP 中使用连接运算符:

<?php
   $x="Hello";
   $y=" ";
   $z="PHP";
   $str=$x . $y . $z;
   echo $str;
?>

它将生成以下 output

Hello PHP

Concatenation Assignment Operator in PHP

PHP 还有一个“.=”运算符,可以称之为连接赋值运算符。它通过追加右手操作数的字符来更新在其左边的字符串。

$leftstring .= $rightstring;

Example

以下示例使用连接赋值运算符。两个字符串操作数连接,返回字符串左侧的更新内容:

<?php
   $x="Hello ";
   $y="PHP";
   $x .= $y;
   echo $x;
?>

它将生成以下 output

Hello PHP

PHP – Array Operators

PHP 定义了以下一组符号,用作数组数据类型的运算符−

Symbol

Example

Name

Result

+

$a + $b

Union

$a 和 $b 的并集。

==

$a == $b

Equality

如果 $a 和 $b 具有相同的键值对,则为 TRUE。

===

$a === $b

Identity

如果 $a 和 $b 在相同顺序中具有相同的键值对且具有相同的类型,则为 TRUE。

!=

$a != $b

Inequality

如果 $a 不等于 $b,则为 TRUE。

<>

$a <> $b

Inequality

如果 $a 不等于 $b,则为 TRUE。

!==

$a !== $b

Non identity

如果 $a 与 $b 不是同一对象,则为 TRUE。

并集运算符将右侧数组追加到左侧数组。如果数组中都存在键,则将使用左侧数组中的元素,并将忽略右侧数组中的匹配元素。

Example: Union Opeator in PHP

以下示例展示了如何在 PHP 中使用并集运算符:

<?php
   $arr1=array("phy"=>70, "che"=>80, "math"=>90);
   $arr2=array("Eng"=>70, "Bio"=>80,"CompSci"=>90);
   $arr3=$arr1+$arr2;
   var_dump($arr3);
?>

它将生成以下 output

array(6) {
   ["phy"]=>
   int(70)
   ["che"]=>
   int(80)
   ["math"]=>
   int(90)
   ["Eng"]=>
   int(70)
   ["Bio"]=>
   int(80)
   ["CompSci"]=>
   int(90)
}

Example: When Two Array are Equal

如果两个数组具有相同的键值对,则称这两个数组相等。

在以下示例中,我们有一个索引数组和另一个关联数组,其键对应于第一个元素中的索引。因此,两者相等。

<?php
   $arr1=array(0=>70, 2=>80, 1=>90);
   $arr2=array(70,90,80);
   var_dump ($arr1==$arr2);
   var_dump ($arr2!=$arr1);
?>

它将生成以下 output

bool(true)
bool(false)

Example: When Two Arrays are Identical

当键值对相同且顺序相同,数组才相同。

<?php
   $arr1=array(0=>70, 1=>80, 2=>90);
   $arr2=array(70,90,80);
   var_dump ($arr1===$arr2);
   $arr3=[70,80,90];
   var_dump ($arr3===$arr1);
?>

它将生成以下 output

bool(false)
bool(true)

PHP – Conditional Operators Examples

当需要根据条件设置值时,可以在 PHP 中使用条件运算符。它也被称为 ternary operator 。它首先评估一个表达式的真值或假值,然后根据评估结果执行给定的两个语句中的一个。

三元运算符提供了一种简洁的方法来编写条件表达式。它们由三部分组成:条件、如果条件评估为真的返回值以及如果条件评估为假的返回值。

Operator

Description

Example

? :

Conditional Expression

如果条件为真?然后值为 X:否则值为 Y

Syntax

其语法如下:

condition ? value_if_true : value_if_false

三元运算符特别适用于将 if-else 语句缩短为一行。可以使用三元运算符根据条件为变量分配不同的值,而无需多行代码。它可以提高代码的可读性。

但是,您应明智地使用三元运算符,否则最终会使代码过于复杂,难以理解。

Example

尝试以下示例以了解条件运算符在 PHP 中是如何工作的。复制并粘贴以下 PHP 程序到 test.php 文件中,并将其放在 PHP 服务器的文档根目录中,然后使用任何浏览器浏览它。

<?php
   $a = 10;
   $b = 20;

   /* If condition is true then assign a to result otheriwse b */
   $result = ($a > $b ) ? $a :$b;

   echo "TEST1 : Value of result is $result \n";

   /* If condition is true then assign a to result otheriwse b */
   $result = ($a < $b ) ? $a :$b;

   echo "TEST2 : Value of result is $result";
?>

它将生成以下 output

TEST1 : Value of result is 20
TEST2 : Value of result is 10

PHP - Spread Operator

PHP 将三个点符号(…​)识别为 spread operator 。展开运算符有时也称为 splat operator 。此运算符最初在 PHP 7.4 版本中引入。它可以在许多情况下有效使用,例如解包数组。

Example 1

在下面的示例中,$arr1 中的元素插入到 $arr2 中其自身元素的列表之后。

<?php
   $arr1 = [4,5];
   $arr2 = [1,2,3, ...$arr1];

   print_r($arr2);
?>

它将生成以下 output

Array
(
   [0] => 1
   [1] => 2
   [2] => 3
   [3] => 4
   [4] => 5
)

Example 2

展开运算符可以在表达式中多次使用。例如,在以下代码中,通过扩展两个数组中的元素来创建一个第三个数组。

<?php
   $arr1 = [1,2,3];
   $arr2 = [4,5,6];
   $arr3 = [...$arr1, ...$arr2];

   print_r($arr3);
?>

它将生成以下 output

Array
(
   [0] => 1
   [1] => 2
   [2] => 3
   [3] => 4
   [4] => 5
   [5] => 6
)

Example 3

请注意,可以使用 array_merge() 函数获得相同的结果,如下所示:

<?php
   $arr1 = [1,2,3];
   $arr2 = [4,5,6];
   $arr3 = array_merge($arr1, $arr2);

   print_r($arr3);
?>

它将产生相同的 output ——

Array
(
   [0] => 1
   [1] => 2
   [2] => 3
   [3] => 4
   [4] => 5
   [5] => 6
)

但是,使用(…​)运算符的效率要高得多,因为它避免了函数调用的开销。

Example 4

PHP 8.1.0 还引入了另一项功能,允许在解包参数后使用命名参数。不必为每个参数分别提供值,而是将数组中的值解包到相应的参数中,在数组前使用 …​(三个点)。

<?php
   function  myfunction($x, $y, $z=30) {
      echo "x = $x  y = $y  z = $z";
   }

   myfunction(...[10, 20], z:30);
?>

它将生成以下 output

x = 10  y = 20  z = 30

Example 5

在以下示例中,函数的返回值是一个数组。然后数组元素被展开和解包。

<?php
   function get_squares() {
      for ($i = 0; $i < 5; $i++) {
         $arr[] = $i**2;
      }
      return $arr;
   }
   $squares = [...get_squares()];
   print_r($squares);
?>

它将生成以下 output

Array
(
   [0] => 0
   [1] => 1
   [2] => 4
   [3] => 9
   [4] => 16
)

PHP - Null Coalescing Operator

Null Coalescing 运算符是 PHP 7 引入的许多新功能之一。“coalescing”一词的意思是将许多事物组合成一个。此运算符用于替换与 isset() 函数结合使用时的三元运算。

Ternary Operator in PHP

PHP 有一个三元运算符,由“ ? ”符号表示。三元运算符比较布尔表达式,如果为真则执行第一个操作数,否则执行第二个操作数。

expr ? statement1 : statement2;

Example

让我们使用三元运算符来检查某个变量是否设置,借助 isset() 函数,如果已声明则返回 true,否则返回 false。

<?php
   $x = 1;
   $var = isset($x) ? $x : "not set";
   echo "The value of x is $var";
?>

它将生成以下 output

The value of x is 1

现在,让我们删除“x”的声明并重新运行代码:

<?php
   # $x = 1;
   $var = isset($x) ? $x : "not set";
   echo "The value of x is $var";
?>

现在,代码将产生以下 output

The value of x is not set

The Null Coalescing Operator

Null Coalescing 运算符由“??”符号表示。它用作三元运算符与 isset() 结合使用的便捷快捷方式。它返回其第一个操作数(如果存在且不为 null);否则返回其第二个操作数。

$Var = $operand1 ?? $operand2;

第一个操作数检查特定变量是否为 null 或不为 null(或是否已设置或未设置)。如果它不是 null,则返回第一个操作数,否则返回第二个操作数。

Example

请看以下示例:

<?php
   # $num = 10;
   $val = $num ?? 0;
   echo "The number is $val";
?>

它将生成以下 output

The number is 0

现在取消对将 $num 设置为 10 的第一条语句的注释,并重新运行代码:

<?php
   $num = 10;
   $val = $num ?? 0;
   echo "The number is $val";
?>

现在会生成以下 output

The number is 10

空值合并运算符的一个实用应用是在检查用户名是否由客户端浏览器提供时。

Example

下面代码从 URL 中读取 name 变量。如果 URL 中 name 参数确实有值,则会显示一条欢迎信息。但是,如果没有,则用户被称为 Guest。

<?php
   $username = $_GET['name'] ?? 'Guest';
   echo "Welcome $username";
?>

假设此脚本 “hello.php” 位于 PHP 服务器的 htdocs 文件夹中,在 URL 中输入 http://localhost/hello.php?name=Amar ,浏览器将显示以下消息 −

Welcome Amar

如果 http://localhost/hello.php 是 URL,则浏览器将显示以下消息 −

Welcome Guest

空值合并运算符用作检查 isset() 函数的三元运算符特定案例的替换项。因此,以下语句给出了类似的结果 −

<?php
   $username = isset($_GET['name']) ? $_GET['name'] : 'Guest';
   echo "Welcome $username";
?>

现在会生成以下 output

Welcome Guest

你可以连接 “??” 运算符,如下所示 −

<?php
   $username = $_GET['name'] ?? $_POST['name'] ?? 'Guest';
   echo "Welcome $username";
?>

现在会生成以下 output

Welcome Guest

如果 $name 变量未通过 GET 或 POST 方法设置,这会将 username 设置为 Guest。

PHP - Spaceship Operator

Spaceship 运算符是 PHP 7.0 版本中引入的众多新功能之一。它是一个三向比较运算符。

常规比较运算符 (<, >, !=, == 等) 返回 true 或 false(等同于 1 或 0)。另一方面,Spaceship 运算符有三个可能的返回值:-1、0 或 1。该运算符可用于整数、浮点数、字符串、数组、对象等。

Syntax

用于 Spaceship 运算符的符号为 "<⇒"

$retval = operand1 <=> operand2

此处,如果操作数 1 小于操作数 2,则 $retval 为 -1;如果两个操作数相等,则为 0;如果操作数 1 大于操作数 2,则为 1。

Spaceship 运算符作为组合比较运算符实现。常规比较运算符可以被认为仅仅是下表的简写 −

Operator

<⇒ equivalent

$a < $b

($a <⇒ $b) === -1

$a ⇐ $b

($a <⇒ $b) === -1

($a <⇒ $b) === 0

$a == $b

($a <⇒ $b) === 0

$a != $b

($a <⇒ $b) !== 0

$a >= $b

($a <⇒ $b) === 1

($a <⇒ $b) === 0

$a > $b

($a <⇒ $b) === 1

Example 1

以下示例展示了如何在 PHP 中使用 Spaceship 运算符 −

<?php
   $x = 5;
   $y = 10;
   $z = $x <=> $y/2;

   echo "$x <=> $y/2 = $z";
?>

它将生成以下 output

5 <=> 10/2 = 0

Example 2

更改 $x=4 并检查结果 −

<?php
   $x = 4;
   $y = 10;
   $z = $x <=> $y/2;

   echo "$x <=> $y/2 = $z";
?>

它将生成以下 output

4 <=> 10/2 = -1

Example 3

更改 $y=7 并再次检查结果 −

<?php
   $x = 7;
   $y = 10;
   $z = $x <=> $y/2;

   echo "$x <=> $y/2 = $z";
?>

它将生成以下 output

7 <=> 10/2 = 1

Example 4

当用于字符串操作数时,Spaceship 操作数的作用与 strcmp() 函数相同。

<?php
   $x = "bat";
   $y = "ball";
   $z = $x <=> $y;

   echo "$x <=> $y = $z";
?>

它将生成以下 output

bat <=> ball = 1

Example 5

更改 $y = "baz" 并检查结果 −

<?php
   $x = "bat";
   $y = "baz";
   $z = $x <=> $y;

   echo "$x <=> $y = $z";
?>

它将生成以下 output

bat <=> baz = -1

Spaceship Operator with Boolean Operands

Spaceship 运算符也可以用于布尔操作数 −

true <=> false returns 1
false <=> true returns -1
true <=> true as well as false <=> false returns 0

PHP – Decision Making

计算机程序默认按照输入-处理-输出路径顺序执行。这种顺序流可以借助所有计算机编程语言(包括 PHP)提供的决策控制语句进行更改。

Decision Making in a Computer Program

决策是预测程序执行期间出现的条件并根据条件采取指定操作。

你可以在代码中使用条件语句来做出决策。实现条件逻辑的能力是编程语言基本要求之一。

A Typical Decision Making Structure

以下是大多数编程语言中常见的典型决策结构的一般形式 −

decisions making

Decision Making Statements in PHP

PHP 支持以下三个决策表述:

  1. if&#8230;&#8203;else statement − 如果你希望在条件为真的时候执行一组代码,而在条件不为真的时候执行另一组代码,那就使用此语句。

  2. elseif statement − 将此语句与 if…​else 语句搭配使用,以便在许多条件中有一个为真时执行一组代码

  3. switch statement − 如果希望从许多代码块中选择一个要执行的代码块,请使用 Switch 语句。 switch 语句用于避免长长的 if..elseif..else 代码块。

几乎所有编程语言(包括 PHP)都定义了 if-else 语句。这允许有条件地执行代码片段。PHP 中使用 if-else 语句的语法类似于 C 中的语法 −

if (expr)
   statement1
else
   statement2

此处表达式是布尔表达式,对 true 或 false 进行计算

  1. 任何涉及布尔运算符(如 <、>、⇐、>=、!= 等)的表达式都是布尔表达式。

  2. 如果表达式产生 true,则会执行后续语句 − 它可以是简单语句或复合语句,即一对大括号中含有的语句组。

  3. 如果表达式为 false,则后续语句被忽略,而程序流程会继续执行下一条语句。

  4. 使用 else 语句是可选的。如果程序逻辑需要在表达式( if 关键字之后)计算结果为 false 的情况下执行另一个语句或一组语句。

decision making 1

elseif 语句是 ifelse 的组合。它允许你检查多个条件的 TRUE 值,并在其中一个条件计算结果为 TRUE 时执行一组代码。就像 else 语句一样, elseif 语句是可选的。

switch 语句类似于针对同一表达式的一系列 if 语句。我们将在本教程的后几章详细了解这些语句。

PHP - If…Else Statement

实现条件逻辑的能力是任何编程语言(包括 PHP)的基本要求。PHP 有三个关键字(也称为 language constructs) – if, elseifelse – 根据不同的条件做出决策。

if 关键字是代码片段条件执行的基本结构。 if 关键字通常与 else 关键字结合使用,尽管它并不总是必需的。

如果你想在条件为 true 时执行一些代码,在相同条件为 false 时执行其他代码,则使用 “if…​.else” 语句。

Syntax

%{s8} 语句在 PHP 中的使用和语法类似于 C 语言。以下是 PHP 中 if 语句的语法 −

if (expression)
   code to be executed if expression is true;
else
   code to be executed if expression is false;

if 语句总后跟一个布尔表达式。

  1. 如果布尔表达式的估值为 true,PHP 将执行布尔表达式后面的语句。

  2. 如果布尔表达式的估值为 false,则该语句将被忽略。

  3. 如果算法需要在表达式为 false 时执行其他语句,则在 else 关键字之后编写该语句。

Example

以下是一个演示 if else 语句用法的简单 PHP 代码。有两个变量 $a 和 $b。该代码识别出它们中的哪一个更大。

<?php
   $a=10;
   $b=20;
   if ($a > $b)
      echo "a is bigger than b";
   else
      echo "a is not bigger than b";
?>

运行上述代码时,它会显示以下 output

a is not bigger than b

交换 “a” 和 “b” 的值,然后重新运行。现在,你将获得以下输出 −

a is bigger than b

Example

如果当前是星期五,下列示例将输出“Have a nice weekend!”,否则将输出“Have a nice day!” −

<?php
   $d = date("D");

   if ($d == "Fri")
      echo "Have a nice weekend!";
   else
      echo "Have a nice day!";
?>

它将生成以下 output

Have a nice weekend!

Using endif in PHP

PHP 代码通常与 HTML 脚本混合在一起。我们可以在 if 部分和 PHP 代码中的 else 部分插入 HTML 代码。PHP 为 ifelse 语句提供了替代语法。将左大括号改为冒号 (:),将右大括号改为 endif; ,这样可以将 HTML 块添加到 ifelse 部分。

<?php
   $d = date("D");

   if ($d == "Fri"): ?>
      <h2>Have a nice weekend!</h2>

   <?php else: ?>
      <h2>Have a nice day!</h2>
<?php endif ?>

确保上述脚本位于 PHP 服务器的文档根目录中。访问 URL http://localhost/hello.php 。如果当前不是星期五,浏览器中应显示以下输出 −

Have a nice day!

Using elseif in PHP

如果某几个条件中有一个条件是真的,而您希望执行一些代码,则使用 elseif 语句。PHP 中的 elseif 语言结构是 ifelse 的组合。

  1. else 类似,它指定了一个备用语句,当原始 if 表达式计算为假时执行。

  2. 然而,与 else 不同,仅当 elseif 条件表达式计算为真时,它才会执行该备用表达式。

if (expr1)
   code to be executed if expr1 is true;
elseif (expr2)
   code to be executed if expr2 is true;
else
   code to be executed if expr2 is false;

Example

让我们修改上述代码以在星期日、星期五和其他日子显示不同的消息。

<?php
   $d = date("D");
   if ($d == "Fri")
      echo "<h3>Have a nice weekend!</h3>";

   elseif ($d == "Sun")
      echo "<h3>Have a nice Sunday!</h3>";

   else
      echo "<h3>Have a nice day!</h3>";
?>

在星期日,浏览器应显示以下 output

Have a nice Sunday!

Example

这里有另一个示例,说明 if–elselif–else 语句的用法 −

<?php
   $x=13;
   if ($x%2==0) {
      if ($x%3==0)
         echo "<h3>$x is divisible by 2 and 3</h3>";
      else
         echo "<h3>$x is divisible by 2 but not divisible by 3</h3>";
   }

   elseif ($x%3==0)
      echo "<h3>$x is divisible by 3 but not divisible by 2</h3>";

   else
      echo "<h3>$x is not divisible by 3 and not divisible by 2</h3>";
?>

上述代码还使用 nestedif 语句。

x 的值为 13、12 和 10 时, output 如下 −

13 is not divisible by 3 and not divisible by 2
12 is divisible by 2 and 3
10 is divisible by 2 but not divisible by 3

PHP - Switch Statement

PHP 中的 switch 语句可以看作对相同表达式中的一系列 if…else 语句的替代。假设你需要用许多不同的值来比较一个表达式或一个变量,并且根据它等于哪个值执行不同的代码片段。在这样的情况下,你需要使用多重 if…​elseif…​else 构造。

然而,这样的构造会使代码变得很乱,并且难以理解。为了简化这样的代码,可以在 PHP 中使用 switch case 构造,它提供了一个更简洁的替代方案来避免 if..elseif..else 代码的长块。

下面的 PHP 脚本使用 if elseif 语句:

if ($x == 0) {
   echo "x equals 0";
} elseif ($x == 1) {
   echo "i equals 1";
} elseif ($x == 2) {
   echo "x equals 2";
}

你可以使用 switch case 语句来获得相同的结果,如下所示:

switch ($x) {
   case 0:
      echo "x equals 0";
   break;
   case 1:
      echo "x equals 1";
   break;
   case 2:
      echo "x equals 2";
   break;
}

switch 语句后跟一个表达式,该表达式与每个 case 子句中的值依次进行比较。如果发现表达式与任何 case 匹配,则执行相应的语句块。

  1. switch 语句按行执行大括号内的情语句。

  2. 当且仅当找到一个 case 语句,其表达式运算得到的值与 switch 表达式的值相匹配时,PHP 才会开始执行语句,直到 switch 块的末尾,或者第一次遇到一个 break 语句。

  3. 如果您不在 case 语句列表的末尾编写一个 break 语句,那么 PHP 将继续执行后续 case 的语句。

Example

尝试移除 break,然后再运行上面的代码。如果 x 的值是 0,那么您会发现输出包括 "x equals 1" 和 "x equals 2" 这两行。

<?php
   $x=0;
   switch ($x) {
      case 0:
         echo "x equals 0 \n";
      case 1:
         echo "x equals 1 \n";
      case 2:
         echo "x equals 2";
   }
?>

它将生成以下 output

x equals 0
x equals 1
x equals 2

因此,确保以 break 语句结束每个 case 块很重要。

The Default Case in Switch

default case 是一个特例。这种 case 与其他 case 都不匹配。使用 default 是可选的,但如果使用,这必须是大括号内最后一个 case。

您可以将多个 case 组合起来,以模拟与 or 运算符组合在一起的多个逻辑表达式。

<?php
   $x=10;
   switch ($x) {
      case 0:
      case 1:
      case 2:
         echo "x between 0 and 2 \n";
      break;
      default:
         echo "x is less than 0 or greater than 2";
   }
?>

要比较的值都给在 case clause 中。值可以是一个数字、一个字符串,甚至是一个函数。不过,您不能在 case clause 中使用比较运算符 (<、>、== 或 !=) 作为值。

您可以在 case 子句中选择使用分号,而不是冒号。如果没有匹配的 case,并且也没有 default 分支,那么就不会执行任何代码,就像没有 if 语句为 true 一样。

The switch-endswitch Statement

PHP 允许使用替代语法,通过 switch-endswitch 语句来界定 switch 结构。以下版本的 switch case 是可以接受的。

<?php
   $x=0;
   switch ($x) :
      case 0:
         echo "x equals 0";
      break;
      case 1:
         echo "x equals 1 \n";
      break;
      case 2:
         echo "x equals 2 \n";
      break;
      default:
         echo "None of the above";
   endswitch
?>

Using the Break Statement in Switch…Case

显然,您不用编写 break 来终止 default case,因为它在 switch 结构中是最后一个 case。

Example

请看以下示例:

<?php
   $d = date("D");

   switch ($d){
      case "Mon":
         echo "Today is Monday";
      break;

      case "Tue":
         echo "Today is Tuesday";
      break;

      case "Wed":
         echo "Today is Wednesday";
      break;

      case "Thu":
         echo "Today is Thursday";
      break;

      case "Fri":
         echo "Today is Friday";
      break;

      case "Sat":
         echo "Today is Saturday";
      break;

      case "Sun":
         echo "Today is Sunday";
      break;

      default:
         echo "Wonder which day is this ?";
   }
?>

它将生成以下 output

Today is Monday

PHP – Loop Types

PHP 中的循环用于对同一代码块执行指定次数。PHP 支持以下四种类型的循环。

  1. for − 对代码块执行指定的次数。

  2. foreach − 对数组中每个元素对代码块进行循环

  3. while − 在指定条件为真的情况下对代码块进行循环

  4. do-while − 对代码块进行一次循环,然后只要特殊的条件为真,就可以重复循环

此外,我们还将说明在 PHP 中如何使用 continuebreak 语句来控制循环的执行。

PHP for Loop

当你清楚知道要执行一条或多条语句的次数时,就可以使用 for 语句。

php for loop

Syntax

for (initialization; condition; increment){
   code to be executed;
}

初始值设定程序用于设置循环迭代计数器的起始值。为此目的,此处可以声明一个变量,而按传统,此变量被命名为 $i。

Example

以下实例进行五次迭代,并在循环的每次遍历中更改两个变量的赋值——

<?php
   $a = 0;
   $b = 0;

   for( $i = 0; $i<5; $i++ ) {
      $a += 10;
      $b += 5;
   }

   echo ("At the end of the loop a = $a and b = $b" );
?>

它将生成以下 output

At the end of the loop a = 50 and b = 25

PHP foreach Loop

foreach 语句用于循环遍历数组。每次遍历时,当前数组元素的值分配给 $value,数组指针移动一位,在下次遍历中,将处理下一个元素。

Syntax

foreach (array as value) {
   code to be executed;
}

Example

尝试以下实例列出数组的值。

<?php
   $array = array( 1, 2, 3, 4, 5);

   foreach( $array as $value ) {
      echo "Value is $value \n";
   }
?>

它将生成以下 output

Value is 1
Value is 2
Value is 3
Value is 4
Value is 5

PHP while Loop

while 语句会在测试表达式为 true 的情况下执行代码块。

如果测试表达式为 true,则会执行代码块。代码执行后,测试表达式将再次进行评估,并且循环将继续进行,直到发现测试表达式为 false。

php while loop

Syntax

while (condition) {
   code to be executed;
}

Example

此示例在循环的每次迭代中递减变量值,并且计数器会递增,直到达到 10(此时评估为 false)并结束循环。

<?php
   $i = 0;
   $num = 50;

   while($i < 10) {
      $num--;
      $i++;
   }

   echo ("Loop stopped at i = $i and num = $num" );
?>

它将生成以下 output

Loop stopped at i = 10 and num = 40

PHP do-while Loop

do-while 语句会至少执行代码块一次——然后,只要某个条件为真,它就会重复循环。

Syntax

do {
   code to be executed;
}
while (condition);

Example

以下示例会至少递增一次 i 的值,并且只要 i 的值为小于 10,它就会继续递增 i 的变量——

<?php
   $i = 0;
   $num = 0;

   do {
      $i++;
   }

   while( $i < 10 );
   echo ("Loop stopped at i = $i" );
?>

它将生成以下 output

Loop stopped at i = 10

PHP break Statement

PHP break 关键字用于过早终止循环的执行。

break 语句位于语句块内。它会为你提供完全的控制权,无论何时你想要退出循环,都可以退出。退出循环后,会执行循环的后续语句。

cpp break statement

Example

在以下示例中,当计数器值达到 3 时,条件测试变为 true,并且循环终止。

<?php
   $i = 0;

   while( $i < 10) {
      $i++;
      if( $i == 3 )break;
   }
   echo ("Loop stopped at i = $i" );
?>

它将生成以下 output

Loop stopped at i = 3

PHP continue Statement

PHP continue 关键字用于中止循环的当前迭代,但不会终止循环。

break 语句类似, continue 语句位于包含循环执行的代码的语句块内,在语句块前面是一个条件测试。对于遇到 continue 语句的遍历,将跳过循环代码的剩余部分,然后开始下一次遍历。

cpp continue statement

Example

在以下示例中,循环打印数组的值,但是对于条件变为真的值,它只跳过代码,然后打印下一个值。

<?php
   $array = array( 1, 2, 3, 4, 5);

   foreach( $array as $value ) {
      if( $value == 3 )continue;
      echo "Value is $value \n";
   }
?>

它将生成以下 output

Value is 1
Value is 2
Value is 4
Value is 5

PHP - For Loop

程序默认情况下会按照语句的顺序进行执行。如果程序流被定向到程序中的任何早期语句,它就构成了循环。PHP 中的 for 语句是构成 PHP 脚本中循环的便捷工具。在本节中,我们将讨论 PHP 的 for 语句。

Flowchart of "for" Loop

以下流程图说明了 for 循环的工作原理——

php for loop

for 语句用于在你已知想要执行语句或语句块的次数时。

Syntax of "for" Loop

PHP 中 for 语句的语法与 C 语言中的 for 语句类似。

for (expr1; expr2; expr3){
   code to be executed;
}

for 关键字后面是圆括号,圆括号内包含三个用分号分隔的表达式。这三个表达式各自可以为空,也可以包含多个用逗号分隔的表达式。括号后面是一条或多条放在大括号中的语句。这些语句构成了循环体。

括号中的第一个表达式只在循环开始时执行。它通常充当 initializer ,用于设置循环迭代计数器的起始值。

在每次迭代的开始,都会计算 expr2 。如果计算结果为真,则循环继续并且执行主体块中的语句。如果计算结果为假,则循环执行结束。通常, expr2 指定计数器的最终值。

expr3 在每次迭代的末尾执行。在大多数情况下,此表达式会递增计数器变量。

Example

for 循环的最一般示例如下 -

<?php
   for ($i=1; $i<=10; $i++){
      echo "Iteration No: $i \n";
   }
?>

以下是它的 @{s0}

Iteration No: 1
Iteration No: 2
Iteration No: 3
Iteration No: 4
Iteration No: 5
Iteration No: 6
Iteration No: 7
Iteration No: 8
Iteration No: 9
Iteration No: 10

An infinite "for" loop

请注意,括号中的所有三个表达式都是可选的。仅含两个分号的 for 语句构成一个无限循环。

for (; ;) {
   Loop body
}

要停止无限迭代,您需要在循环体中使用 break 语句。

A decrementing "for" loop

您还可以形成递减 for 循环。为了创建一个从 10 到 1 的 for 循环,请用 10 初始化循环变量,在每次迭代开始时计算的中间表达式检查它是否大于 1。在每次迭代末尾执行的最后一个表达式应该递减它 1。

<?php
   for ($i=10; $i>=1; $i--){
      echo "Iteration No: $i \n";
   }
?>

它将生成以下 output

Iteration No: 10
Iteration No: 9
Iteration No: 8
Iteration No: 7
Iteration No: 6
Iteration No: 5
Iteration No: 4
Iteration No: 3
Iteration No: 2
Iteration No: 1

Using the "for…endfor" construct

您还可以使用冒号 (:) 符号来启动循环块,并在块的末尾放置 endfor 语句。

<?php
   for ($i=1; $i<=10; $i++):
      echo "Iteration No: $i \n";
   endfor;
?>

Iterating an indexed array using "for" loop

数组中的每个元素都由以 "0" 开头的递增索引标识。如果存在一个包含 5 个元素的数组,则它的下限为 0,上限为 4(数组大小 -1)。

要获得数组中的元素数量,有一个 count() 函数。因此,我们可以使用以下 for 语句遍历索引数组 -

<?php
   $numbers = array(10, 20, 30, 40, 50);

   for ($i=0; $i<count($numbers); $i++){
      echo "numbers[$i] = $numbers[$i] \n";
   }
?>

它将生成以下 output

numbers[0] = 10
numbers[1] = 20
numbers[2] = 30
numbers[3] = 40
numbers[4] = 50

Iterating an Associative Array Using "for" Loop

PHP 中的关联数组是键值对的集合。箭头符号 (⇒) 用于显示键与其值之间的关联。我们使用 array_keys() 函数获取键的数组。

下面的 for 循环从代码中定义的关联数组 $capitals 中打印每个州的首府 -

<?php
   $capitals = array(
      "Maharashtra"=>"Mumbai",
      "Telangana"=>"Hyderabad",
      "UP"=>"Lucknow",
      "Tamilnadu"=>"Chennai"
   );
   $keys=array_keys($capitals);

   for ($i=0; $i<count($keys); $i++){
      $cap = $keys[$i];
      echo "Capital of $cap is $capitals[$cap] \n";
   }
?>

以下是它的 @{s0}

Capital of Maharashtra is Mumbai
Capital of Telangana is Hyderabad
Capital of UP is Lucknow
Capital of Tamilnadu is Chennai

Using Nested "for" Loops in PHP

如果在现有循环的体内使用另一个 for 循环,则这两个循环就被称为嵌套的。

对于外部循环的计数器变量的每个值,内部循环的所有迭代都已完成。

<?php
   for ($i=1; $i<=3; $i++){
      for ($j=1; $j<=3; $j++){
         echo "i= $i j= $j \n";
      }
   }
?>

它将生成以下 output

i= 1 j= 1
i= 1 j= 2
i= 1 j= 3
i= 2 j= 1
i= 2 j= 2
i= 2 j= 3
i= 3 j= 1
i= 3 j= 2
i= 3 j= 3

请注意,字符串是一种数组形式。 strlen() 函数给出字符串中的字符数量。

Example

下面的 PHP 脚本使用两个嵌套循环在每行打印一个字符串中递增数量的字符。

<?php
   $str = "TutorialsPoint";
   for ($i=0; $i<strlen($str); $i++){
      for ($j=0; $j<=$i; $j++){
         echo "$str[$j]";
      }
      echo "\n";
   }
?>

它将生成以下 output

T
Tu
Tut
Tuto
Tutor
Tutori
Tutoria
Tutorial
Tutorials
TutorialsP
TutorialsPo
TutorialsPoi
TutorialsPoin
TutorialsPoint

PHP - Foreach Loop

PHP 中的 foreach 构造函数专门用于迭代数组。如果你在数据类型不同的变量上尝试使用它,PHP 会报错。

PHP 中的 foreach 循环可用于索引数组和关联数组。有两种使用语法可用——

foreach (array as $value) {
   statements
}

当你想迭代索引数组时,上述方法很有用。下述语法更适合关联数组。

foreach (array as $key => $value) {
   statements
}

然而,这两种方法都适用于索引数组,因为数组中项目索引也充当键。

Using "foreach" Loop with an Indexed Array

上述第一种类型的语法在 foreach 关键词前面显示了一个括号。要遍历的数组的名称之后是 as 关键词,然后再是变量。

当第一个迭代开始时,第一个数组元素分配给变量。循环块结束后,变量获取下一个元素的值,并重复循环体中的语句,直到数组中的元素耗尽。

foreach 循环的典型用法如下——

<?php
   $arr = array(10, 20, 30, 40, 50);
   foreach ($arr as $val) {
      echo "$val \n";
   }
?>

Example

PHP 提供了一个非常有用的 array_search() 函数,它返回给定值的键。由于索引本身是索引数组中的键,因此,每个 $val 的 array_search() 会返回每个值的基于零的索引。以下代码展示它是如何工作的——

<?php
   $arr = array(10, 20, 30, 40, 50);

   foreach ($arr as $val) {
      $index = array_search($val, $arr);
      echo "Element at index $index is $val \n";
   }
?>

它将生成以下 output

Element at index 0 is 10
Element at index 1 is 20
Element at index 2 is 30
Element at index 3 is 40
Element at index 4 is 50

Example

foreach 语法的第二个变体将数组中的每个元素解压缩到两个变量中:一个用于 key ,一个用于 value

由于在索引数组的情况下,索引本身充当键,因此 $k 变量会连续获取数组中每个元素的增量索引。

<?php
   $arr = array(10, 20, 30, 40, 50);
   foreach ($arr as $k=>$v) {
      echo "Key: $k => Val: $v \n";
   }
?>

它将生成以下 output

Key: 0 => Val: 10
Key: 1 => Val: 20
Key: 2 => Val: 30
Key: 3 => Val: 40
Key: 4 => Val: 50

Iterating an Associative Array using "foreach" Loop

关联数组是由键值对收集的。若要迭代关联数组,第二种 foreach 语法变体是合适的。数组中的每个元素都解压缩到两个变量中,每个变量都获取键及其值。

Example

这里有一个使用 foreach 循环遍历各州及其对应首府的数组的示例。

<?php
   $capitals = array(
      "Maharashtra"=>"Mumbai", "Telangana"=>"Hyderabad",
      "UP"=>"Lucknow", "Tamilnadu"=>"Chennai"
   );

   foreach ($capitals as $k=>$v) {
      echo "Capital of $k is $v \n";
   }
?>

它将生成以下 output

Capital of Maharashtra is Mumbai
Capital of Telangana is Hyderabad
Capital of UP is Lucknow
Capital of Tamilnadu is Chennai

然而,你仍可以使用 foreach 陈述的第一个版本,其中仅数组中每个键值对的值存储在变量中。然后使用之前使用过的 array_search() 函数获取对应于该值的关键。

<?php
   $capitals = array(
      "Maharashtra"=>"Mumbai", "Telangana"=>"Hyderabad",
      "UP"=>"Lucknow", "Tamilnadu"=>"Chennai"
   );

   foreach ($capitals as $pair) {
      $cap = array_search($pair, $capitals);
      echo "Capital of $cap is $capitals[$cap] \n";
   }
?>

Iterating a 2D Array using "foreach" Loop

可以在 PHP 中声明多维数组,其中数组中的每个元素都是另一个数组本身。请注意外部数组和子数组都可以是索引数组或关联数组。

在下面的示例中,我们有一个二维数组,它可以称为数组或数组。我们需要嵌套循环以遍历嵌套数组结构,如下所示——

<?php
   $twoD = array(
      array(1,2,3,4),
      array("one", "two", "three", "four"),
      array("one"=>1, "two"=>2, "three"=>3)
   );

   foreach ($twoD as $idx=>$arr) {
      echo "Array no $idx \n";
      foreach ($arr as $k=>$v) {
         echo "$k => $v" . "\n";
      }
      echo "\n";
   }
?>

它将生成以下 output

Array no 0
0 => 1
1 => 2
2 => 3
3 => 4

Array no 1
0 => one
1 => two
2 => three
3 => four

Array no 2
one => 1
two => 2
three => 3

PHP - While Loop

在 PHP 脚本中创建循环的最简单的办法是使用 while 结构。PHP 中 while 循环的语法与 C 语言中的类似。只要 while 语句中的布尔表达式为 true,循环体块就会被反复执行。

以下流程图有助于理解 PHP 中 while 循环如何运行 −

php while loop

表达式中的值在每次循环开始之前都会被检查。如果 while 表达式从一开始就评估为 false,那么循环甚至不会运行一次。即使表达式在执行块期间变成了 false,在迭代结束之前也不会停止执行。

while 循环的语法可以这样表示 −

while (expr){
   statements
}

Example

以下代码展示了一个 while 循环在 PHP 中如何工作的简单示例。变量 $x 在循环开始之前被初始化为 1。只要变量小于或等于 10,循环体就会被要求执行。循环体中的 echo 语句打印当前的迭代次数并增加 x 的值,这样条件最终会变成 false。

<?php
   $x = 1;

   while ($x<=10) {
      echo "Iteration No. $x \n";
      $x++;
   }
?>

它将生成以下 output

Iteration No. 1
Iteration No. 2
Iteration No. 3
Iteration No. 4
Iteration No. 5
Iteration No. 6
Iteration No. 7
Iteration No. 8
Iteration No. 9
Iteration No. 10

请注意测试条件在每次迭代的开头都会被检查。即使条件在循环内变成了 false,执行也会继续到迭代的结尾。

Example

在以下示例中,“x” 在每次迭代中都会增加 3。在第三次迭代中,“x” 变成 9。由于测试条件仍然为 true,所以下一轮会发生,“x” 变成 12。由于条件变为 false,所以循环会停止。

<?php
   $x = 0;
   while ($x<=10){
      $x+=3;
      echo "Iteration No. $x \n";
   }
?>

它将生成以下 output

Iteration No. 3
Iteration No. 6
Iteration No. 9
Iteration No. 12

Example

不一定总是让循环变量增加。如果循环变量的初始值大于循环应该结束时的值,那么需要对其进行减少。

<?php
   $x = 5;
   while ($x>0) {
      echo "Iteration No. $x \n";
      $x--;
   }
?>

它将生成以下 output

Iteration No. 5
Iteration No. 4
Iteration No. 3
Iteration No. 2
Iteration No. 1

Iterating an Array with "while"

PHP 中的一个索引数组是一个元素集合,其中每个元素都通过一个从 0 开始的递增索引进行标识。

你可以通过组成一个 while 循环来遍历一个数组,重复访问 xth 索引处的元素,直到“x”达到数组的长度。这里“x”是一个计数变量,在每次迭代中都会增加。我们还需要一个 count() 函数来返回数组的大小。

Example

请看以下示例:

<?php
   $numbers = array(10, 20, 30, 40, 50);
   $size = count($numbers);
   $x=0;

   while ($x<$size) {
      echo "Number at index $x is $numbers[$x] \n";
      $x++;
   }
?>

它将生成以下 output

Number at index 0 is 10
Number at index 1 is 20
Number at index 2 is 30
Number at index 3 is 40
Number at index 4 is 50

Nested "while" Loops

你可以在另一个 while 循环中加入一个 while 循环。外部和内部 while 循环都受两个独立变量控制,这些变量在每次迭代后都会增加。

Example

<?php
   $i=1;
   $j=1;

   while ($i<=3){
      while ($j<=3){
         echo "i= $i j= $j \n";
         $j++;
      }
      $j=1;
      $i++;
   }
?>

它将生成以下 output

i= 1 j= 1
i= 1 j= 2
i= 1 j= 3
i= 2 j= 1
i= 2 j= 2
i= 2 j= 3
i= 3 j= 1
i= 3 j= 2
i= 3 j= 3

要注意“j”是内部 while 循环的计数变量,在它获取所有值之后被重新初始化为 1,因此“i”的下一个值“j”又从 1 开始。

Traversing the Characters in a String

在 PHP 中,一个字符串可以被认为是有序的字符集合。因此,一个 while 循环,其中一个计数变量从“0”到字符串的长度,可以用来一次获取一个字符。

Example

以下示例统计给定字符串中的元音数量。我们使用 strlen() 来获得长度,使用 str_contains() 来检查字符是否为元音之一。

<?php
   $line = "PHP is a popular general-purpose scripting language that is especially suited to web development.";
   $vowels="aeiou";
   $size = strlen($line);
   $i=0;
   $count=0;

   while ($i<$size){
      if (str_contains($vowels, $line[$i])) {
         $count++;
      }
      $i++;
   }
   echo "Number of vowels = $count";
?>

它将生成以下 output

Number of vowels = 32

Using the "endwhile" Statement

PHP 还允许你为 while 循环使用替代语法。不是在花括号中组合一个以上的语句,而是使用符号“:”(冒号)来标记条件后面的循环体,并在末尾使用 endwhile 语句。

Example

<?php
   $x = 1;
   while ($x<=10):
      echo "Iteration No. $x \n";
      $x++;
   endwhile;
?>

它将生成以下 output

Iteration No. 1
Iteration No. 2
Iteration No. 3
Iteration No. 4
Iteration No. 5
Iteration No. 6
Iteration No. 7
Iteration No. 8
Iteration No. 9
Iteration No. 10

请注意 endwhile 语句以分号结束。

PHP - Do…While Loop

"do…while" 循环是 PHP 中提供的另一种循环构造。此类型的循环类似于 while 循环,只是测试条件在每次迭代的末尾检查,而不是在新迭代的开始检查。

while 循环在进入循环之前验证真条件,而在 "do…while" 循环中,真条件在重新进入循环之前得到验证。因此,无论真条件如何,"do…while" 循环都保证至少有一次迭代。

下图通过使用两个比较流程图表示形式,展示了 "while" 循环和 "do…while" 循环的区别。

php do while loop

构成“do…while”循环的 syntax 与 C 语言中对应的部分类似。

do {
   statements;
}
while (expression);

Example

这里是一个“do…while”循环的简单示例,它打印从 1 到 5 的迭代编号。

<?php
   $i=1;
   do{
      echo "Iteration No: $i \n";
      $i++;
   }
   while ($i<=5);
?>

它将生成以下 output

Iteration No: 1
Iteration No: 2
Iteration No: 3
Iteration No: 4
Iteration No: 5

Example

以下代码使用 while 循环,也会生成相同的输出 −

<?php
   $i=1;
   while ($i<=5){
      echo "<h3>Iteration No: $i</h3>";
      $i++;
   }
?>

因此,可以说“do…while”和“while”循环表现得类似。然而,当计数器变量(在这种情况下为 $i )的初始值被设置为任何大于 while 关键字前面的括号中的测试表达式中使用的一个,就会体现出差异。

Example

在以下代码中,使用了两个循环 – while 和 “ do…while ”。 while 循环的计数器变量是 $i ,而“do…while”循环的计数器变量是 $j 。两者都被初始化为 10(任何大于 5 的值)。

<?php
   echo "while Loop \n";
   $i=10;
   while ($i<=5){
      echo "Iteration No: $i \n";
      $i++;
   }

   echo "do-while Loop \n";
   $j=10;
   do{
      echo "Iteration No: $j \n";
      $j++;
   }
   while ($j<=5);
?>

它将生成以下 output

while Loop
do - while Loop
Iteration No: 10

结果表明 while 循环不会执行任何迭代,因为条件在一开始就是假的( $i 被初始化为 10,这大于测试条件 $i⇐5 )。另一方面,“do…while”循环确实会进行第一次迭代,即使计数器变量 $j 被初始化为大于测试条件的值也是如此。

因此,我们可以推断出“do…while”循环至少可以保证一次迭代,因为测试条件是在循环块的末尾验证的。 while 循环可能不会执行任何迭代,因为在进入循环块之前验证了测试条件。

另一个语法差异是“do…while”中的 while 语句以分号结尾。对于 while 循环,圆括号后面是一个大括号循环块。

除此之外,没有其他差异。可以互换使用这两种类型的循环。

Decrementing a "do…while" Loop

要设计一个带递减计数的“do…while”,请将计数器变量初始化为一个较大的值,在循环内使用递减运算符 (--) 以在每次迭代时减少计数器的值,并将 while 括号中的测试条件设置为在计数器大于所需最后值时运行循环。

Example

在下面的示例中,计数器从 5 减小到 1。

<?php
   $j=5;
   do{
      echo "Iteration No: $j \n";
      $j--;
   }
   while ($j>=1);
?>

它将生成以下 output

Iteration No: 5
Iteration No: 4
Iteration No: 3
Iteration No: 2
Iteration No: 1

Traverse a String in Reverse Order

在 PHP 中,一个字符串可以被视为一个带有字符的索引数组。我们可以通过运行一个递减的“do…while”循环从尾端到开头依次提取和显示一个个字符,如下所示 −

<?php
   $string = "TutorialsPoint";
   $j = strlen($string);

   do{
      $j--;
      echo "Character at index $j : $string[$j] \n";
   }
   while ($j>=1);
?>

它将生成以下 output

Character at index 13 : t
Character at index 12 : n
Character at index 11 : i
Character at index 10 : o
Character at index 9 : P
Character at index 8 : s
Character at index 7 : l
Character at index 6 : a
Character at index 5 : i
Character at index 4 : r
Character at index 3 : o
Character at index 2 : t
Character at index 1 : u
Character at index 0 : T

Nested "do…while" Loops

就像 for 循环或 while 循环一样,你也可以编写嵌套的“do…while”循环。在以下示例中,上面的“do…while”循环使用 $i 计数迭代,里面的“do…while”循环递增 $j ,并且每次打印 $i*j 的乘积,从而打印出从 1 到 10 的乘法表。

<?php
   $i=1;
   $j=1;

   do{
      print "\n";
      do{
         $k = sprintf("%4u",$i*$j);
         print "$k";
         $j++;
      }
      while ($j<=10);
      $j=1;
      $i++;
   }
   while ($i<=10);
?>

它将生成以下 output

1   2   3   4   5   6   7   8   9  10
2   4   6   8  10  12  14  16  18  20
3   6   9  12  15  18  21  24  27  30
4   8  12  16  20  24  28  32  36  40
5  10  15  20  25  30  35  40  45  50
6  12  18  24  30  36  42  48  54  60
7  14  21  28  35  42  49  56  63  70
8  16  24  32  40  48  56  64  72  80
9  18  27  36  45  54  63  72  81  90
10  20  30  40  50  60  70  80  90 100

PHP - Break Statement

PHP 中的 break 语句和 continue 语句统称为“循环控制语句”。PHP 中的任何类型的循环( forwhiledo-while )都被设计为按照所使用的测试条件运行一定次数的迭代。循环块中的 break 语句将程序流带到块外部,放弃可能剩余的其他迭代。

break 语句通常有条件地使用。否则,循环将终止而不完成第一次迭代。

syntax 中 break 语句如下所示:

while(expr){
   if (condition){
      break;
   }
}

以下 flowchart 说明 break 语句的工作原理:

php break statement

Example

以下 PHP 代码展示了在循环中使用 break 的一个简单示例。 while 循环预期执行十次迭代。但是,当计数器超过 3 时,循环中的 break 语句终止循环。

<?php
   $i = 1;

   while ($i<=10){
      echo "Iteration No. $i \n";
      if ($i>=3){
         break;
      }
      $i++;
   }
?>

它将生成以下 output

Iteration No. 1
Iteration No. 2
Iteration No. 3

可以在 break 关键字的前面指定一个可选的数字参数。这在嵌套循环构造中特别有用。它会说明要中断多少个嵌套的包围结构。默认值为 1,只会中断直接的包围结构。

Example

以下示例包含三个嵌套循环:一个 for 循环,其中有一个 while 循环,而 while 循环又包含一个 do-while 循环。

最里层的循环执行 break 。其前面的数字“2”会将控制从当前作用域传出至 for 循环,而不是直接的 while 循环。

<?php
   for ($x=1; $x<=3; $x++){
      $y=1;
      while ($y<=3){
         $z=1;
         do {
            echo "x:$x y:$y z:$z \n";
            if ($z==2){
               break 2;
            }
            $z++;
         }
         while ($z<=3);
         $z=1;
         $y++;
      }
   }
?>

它将生成以下 output

x:1 y:1 z:1
x:1 y:1 z:2
x:2 y:1 z:1
x:2 y:1 z:2
x:3 y:1 z:1
x:3 y:1 z:2

请注意,每当“z”的值变为 2 时,程序就会中断“y”循环。因此,“y”的值始终为 1。

PHP - Continue Statement

break 语句类似, continue 是 PHP 中的另一个“循环控制语句”。与 break 语句不同, continue 语句会跳过当前迭代,并在条件评估和下一次迭代开始时继续执行。

continue 语句可以在任何类型的循环构造中使用,即 for, foreach, whiledo-while 循环。与 break 类似, continue 关键字通常也以条件方式使用。

while(expr){
   if (condition){
      continue;
   }
}

以下 flowchart 解释了 continue 语句的工作原理 −

php continue statement

Example

以下是一个简单的示例,演示 continue 的用法。预计 for 循环将完成十次迭代。然而,每当计数器 id 为偶数时, continue 语句都会跳过迭代。

<?php
   for ($x=1; $x<=10; $x++){
      if ($x%2==0){
         continue;
      }
      echo "x = $x \n";
   }
?>

它将生成以下 output

x = 1
x = 3
x = 5
x = 7
x = 9

Example

continue 语句接受一个可选的数字参数,告诉它应该跳到哪个嵌套循环的末尾。默认值为 1。

<?php
   for ($i=1; $i<=3; $i++){
      for ($j=1; $j<=3; $j++){
         for ($k=1; $k<=3; $k++){
            if ($k>1){
               continue 2;
            }
            print "i: $i  j:$j  k: $k\n";
         }
      }
   }
?>

它将生成以下 output

i: 1  j:1  k: 1
i: 1  j:2  k: 1
i: 1  j:3  k: 1
i: 2  j:1  k: 1
i: 2  j:2  k: 1
i: 2  j:3  k: 1
i: 3  j:1  k: 1
i: 3  j:2  k: 1
i: 3  j:3  k: 1

内嵌 for 循环中的 continue 语句跳过了迭代 2 和 3,并直接跳转到中间循环。因此,输出显示“k”对于“i”和“k”变量的所有值都是 1。

PHP - Arrays

数组是一个数据结构,它在一个变量中存储一个或多个数据值,它们之间存在某种关系。例如,如果你想存储一个班级里 10 个学生的成绩,那么你可以定义一个长度为 10 的数组,而不是定义 10 个不同的变量。

PHP 中的数组的行为与 C 中的数组略有不同,因为 PHP 是一个动态类型语言,而 C 是一个静态类型语言。

  1. PHP 中的数组是一个有序的映射,它将值与键相关联。

  2. PHP 数组可用于实现不同的数据结构,例如堆栈、队列、列表(向量)、哈希表、字典等。

  3. 数组元素的值部分可以是其他数组。这个事实可以用来实现树数据结构和多维数组。

在 PHP 中声明数组有两种方法。一种是使用内置 array() 函数,另一种是使用更短的语法,其中数组元素放在方括号内。

The array() Function

内置 array() 函数使用提供给它的参数并返回数组类型对象。一个或多个以逗号分隔的参数是数组中的元素。

array(mixed ...$values): array

括号中的每个值可以是单个值(可能是数字、字符串、任何对象,甚至另一个数组),或键值对。键与其值之间的关联由“⇒”符号表示。

Examples

$arr1 = array(10, "asd", 1.55, true);
$arr2 = array("one"=>1, "two"=>2, "three"=>3);
$arr3 = array(
   array(10, 20, 30),
   array("Ten", "Twenty", "Thirty"),
   array("physics"=>70, "chemistry"=>80, "maths"=>90)
);

Using Square Brackets [ ]

除了 array() 函数之外,还可以将以逗号分隔的数组元素置于方括号内以声明数组对象。在这种情况下,元素也可以是单个值、字符串或另一个数组。

$arr1 = [10, "asd", 1.55, true];
$arr2 = ["one"=>1, "two"=>2, "three"=>3];
$arr3 = [ [10, 20, 30],
   ["Ten", "Twenty", "Thirty"],
   ["physics"=>70, "chemistry"=>80, "maths"=>90] ];

Types of Arrays in PHP

有三种不同种类的数组,并且每个数组值都使用一个 ID(称为数组索引)访问。

  1. Indexed Array - 仅含有一系列值的数组称为索引数组。每个值通过从“0”开始的位置索引进行标识。值以线性方式存储和访问。

  2. Associative Array - 如果数组是键值对的集合,则称其为关联数组。对的键组件可以是数字或字符串,而值部分可以是任何类型。关联数组按键值(而不是在严格的线性索引顺序中)存储元素值。

  3. Multi Dimensional Array - 如果索引数组或关联数组中的每个值本身是数组,则称其为多维数组。使用多个索引访问值。

NOTE - 内置数组函数在函数引用 PHP Array Functions 中给出。

值得注意的是,PHP 内部将上述任何类型都视为关联数组本身。对于索引数组(其中每个值具有索引),则索引本身就是其键。var_dump() 函数揭示了这一事实。

Example

在此示例中, arr1 是一个索引数组。但是,var_dump()(显示任何对象的结构化信息)显示每个值都具有索引作为其键。

<?php
   $arr1 = [10, "asd", 1.55, true];
   var_dump($arr1);
?>

它将生成以下 output

array(4) {
  [0]=>
  int(10)
  [1]=>
  string(3) "asd"
  [2]=>
  float(1.55)
  [3]=>
  bool(true)
}

Example

对于多维索引数组也适用相同的原则,其中数组中的每个值都是另一个数组。

<?php
   $arr1 = [
      [10, 20, 30],
      ["Ten", "Twenty", "Thirty"],
      [1.1, 2.2, 3.3]
   ];

   var_dump($arr1);
?>

它将生成以下 output

array(3) {
  [0]=>
  array(3) {
    [0]=>
    int(10)
    [1]=>
    int(20)
    [2]=>
    int(30)
  }
  [1]=>
  array(3) {
    [0]=>
    string(3) "Ten"
    [1]=>
    string(6) "Twenty"
    [2]=>
    string(6) "Thirty"
  }
  [2]=>
  array(3) {
    [0]=>
    float(1.1)
    [1]=>
    float(2.2)
    [2]=>
    float(3.3)
  }
}

Accessing the Array Elements

要从给定的数组访问任何元素,可以使用数组[键] 语法。

Example

对于索引数组,将索引放到方括号中,因为索引本身就是键。

<?php
   $arr1 = [10, 20, 30];
   $arr2 = array("one"=>1, "two"=>2, "three"=>3);

   var_dump($arr1[1]);
   var_dump($arr2["two"]);
?>

它将生成以下 output

int(20)
int(2)

我们将在后续章节中更详细地探讨 PHP 数组的类型。

PHP - Indexed Array

在 PHP 中,数组元素可以是键值对的集合,也可以仅包含值。如果数组仅包含值,则称之为索引数组,因为每个元素都由一个递增的索引标识,从“0”开始。

可以使用 array() 函数或方括号语法在 PHP 中创建一个索引数组。

$arr1 = array("a", 10, 9.99, true);
$arr2 = ["a", 10, 9.99, true];

数组中的每个元素都有一个位置索引,第一个元素的索引为“0”。var_dump() 函数揭示了这些数组的结构化信息,如下所示:

array(4) {
  [0]=>
  string(1) "a"
  [1]=>
  int(10)
  [2]=>
  float(9.99)
  [3]=>
  bool(true)
}

我们可以使用索引遍历数组,获取给定索引处的值或修改元素的值。

Traversing an Indexed Array in PHP

任何类型的 PHP 循环都可以用来遍历数组。如果我们想使用 forwhile 循环,我们必须使用 count() 函数找到数组中的元素数量,并将其值用作计数 forwhile 循环的测试条件。

Example

以下代码使用 for 循环列出索引数组中的所有元素。

<?php
   $numbers = array(10, 20, 30, 40, 50);

   for ($i=0; $i<count($numbers); $i++){
      echo "numbers[$i] = $numbers[$i] \n";
   }
?>

它将生成以下 output

numbers[0] = 10
numbers[1] = 20
numbers[2] = 30
numbers[3] = 40
numbers[4] = 50

您还可以使用 whiledo-while 循环遍历索引数组。同样,我们需要使用 count() 函数找到数组长度。

Example

以下代码以相反的顺序遍历给定的索引数组:

<?php
   $numbers = array(10, 20, 30, 40, 50);
   $i = count($numbers)-1;
   while ($i>=0){
      echo "numbers[$i] = $numbers[$i] \n";
      $i--;
   }
?>

它将生成以下 output

numbers[4] = 50
numbers[3] = 40
numbers[2] = 30
numbers[1] = 20
numbers[0] = 10

Accessing the Array Elements Using Index

使用 array[index] 语法,可以访问数组中的任何值。特定索引处的可以分配新值。从而对数组进行修改。

Example

以下程序从数组 $arr1 中获取值,并以相反的顺序将它们放在 $arr2 中,因此 $arr1 中的第 0 个位置的值将变为 $arr2 中的最后一个值。

<?php
   $arr1 = array(10, 20, 30, 40, 50);
   $size = count($arr1);

   for ($i=0; $i<$size; $i++){
      $arr2[$size-$i-1] = $arr1[$i];
   }

   for ($i=0; $i<$size; $i++){
      echo "arr1[$i] = $$arr1[$i] arr2[$i] = $$arr2[$i] \n";
   }
?>

它将生成以下 output

arr1[0] = $10 arr2[0] = $50
arr1[1] = $20 arr2[1] = $40
arr1[2] = $30 arr2[2] = $30
arr1[3] = $40 arr2[3] = $20
arr1[4] = $50 arr2[4] = $10

Traversing an Indexed Array Using "foreach" Loop

您还可以使用 foreach 来遍历一个索引数组。看看下面的 example

<?php
   $arr1 = [10, 20, 30, 40, 50];
   foreach ($arr1 as $val){
      echo "$val \n";
   }
?>

它将生成以下 output

10
20
30
40
50

请注意,PHP 在内部将索引数组视为关联数组,其中索引被视为键。此事实可以通过数组的 var_dump() 输出得到验证。

Example

我们可以使用 foreach 语法在 key 和 value 变量中解包一个索引数组的每个元素 −

<?php
   $arr1 = [10, 20, 30, 40, 50];
   foreach ($arr1 as $key => $val){
      echo "arr1[$key] = $val \n";
   }
?>

它将生成以下 output

arr1[0] = 10
arr1[1] = 20
arr1[2] = 30
arr1[3] = 40
arr1[4] = 50

在 PHP 中,一个数组可能只是值和键值对的组合。PHP 只为没有键的值分配索引。

Example

在这个示例中,PHP 为数字分配了递增索引,跳过出现的键值对。

<?php
   $arr1 = [10, 20,
         "vals" => ["ten", "twenty"],
         30, 40, 50];

   var_dump($arr1);
?>

它将生成以下 output

array(6) {
  [0]=>
  int(10)
  [1]=>
  int(20)
  ["vals"]=>
  array(2) {
    [0]=>
    string(3) "ten"
    [1]=>
    string(6) "twenty"
  }
  [2]=>
  int(30)
  [3]=>
  int(40)
  [4]=>
  int(50)
}

PHP - Associative Array

如果 PHP 数组中的每个元素都是键值对,则这样的数组称为 associative array 。在这类型数组中,每个值都由其关联的键而不是索引标识。

  1. 关联数组用于实现字典、映射、树等数据结构。

  2. 在 PHP 中,符号“⇒”用于在键与其值之间建立关联。

How to Declare an Associative Array in PHP?

可以使用两种声明数组的方法——array() 函数和方括号表示法。

$arr1 = array(
   "Maharashtra"=>"Mumbai",
   "Telangana"=>"Hyderabad",
   "UP"=>"Lucknow",
   "Tamilnadu"=>"Chennai"
);

$arr2 = ["Maharashtra"=>"Mumbai",
   "Telangana"=>"Hyderabad",
   "UP"=>"Lucknow",
   "Tamilnadu"=>"Chennai"];

如果我们调用 var_dump() 函数,则以上两个数组将显示相似的结构 −

array(4) {
   ["Maharashtra"]=>
   string(6) "Mumbai"
   ["Telangana"]=>
   string(9) "Hyderabad
   ["UP"]=>
   string(7) "Lucknow"
   ["Tamilnadu"]=>
   string(7) "Chennai"
}

关联数组中每个元素的 key 部分可以是任意数字(整数、浮点数或布尔值)或字符串。 value 部分可以是任意类型。但是,浮点数键会被强制转换为整数。因此,布尔值 true/false 用作“1”或“0”作为键。

Example

请看以下示例:

<?php
   $arr1 = array(
      10=>"hello",
      5.75=>"world",
      -5=>"foo",
      false=>"bar"
   );
   var_dump($arr1);
?>

它将生成以下 output

array(4) {
  [10]=>
  string(5) "hello"
  [5]=>
  string(5) "world"
  [-5]=>
  string(3) "foo"
  [0]=>
  string(3) "bar"
}

请注意,键 5.75 会四舍五入到 5,并且键“true”反映为“0”。如果同一个键在数组中出现多次,则最后出现的键值对将保留,从而舍弃键与较早值的关联。

PHP 在内部甚至将索引数组视为关联数组,其中索引实际上是值的键。这意味着 0 索引处的值具有等于“0”的键,依此类推。对索引数组执行 var_dump() 也会显示出 PHP 数组的这一特性。

Iterating a PHP Associative Array

foreach 循环是遍历关联数组最简单的方法,并且是最好的方法,尽管也可以使用其他类型的循环方法。

Example

让我们看看 foreach 的循环实现,每个键值对都在两个变量中解包。

<?php
   $capitals = array(
      "Maharashtra"=>"Mumbai",
      "Telangana"=>"Hyderabad",
      "UP"=>"Lucknow",
      "Tamilnadu"=>"Chennai"
   );

   foreach ($capitals as $k=>$v) {
      echo "Capital of $k is $v \n";
   }
?>

它将生成以下 output

Capital of Maharashtra is Mumbai
Capital of Telangana is Hyderabad
Capital of UP is Lucknow
Capital of Tamilnadu is Chennai

还有另一种在 PHP 中使用 foreach 循环的方法,其中每个元素都存储在一个变量中。然后,我们可以使用 array_search() 分离键和值部分,并使用它们在循环中。

<?php
   $capitals = array(
      "Maharashtra"=>"Mumbai",
      "Telangana"=>"Hyderabad",
      "UP"=>"Lucknow",
      "Tamilnadu"=>"Chennai"
   );

   foreach ($capitals as $pair) {
      $cap = array_search($pair, $capitals);
      echo "Capital of $cap is $capitals[$cap] \n";
   }
?>

它将生成以下 output

Capital of Maharashtra is Mumbai
Capital of Telangana is Hyderabad
Capital of UP is Lucknow
Capital of Tamilnadu is Chennai

若要使用 for、 whiledo-while 循环,我们首先必须获取所有键的数组(使用 array_keys()),查找大小并将其用作循环语法中的测试条件。

Example

以下是如何使用 for 循环来遍历关联数组 −

<?php
   $capitals = array(
      "Maharashtra"=>"Mumbai",
      "Telangana"=>"Hyderabad",
      "UP"=>"Lucknow",
      "Tamilnadu"=>"Chennai"
   );
   $keys=array_keys($capitals);

   for ($i=0; $i<count($keys); $i++){
      $cap = $keys[$i];
      echo "Capital of $cap is $capitals[$cap] \n";
   }
?>

它将生成以下 output

Capital of Maharashtra is Mumbai
Capital of Telangana is Hyderabad
Capital of UP is Lucknow
Capital of Tamilnadu is Chennai

Accessing the Value with its Key

在关联数组中,键是值而不是索引的标识符。因此,要获取与特定键关联的值,请使用 $arr[key] 语法。同样的语法也可以用于更新特定键的值。

Example

在以下代码中,声明了一个关联数组 $arr1 。创建了另一个数组 $arr2 ,使其储存 $arr1 中的每对元素,并且每个键的值都加倍。

<?php
   $arr1 = array("a"=>10, "b"=>20, "c"=>30, "d"=>40);
   foreach ($arr1 as $k=>$v){
      $arr2[$k] = $v*2;
   }
   print_r($arr2);
?>

它将生成以下 output

Array
(
   [a] => 20
   [b] => 40
   [c] => 60
   [d] => 80
)

此处使用的 print_r() 函数以易于理解的人类可读形式显示存储在数组中的数据。

PHP - Multidimensional Array

多维数组是数组的数组。在 PHP 数组中,每个元素可以是另一个数组。如果数组由值或键值对组成,且值属于标量的单数类型,则它是一维数组。如果数组中的每个元素都是一个或多个标量值组成的数组,则它是二维数组。

PHP 数组也可能是一个二维关联数组,其中外层数组的每个元素都是键值对,而该值又是另一个关联数组。

# one dimensional indexed array
$arr = [10, 20, 30, 40];

# one dimensional associative array
$arr = ["key1"=> "val1", "key2" => "val2", "key3" => "val3"];

# two dimensional indexed array
$arr = [
   [1,2,3,4],
   [10, 20, 30, 40],
   [100, 200, 300, 400]
];

# two dimensional associative array
$arr = [
   "row1" => ["key11" => "val11", "key12" => "val12", "key13" => "val13"],
   "row2" => ["key21" => "val21", "key22" => "val22", "key23" => "val23"],
   "row3" => ["key31" => "val31", "key32" => "val32", "key33" => "val33"]
];

Iterating over a 2D Array

遍历二维数组中的所有元素需要两个嵌套的循环。 foreach 循环更适合数组遍历。二维数组类似于行和列中数据的表格形式表示。

Example

以下示例展示了如何以表格形式重现二维数组 −

<?php
   $tbl = [
      [1,2,3,4],
      [10, 20, 30, 40],
      [100, 200, 300, 400]
   ];
   echo ("\n");
   foreach ($tbl as $row){
      foreach ($row as $elem){
         $val = sprintf("%5d", $elem);
         echo $val;
      }
      echo "\n";
   }
?>

它将生成以下 output

  1    2    3    4
 10   20   30   40
100  200  300  400

Example

我们也可以用两个嵌套的 foreach 循环来遍历二维关联数组。在 row-key 和 row-value 变量中解包外层数组的每一行,并用内层 foreach 循环遍历每一行元素。

<?php
   $tbl = [
      "row1" => ["key11" => "val11", "key12" => "val12", "key13" => "val13"],
      "row2" => ["key21" => "val21", "key22" => "val22", "key23" => "val23"],
      "row3" => ["key31" => "val31", "key32" => "val32", "key33" => "val33"]
   ];

   echo ("\n");
   foreach ($tbl as $rk=>$rv){
      echo "$rk\n";
      foreach ($rv as $k=>$v){
         echo "$k => $v  ";
      }
      echo "\n";
   }
?>

它将生成以下 output

row1
key11 => val11  key12 => val12  key13 => val13
row2
key21 => val21  key22 => val22  key23 => val23
row3
key31 => val31  key32 => val32  key33 => val33

Accessing the Elements in a 2D Array

访问和修改数组中元素的 $arr[$key] 语法也可以扩展到二维数组。对于二维索引数组,可以使用表达式 “@ {s7}” 获取和分配第 i 行的第 j 个元素。

Example

<?php
   $tbl = [[1,2,3,4], [10, 20, 30, 40], [100, 200, 300, 400]];

   # prints number in index 2 of the row 2
   print ("Value at [2], [2] :" . $tbl[2][2]);
?>

它将生成以下 output

Value at [2], [2] :300

类似地,可以将第 i 行和第 j 列的值设置为另一个值。

$tbl[2][2] = 250;

Example

如果它是一个二维关联数组,我们需要使用所需列的行键和键值变量来访问或修改其值。

<?php
   $tbl = [
   "row1" => ["key11" => "val11", "key12" => "val12", "key13" => "val13"],
   "row2" => ["key21" => "val21", "key22" => "val22", "key23" => "val23"],
   "row3" => ["key31" => "val31", "key32" => "val32", "key33" => "val33"]
   ];

   print "value at row2 - key22 is " . $tbl["row2"]["key22"];
?>

它将生成以下 output

value at row2 - key22 is val22

Multi-dimensional Array

在上面的示例中,我们有了一个数组,其中每个键的关联值是另一组键值对集合,我们称之为二维数组。该概念可以扩展到任意多个级别。例如,如果内层数组中的每个元素将其键与另一个数组关联,则它将变成一个三维数组。

以下是 example 三维数组的示例 −

$arr3D = [
   [
      [1, 0, 9],
      [0, 5, 6],
      [1, 0, 3]
   ],
   [
      [0, 4, 6],
      [0, 0, 1],
      [1, 2, 7]
   ],
];

Example

要遍历这样的三维数组,我们需要三个嵌套的 foreach 循环,如下所示 −

<?php
   $arr3D = [
      [[1, 0, 9],[0, 5, 6],[1, 0, 3]],
      [[0, 4, 6],[0, 0, 1],[1, 2, 7]],
   ];

   foreach ($arr3D as $arr) {
      foreach ($arr as $row) {
         foreach ($row as $element) {
            echo "$element ";
         }
         echo "\n";
      }
      echo "\n";
   }
?>

它将生成以下 output

1 0 9
0 5 6
1 0 3

0 4 6
0 0 1
1 2 7

然而,完全有可能声明一个扩展到任意维度的数组。为此,我们需要一个通用的解决方案来遍历任意维度的数组。

Recurve Traversal of Multidimensional Array

以下代码展示了一个递归函数,如果某个键的值是另一个数组,它会自己调用自己。如果我们向此函数传递任何数组作为参数,它将被遍历,显示其中的所有 k-v 对。

function showarray($arr) {
   foreach ($arr as $k=>$v) {
      if (is_array($v)) {
         showarray($v);
      } else {
         echo "$k => $v  ";
      }
   }
   echo "\n";
}

Example

让我们将上面的三维数组 $arr3D 传递给它并查看结果 −

<?php
   $arr3D = [
      [[1, 0, 9],[0, 5, 6],[1, 0, 3]],
      [[0, 4, 6],[0, 0, 1],[1, 2, 7]],
   ];

   function showarray($arr){
      foreach ($arr as $k=>$v){
         if (is_array($v)){
            showarray($v);
         } else {
            echo "$k => $v  ";
         }
      }
      echo "\n";
   }
   showarray($arr3D);
?>

它将生成以下 output

0 => 1  1 => 0  2 => 9
0 => 0  1 => 5  2 => 6
0 => 1  1 => 0  2 => 3
0 => 0  1 => 4  2 => 6
0 => 0  1 => 0  2 => 1
0 => 1  1 => 2  2 => 7

此递归函数可用于任何类型的数组,无论是索引数组还是关联数组,还可以用于任何维度。

Example

让我们使用一个二维关联数组作为参数来展示 showarray() 函数 −

<?php
   $tbl = [
      "row1" => ["key11" => "val11", "key12" => "val12", "key13" => "val13"],
      "row2" => ["key21" => "val21", "key22" => "val22", "key23" => "val23"],
      "row3" => ["key31" => "val31", "key32" => "val32", "key33" => "val33"]
   ];

   function showarray($arr){
      foreach ($arr as $k=>$v){
         if (is_array($v)){
            showarray($v);
         } else {
            echo "$k => $v  ";
         }
      }
      echo "\n";
   }
   showarray($tbl);
?>

它将生成以下 output

key11 => val11  key12 => val12  key13 => val13
key21 => val21  key22 => val22  key23 => val23
key31 => val31  key32 => val32  key33 => val33

PHP Array Functions

PHP Array Functions 允许您通过各种方式与数组进行交互并操作数组。PHP 数组对于存储、管理和操作变量集至关重要。

PHP 支持简单的和多维数组并且可以是用户创建的或由其他函数创建的。

Installation

使用 PHP 数组函数不需要安装;它们是 PHP 核心的一部分,并附带标准 PHP 安装。

Runtime Configuration

此扩展没有在 php.ini 中定义任何配置指令。

PHP Array Functions

下表列出了所有与 PHP 数组相关的函数。此处列出的版本表示支持该函数的最早的 PHP 版本。

Sr.No

Function & Description

Version

1

array()Create an array

4.2.0

2

array_change_key_case() 返回所有键小写或大写的数组

4.2.0

3

array_chunk() 将数组拆分为数组块

4.2.0

3

array_column() 返回输入数组中单列中的值

5.5.0

4

array_combine() 通过一个数组作为键,另一个数组作为其值来创建数组

5

5

array_count_values() 返回数组中每个值的出现次数

4

6

array_diff() 比较数组值,并返回差异

4

7

array_diff_assoc() 比较数组键和值,并返回差异

4

8

array_diff_key() 比较数组键,并返回差异

5

9

array_diff_uassoc() 用一个额外的用户自定义函数检查比较数组键和值,并返回差异

5

10

array_diff_ukey() 用一个额外的用户自定义函数检查比较数组键,并返回差异

5

11

array_fill() 用值填充数组

4

12

array_fill_keys() 用值填充数组,指定键

5

13

array_filter() 使用用户自定义函数筛选数组元素

4

14

array_flip() 在数组中用关联的值交换所有键

4

15

array_intersect() 比较数组值并返回匹配项

4

16

array_intersect_assoc() 比较数组键和值并返回匹配项

4

17

array_intersect_key() 比较数组键并返回匹配项

5

18

array_intersect_uassoc() 比较数组键和值,并使用额外的用户自定义函数检查,并返回匹配项

5

19

array_intersect_ukey() 比较数组键,并使用额外的用户自定义函数检查,并返回匹配项

5

20

array_key_exists() 检查数组中是否存在指定键

4

21

array_keys() 返回数组的所有键

4

22

array_map() 将数组的每个值发送到用户自定义函数,该函数返回新值

4

23

array_merge() 将一个或多个数组合并为一个数组

4

24

array_merge_recursive() 将一个或多个数组合并为一个数组

4

25

array_multisort() 对多个或多维数组进行排序

4

26

array_pad() 向数组插入指定数量的具有指定值的项

4

27

array_pop() 删除数组的最后一个元素

4

28

array_product() 计算数组中值的乘积

5

29

array_push() 在数组末尾插入一个或多个元素

4

30

array_rand() 从数组中返回一个或多个随机键

4

31

array_reduce() 使用用户定义的函数将数组返回为字符串

4

32

array_reverse() 以相反的顺序返回数组

4

33

array_search() 在数组中搜索给定值并返回键

4

34

array_shift() 移除数组中的第一个元素,并返回已移除元素的值

4

35

array_slice() 返回数组中选定的部分

4

36

array_splice() 移除并替换数组中指定元素

4

37

array_sum() 返回数组中值之和

4

38

array_udiff() 在用户自定义函数中比较数组值并返回数组

5

39

array_udiff_assoc() 比较数组键,在用户自定义函数中比较数组值,并返回数组

5

40

array_udiff_uassoc() 在用户自定义函数中比较数组键和数组值,并返回数组

5

41

array_uintersect() 在用户自定义函数中比较数组值并返回数组

5

42

array_uintersect_assoc() 比较数组键,在用户自定义函数中比较数组值,并返回数组

5

43

array_uintersect_uassoc() 在用户自定义函数中比较数组键和数组值,并返回数组

5

44

array_unique() 从数组中移除重复值

4

45

array_unshift() 在数组开头添加一个或多个元素

4

46

array_values() 返回数组全部值

4

47

array_walk() 对数组的每个成员应用用户函数

3

48

array_walk_recursive() 对数组的每个成员递归应用用户函数

5

49

arsort() 按逆序对数组进行排序,并保持索引关联

3

50

asort() 对数组进行排序,并保持索引关联

3

51

compact() 创建包含变量及其值的数组

4

52

count() 计算数组中的元素,或对象中的属性

3

53

current() 返回数组中的当前元素

3

54

each() 返回数组中的当前键值对

3

55

end() 将数组的内部指针设置到其最后一个元素

3

56

extract() 从数组导入变量到当前符号表

3

57

in_array() 检查指定值在数组中是否存在

4

58

key() 从数组获取一个键

3

59

krsort() 按相反顺序按键对数组进行排序

3

60

ksort() 按键对数组进行排序

3

61

list() 将变量分配为数组

3

62

natcasesort() 使用不区分大小写的“自然顺序”算法对数组进行排序

4

63

natsort() 使用“自然顺序”算法对数组进行排序

4

64

next() 推进数组的内部数组指针

3

65

pos()Alias of current()

3

66

prev() 倒带内部数组指针

3

67

range() 创建一个包含一系列元素的数组

3

68

reset() 将数组的内部指针设置到其第一个元素

3

69

rsort() 按相反顺序对数组进行排序

3

70

shuffle()Shuffles an array

3

71

sizeof()Alias of count()

3

72

sort()Sorts an array

3

73

uasort() 使用用户定义的函数对数组进行排序,并维持索引关联

3

74

uksort() 使用用户定义的函数按键对数组进行排序

3

75

usort() 使用用户定义的函数按值对数组进行排序

3

PHP Array Constants

Sr.No

Constant & Description

1

CASE_LOWER 与 array_change_key_case() 一起使用,将数组键转换为小写

2

CASE_UPPER 与 array_change_key_case() 一起使用,将数组键转换为大写

3

SORT_ASC 与 array_multisort() 一起使用,以升序进行排序

4

SORT_DESC 与 array_multisort() 一起使用,以降序进行排序

5

SORT_REGULAR 用于正常比较项

6

SORT_NUMERIC 用于对项进行数字比较

7

SORT_STRING 用于将项作为字符串进行比较

8

SORT_LOCALE_STRING 用于根据当前区域设置将项作为字符串进行比较

9

COUNT_NORMAL

10

COUNT_RECURSIVE

11

EXTR_OVERWRITE

12

EXTR_SKIP

13

EXTR_PREFIX_SAME

14

EXTR_PREFIX_ALL

15

EXTR_PREFIX_INVALID

16

EXTR_PREFIX_IF_EXISTS

17

EXTR_IF_EXISTS

18

EXTR_REFS

PHP - Constant Arrays

在 PHP 5.6 版本之前,无法声明常量数组。从 PHP 5.6 开始,可以使用“const”关键字声明常量数组。从 PHP 7 开始,常量数组也可以通过 define() 函数来形成。

常量数组是形成后无法修改的数组。与普通数组不同,它的标识符不以“$”符号开头。

声明常量数组的较旧语法为:

const ARR = array(val1, val2, val3);

Example

<?php
   const FRUITS = array(
      "Watermelon",
      "Strawberries",
      "Pomegranate",
      "Blackberry",
   );
   var_dump(FRUITS);
?>

它将生成以下 output

array(4) {
   [0]=>
   string(10) "Watermelon"
   [1]=>
   string(12) "Strawberries"
   [2]=>
   string(11) "Pomegranate"
   [3]=>
   string(10) "Blackberry"
}

您还可以在 PHP 中使用传统的方括号语法来声明常量数组:

const FRUITS = [
   "Watermelon",
   "Strawberries",
   "Pomegranate",
   "Blackberry",
];

Example

无法修改常量数组中的任何元素。因此,以下代码会引发致命错误:

<?php
   const FRUITS = [
      "Watermelon",
      "Strawberries",
      "Pomegranate",
      "Blackberry",
   ];
   FRUITS[1] = "Mango";
?>

它将生成以下 output

PHP Fatal error:  Cannot use temporary expression in write context

Constant Arrays PHP 7 Onwards

较新版本的 PHP 允许您通过 define() 函数来声明常量数组。

<?php
   define ('FRUITS',  [
      "Watermelon",
      "Strawberries",
      "Pomegranate",
      "Blackberry",
   ]);
   print_r(FRUITS);
?>

它将生成以下 output

Array
(
   [0] => Watermelon
   [1] => Strawberries
   [2] => Pomegranate
   [3] => Blackberry
)

您还可以使用 array() 函数在此声明常量数组。

define ('FRUITS',  array(
   "Watermelon",
   "Strawberries",
   "Pomegranate",
   "Blackberry",
));

Example

也可以声明一个 associative constant array 。以下是一个示例:

<?php
   define ('CAPITALS',  array(
      "Maharashtra" => "Mumbai",
      "Telangana" => "Hyderabad",
      "Gujarat" => "Gandhinagar",
      "Bihar" => "Patna"
   ));
   print_r(CAPITALS);
?>

它将生成以下 output

Array
(
   [Maharashtra] => Mumbai
   [Telangana] => Hyderabad
   [Gujarat] => Gandhinagar
   [Bihar] => Patna
)

PHP - Functions

与大多数编程语言类似,PHP 中的一个函数是一段有组织的可重用代码,用于执行一个相关的单一操作。函数为您的应用程序提供了更好的模块化和高程度的代码重用。

PHP 通过通过定义独立的可重用函数块来安排处理逻辑,支持结构化编程方法。这种方法的主要优点是代码变得易于理解、开发和维护。

下图显示了如何将工资计算过程逐步细化为独立的可重用函数。

php functions

Types of Functions

你已经见过了很多诸如 fopen()fread() 等函数。它们是内置函数,但 PHP 也允许你创建你自己的函数。PHP 中有两种类型的函数−

  1. Built-in functions − PHP 的标准库包含大量用于字符串处理、文件 I/O、数学计算等的内置函数。

  2. User-defined functions − 你还可以创建用户自定义函数,针对编程逻辑的要求进行定制。

可以通过传递必要的数据(称为 parametersarguments ),让一个函数从任何其他函数调用。被调用的函数将它的结果返回给调用环境。

这里有两部分需要明确 −

  1. Creating a PHP Function

  2. Calling a PHP Function

事实上,你几乎不需要创建你自己的 PHP 函数,因为已经为不同的区域创建了超过 1000 个内置库函数,你只需要根据你的需求调用它们。

请参阅 PHP Function Reference ,了解一组有用的函数。

User-defined Functions in PHP

创建你自己的 PHP 函数非常容易。我们从一个简单的示例开始,然后再详细阐述它的工作原理。假设你想创建一个 PHP 函数,当你在浏览器中调用它时,它会简单的写一条消息。

Example

在这个示例中,我们创建了一个名为 writeMessage() 的函数,然后调用它来打印一条简单消息 −

<?php

   /* Defining a PHP Function */
   function writeMessage() {
      echo "You are really a nice person, Have a nice time!";
   }

   /* Calling a PHP Function */
   writeMessage();

?>

它将生成以下 output

You are really a nice person, Have a nice time!

Creating a Function in PHP

现在,让我们详细了解这个过程。第一步是编写一个函数,然后你可以根据需要多次调用它。要创建一个新 function ,请使用 function 关键字,后跟你想使用的函数名称。在名称前面放上一个圆括号,它可能包含也可能不包含参数。在其后面放上一个用大括号分隔的语句块。此函数块中包含每次调用此函数时要执行的语句。

定义函数的一般 syntax 如下:

function foo($arg_1, $arg_2, $arg_n) {
   statements;
   return $retval;
}

如果这个函数打算将某些结果返回给调用环境,则应在函数块中的最后一个语句中设置 return 语句。不必有 return 语句,因为即使没有它,程序流也会返回给调用者,尽管不会携带任何值。

任何有效的 PHP 代码都可能显示在某个函数内部,甚至可以是其他函数和类定义。函数的名称必须遵循与用于形成变量名称相同的规则。它应以字母或下划线开头,后面可以跟任意数量的字母、数字或下划线。

下面是 PHP 中的一个简单函数。每当被调用时,它就会显示消息“你好,世界”。

function sayhello() {
   echo "Hello World";
}

Calling a Function in PHP

一旦定义了一个函数,就可以在 PHP 代码的任何地方多次调用它。请注意,函数不会自动调用。要调用某个函数,请在语句中使用它的名称;函数名称后面跟着一个分号。

<?php
   # define a function
   function sayhello(){
      echo "Hello World";
   }
   # calling the function
   sayhello();
?>

它将生成以下 output

Hello World

假设上述脚本 "hello.php" 出现在 PHP 服务器的文档根目录中,打开浏览器并输入 URL,如下 http://localhost/hello.php 。你应该在浏览器窗口中看到消息“你好,世界”。

在此示例中,函数会被定义,而没有任何参数或返回值。在随后的章节中,我们将了解如何定义和传递参数,以及如何让一个函数返回一些值。还将详细解释 PHP 函数的一些高级特性,例如递归函数、按值或引用调用函数等。

PHP - Function Parameters

PHP 中的某个函数可能会被定义为接受一个或多个参数。在定义函数时,函数参数是函数名称前面圆括号内的表达式的逗号分隔列表。参数可以是任何标量类型(数字、字符串或布尔值)、数组、对象,甚至可以是另一个函数。

function foo($arg_1, $arg_2, $arg_n) {
   statements;
   return $retval;
}

在函数体中,参数作为要处理的变量。因此,它们遵循与任何普通变量相同的命名约定,即它们应以 “$” 开头,可以包含字母、数字和下划线。

Note −定义的参数数量没有限制。

当需要调用参数化的函数时,你必须确保传递给它的值与函数定义中的参数数量相同。

foo(val1, val2, val_n);

使用参数定义的函数可以产生根据传递的值动态改变的结果。

Example

以下代码包含一个带有两个参数的 addition() 函数定义,并显示这两个参数的和。运行时输出取决于传递给函数的两个值。

<?php
   function addition($first, $second) {
      $result = $first+$second;
      echo "First number: $first \n";
      echo "Second number: $second \n";
      echo "Addition: $result";
   }

   addition(10, 20);

   $x=100;
   $y=200;
   addition($x, $y);
?>

它将生成以下 output

First number: 10
Second number: 20
Addition: 30
First number: 100
Second number: 200
Addition: 300

Formal and Actual Arguments

有时, argument 一词被用来表示 parameter 。实际上,这两个术语之间存在一定的差异。

  1. 参数是指函数定义中使用的变量,而实参是指在调用时传递给函数的值。

  2. 实参可以是字面量、变量或表达式。

  3. 函数定义中的参数通常也称为 formal arguments ,而传递的内容称为 actual arguments

  4. 形式实参和实际实参的名称不必相同。实际实参的值会从左到右的顺序分配给相应的形式实参。

  5. 函数中定义的形式实参数量和传递的实际实参数量应相同。

Example

当实际实参数量少于形式实参数量时,PHP 会引发 ArgumentCountError 。但是,如果实际实参比形式实参多,额外的实际实参会被忽略。

<?php
   function addition($first, $second) {
      $result = $first+$second;
      echo "First number: $first \n";
      echo "Second number: $second \n";
      echo "Addition: $result \n";
   }

   # Actual arguments more than formal arguments
   addition(10, 20, 30);

   # Actual arguments fewer than formal arguments
   $x=10;
   $y=20;
   addition($x);
?>

它将生成以下 output

First number: 10
Second number: 20
Addition: 30
PHP Fatal error:  Uncaught ArgumentCountError: Too few arguments
to function addition(), 1 passed in /home/cg/root/20048/main.php
on line 16 and exactly 2 expected in /home/cg/root/20048/main.php:2

Arguments Type Mismatch

PHP 是一种动态类型语言,因此它在使用实际实参的值复制形式实参时不强制进行类型检查。然而,如果函数体内的任何语句尝试对不支持特定数据类型执行特定操作,PHP 会引发异常。

在上面的 addition() 函数中,假定传递的是数值实参。如果传递字符串实参,PHP 不会有任何反对意见,但执行加法的语句会遇到异常,因为字符串类型未定义“+”运算。

Example

请看以下示例:

<?php
   function addition($first, $second) {
      $result = $first+$second;
      echo "First number: $first \n";
      echo "Second number: $second \n";
      echo "Addition: $result";
   }

   # Actual arguments are strings
   $x="Hello";
   $y="World";
   addition($x, $y);
?>

它将生成以下 output

PHP Fatal error:  Uncaught TypeError: Unsupported operand types: string + string in hello.php:5

但是,PHP 是一种弱类型语言。它会尝试尽可能将变量强制转换为兼容类型。因此,如果传递的值之一是数字的字符串表示,而第二个是数值变量,则 PHP 会将字符串变量强制转换为数值类型来执行加法运算。

Example

请看以下示例:

<?php
   function addition($first, $second) {
      $result = $first+$second;
      echo "First number: $first \n";
      echo "Second number: $second \n";
      echo "Addition: $result";
   }

   # Actual arguments are strings
   $x="10";
   $y=20;
   addition($x, $y);
?>

它将生成以下 output

First number: 10
Second number: 20
Addition: 30

PHP - Call by Value

默认情况下,PHP 对传递给函数的参数使用“按值调用”机制。当一个函数被调用时,实际实参的值会被复制到函数定义的形式实参中。

在函数体执行期间,如果任何 formal arguments 的值发生任何变化,它不会反映在 actual arguments 中。

  1. Actual Arguments −在函数调用中传递的参数。

  2. Formal Arguments −在函数定义中声明的参数。

Example

让我们考虑以下代码中使用的函数−

<?php
   function  change_name($nm) {
      echo "Initially the name is $nm \n";
      $nm = $nm."_new";
      echo "This function changes the name to $nm \n";
   }

   $name = "John";
   echo "My name is $name \n";
   change_name($name);
   echo "My name is still $name";
?>

它将生成以下 output

My name is John
Initially the name is John
This function changes the name to John_new
My name is still John

在这个示例中, change_name() 函数将 _new 附加到它传入的字符串参数。然而,传入它的变量的值在函数执行之后仍然保持不变。

事实上,形式参数充当函数的局部变量。此类变量只可以在其初始化的范围内访问。对于函数而言,用花括号 "{ }" 标记的主体就是其范围。此范围内任何变量都不可用于其外部的代码。因此,任何局部变量的处理都不会影响外部的世界。

“按值调用”方法适合使用传给它的值来执行计算的函数。它执行某些计算并返回结果,无需改变传入它的参数的值。

Note − 执行公式类型计算的任何函数都是按值调用的示例。

Example

请看以下示例:

<?php
   function addFunction($num1, $num2) {
      $sum = $num1 + $num2;
      return $sum;
   }
   $x = 10;
   $y = 20;
   $num = addFunction($x, $y);
   echo "Sum of the two numbers is : $num";
?>

它将生成以下 output

Sum of the two numbers is : 30

Example

下面是通过按值传递参数来调用函数的另一个示例。该函数将接收到的数字增加 1,但这不会影响传入它的变量。

<?php
   function increment($num) {
      echo "The initial value: $num \n";
      $num++;
      echo "This function increments the number by 1 to $num \n";
   }
   $x = 10;
   increment($x);
   echo "Number has not changed: $x";
?>

它将生成以下 output

The initial value: 10
This function increments the number by 1 to 11
Number has not changed: 10

PHP 也支持在调用时将变量的引用传递给函数。我们将在下一章讨论它。

PHP - Call by Reference

PHP 默认使用“按值调用”机制来将参数传递给函数。如果函数内的参数改变,这些改变不会反映在函数外部。要允许函数修改其参数,必须使用“按引用调用”机制。

在 PHP 中,一个引用变量充当原始或寄主变量的“别名”,以便它们两个可以读写单个值。换句话说,两个不同名称的变量可以访问相同的值,它们的行为就好像它们是同一个变量。

以下 PHP 脚本将帮助你理解什么是引用。在此, $var 是一个普通字符串变量。我们将 $var1 声明为 $var 的引用,为后者附加“&”符号。

$var = "Hello";
$var1 = &$var;

当我们说 $var1$var 的别名或引用时,这意味着它值的任何更改也会更改 $var 的值,反之亦然。

Example

以下示例演示了 PHP 中“按引用调用”的工作方式 −

<?php
   $var = "Hello";
   $var1 = &$var;

   $var1 = "Hello World";
   echo "var=$var var1=$var1" . PHP_EOL;

   $var = "How are you?";
   echo "var=$var var1=$var1" . PHP_EOL;
?>

它将生成以下 output

var=Hello World var1=Hello World
var=How are you? var1=How are you?

Calling a PHP Function by Reference

要按引用调用函数,你需要声明由“&”符号作为前缀的名称形式参数。

function callref(&$arg1, &$arg2) {
   Statements;
}

对函数的调用就像“按值调用”方法一样。

callref($x, $y);

当调用函数时, $arg1 成为 $x 的引用, $arg2 成为 $y 的引用。

如果在函数体内部, $arg1$arg2 (或两者)的值改变,它还会导致 $x$y 的值改变。

Example

让我们来看看以下示例 −

<?php
   function  change_name(&$nm) {
      echo "Initially the name is $nm" . PHP_EOL;
      $nm = $nm."_new";
      echo "This function changes the name to $nm" . PHP_EOL;
   }

   $name = "John";
   echo "My name is $name" . PHP_EOL;
   change_name($name);
   echo "My name now is $name" . PHP_EOL;
?>

变量 $name 传递给函数 change_name() 。引用变量 &$nm 成为它的引用变量。 $nm 的任何更改都会反映在函数外的 $name 中。

它将生成以下 output

My name is John
Initially the name is John
This function changes the name to John_new
My name now is John_new

Swapping Two Variables

在以下 PHP 代码中,我们按值传递参数来调用函数。该函数尝试交换它们的值。

在函数内部,它们的值发生变化,但这不反映在函数执行后的实际参数中。

当使用引用方式传递参数来调用相同函数时,交换效果也会反映在实际参数中。

<?php
   function  swap_value($a, $b) {
      echo "Initial values a = $a b = $b \n";
      $c = $a; $a = $b; $b = $c;
      echo "Swapped values a = $a b = $b \n";
   }

   $x = 10; $y =20;
   echo "Actual arguments x = $x y = $y \n\n";

   swap_value($x, $y);
   echo "Actual arguments do not change after the function: \n";
   echo "x = $x y = $y \n\n";

   function  swap_ref(&$a, &$b) {
      echo "Initial values a = $a b = $b \n";
      $c = $a; $a = $b; $b = $c;
      echo "Swapped values a = $a b = $b \n";
   }

   swap_ref($x, $y);
   echo "Actual arguments get changed after the function: \n";
   echo "x = $x y = $y";
?>

它将生成以下 output

Actual arguments x = 10 y = 20

Initial values a = 10 b = 20
Swapped values a = 20 b = 10
Actual arguments do not change after the function:
x = 10 y = 20

Initial values a = 10 b = 20
Swapped values a = 20 b = 10
Actual arguments get changed after the function:
x = 20 y = 10

Return by Reference

除了 PHP 中的函数能按引用接受参数,它还能返回引用。要定义返回引用的函数,请在函数名称前添加“&”符号。

Example

下面的代码显示了返回引用的函数示例。它返回 $x ,这是 myfunction() 内部的 local 静态变量。由于在其前添加了“&”符号, $a (存储返回值的变量)成为 &x 的引用。因此,对 $a 中的任何更改也会更改 $x 的值。

<?php
   function &myfunction(){
      static $x=10;
      echo "x Inside function: $x \n";
      return $x;
   }

   $a=&myfunction();
   echo "Returned by Reference: $a \n";
   $a=$a+10;
   $a=&myfunction();
?>

它将生成以下 output

x Inside function: 10
Returned by Reference: 10
x Inside function: 20

PHP - Default Arguments

类似于支持命令式编程的大多数语言,PHP 中的函数可以有一个或多个具有默认值的参数。因此,可以调用这样的函数而无需向其传递任何值。如果没有任何要传递的值,函数会获取其默认值进行处理。如果函数调用确实提供了值,则默认值将被覆盖。

function fun($arg1 = val1, $arg2 = val2) {
   Statements;
}

可以采用不同方式调用这样的函数 −

fun();			# Function will use defaults for both arguments
fun($x);		# Function passes $x to arg1 and uses default for arg2
fun($x, $y);	# Both arguments use the values passed

Example 1

在此,我们定义一个名为 greeting() 的函数,具有两个参数,两个参数都有 string 作为其默认值。我们通过传递一个字符串、两个字符串和无任何参数来调用它。

<?php
   function  greeting($arg1="Hello", $arg2="world") {
      echo $arg1 . " ". $arg2 . PHP_EOL;
   }

   greeting();
   greeting("Thank you");
   greeting("Welcome", "back");
   greeting("PHP");
?>

它将生成以下 output

Hello world
Thank you world
Welcome back
PHP world

Example 2

你可以定义一个仅具部分参数默认值且必须向其他参数传递值的函数。

<?php
   function  greeting($arg1, $arg2="World") {
      echo $arg1 . " ". $arg2 . PHP_EOL;
   }

   # greeting(); ## This will raise ArgumentCountError
   greeting("Thank you");
   greeting("Welcome", "back");
?>

它将生成以下 output

Thank you World
Welcome back

第一个调用(无参数)引发 ArgumentCountError ,因为你必须为第一个参数传递值。如果仅传递一个值,则它将被列表中的第一个参数使用。

不过,如果你在无默认值的参数之前使用 default 声明参数,则只有在同时为两个参数传递值的情况下才能调用这样的函数。无法出现第一个参数使用默认值、第二个参数使用传递值的情况。

greeting() 函数现在具有默认 $arg1 和无默认 $arg2 值。

function  greeting($arg1="Hello", $arg2) {
   echo $arg1 . " ". $arg2 . PHP_EOL;
}

如果你传递一个字符串“PHP”−

greeting("PHP");

意图在于将结果打印为“Hello PHP”,则会显示以下错误消息。

PHP Fatal error: Uncaught ArgumentCountError: Too few arguments to function
greeting(), 1 passed in hello.php on line 10 and exactly 2 expected

Example 3

让我们定义函数 percent() 来计算三门科目的成绩百分比。

假设每门科目的成绩为 100 分,则函数定义中的 $total 参数的默认值为 300。

<?php
   function  percent($p, $c, $m, $ttl=300) {
      $per = ($p+$c+$m)*100/$ttl;
      echo "Marks obtained: \n";
      echo "Physics = $p Chemistry = $c Maths = $m \n";
      echo "Percentage = $per \n";
   }
   percent(50, 60, 70);
?>

它将生成以下 output

Marks obtained:
Physics = 50 Chemistry = 60 Maths = 70
Percentage = 60

不过,如果每门科目的最高分数为 50,则你必须向此函数传递第四个值,否则将根据 300 而不是 150 计算百分比。

<?php
   function  percent($p, $c, $m, $ttl=300) {
      $per = ($p+$c+$m)*100/$ttl;
      echo "Marks obtained: \n";
      echo "Physics = $p Chemistry = $c Maths = $m \n";
      echo "Percentage = $per \n";
   }
   percent(30, 35, 40, 150);
?>

它将生成以下 output

Marks obtained:
Physics = 30 Chemistry = 35 Maths = 40
Percentage = 70

PHP - Named Arguments

PHP 的 8.0 版本引入了命名参数功能。它是对调用函数时传递位置参数现有机制的扩展。

默认情况下,传递的参数值会复制到相同位置上的对应形式参数。PHP 中的此命名参数功能使得可以根据参数名称传递值,而不是根据位置传递。

如果我们定义了一个函数,如下所示 −

function myfunction($x, $y) {
   statement1;
   statement2;
   . . .
}

并且它被调用为 −

myfunction(10, 20);

在此情况下,这些值按声明顺序传递给变量“x”和“y”。也就是说,第一个值传递给第一个参数,第二个值传递给第二个参数,以此类推。变量“x”和“y”是位置自变量。

要通过已命名自变量传递值,请指定要将参数传递给其值的变量名。参数的名称是形式参数的名称,但没有“$”符号。要传递的值放在冒号“:”符号的前面。

myfunction(x:10, y:20);

Example

这是一段展示了如何在 PHP 中使用 named arguments 的代码 −

<?php
   function  myfunction($x, $y) {
      echo "x = $x  y = $y";
   }

   myfunction(x:10, y:20);
?>

它将生成以下 output

x = 10  y = 20

通过使用 named arguments ,可以按照任何顺序传递值,并且不一定要与参数在函数定义中声明的顺序相同。我们可以按如下所示调用 myfunction() ,它将生成相同的结果。

myfunction(y:20, x:10);

借助此特性,自变量将独立于顺序并且可以自文档化。它还可以跳过带有默认值的自变量。

Combining Named Arguments with Positional Arguments

可以将已命名自变量与位置自变量结合使用,条件是已命名自变量必须位于位置自变量之后。

Example

<?php
   function  myfunction($x, $y, $z) {
      echo "x = $x  y = $y  z = $z";
   }
   myfunction(10, z:20, y:30);
?>

它将生成以下 output

x = 10  y = 30  z = 20

但是,如果你尝试将 $z 作为位置自变量处理,

myfunction(x:10, y:20, 30);

在此情况下,PHP 将遇到以下 error

PHP Fatal error:  Cannot use positional argument after
named argument in hello.php on line 7

Passing Named Arguments from an Array

PHP 8.1.0 还引入了另一项特性,该特性允许在取消参数打包后使用已命名自变量。可以使用数组中的“…​”(三个点),而不是单独向每个参数提供值,将数组中的值解包到对应的参数中。

Example

<?php
   function  myfunction($x, $y, $z=30) {
      echo "x = $x  y = $y  z = $z";
   }
   myfunction(...[10, 20], z:30);
?>

它将生成以下 output

x = 10  y = 20  z = 30

请注意,多次传递同一个参数将导致异常,如下所示 −

myfunction(x:10, z:20, x:20);

Error

PHP Fatal error:  Uncaught Error: Named parameter $x
overwrites previous argument in hello.php:7

PHP - Variable Arguments

在 PHP 中,可以编写一个能够接受具有可变数量元素的自变量列表的函数。要声明可变自变量列表,应在自变量名称前加上“…​”(三个点)符号。所传递的值将收集到一个数组中,该数组名称是自变量的名称。

function myfunction(...$arg) {
   Statement1;
   Statement2;
}

要调用这样的函数,请在圆括号中添加任意数量用逗号分隔的值。

myfunction(v1, v2, v3, . . . , vn);

在函数中声明的形式自变量是传递的所有值的一个数组。我们可以使用任何适当的内置数组函数来执行此过程。

Example

在以下示例中,用户定义的函数 myfunction() 能够接收可变数量的值并找到它们的平均值。

<?php
   function  myfunction(...$numbers) {
      $avg = array_sum($numbers)/count($numbers);
      return $avg;
   }
   $avg = myfunction(5, 12, 9, 23, 8);
   echo "average = $avg";
?>

它将生成以下 output

average = 11.4

尝试更改所传递数组的大小,并再次运行该程序。

可以在函数里面使用 foreach 循环来遍历数组。该函数可以在可变长度的自变量之前具有任何位置自变量。在所接收的值中,位置自变量将首先填充,而其他值将复制到数组中。

Example

<?php
   function myfunction($x, ...$numbers) {
      echo "First number: $x" . PHP_EOL;
      echo "Remaining numbers: ";
      foreach ($numbers as $n) {
         echo "$n  ";
      }
   }
   myfunction(5, 12, 9, 23, 8, 41);
?>

它将生成以下 output

First number: 5
Remaining numbers: 12  9  23  8  41

Variadic Functions

即使没有“…​”语法,也可以处理传递给函数的可变数量的自变量。PHP 具有内置的函数,例如 func_num_args()、func_get_arg() 和 func_get_args(),这些函数可以用类似的结果来使用。

  1. func_num_args() − 返回传递给函数的自变量的数量。

  2. func_get_arg() - 从参数列表返回一个项目

  3. func_get_args() - 返回一个包含函数参数列表的数组

Example

上面可变参数的示例可以用以下函数重写:

<?php
   function myfunction() {
      $sum = 0;
      foreach (func_get_args() as $n) {
         $sum += $n;
      }
      return $sum;
   }
   echo myfunction(5, 12, 9, 23, 8, 41);
?>

它将生成以下 output

98

Example

该程序输出传递给函数的所有数字:

<?php
   function myfunction() {
      $len = func_num_args();
      echo "Numbers : ";
      $i=0;
      for ($i=0; $i<$len; $i++)
      echo func_get_arg($i) . " ";
   }
   myfunction(5, 12, 9, 23, 8, 41);
?>

它将生成以下 output

Numbers : 5 12 9 23 8 41

PHP - Returning Values

PHP 函数的函数体中可以有一个可选的 return 语句作为其最后一个语句。PHP 中的大多数内置函数都返回一个特定值。例如,strlen() 函数返回字符串的长度。类似地,用户定义的函数也可以返回某个值。

函数是一个独立、完整且可重复使用的语句块。调用时,它执行某个任务,并将程序控制权送回其被调用的位置,即使没有使用 return 语句也是如此。return 语句允许它将一个值与控制权一起带回调用环境。

function foo($arg_1, $arg_2) {
   statements;
   return $retval;
}

函数可以返回任何类型的数据,包括标量变量、数组和对象。没有前面表达式的 return 关键字返回 null,并且等同于函数根本没有返回值。

函数返回的值可以存储在变量中,可以放入表达式中,或者如果出现在 print 或 echo 中,则显示在输出中。

$res = foo($x, $y);

它允许在程序中进一步使用函数的返回值。

Example

让我们修改前一章中的 addition() 函数,以包含一个 return 语句来返回加法结果。

<?php
   function addition($first, $second) {
      $result = $first+$second;
      return $result;
   }

   $x=10;
   $y=20;
   $z = addition($x, $y);
   echo "First number: $x Second number: $y Addition: $z". PHP_EOL;
?>

它将生成以下 output

First number: 10 Second number: 20 Addition: 30

PHP 中的函数可以具有任意数量的参数,但只能返回一个值。该函数在首次遇到 return 语句时就返回调用环境,放弃函数体中其余的语句。

Example

如果您尝试在 return 语句中包含多个值,则会遇到以下 PHP 解析错误:

<?php
   function raiseto($x) {
      $sqr =  $x**2;
      $cub =  $x**3;
      return $sqr, $cub;
   }
   $a = 5;
   $val = raiseto($a);
?>

它将生成以下 output

PHP Parse error: syntax error, unexpected token ",", expecting ";"

Conditional Return

可以在不同的条件语句下执行多个 return 语句。

Example

在以下程序中, raiseto() 函数返回索引参数(分别是 2 或 3)的一个数的平方或立方。

<?php
   function raiseto($x, $i) {
      if ($i == 2) {
         return $x**2;
      } elseif ($i==3) {
         return $x**3;
      }
   }
   $a = 5;
   $b = 2;
   $val = raiseto($a, $b);
   echo "$a raised to $b = $val" . PHP_EOL;

   $x = 7;
   $y = 3;
   echo "$x raised to $y = " . raiseto($x, $y) . PHP_EOL;
?>

它将生成以下 output

5 raised to 2 = 25
7 raised to 3 = 343

Return Multiple Values as Array

PHP 中的函数只能返回一个值。不过,这个一个值可以是多个值构成的数组。我们可以利用此功能一次返回一个数的平方和立方。

Example

请看以下示例:

<?php
   function raiseto($x){
      $sqr =  $x**2;
      $cub =  $x**3;
      $ret = ["sqr" => $sqr, "cub" => $cub];
      return $ret;
   }
   $a = 5;
   $val = raiseto($a);
   echo "Square of $a: " . $val["sqr"] . PHP_EOL;
   echo "Cube of $a: " . $val["cub"] . PHP_EOL;
?>

它将生成以下 output

Square of 5: 25
Cube of 5: 125

PHP - Passing Functions

在 PHP 中,除了标量类型、数组和对象以外,您还可以将函数作为其参数之一传递给一个函数。如果定义一个函数来接受另一个函数作为参数,那么传递的函数将在该函数内部调用。PHP 的标准库具有某些此类型的内置函数,其中要传递的参数之一是一个函数,它可能是另一个内置函数,甚至是一个用户定义的函数。

array_map

array_map() 是其中一个内置函数。此函数的第一个参数是一个回调函数。其他的参数可能是一个或多个数组。回调函数应用于数组的所有元素。

array_map(?callable $callback, array $array, array ...$arrays): array

array_map() 函数返回一个数组。它包含将回调函数应用于传递为其他参数的数组的相应元素后得到的结果。

Example

在以下示例中,我们有一个 square() 函数,用于计算传递给它的数字的平方。该函数又作为 array_map() 函数的参数使用,以及另一个数字数组。每个数字都先后传递给 square() 函数。结果数组是平方的列表。

<?php
   function square($number) {
      return $number * $number;
   }

   $arr = [1, 2, 3, 4, 5];
   $squares = array_map('square', $arr);
   var_dump($squares);
?>

它将生成以下 output

array(5) {
   [0]=>
   int(1)
   [1]=>
   int(4)
   [2]=>
   int(9)
   [3]=>
   int(16)
   [4]=>
   int(25)
}

call_user_func

将函数传递给另一个函数的另一示例是 call_user_func()。顾名思义,它调用另一个用户定义的回调函数,并将其他参数传递到回调。

call_user_func(callable $callback, mixed ...$args): mixed

Example

在下面的示例中,square() 函数被反复调用,传递数组中的每个数字。

<?php
   function square($number) {
      return $number * $number;
   }
   $arr = [1, 2, 3, 4, 5];
   foreach($arr as $a) {
      echo "square of $a:" . call_user_func("square", $a). PHP_EOL;
   }
?>

它将生成以下 output

square of 1:1
square of 2:4
square of 3:9
square of 4:16
square of 5:25

usort

作为函数传递的另一个示例,我们来看一下 usort() 函数。

usort(array &$array, callable $callback): true

第一个参数是一个数组。数组将按照作为第二个参数的回调函数进行排序。

回调参数是一个比较函数,如果第一个参数被认为分别小于、等于或大于第二个参数,则该函数必须返回一个小于零、等于零或大于零的整数。

Example

这里有一个示例。我们首先有一个 mysort() 函数。如果第一个数字小于、等于或大于第二个数字,它将比较两个数字并返回“-1”、“0”或“1”。

usort() 的第一个参数是 mysort() 函数,第二个参数是一个数组。首先,前两个数字将传递给 mysort()。如果它返回 1,那么它们将被交换。接下来,第二个和第三个数字被传递,如果比较返回 1,则它们将被交换。相同的过程重复进行,以便按升序排列数组元素。

<?php
   function mysort($a, $b) {
      if ($a == $b) {
         return 0;
      }
      return ($a < $b) ? -1 : 1;
   }

   $a = array(3, 2, 5, 6, 1);

   usort($a, "mysort");

   foreach ($a as $key => $value) {
      echo "$key: $value\n";
   }
?>

它将生成以下 output

0: 1
1: 2
2: 3
3: 5
4: 6

Pass Callback to User-defined Function

除了上述的内置函数外,你还可以定义你自己接受其中一个参数作为另一个函数的函数。

在下面的示例中,我们有两个函数, square()cube() ,它们返回给定数字的平方和平方根。

接下来,是 myfunction() ,它的第一个参数用作一个可变函数,第二个参数传递给 myfunction()

因此,myfunction() 在内部调用 square() 或 cube() 来返回给定数字的平方或立方。

Example

<?php
   function myfunction($function, $number) {
      $result = $function($number);
      return $result;
   }

   function cube($number) {
      return $number ** 2;
   }

   function square($number) {
      return $number ** 3;
   }

   $x = 5;

   $cube = myfunction('cube', $x);
   $square = myfunction('square', $x);

   echo "Square of $x = $square" . PHP_EOL;
   echo "Cube of $x = $cube" . PHP_EOL;
?>

它将生成以下 output

Square of 5 = 125
Cube of 5 = 25

PHP - Recursive Functions

递归函数是一种在满足特定条件之前不断调用自身的函数。在 PHP 中,可以定义递归函数。

  1. 当某个问题通过其自身来定义时,就使用递归。

  2. 有时,使用迭代方法解决问题可能会很乏味。递归方法为看似复杂的问题提供了非常简洁的解决方案。

  3. PHP 中的递归与 C 和 C++ 中的递归非常相似。

  4. 在遍历嵌套数据结构,以及排序算法或搜索算法中,特别使用递归函数。

  5. 二叉树遍历、堆排序和寻找最短路径是使用递归的一些情况。

Calculation of Factorial using Recursion

递归最流行的例子是阶乘的计算。数学上阶乘定义为 -

n! = n × (n-1)!

可以看出,我们使用阶乘本身来定义阶乘。因此,这是一个编写递归函数的合适情况。

让我们展开上述定义,计算 5 的阶乘值

5! = 5 × 4!
      5 × 4 × 3!
      5 × 4 × 3 × 2!
      5 × 4 × 3 ×  2 × 1!
      5 × 4 × 3 ×  2 × 1
   = 120

虽然我们可以使用循环执行此计算,但其递归函数涉及通过递减数字依次调用它,直到数字变为 1。

Example

以下为计算阶乘的递归函数。

<?php
   function factorial ($n) {
      if ($n == 1) {
         echo $n . PHP_EOL;
         return 1;
      } else {
         echo "$n * ";
         return $n*factorial($n-1);
      }
   }
   echo "Factorial of 5 = " . factorial(5);
?>

它将生成以下 output

5 * 4 * 3 * 2 * 1
Factorial of 5 = 120

Binary Search using Recursion

让我们看另一个理解递归工作原理的示例。眼前的问题是检查给定数字是否存在于列表中。

虽然我们可以使用 for 循环并比较每个数字,对列表中的特定数字执行顺序查找,但顺序查找效率不高,尤其是在列表过大的情况下。在此,我们可以使用二分查找算法检查索引“high”是否大于索引“low”。根据“mid”变量中存在的值,再次调用该函数以搜索该元素。

我们有一个数字列表,按升序排列。然后,找到列表的中点,并将检查限制在中点的左侧或右侧,具体取决于所需的数字是否小于或大于中点的数字。

下图显示了二分查找的工作原理 -

php recursive functions

Example

以下代码实现了递归二分查找技术 -

<?php
   function bsearch($my_list, $low, $high, $elem) {
      if ($high >= $low) {
         $mid = intval(($high + $low)/2);

         if ($my_list[$mid] == $elem)
         return $mid;

         elseif ($my_list[$mid] > $elem)
         return bsearch($my_list, $low, $mid - 1, $elem);

         else
         return bsearch($my_list, $mid + 1, $high, $elem);
      }
      else
      return -1;
   }

   $list = [5,12,23, 45, 49, 67, 71, 77, 82];
   $num = 67;
   $result = bsearch($list,0,count($list)-1, $num);
   if ($result != -1)
   echo " Number $num found at index " . $result;
   else
   echo "Element not found!";
?>

它将生成以下 output

Number 67 found at index 5

你可以查看给定列表中存在的不同数字的输出,以及列表中不存在的数字的输出。

PHP - Type Hints

PHP 支持在函数定义中的变量、类中属性或实例变量的声明时使用“类型提示”。PHP 被广泛认为是一种弱类型语言。在 PHP 中,在给变量赋值之前无需声明其类型。

PHP 解析器尽可能地尝试将变量转换为兼容类型。因此,如果传递的值之一是数字的字符串表示,而第二个是数字变量,PHP 会将字符串变量转换为数字以执行加法运算。

Example

请看以下示例:

<?php
   function addition($x, $y) {
      echo "First number: $x Second number: $y Addition: " . $x+$y;
   }
   $x="10";
   $y=20;
   addition($x, $y);
?>

它将生成以下 output

First number: 10 Second number: 20 Addition: 30

但是,如果上述示例中的 $x 是不包含有效数字表现形式的字符串,则会出现错误。

<?php
   function addition($x, $y) {
      echo "First number: $x Second number: $y Addition: " . $x+$y;
   }
   $x="Hello";
   $y=20;
   addition($x, $y);
?>

它将生成以下 output

PHP Fatal error:  Uncaught TypeError: Unsupported operand types: string + int in hello.php:5

类型提示从 PHP 5.6 版本起受支持。这意味着您可以明确说明代码中声明变量的预期类型。PHP 允许您对函数参数、返回值和类属性进行类型提示。有了它,就可以编写更健壮的代码。

让我们在上述程序的加法函数中结合类型提示 −

function addition($x, $y) {
   echo "First number: $x Second number: $y Addition: " . $x+$y;
}

类型提示特性主要由 IDE(集成开发环境)用于提示用户在函数声明中使用的参数的预期类型。

下图显示了 VS 代码编辑器在您键入时弹出的函数原型 −

php type hints 1

如果光标悬停在函数名称上,则会显示参数和返回值的类型声明 −

php type hints 2

请注意,仅在变量声明中使用数据类型并不能防止引发不匹配的类型异常,因为 PHP 是一种动态类型语言。换句话说,$x="10" 和 $y=20 仍然会计算结果为 30,而 $x="Hello" 会使解析器引发错误。

strict_types

PHP 可以强制执行更严格的类型转换规则,这样就不会将“10”隐式转换为 10。这可以通过在 declare() 语句中将 strict_types 指令设置为 1 来强制执行。declare() 语句必须是 PHP 代码中的第一个语句,紧跟在“ <?php ”标签后面。

Example

<?php
   declare (strict_types=1);
   function addition(int $x, int $y) {
      echo "First number: $x Second number: $y Addition: " . $x+$y;
   }
   $x=10;
   $y=20;
   addition($x, $y);
?>

它将生成以下 output

First number: 10 Second number: 20 Addition: 30

现在,如果将 $x 设置为“10”,则不会发生隐式转换,从而导致以下错误 −

PHP Fatal error:  Uncaught TypeError: addition(): Argument #1 ($x) must be of type int, string given

VS Code IDE 也指示出相同的影响错误 −

php type hints 3

从 PHP 7 开始,类型提示支持已扩展到函数返回值,以防止意外的返回值。您可以通过在冒号 (:) 符号后添加预期类型,在参数列表后添加类型提示返回值。

Example

让我们为上述加法函数的返回值添加一个类型提示 −

<?php
   declare (strict_types=1);
   function addition(int $x, int $y) : int {
      return $x+$y;
   }

   $x=10;
   $y=20;

   $result = addition($x, $y);
   echo "First number: $x Second number: $y Addition: " . $result;
?>

同样,如果发现该函数返回的不是整数,则 IDE 会在您运行之前指示原因。

php type hints 4

Union Types

PHP 在其 8.0 版本中引入了联合类型。你现在可以为单个声明指定多个类型。这些数据类型由“ | ”符号分隔。

Example

在下面的 addition() 函数定义中, $x$y 参数可以是 intfloat 类型。

<?php
   declare (strict_types=1);
   function addition(int|float $x, int|float $y) : float {
      return $x+$y;
   }
   $x=10.55;
   $y=20;

   $result = addition($x, $y);
   echo "First number: $x Second number: $y Addition: " . $result;
?>

Type-hinting in Class

在 PHP 7.4 版本中,您可以从版本 7.4 开始在声明类属性和方法时使用类型提示。

Example

在以下示例中,类构造函数使用类型提示 −

<?php
   declare (strict_types=1);
   class Student {
      public $name;
      public $age;
      public function __construct(string $name, int $age) {
         $this->name = $name;
         $this->age = $age;
      }

      public function dispStudent() {
         echo "Name: $this->name Age: $this->age";
      }
   }
   $s1 = new Student("Amar", 21);
   $s1->dispStudent();
?>

也可以在声明类属性时使用类型提示。

class Student {
   public string $name;
   public int $age;

   public function __construct($name, $age) {
      $this->name = $name;
      $this->age = $age;
   }

   public function dispStudent() {
      echo "Name: $this->name Age: $this->age";
   }
}

程序开发中最常见的错误是 type errors 。类型提示功能有助于减少它们。

PHP - Variable Scope

在 PHP 中,变量的作用域是其被定义并可访问的上下文的程度。通常,任何没有循环或函数等的简单顺序 PHP 脚本都只有一个作用域。在 "<?php" 和 "?>" 标记内声明的任何变量都从其定义的点起对整个程序都可用。

根据作用域,PHP 变量可以是以下三种类型中的任何一种 −

主脚本中的变量也可以通过 includerequire 语句引入任何其他脚本。

Example

在下面的示例中,“test.php”脚本被包含在主脚本中。

main.php

<?php
   $var=100;
   include "test.php";
?>

test.php

<?php
   echo "value of \$var in test.php : " . $var;
?>

当主脚本执行时,它将显示以下 output

value of $var in test.php : 100

但是,当脚本具有用户定义的函数时,所有内部变量都有一个局部作用域。因此,无法在外部访问在一个函数内定义的变量。在函数外部(上方)定义的变量具有全局作用域。

Example

请看以下示例:

<?php
   $var=100;   // global variable
   function myfunction() {
      $var1="Hello"; 	// local variable
      echo "var=$var  var1=$var1" . PHP_EOL;
   }
   myfunction();
   echo "var=$var  var1=$var1" . PHP_EOL;
?>

它将生成以下 output

var=  var1=Hello
var=100  var1=

PHP Warning:  Undefined variable $var in /home/cg/root/64504/main.php on line 5
PHP Warning:  Undefined variable $var1 in /home/cg/root/64504/main.php on line 8

Note 全局变量不会自动在函数的局部作用域内可用。此外,无法在外部访问函数内的变量。

The "global" Keyword

要使全局变量能够在函数的局部作用域内访问,应该通过使用“ global ”关键字显式地完成。

Example

PHP 脚本如下所示 −

<?php
   $a=10;
   $b=20;
   echo "Global variables before function call: a = $a b = $b" . PHP_EOL;
   function myfunction() {
      global $a, $b;
      $c=($a+$b)/2;
      echo "inside function a = $a b = $b c = $c" . PHP_EOL;
      $a=$a+10;
   }
   myfunction();
   echo "Variables after function call: a = $a b = $b c = $c";
?>

它将生成以下 output

Global variables before function call: a = 10 b = 20
inside function a = 10 b = 20 c = 15
Variables after function call: a = 20 b = 20 c =
PHP Warning:  Undefined variable $c in /home/cg/root/48499/main.php on line 12

现在可以在函数内处理全局变量。此外,对函数内全局变量所做的任何更改都将在全局名称空间中反映出来。

$GLOBALS Array

PHP 将所有全局变量存储在一个称为 $GLOBALS 的关联数组中。变量的名称和值组成键值对。

Example

在以下 PHP 脚本中,$GLOBALS 数组用于访问全局变量 −

<?php
   $a=10;
   $b=20;
   echo "Global variables before function call: a = $a b = $b" . PHP_EOL;

   function myfunction() {
      $c=($GLOBALS['a']+$GLOBALS['b'])/2;
      echo "c = $c" . PHP_EOL;
      $GLOBALS['a']+=10;
   }
   myfunction();
   echo "Variables after function call: a = $a b = $b c = $c";
?>

它将生成以下 output

Global variables before function call: a = 10 b = 20
c = 15
PHP Warning:  Undefined variable $c in C:\xampp\htdocs\hello.php on line 12
Variables after function call: a = 20 b = 20 c =

Static Variable

使用 static 关键字定义的变量不会在每次调用函数时初始化。此外,它保留其上一次调用的值。

Example

请看以下示例:

<?php
   function myfunction() {
      static $x=0;
      echo "x = $x" . PHP_EOL;
      $x++;
   }
   for ($i=1; $i<=3; $i++) {
      echo "call to function :$i : ";
      myfunction();
   }
?>

它将生成以下 output

call to function :1 : x = 0
call to function :2 : x = 1
call to function :3 : x = 2

PHP - Strict Typing

PHP 通常被认为是一种弱类型语言。在 PHP 中,不需要在将值分配给变量之前声明变量的类型。PHP 解析器会尽力将变量转换为兼容的类型。

例如,如果传递的值之一是数字的字符串表示,而第二个是数字变量,PHP 会将字符串变量转换为数字来执行加法运算。

Example

请看以下示例:

<?php
   function addition($x, $y) {
      echo "First number: $x Second number: $y Addition: " . $x+$y;
   }

   $x="10";
   $y=20;
   addition($x, $y);
?>

它将生成以下 output

First number: 10 Second number: 20 Addition: 30

但是,如果上述示例中的 $x 是不包含有效数字表示的字符串,则会出现错误。

<?php
   function addition($x, $y) {
      echo "First number: $x Second number: $y Addition: " . $x+$y;
   }
   $x="Hello";
   $y=20;
   addition($x, $y);
?>

它将生成以下 output

PHP Fatal error:  Uncaught TypeError: Unsupported operand
types: string + int in hello.php:5

Type Hints

类型提示从 PHP 5.6 版本起受支持。这意味着您可以明确说明代码中声明变量的预期类型。PHP 允许您对函数参数、返回值和类属性进行类型提示。有了它,就可以编写更健壮的代码。

让我们在上述程序的加法函数中结合类型提示 −

function addition(int $x, int $y) {
   echo "First number: $x Second number: $y Addition: " . $x+$y;
}

请注意,仅仅在变量声明中使用数据类型并不能防止出现不匹配的类型异常,因为 PHP 是一种动态类型语言。换而言之,$x=”10”和$y=20 仍然会导致加法结果为 30,而$x=”Hello”会让解析器发出错误。

Example

<?php
   function addition($x, $y) {
      echo "First number: $x \n";
      echo "Second number: $y \n";
      echo "Addition: " . $x+$y . "\n\n";
   }

   $x=10;
   $y=20;
   addition($x, $y);

   $x="10";
   $y=20;
   addition($x, $y);

   $x="Hello";
   $y=20;
   addition($x, $y);
?>

它将生成以下 output

First number: 10
Second number: 20
Addition: 30

First number: 10
Second number: 20
Addition: 30

First number: Hello
Second number: 20
PHP Fatal error:  Uncaught TypeError: Unsupported operand
types: string + int in hello.php:5

strict_types

可以使 PHP 强制实施更严格的类型转换规则,这样就不会将“10”隐式转换为 10。这可以通过在 declare() 语句中将 strict_types 指令设置为 1 来强制执行。

declare() 语句必须是 PHP 代码中的第一条语句,紧挨在“<?php”标签后面。

Example

请看以下示例:

<?php
   declare (strict_types=1);
   function addition(int $x, int $y) {
      echo "First number: $x Second number: $y Addition: " . $x+$y;
   }

   $x=10;
   $y=20;
   addition($x, $y);
?>

它将生成以下 output

First number: 10 Second number: 20 Addition: 30

现在,如果将 $x 设置为“10”,则不会执行隐式强制转换,导致以下 error

PHP Fatal error:  Uncaught TypeError: addition(): Argument #1
($x) must be of type int, string given

从 PHP 7 开始,已对函数返回类型提示支持进行了扩展以防止意外返回值。您可以在参数列表后添加带冒号 (:) 符号前缀的目标类型,从而对返回值进行类型提示。

Example

我们为以下 division() 函数的返回值添加类型提示。

<?php
   declare (strict_types=1);
   function division(int $x, int $y) : int {
      return $x/$y;
   }

   $x=10;
   $y=20;
   $result = division($x, $y);
   echo "First number: $x Second number: $y Addition: " . $result;
?>

因为该函数返回 0.5,而这并非 int 类型(也就是函数返回值所使用的类型提示),所以会显示以下 error

Fatal error: Uncaught TypeError: division(): Return value must be
of type int, float returned in hello.php:5

PHP - Anonymous Functions

What are Anonymous Functions?

PHP 允许定义匿名函数。通常,当我们在 PHP 中定义一个函数时,我们会为其提供一个名称,该名称用于在需要时调用该函数。相比之下, anonymous function 是一个在定义时没有任何指定名称的函数。此类函数也称为 closurelambda function

有时,您可能只想使用一次函数。匿名函数最常见的一个用法是创建一个 inline callback function

匿名函数是使用 Closure 类实现的。闭包是一个匿名函数,它围绕其定义的环境进行闭合。

用于定义匿名函数的 syntax 如下 −

$var=function ($arg1, $arg2) { return $val; };

请注意, function 关键字与左括号之间没有函数名,并且函数定义后有一个分号。这意味着匿名函数定义是表达式。当分配给变量时,可以使用变量名稍后调用匿名函数。

Example

请看以下示例:

<?php
   $add = function ($a, $b) {
      return "a:$a b:$b addition: " . $a+$b;
   };
   echo $add(5,10);
?>

它将生成以下 output

a:5 b:10 addition: 15

Anonymous Function as a Callback

匿名函数通常用作回调。回调函数用作另一个函数的参数之一。匿名函数即时执行,其返回值成为父函数的参数,父函数可以是内置函数,也可以是用户定义的函数。

Example

在此示例中,我们在 usort() 函数中使用匿名函数,这是一个使用用户定义的比较函数按值对数组进行排序的内置函数。

<?php
   $arr = [10,3,70,21,54];
   usort ($arr, function ($x , $y) {
      return $x > $y;
   });
   foreach ($arr as $x){
      echo $x . "\n";
   }
?>

它将生成以下 output

3
10
21
54
70

Example

以下示例使用匿名函数计算数组中连续数字之后的累积和。在此,我们使用 array_walk() 函数。此函数将用户定义的函数应用于数组中的每个元素。

<?php
   $arr=array(1,2,3,4,5);
   array_walk($arr, function($n){
      $s=0;
      for($i=1;$i<=$n;$i++){
         $s+=$i;
      }
      echo "Number: $n Sum: $s". PHP_EOL;
   });
?>

它将生成以下 output

Number: 1 Sum: 1
Number: 2 Sum: 3
Number: 3 Sum: 6
Number: 4 Sum: 10
Number: 5 Sum: 15

Anonymous Function as Closure

闭包也是一个匿名函数,可以在 " use " 关键字的帮助下访问其作用域之外的变量。

Example

请看以下示例 −

<?php
   $maxmarks=300;
   $percent=function ($marks) use ($maxmarks) {
      return $marks*100/$maxmarks;
   };
   $m = 250;
   echo "Marks = $m Percentage = ". $percent($m);
?>

它将生成以下 output

Marks = 250 Percentage = 83.333333333333

PHP - Arrow Functions

箭头函数在 PHP 7.4 版本中引入。箭头函数为编写匿名函数提供了更简单、更简洁的语法。在 PHP 7.4 中,引进了关键词 " fn " 来定义箭头函数,取代原先通用的关键词 " function "。

fn (argument_list) => expr
  1. " &#8658; " 符号后面只允许有一个表达式,其值为箭头函数的返回值。

  2. 箭头函数没有显式的 return 语句。

  3. 与匿名函数一样,箭头函数赋值给变量才能被调用。

Example

以下示例展示了如何在 PHP 中使用箭头函数 −

<?php
   $add = fn ($a, $b) => $a + $b;

   $x = 10;
   $y = 20;
   echo " x: $x y: $y Addition: " . $add($x, $y);
?>

它将生成以下 output

x: 10 y: 20 Addition: 30

Using the Arrow Function as a Callback Function

还可以使用箭头函数作为回调函数。回调函数作为其他函数的参数之一来使用。箭头函数会即时执行,而 "⇒" 符号后面的表达式的值会变成父函数的参数,父函数可以是内置函数,也可以是用户定义的函数。

Example

在本例中,我们使用箭头函数在 usort() 函数中,这是一个内置函数,使用用户自定义比较函数按值对数组进行排序。

<?php
   $arr = [10,3,70,21,54];
   usort ($arr, fn ($x , $y) => $x > $y);

   foreach ($arr as $x){
      echo $x . "\n";
   }
?>

它将生成以下 output

3
10
21
54
70

Accessing Variables from the Parent Scope

箭头函数可以自动访问父作用域中的变量。与匿名函数不同,它不需要 " use " 关键词才能作为闭包。当表达式中使用的变量在父函数中定义时,会隐式按值捕获它。

<?php
   $maxmarks=300;
   $percent=fn ($marks) => $marks*100/$maxmarks;

   $m = 250;
   echo "Marks = $m Percentage = ". $percent($m);
?>

它将生成以下 output

Marks = 250 Percentage = 83.333333333333

Example

即使嵌套,箭头函数也可以自动按值捕获变量。

在以下示例中,在另一个箭头函数的表达式中定义了一个箭头函数。

<?php
   $z = 1;
   $fn = fn($x) => fn($y) => $x * $y + $z;
   $x = 5;
   $y = 10;
   echo "x:$x y:$y \n";
   echo "Result of nested arrow functions: " . ($fn($x)($y));
?>

它将生成以下 output

x:5 y:10
Result of nested arrow functions: 51

与匿名函数一样,箭头函数语法允许任意函数签名,包括参数和返回类型、默认值、变参,以及引用传递和返回。

PHP Variable Handling Functions

PHP Variable Handling Functions 是内置的 PHP 库函数,使我们能够以多种方式操作和测试 PHP 变量。

Installation

无需安装即可使用 PHP 变量处理函数;它们是 PHP 内核的一部分,并随标准 PHP 安装一起提供。

Runtime Configuration

此扩展没有在 php.ini 中定义任何配置指令。

PHP Variable Handling Functions

下表列出了与 PHP 变量处理相关的所有函数。此处的版本列表示支持该函数的 PHP 最早版本。

Sr.No

Function & Description

Version

1

boolval() 函数返回已定义变量的布尔值,即返回 TRUE 或 FALSE。

5.5.0

2

debug_zval_dump() 函数用于转储内部 zend 值的字符串表示形式以输出。

4.2.0

3

doubleval() 函数用于返回已定义变量的浮点数。

4, 5, 7, 8

4

empty() 函数用于检查已定义变量的值是否为空。

4, 5, 7, 8

5

floatval() 函数用于返回已定义变量的浮点数。

4.2.0, 5, 7, 8

6

get_defined_vars() 函数用于将所有已定义变量作为数组返回。

4.0.4, 5, 7, 8

7

get_resource_id() 函数用于返回给定资源的整数标识符。

8

8

get_resource_type() 函数返回已定义变量的资源类型。

4.0.2, 5, 7, 8

9

gettype() 函数返回已定义变量的类型。

4, 5, 7, 8

10

intval() 函数返回已定义变量的整数值。

4, 5, 7, 8

11

is_array() 函数用于检查已定义变量是否是数组。

4, 5, 7, 8

12

is_bool() 函数用于检查已定义变量是否是布尔值,即返回真或假值。

4, 5, 7, 8

13

is_callable() 此函数用于检查变量中的数据是否可以被调用为一个函数

4.0.6, 5, 7, 8

14

is_countable() 此函数用于检查变量中的数据是否是可枚举的。

7.3.0, 8

15

is_double() 此函数用于检查已定义变量的类型是否为 float

4, 5, 7, 8

16

is_float() 此函数用于检查已定义变量是否为 float

4, 5, 7, 8

17

is_int() 此函数用于检查已定义变量的类型是否为 integer

4, 5, 7, 8

18

is_integer() 此函数用于检查已定义变量是否为 integer

4, 5, 7, 8

19

is_iterable() 此函数用于检查变量中的数据是否为可迭代值。

7.1.0, 8

20

is_long() 此函数用于检查变量的类型是否为 integer

4, 5, 7, 8

21

is_null() 此函数检查变量是否有 NULL 值。

4.0.4, 5, 7, 8

22

is_numeric() 此函数用于检查已定义变量是否是数字或数字字符串。

4, 5, 7, 8

23

is_object() 此函数用于检查变量是否是一个对象。

4, 5, 7, 8

24

is_real() 此函数用于检查已定义变量的类型是否是 float

4, 5, 7, 8

25

is_resource() 此函数用于检查已定义变量是否为资源。

4, 5, 7, 8

26

is_scalar() 此函数用于检查已定义变量是否为标量。

4.0.5, 5, 7, 8

27

is_string() 此函数用于检查已定义变量的类型是否为 string。

4, 5, 7, 8

28

isset() 此函数用于检查一个变量是否已经声明和设置。

4, 5, 7, 8

29

print_r() 此函数用于将变量的数据表示或打印为可读格式。

4, 5, 7, 8

30

serialize() 此函数用于将变量的数据转换为可存储表示形式,以便将数据存储在文件或内存缓冲区中。

4, 5, 7, 8

31

settype() 此函数用于将变量设置为特定类型。

4, 5, 7, 8

32

strval() 函数用于返回变量的字符串值。

4, 5, 7, 8

33

unserialize() 函数用于反序列化变量的数据。即,此函数返回序列化变量的实际数据。

4, 5, 7, 8

34

unset() 函数用于取消设置变量

4, 5, 7, 8

35

var_dump() 函数用于转储一个或多个变量的信息。该信息包含变量的类型和值。

4, 5, 7, 8

36

var_export() 函数返回有关变量的结构化信息。

4.2.0, 5, 7, 8

PHP - Local Variables

作用域可以定义为变量在其中声明的程序中可用性的范围。PHP 变量可以是四种作用域类型之一−

  1. Local Variables

  2. Global Variables

  3. Static Variables

  4. Function Parameters

Local Variables

在函数中声明的变量被视为局部变量;也就是说,它只能在该函数中引用。该函数之外的任何赋值都将被视为与函数中包含的变量完全不同的变量 -

<?php
   $x = 4;

   function assignx () {
      $x = 0;
      print "\$x inside function is $x. \n";
   }

   assignx();
   print "\$x outside of function is $x.";
?>

这会产生以下结果 −

$x inside function is 0.
$x outside of function is 4.

PHP - Global Variables

在 PHP 中,任何可以在 PHP 脚本中的任何地方访问的变量都称为 global variable 。如果变量在脚本中的所有函数或类之外声明,它将成为全局变量。

虽然全局变量可以在函数外部直接访问,但它们不会自动在函数内部提供。

Example

在下面的脚本中, $name 对于函数 sayhello() 是全局的。

<?php
   $name = "Amar";
   function sayhello() {
      echo "Hello " . $name;
   }
   sayhello();
?>

但是,该变量在该函数内部不可访问。因此,您将收到 error message "未定义变量 $name"。

Hello
PHP Warning: Undefined variable $name in /home/cg/root/93427/main.php on line 5

Example

要在函数内访问,您需要在变量之前使用 "global" 关键字。

<?php
   $name = "Amar";
   function sayhello() {
      GLOBAL $name;
      echo "Hello " . $name;
   }
   sayhello();
?>

它将生成以下 output

Hello Amar

如果某个函数访问全局变量并修改该变量,则修改后的值在函数调用完成后随处可用。

让我们在 sayhello() 函数中更改 $name 的值,并在调用该函数后检查其值。

Example

请查看以下示例:

<?php
   $name = "Amar";
   function sayhello() {
      GLOBAL $name;
      echo "Global variable name: $name" .PHP_EOL;
      $name = "Amarjyot";
      echo "Global variable name changed to: $name" .PHP_EOL;
   }
   sayhello();
   echo "Global variable name after function call: $name" .PHP_EOL;
?>

它将生成以下 output

Global variable name: Amar
Global variable name changed to: Amarjyot
Global variable name after function call: Amarjyot

The $GLOBALS Array

PHP 维护一个名为 $GLOBALS 的关联数组,其中包含在全局作用域中声明的所有变量及其值。$GLOBALS 数组还存储许多称为超全局变量的预定义变量以及用户定义的全局变量。

任何全局变量也可以在任何函数内访问,方法是在访问箭头元素的常规语法中使用它。例如,全局变量 $name 的值由 $GLOBALS["name"] 提供。

Example

在下面的示例中,在 addition() 函数内部访问了两个全局变量 $x 和 $y。

<?php
   $x = 10;
   $y = 20;

   function addition() {
      $z = $GLOBALS['x']+$GLOBALS['y'];
      echo "Addition: $z" .PHP_EOL;
   }
   addition();
?>

它将生成以下 output

Addition: 30

Example

您还可以通过将它添加到 $GLOBALS 数组中将任何局部变量添加到全局作用域。让我们在全局作用域中添加 $z

<?php
   $x = 10;
   $y = 20;
   function addition() {
      $z = $GLOBALS['x']+$GLOBALS['y'];
      $GLOBALS['z'] = $z;
   }
   addition();
   echo "Now z is the global variable. Addition: $z" .PHP_EOL;
?>

它将生成以下 output

Now z is the global variable. Addition: 30

Including One PHP Script in Another

您可以在另一个 PHP 脚本中包含一个 PHP 脚本。包含在脚本中的变量被添加到包含它的 PHP 脚本的全局作用域中。

这是 "a.php" 文件 -

<?php
   include 'b.php';
   function addition() {
      $z = $GLOBALS['x']+$GLOBALS['y'];
      echo "Addition: $z" .PHP_EOL;
   }
   addition();
?>

其中包括有 $x$y 变量的 “b.php”,因此它们变成 “a.php” 脚本中 addition() 函数的全局变量。

<?php
   $x = 10;
   $y = 20;
?>

在实现singleton模式、获取嵌入式系统寄存器以及一个变量被多个函数使用时,通常会使用全局变量。

PHP - Superglobals

PHP 解析器会用很多预定义变量及其全局命名空间填充当前脚本。预定义变量称为 “ PHP superglobals ”。

  1. 任何在任何函数、方法或类外部声明的用户自定义变量也是一个全局变量。然而,要访问它,你需要使用 global 关键字。

  2. 相比之下, superglobals 始终在 PHP 脚本的任何地方都可用,而无需以 global 关键字对其进行声明。

PHP 中的大多数超级全局变量都是关联数组,并且 Web 服务器会填充它们。因此,如果在命令行环境中运行脚本,则某些超级全局变量可能为空。

PHP 中的超级全局变量列表包括以下内容:

  1. $GLOBALS

  2. $_SERVER

  3. $_GET

  4. $_POST

  5. $_FILES

  6. $_COOKIE

  7. $_SESSION

  8. $_REQUEST

  9. $_ENV

在本章中,我们将对 PHP 中的这些超级全局变量进行简要介绍。在后续章节中,我们将详细讨论这些超级全局变量。

$GLOBALS

它是对所有全局定义变量的引用的关联数组。变量名称构成键,其内容是关联数组的值。

$_SERVER

所有与服务器和执行环境相关的信息都包含在该关联数组中。

5.4.0 之前的 PHP 版本包含以 $HTTP_SERVER_VARS 形式存在相同信息的变量,但现在已删除。

$_GET

它是通过附加至 HTTP 请求的 URL 的查询字符串传给当前脚本的变量的关联数组。请注意,除了 GET 请求之外,还通过包含查询字符串的所有请求填充该数组。

查询字符串是所有变量及其值按“var=val”形式形成的列表,并以“&”符号连接起来。

查询字符串本身在问号“?”之后附加至 PHP 脚本名称。例如 http://localhost/hello.php?first_name=Amar&last_name=Sharma

$_POST

它是由 HTTP POST 方法通过查询字符串传给 URL 的键-值对的关联数组,在请求中使用 URLEncodedmultipart/form-data 内容类型。

$HTTP_POST_VARS 还包含与 $_POST 相同的信息,但不是超级全局变量,现已不赞成使用。向服务器发送具有 POST 请求的数据的最简单方法是将 HTML 表单的方法属性指定为 POST。

$_FILES

变量 $_FILES 是一个关联数组,其中包含通过 HTTP POST 方法上传的项。当一个 HTML 表单包含一个文件类型的输入元素,它的 enctype 属性设置为 multipart/form-data,并且方法属性设置为 HTTP POST 方法时,就会上传一个文件。

Cookie 是服务器存储在客户端计算机上的文本文件,并且它们被保留以用于跟踪目的。

超级全局变量 $_COOKIE 将通过 HTTP 请求传递给当前 PHP 脚本的变量以 cookie 的形式存储起来。

$_SESSION

HTTP 会话是用户与服务器建立连接的时间持续期,以及连接被终止的时间之间的时间段。在此间隔期间,某些数据是以会话变量的形式永久存在于页面中。

$_SESSION 超全局变量是会话变量的关联数组,当前脚本可以使用。

$_REQUEST

$_REQUEST 是一个关联数组,它包含 $_GET、$_POST 和 $_COOKIE 变量的内容。

这些变量的顺序由 "php.ini" 文件中 requests_ordervarables_order 设置的值决定。

$_ENV

$_ENV 是一个关联数组,它存储当前脚本可用的所有环境变量。如果 PHP 以服务器模块或 CGI 处理器的形式运行,此数组中还将包含 CGI 变量。

PHP - $GLOBALS

$GLOBALS 是 PHP 中的 " superglobal " 或 " automatic global " 变量之一。它在脚本的各个范围中均可用。无需在函数或方法中访问它时执行 " global $variable; "。

$GLOBALS 是对所有全局定义的变量的引用的关联数组。变量的名称形成键,其内容是关联数组的值。

Example

此示例显示 $GLOBALS 数组包含全局变量的名称和内容−

<?php
   $var1="Hello";
   $var2=100;
   $var3=array(1,2,3);

   echo $GLOBALS["var1"] . "\n";
   echo $GLOBALS["var2"] . "\n";
   echo implode($GLOBALS["var3"]) . "\n";
?>

它将生成以下 output

Hello
100
123

Example

在以下示例中, $var1 在全局命名空间和函数内部的局部变量中进行定义。全局变量从 $GLOBALS 数组中提取。

<?php
   function myfunction() {
      $var1="Hello PHP";
      echo "var1 in global namespace: " . $GLOBALS['var1']. "\n";
      echo "var1 as local variable: ". $var1;
   }
   $var1="Hello World";
   myfunction();
?>

它将生成以下 output

var1 in global namespace: Hello World
var1 as local variable: Hello PHP

Example

在 PHP 8.1.0 版本之前,全局变量可以通过 $GLOBALS 数组的副本进行修改。

<?php
   $a = 1;
   $globals = $GLOBALS;
   $globals['a'] = 2;
   var_dump($a);
?>

它将生成以下 output

int(1)

在此处, $globals 是 $GLOBALS 超全局变量的副本。修改副本中键为 "a" 的元素值至 2,实际上会更改 $a 的值。

它将生成以下 output

int(2)

Example

在 PHP 8.1.0 及更高版本中,$GLOBALS 是全局符号表的只读副本。也就是说,全局变量无法通过其副本进行修改。与上述操作相同的操作不会将 $a 更改为 2。

<?php
   $a = 1;
   $globals = $GLOBALS;
   $globals['a'] = 2;
   var_dump($a);
?>

它将生成以下 output

int(1)

PHP - $_SERVER

$_SERVER 是 PHP 中的超全局变量。其中包含有关 HTTP 标头、路径以及脚本位置等信息。

  1. $_SERVER 是一个关联数组,其中包含所有服务器和执行环境相关信息。

  2. 此关联数组中的大多数条目均由 Web 服务器填充。由于服务器会省略一些信息或提供其他信息,因此这些条目可能因不同的 Web 服务器而异。

  3. 对于在命令行上运行的 PHP 脚本,大多数这些条目都不可用或没有任何意义。

  4. PHP 还将使用请求标头中的值创建其他元素。这些条目的名称为 "HTTP_",后跟标头名称,该名称以大写字母表示,并用下划线替换连字符。

  5. 例如,"Accept-Language" 标头可以作为 $_SERVER['HTTP_ACCEPT_LANGUAGE']。

  6. 5.4.0 版本之前的 PHP 使用 $HTTP_SERVER_VARS,其中包含相同的信息,但现在已将其移除。

下表列出了 $_SERVER 数组的一些重要服务器变量,后跟对其值的说明。

Sr.No

Server Variables & Description

1

PHP_SELF 存储当前正在执行的脚本的文件名。

2

SERVER_ADDR 数组的此属性将返回当前脚本正在执行的服务器的 IP 地址。

3

SERVER_NAME 当前脚本正在执行的服务器主机的名称。对于在本地运行的服务器,将返回 localhost。

4

QUERY_STRING 查询字符串是由 “&” 符号分隔并附加在 “?” 符号后的 URL 的键值对字符串。例如:[role="bare"] [role="bare"]http://localhost/testscript?name=xyz&age=20 URL 返回尾随查询字符串

5

REQUEST_METHOD 用于访问 URL 的 HTTP 请求方法,例如 POST、GET、POST、PUT 或 DELETE。在上面的查询字符串示例中,用于查询字符串并带有 “?” 符号的 URL 向页面发出 GET 方法的请求

6

DOCUMENT_ROOT 返回服务器上被配置为文档根目录的目录的名称。在 XAMPP Apache 服务器上,将返回 htdocs 作为文档根目录 c:/xampp/htdocs 的名称

7

REMOTE_ADDR 用户用来查看当前页面的机器的 IP 地址。

8

SERVER_PORT Web 服务器在上面监听传入请求的端口号。默认值为 80

Example

从 XAMPP 服务器的文档根目录调用的以下脚本将列出所有服务器变量 −

<?php
   foreach ($_SERVER as $k=>$v)
   echo $k . "=>" . $v . "\n";
?>

它将生成以下 output

MIBDIRS=>C:/xampp/php/extras/mibs
MYSQL_HOME=>\xampp\mysql\bin
OPENSSL_CONF=>C:/xampp/apache/bin/openssl.cnf
PHP_PEAR_SYSCONF_DIR=>\xampp\php
PHPRC=>\xampp\php
TMP=>\xampp\tmp
HTTP_HOST=>localhost
HTTP_CONNECTION=>keep-alive
HTTP_SEC_CH_UA=>"Chromium";v="116", "Not)
A;Brand";v="24", "Google Chrome";v="116"
HTTP_SEC_CH_UA_MOBILE=>?0
HTTP_SEC_CH_UA_PLATFORM=>"Windows"
HTTP_DNT=>1
HTTP_UPGRADE_INSECURE_REQUESTS=>1
HTTP_USER_AGENT=>Mozilla/5.0 (Windows NT 10.0; Win64; x64)
 AppleWebKit/537.36 (KHTML, like Gecko) Chrome/116.0.0.0 Safari/537.36
HTTP_ACCEPT=>text/html,application/xhtml+xml,application/xml;
q=0.9,image/avif,image/webp,image/apng,*/*;
q=0.8,application/signed-exchange;v=b3;q=0.7
HTTP_SEC_FETCH_SITE=>none
HTTP_SEC_FETCH_MODE=>navigate
HTTP_SEC_FETCH_USER=>?1
HTTP_SEC_FETCH_DEST=>document
HTTP_ACCEPT_ENCODING=>gzip, deflate, br
HTTP_ACCEPT_LANGUAGE=>en-US,en;q=0.9,mr;q=0.8
PATH=>C:\Python311\Scripts\;
C:\Python311\;C:\WINDOWS\system32;
C:\WINDOWS;C:\WINDOWS\System32\Wbem;
C:\WINDOWS\System32\WindowsPowerShell\v1.0\;
C:\WINDOWS\System32\OpenSSH\;C:\xampp\php;
C:\Users\user\AppData\Local\Microsoft\WindowsApps;
C:\VSCode\Microsoft VS Code\bin
SystemRoot=>C:\WINDOWS
COMSPEC=>C:\WINDOWS\system32\cmd.exe
PATHEXT=>.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE;.WSF;.WSH;.MSC;.PY;.PYW
WINDIR=>C:\WINDOWS
SERVER_SIGNATURE=>
Apache/2.4.56 (Win64) OpenSSL/1.1.1t PHP/8.0.28 Server at localhost Port 80

SERVER_SOFTWARE=>Apache/2.4.56 (Win64) OpenSSL/1.1.1t PHP/8.0.28
SERVER_NAME=>localhost
SERVER_ADDR=>::1
SERVER_PORT=>80
REMOTE_ADDR=>::1
DOCUMENT_ROOT=>C:/xampp/htdocs
REQUEST_SCHEME=>http
CONTEXT_PREFIX=>
CONTEXT_DOCUMENT_ROOT=>C:/xampp/htdocs
SERVER_ADMIN=>postmaster@localhost
SCRIPT_FILENAME=>C:/xampp/htdocs/hello.php
REMOTE_PORT=>54148
GATEWAY_INTERFACE=>CGI/1.1
SERVER_PROTOCOL=>HTTP/1.1
REQUEST_METHOD=>GET
QUERY_STRING=>
REQUEST_URI=>/hello.php
SCRIPT_NAME=>/hello.php
PHP_SELF=>/hello.php
REQUEST_TIME_FLOAT=>1694802456.9816
REQUEST_TIME=>1694802456

PHP - $_REQUEST

在 PHP 中,$_REQUEST 是一个超级全局变量。它是一个关联数组,由 $_GET、$_POST 和 $_COOKIE 变量的内容集合组成。

  1. “php.ini” 文件中的设置决定了此变量的组成。

  2. “php.ini” 中的一个指令是 request_order ,它决定了 PHP 注册 GET、POST 和 COOKIE 变量的顺序。

  3. 此数组中列出的变量的存在和顺序根据 PHP variables_order 进行定义。

  4. 如果通过命令行运行 PHP 脚本,则 argcargv 变量不会包含在 $_REQUST 数组中,因为它们的值取自 $_SERVER 数组,而该数组又由 Web 服务器填充。

$_REQUEST with GET Method

将以下脚本保存在 Apache 服务器的文档文件夹中。如果你在 Windows 上使用 XAMPP 服务器,请将脚本作为 “hello.php” 放在 “c:/xampp/htdocs” 文件夹中。

<html>
<body>
   <?php
      echo "<h3>First Name: " . $_REQUEST['first_name'] . "<br />"
      . "Last Name: " . $_REQUEST['last_name'] . "</h3>";
   ?>
</body>
</html>

启动 XAMPP 服务器并在浏览器窗口中输入 http://localhost/hello.php?first_name=Amar&last_name=Sharma 作为 URL。

你应该可以获得 output 如下 −

php $ request 1

$_REQUEST with POST Method

在文档根目录下,将以下脚本保存为 “hello.html”。

<html>
<body>
   <form action="hello.php" method="post">
      First Name: <input type="text" name="first_name" /> <br />
      Last Name: <input type="text" name="last_name" />
      <input type="submit" value="Submit" />
   </form>
</body>
</html>

在您的浏览器中,输入 URL “http://localhost/hello.html”。您应该在浏览器窗口中获得类似的 output

php $ request 2

您还可以在 HTML 脚本中嵌入 PHP 代码,并使用 PHP_SELF 变量将表单 POST 到自身 −

<html>
<body>
   <form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
      <p>First Name: <input type="text" name="first_name" /></p>
      <p>Last Name: <input type="text" name="last_name" /></p>
      <input type="submit" value="Submit" />
   </form>
   <?php
      if ($_SERVER["REQUEST_METHOD"] == "POST")
      echo "<h3>First Name: " . $_REQUEST['first_name'] . "<br />"
      . "Last Name: " . $_REQUEST['last_name'] . "</h3>";
   ?>
</body>
</html>

它将生成以下 output

php $ request 3

PHP - $_POST

$_POST 是 PHP 中的一个预定义的超全局变量。它是由 HTTP POST 方法(在请求中使用 URLEncoded 或 multipart/form-data 内容类型)传递给 URL 的键值对关联数组。

  1. $HTTP_POST_VARS 也包含与 $_POST 相同的信息,但不是超全局变量,现已弃用。

  2. 使用 POST 请求将数据发送到服务器最简单的方法是将 HTML 表单的 method attribute 指定为 POST

假设浏览器中的 URL 为“http://localhost/hello.php”,method=POST 在 HTML 表单“hello.html”中设置如下 −

<html>
<body>
   <form action="hello.php" method="post">
      <p>First Name: <input type="text" name="first_name"/> </p>
      <p>Last Name: <input type="text" name="last_name" /> </p>
      <input type="submit" value="Submit" />
   </form>
</body>
</html>

此练习的“hello.php”脚本(位于文档根目录文件夹中)如下:

<?php
   echo "<h3>First name: " . $_POST['first_name'] . "<br /> " .
   "Last Name: " . $_POST['last_name'] . "</h3>";
?>

现在,在你的浏览器中打开 http://localhost/hello.html 。你应该在屏幕上获得以下输出 −

php $ post 1

当您按下 Submit 按钮时,数据将使用 POST 方法提交至“hello.php”。

php $ post 2

您还可以将 HTML 表单与 hello.php 中的 PHP 代码混合使用,并使用“PHP_SELF”变量将其表单数据发布给自己 -

<html>
<body>
   <form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
      <p>First Name: <input type="text" name="first_name"/> </p> <br />
      <p>Last Name: <input type="text" name="last_name" /></p>
      <input type="submit" value="Submit" />
   </form>
   <?php
      echo "<h3>First Name: " . $_POST['first_name'] . "<br /> " .
      "Last Name: " . $_POST['last_name'] . "</h3>";
   ?>
</body>
</html>

它将生成以下 output

php $ post 3

PHP - $_GET

$_GET 是 PHP 中的超级全局变量之一。它是一个关联数组,其中包含通过附加到 HTTP 请求 URL 的查询字符串传递给当前脚本的变量。请注意,除了 GET 请求外,所有带有查询字符串的请求都会填充此数组。

$HTTP_GET_VARS 包含相同的基本信息,但它现在已被弃用。

默认情况下,客户端浏览器通过使用 HTTP GET 方法向服务器上的 URL 发送请求。附加到 URL 的查询字符串可能包含由“&”符号连接的键值对。$_GET 关联数组存储这些键值对。

将以下脚本保存在 Apache 服务器的文档文件夹中。如果您在 Windows 上使用 XAMPP 服务器,请将脚本作为“hello.php”放置在“c:/xampp/htdocs”文件夹中。

<?php
   echo "<h3>First Name: " . $_REQUEST['first_name'] . "<br />" .
   "Last Name: " . $_REQUEST['last_name'] . "</h3>";
?>

启动 XAMPP 服务器,并在浏览器窗口中输入“http://localhost/hello.php?first_name=Mukesh&last_name=Sinha”作为 URL。您应该获得以下 output

php $ get 1

当 HTML 表单数据被提交到带有 GET 动作的 URL 时,$_GET 数组也会被填充。

在文档根目录下,将以下脚本保存为“ hello.html ”−

<html>
<body>
   <form action="hello.php" method="get">
      <p>First Name: <input type="text" name="first_name"/></p>
      <p>Last Name: <input type="text" name="last_name" /></p>
      <input type="submit" value="Submit" />
   </form>
</body>
</html>

在您的浏览器中,输入 URL "http://localhost/hello.html"

php $ get 2

您应该在浏览器窗口中获得类似的 output

php $ get 3

在以下示例中,htmlspecialchars() 用于将字符转换为 HTML 实体 −

Character

Replacement

& (ampersand)

&

" (double quote)

"

' (single quote)

' or '

< (less than)

<

> (greater than)

>

假设浏览器中的 URL 为“http://localhost/hello.php?name=Suraj&age=20”−

<?php
   echo  "Name: " . htmlspecialchars($_GET["name"]) . "";
   echo  "Age: " . htmlspecialchars($_GET["age"]) . "<br/>";
?>

它将生成以下 output

Name: Suraj
Age: 20

PHP - $_FILES

$_FILES 是 PHP 中的“超全局”或自动全局变量之一。它在脚本的整个范围内都可用。$_FILES 变量是一个关联数组,包含通过 HTTP POST 方法上传的项目。

当 HTML 表单包含文件类型的输入元素,其 enctype 属性设置为 multipart/form-data,且方法属性设置为 HTTP POST 方法时,便会上传文件。

$HTTP_POST_FILES 也包含相同的信息,但它不是超全局的,并且现在已被弃用。

以下 HTML 脚本包含一个 input 元素的 file 类型的表单——

<input type="file" name="file">

这个“输入类型”渲染出一个带有文件标题的按钮。点击时,会出现一个文件对话框。您可以选择要上传的文件。

服务器上的 PHP 脚本可以访问 $_FILES 变量中的文件数据。

$_FILES 数组包含以下属性−

  1. $_FILES['file']['name'] − 用户选择要上传的文件的原始名称。

  2. $_FILES['file']['type'] − 文件的 MIME 类型。一个示例是“image/gif”。但是,PHP 方面并未检查此 MIME 类型。

  3. $_FILES['file']['size'] − 上传的文件大小(以字节为单位)。

  4. $_FILES['file']['tmp_name'] − 已上传的文件在服务器上存储的临时文件名。

  5. $_FILES['file']['full_path'] − 浏览器提交的完整路径。PHP 8.1.0 起可用。

  6. $_FILES['file']['error'] −与此文件上传关联的错误代码。

error codes 如下枚举−

Error Codes

Description

UPLOAD_ERR_OK (Value=0)

没有错误,文件上传成功。

UPLOAD_ERR_INI_SIZE (Value=1)

上传的文件超过了 php.ini 中的 upload_max_filesize 指令。

UPLOAD_ERR_FORM_SIZE (Value=2)

上传的文件超过了 MAX_FILE_SIZE。

UPLOAD_ERR_PARTIAL (Value=3)

上传的文件仅部分上传。

UPLOAD_ERR_NO_FILE (Value=4)

No file was uploaded.

UPLOAD_ERR_NO_TMP_DIR (Value=6)

Missing a temporary folder.

UPLOAD_ERR_CANT_WRITE (Value=7)

未能将文件写入磁盘。

UPLOAD_ERR_EXTENSION (Value=8)

PHP 扩展停止了文件上传。

Example

以下“test.html”包含一个 HTML 表单,其 enctype 设置为 multiform/form-data。它还具有一个输入文件元素,该元素在表单上显示一个按钮,供用户选择要上传的文件。将此文件保存在 Apache 服务器的文档根目录中。

<html>
<body>
   <form action="hello.php" method="POST" enctype="multipart/form-data">
      <p><input type="file" name="file"></p>
      <p><input type ="submit" value="submit"></p>
   </form>
</body>
</html>

上述 HTML 在浏览器窗口中渲染一个名为“选择文件”的按钮。要打开文件对话框,请单击“选择文件”按钮。当出现所选文件的名称时,请单击 submit 按钮。

php $ files 1

Example

文档根目录中的服务器端 PHP 脚本 ( upload.php ) 如下读取变量 $_FILES 数组−

<?php
   echo "Filename: " . $_FILES['file']['name']."<br>";
   echo "Type : " . $_FILES['file']['type'] ."<br>";
   echo "Size : " . $_FILES['file']['size'] ."<br>";
   echo "Temp name: " . $_FILES['file']['tmp_name'] ."<br>";
   echo "Error : " . $_FILES['file']['error'] . "<br>";
?>

它将生成以下 output

Filename: abc.txt
Type : text/plain
Size : 556762
Temp name: C:\xampp\tmp\phpD833.tmp
Error : 0

Example

在 PHP 中,您可以使用 HTML 数组功能上传多个文件 −

<html>
<body>
   <form action="hello.php" method="POST" enctype="multipart/form-data">
      <input type="file" name="files[]"/>
      <input type="file" name="files[]"/>
      <input type ="submit" value="submit"/>
   </form>
</body>
</html>

现在,将 PHP 脚本 ( hello.php ) 更改为 −

<?php
   foreach ($_FILES["files"]["name"] as $key => $val) {
      echo "File uploaded: $val <br>";
   }
?>

浏览器将显示多个“选择文件”按钮。在您通过单击“提交”按钮上传选定的文件后,浏览器将显示名称为文件,以响应 URL http://localhost/hello.html ,如下图所示 −

php $ files 2

PHP - $_ENV

$_ENV 是 PHP 中的超级全局变量。它是一个关联数组,其中存储在当前脚本中可用的所有环境变量。 $HTTP_ENV_VARS 也包含相同的信息,但它不是超级全局变量,并且现在已弃用。

将环境变量导入到全局命名空间中。其中大多数变量是由 PHP 解析器正在运行之下的 shell 提供的。因此,不同平台上的环境变量列表可能不同。

如果 PHP 作为服务器模块或 CGI 处理器运行,这个数组 ($_ENV) 还包括 CGI 变量。

我们可以使用 foreach 循环来显示所有可用的环境变量 −

<?php
   foreach ($_ENV as $k=>$v)
   echo $k . " => " . $v . "<br>";
?>

在 Windows 操作系统和 XAMPP 服务器上,您可能会获得以下环境变量列表 −

Variable

Value

ALLUSERSPROFILE

C:\ProgramData

APPDATA

C:\Users\user\AppData\Roaming

CommonProgramFiles

C:\Program Files\Common Files

CommonProgramFiles(x86)

C:\Program Files (x86)\Common Files

CommonProgramW6432

C:\Program Files\Common Files

COMPUTERNAME

GNVBGL3

ComSpec

C:\WINDOWS\system32\cmd.exe

DriverData

C:\Windows\System32\Drivers\DriverData

HOMEDRIVE

C −

HOMEPATH

\Users\user

LOCALAPPDATA

C:\Users\user\AppData\Local

LOGONSERVER

\\GNVBGL3

MOZ_PLUGIN_PATH

C:\Program Files (x86)\ Foxit Software\ Foxit PDF Reader\plugins\

NUMBER_OF_PROCESSORS

8

OneDrive

C:\Users\user\OneDrive

OneDriveConsumer

C:\Users\user\OneDrive

OS

Windows_NT

Path

C:\Python311\Scripts\;C:\Python311\;C:\Windows\System32;C:\Windows;C:\Windows\System32\Wbem;C:\Windows\System32\WindowsPowerShell\ v1.0\;C:\Windows\System32\OpenSSH\;C:\xampp\php;C:\Users\user\AppData\Local\Microsoft\WindowsApps;C:\VSCode\Microsoft VS Code\bin

PATHEXT

.COM;.EXE;.BAT;.CMD;.VBS;.VBE;.JS;.JSE; .WSF;.WSH;.MSC;.PY;.PYW

PROCESSOR_ARCHITECTURE

AMD64

PROCESSOR_IDENTIFIER

英特尔64家族6型号140步进1,GenuineIntel

PROCESSOR_LEVEL

6

PROCESSOR_REVISION

8c01

ProgramData

C:\ProgramData

ProgramFiles

C:\Program Files

ProgramFiles(x86)

C:\Program Files (x86)

ProgramW6432

C:\Program Files

PSModulePath

C:\Program Files\WindowsPowerShell\Modules; C:\WINDOWS\system32\WindowsPowerShell\v1.0\ Modules

PUBLIC

C:\Users\Public

SystemDrive

C −

SystemRoot

C:\WINDOWS

TEMP

C:\Users\user\AppData\Local\Temp

TMP

C:\Users\user\AppData\Local\Temp

USERDOMAIN

GNVBGL3

USERDOMAIN_ROAMINGPROFILE

GNVBGL3

USERNAME

user

USERPROFILE

C:\Users\user

windir

C:\WINDOWS

ZES_ENABLE_SYSMAN

1

__COMPAT_LAYER

RunAsAdmin Installer

AP_PARENT_PID

10608

你也可以访问各个环境变量的值。此代码获取 PATH 环境变量 −

<?php
   echo "Path: " . $_ENV['Path'];
?>

它将生成以下 output

Path:
C:\Python311\Scripts\;C:\Python311\;C:\WINDOWS\system32;
C:\WINDOWS;C:\WINDOWS\System32\Wbem;
C:\WINDOWS\System32\WindowsPowerShell\v1.0\;
C:\WINDOWS\System32\OpenSSH\;C:\xampp\php;
C:\Users\mlath\AppData\Local\Microsoft\WindowsApps;
C:\VSCode\Microsoft VS Code\bin

Note − $_ENV 数组可能会产生空的结果,具体取决于“php.ini”设置“variables_order”。你可能需要编辑“php.ini”文件并设置 variables_order="EGPCS" 而不是 variables_order="GPCS" 值。

The getenv() Function

PHP 库提供了 getEnv() 函数来检索所有环境变量或特定环境变量的值。

以下脚本显示所有可用环境变量的值 −

<?php
   $arr=getenv();
   foreach ($arr as $key=>$val)
   echo "$key=>$val";
?>

要获取特定变量的值,请使用其名称作为 getEnv() 函数的参数 −

<?php
   echo "Path: " . getenv("PATH");
?>

The putenv() Function

PHP 还提供了 putenv() 函数来创建新的环境变量。该环境变量只会存在于当前请求的持续时间内。

应避免更改某些环境变量的值。默认情况下,用户只能设置以“ PHP_ ”开头的环境变量(比如 PHP_FOO=BAR)。

“php.ini”中的“safe_mode_protected_env_vars”指令包含一个环境变量逗号分隔列表,最终用户无法使用 putenv() 更改这些变量。

<?php
   putenv("PHP_TEMPUSER=GUEST");
   echo "Temp user: " . getenv("PHP_TEMPUSER");
?>

浏览器将显示以下 output

Temp user: GUEST

PHP 超全局变量 $_COOKIE 存储通过 HTTP 请求以 cookie 形式传递给当前 PHP 脚本的变量。$HTTP_COOKIE_VARS 也包含相同信息,但它不是超全局变量,现在已被弃用。

cookie 是由服务器存储在客户端计算机上的文本文件,用于跟踪目的。PHP 透明支持 HTTP cookie。cookie 通常在 HTTP 标头中设置。JavaScript 也可以直接在浏览器上设置 cookie。

服务器脚本将一组 cookie 发送到浏览器。它将此信息存储在本地计算机上以供将来使用。下次当浏览器向 Web 服务器发送任何请求时,它会将这些 cookie 信息发送到服务器,而服务器则使用这些信息来识别用户。

The setcookie() Function

PHP 提供 setcookie 函数来创建要随 HTTP 响应一起发送到客户端的 cookie 对象。

setcookie(name, value, expire, path, domain, security);

Parameters

  1. Name − 存储的 cookie 名称。

  2. Value − 此设置指定了已命名变量的值。

  3. Expiry − 此设置指定从 1970 年 1 月 1 日 00:00:00 GMT 开始以秒为单位表示的未来时间。

  4. Path − cookie 有效的目录。

  5. Domain − 指定域名在非常大的域中。

  6. Security − HTTPS 为 1. 常规 HTTP 的默认值为 0。

How to Set Cookies

查看以下 example 。此脚本设置一个名为 username 的 Cookie(如果尚未设置)。

Example

<?php
   if (isset($_COOKIE['username'])) {
      echo "<h2>Cookie username already set: " . $_COOKIE['username'] . "</h2>";
   } else {
      setcookie("username", "Mohan Kumar");
      echo "<h2>Cookie username is now set.</h2>";
   }
?>

从 Apache 服务器的根文档运行此脚本来。您应看到以下消息作为 output

Cookie username is now set

如果重新执行此脚本,则现在已设置 Cookie。

Cookie username already set: Mohan Kumar

Example

在客户端后续访问时检索 Cookie −

<?php
   $arr=$_COOKIE;
   foreach ($arr as $key=>$val);
   echo "<h2>$key => $val </h2>";
?>

浏览器将显示以下 output

Username => Mohan Kumar

How to Remove Cookies

要删除 cookie,请设置具有已经过期的日期的 cookie,以便浏览器触发 cookie 删除机制。

<?php
   setcookie("username", "", time() - 3600);
   echo "<h2>Cookie username is now removed</h2>";
?>

浏览器现在将显示以下 output

Cookie username is now removed

Setting Cookies Using the Array Notation

您还可以使用 Cookie 名称中的数组符号来设置数组 Cookie。

setcookie("user[three]", "Guest");
setcookie("user[two]", "user");
setcookie("user[one]", "admin");

如果 Cookie 名称包含句点 (.),则 PHP 将它们替换为下划线 (_)。

PHP - $_SESSION

PHP 中的超全局变量之一 $_SESSION 是当前脚本中可用的会话变量的关联数组。 $HTTP_SESSION_VARS 也包含相同的信息,但它不是超全局变量,现在已被弃用。

What is a Session?

会话是另一种方法,可跨整个网站的页面访问数据。它是用户与服务器建立连接时和连接终止时之间的持续时间。在此时间段内,用户可能会导航到不同的页面。许多时候,希望某些数据持续可在所有页面中使用。这由 session variables 实现。

会话在服务器临时目录中创建一个文件,其中存储已注册的会话变量及其值。此数据在该访问期间可供站点上的所有页面使用。

服务器为每个会话分配一个唯一的 SESSIONID。由于 HTTP 是一种无状态协议,因此当会话终止时,会话变量中的数据将自动删除。

The session_start() Function

为了启用对会话数据的访问,必须调用 session_start() 函数。session_start() 基于通过 GET 或 POST 请求或通过 Cookie 传递的会话标识符创建一个会话或恢复当前会话。

session_start(array $options = []): bool

如果会话已成功启动,则此函数返回 true ,否则返回 false

Handling Session Variables

要创建新的会话变量,请在 $_SESSION 数组中添加键值对 −

$_SESSION[ "var"]=value;

要读回会话变量的值,您可以使用 echo/print 语句或 var_dump()print_r() 函数。

echo $_SESSION[ "var"];

要获取当前会话中所有会话变量的列表,可以使用 foreach 循环遍历 $_SESSION

foreach ($_SESSION as $key=>$val)
echo $key . "=>" . $val;

若要手动清除所有会话数据,则有 session_destroy() 函数。也可以通过调用 unset() 函数来释放特定的会话变量。

unset($_SESSION[ "var"]);

List of Session Functions

在 PHP 中,有许多用于管理会话数据的内置函数。

Session Functions

Description

session_abort

放弃会话数组更改并结束会话

session_cache_expire

Return current cache expire

session_cache_limiter

获取和/或设置当前缓存限制器

session_commit

Alias of session_write_close

session_create_id

Create new session id

session_decode

从会话编码字符串中解码会话数据

session_destroy

销毁注册到会话的所有数据

session_encode

将当前会话数据编码为会话编码字符串

session_gc

执行会话数据垃圾回收

session_get_cookie_params

获取会话 Cookie 参数

session_id

获取和/或设置当前会话 ID

session_is_registered

找出是否在会话中注册了全局变量

session_module_name

获取和/或设置当前会话模块

session_name

获取和/或设置当前会话名称

session_regenerate_id

用新生成的当前会话 ID 更新当前会话 ID

session_register_shutdown

Session shutdown function

session_register

使用当前会话注册一个或多个全局变量

session_reset

使用原始值重新初始化会话数组

session_save_path

获取和/或设置当前会话保存路径

session_set_cookie_params

设置会话 Cookie 参数

session_set_save_handler

设置用户级会话存储函数

session_start

开启新的或恢复现有的会话

session_status

返回当前的会话状态

session_unregister

注销当前会话中的一个全局变量

session_unset

Free all session variables

session_write_close

写入会话数据并结束会话

Example

以下 PHP 脚本呈现一个 HTML 表单。表格数据用于创建三个会话变量。一个超链接将浏览器带到另一个页面,该页面读回会话变量。

将此代码另存为“test.php”,并将其保存在文档根目录中,然后使用浏览器打开它。输入数据,然后按 Submit 按钮。

<html>
<body>
   <form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
      <h3>User's ID: <input type="text" name="ID"/></h3>
      <h3>Your Name: <input type="text" name="name"/></h3>
      <h3>Enter Age: <input type="text" name="age"/></h3>
      <input type="submit" value="Submit"/>
   </form>
   <?php
      session_start();
      if ($_SERVER["REQUEST_METHOD"] == "POST") {
         $_SESSION['UserID'] = $_POST['ID'];
         $_SESSION['Name'] = $_POST['name'];
         $_SESSION['age'] = $_POST['age'];
      }
      echo "Following Session Variables Created: \n";

      foreach ($_SESSION as $key=>$val)
      echo "<h3>" . $key . "=>" . $val . "</h3>";
      echo "<br/>" . '<a href="hello.php">Click Here</a>';
   ?>
</body>
</html>

单击“提交”按钮后,它将显示创建的所有会话变量的列表 -

php $ session 1

接下来,在“hello.php”文件中保存以下脚本。

<?php
session_start();
   echo "<h2>Following Session variables Read:</h2>";
   foreach ($_SESSION as $key=>$val)
   echo "<h3>" . $key . "=>" . $val . "</h3>";
?>

现在,点击“test.php”页面上的链接导航到“hello.php”。它将显示被读到的会话变量 -

php $ session 2

PHP - File Handling

在 PHP 中,文件是一种资源对象,可以按线性方式从其中读写数据。“文件处理”一词是指 PHP 中的一组函数,这些函数允许使用 PHP 代码对磁盘文件执行读/写操作。

一个文件对象会被分类为 stream 。可以在其上执行线性读/写操作的任何资源都是流。其他类似流的对象是 TCP 套接字、标准输入流,即由“php://stdin”表示的系统键盘、由“php://stdout”表示的标准输出流以及错误流“php://stderr”。

Note − 常量 STDIN、STDOUT 和 STDERR 分别代表相应的标准流。

尽管 PHP 被视为用于开发 Web 应用程序的服务器端脚本语言,但 PHP 还有一个命令行界面来执行控制台 IO 操作。

Example

PHP 中的 readline() 函数接受来自标准键盘的用户输入,echo/print 语句在控制台上呈现输出。

<?php
   $str = readline("Type something:");
   echo $str;
?>

它将生成以下 output

C:\xampp\php>php hello.php
Type something: Are you enjoying this PHP tutorial?
Are you enjoying this PHP tutorial?

Example

我们可以通过从“php://stdin”读取输入并将其输出到“php://stdout”来获得相同的效果。

<?php
   $f = fopen("php://stdin", "r");
   echo "Type something: ";

   $str = fgets($f);
   $f1 = fopen("php://stdout", "w");

   fputs($f1, $str);
?>

这里,fopen() 函数用于打开 stdin 流以进行读取并打开 stdout 流以进行写入。

Example

PHP 支持各种流协议,以用于流相关函数,例如 fopen()、file_exists() 等。使用 php_get_wrappers() 函数获取所有已注册包装器的列表。

<?php
   print_r(stream_get_wrappers());
?>

它将生成以下 output

Array
(
   [0] => php
   [1] => file
   [2] => glob
   [3] => data
   [4] => http
   [5] => ftp
   [6] => zip
   [7] => compress.zlib
   [8] => compress.bzip2
   [9] => https
   [10] => ftps
   [11] => phar
)

这些流被引用为“scheme://target”。例如,文件流为“file://xyz.txt”。

在应用程序运行之前,来自控制台的输入数据存储在计算机的主内存(RAM)中。此后,来自 RAM 的内存内容会被擦除。

我们希望以一种方式存储它,以便在永久介质(如磁盘文件)中需要时可以检索它。因此,我们将使用磁盘文件(而非标准流(键盘用于输入,显示设备用于输出))来读取数据,以及将数据存储的目的位置。

除了上面示例中使用(使用标准流的 IO 操作)的读写模式外,还可以使用“r+”和“w+”(用于同时读写)、“b”(用于二进制模式)等各种其他模式打开文件流。

要打开磁盘文件以便读取并获取其引用指针,请使用 fopen() 函数。

$handle = fopen('file://' . __DIR__ . '/data.txt', 'r');

“file://”方案是默认方案。因此,可以很容易地将其删除,尤其是在处理本地文件时。

Note − 强烈建议关闭已打开的流。为此,请使用 fclose() 函数。

fclose($handle);

PHP 包含几个用于在文件流上执行读/写操作的内置函数。在后续的章节中,我们将探索文件系统函数。

PHP - Open File

PHP 的内置函数库提供了 fopen() 函数来打开一个文件或任何其他流,并返回其“引用指针”,也称为“句柄”。

PHP 中的 fopen() 函数类似于 C 中的 fopen(),只不过在 C 中,它无法打开 URL。

Syntax of fopen()

fopen() 函数具有以下签名 -

fopen(
   string $filename,
   string $mode,
   bool $use_include_path = false,
   ?resource $context = null
): resource|false

参数 $filename$mode 是必需的。以下是参数说明 -

  1. $filename - 此参数是一个字符串,表示要打开的资源。它可以是本地文件系统中的文件,也可以是具有 scheme:// 前缀的远程服务器上的文件。

  2. $mode - 一个字符串,用于表示对文件/资源的访问类型。

  3. $use_include_path - 一个可选布尔参数,如果要搜索 include_path 中的文件,可以将其设置为“1”或 true。

  4. $context - 一个上下文流资源。

Modes of Opening a File

PHP 允许文件以以下模式打开 -

Modes

Description

r

读出打开一个文件。

w

只写打开文件,即使文件已存在,也会创建新文件。

a

以追加模式打开文件

x

创建新文件,只写。

r+

读/写打开文件。

w+

读/写打开文件,即使文件已存在,也会创建新文件。

a+

以追加模式读/写打开文件。

x+

创建新文件,读/写。

c

如果文件不存在,则以写方式打开;但如果存在,则不截断(w 模式除外)。

c++

如果文件不存在,则以读/写方式打开;但如果存在,则不截断(w 模式除外)。

e

打开文件描述符时,设置 close-on-exec 标识。仅适用于符合 POSIX.1-2008 规范的 PHP 编译系统中。

如果 fopen() 函数执行成功,则会返回绑定到文件流的“文件指针”或“句柄”资源。不过,如果失败,则会返回 FALSE,并发出 E_WARNING。

$handle = fopen('a.txt, 'r');
var_dump($handle);

如果文件存在于当前目录中,则由 output 显示成功 −

resource(5) of type (stream)

如果不显示,则会得到以下 error message

Warning: fopen(a.txt): Failed to open stream:
No such file or directory in a.php on line 2
bool(false)

Examples

以下示例显示了 fopen() 函数的不同用法 −

<?php
   $handle = fopen("hello.txt", "w");
   $handle = fopen("c:/xampp/htdocs/welcome.png", "rb");
   $handle = fopen("http://localhost/hello.txt", "r");
?>

请注意,当文件名是目录时,此函数也可能成功。在这种情况下,您可能需要使用 is_dir() 函数检查它是否是在执行任何读/写操作之前是一个文件。

一旦打开文件,就可以使用 fwrite()fputs() 等函数在其中写入数据,并使用 fread()fgets() 函数从中读取数据。

Closing a File

始终建议关闭句柄引用的打开流 −

fclose($handle);

PHP - Read File

PHP 中有许多选项可用于读取已使用 fopen() 函数打开的文件中的数据。PHP 库中的以下内置函数可以帮助我们执行读取操作 −

  1. fgets() − 从文件指针获取一行。

  2. fgetc() − 从文件指针返回一个包含单个字符的字符串。

  3. fread() − 从文件指针读取指定数量的字节。

  4. fscanf() − 从文件中读取数据,并按照指定格式对其进行解析。

The fgets() Function

fgets() 函数可以从一个打开的文件中返回一行。此函数停止在指定长度的新行或 EOF 处返回,以先遇到的为准,并在失败时返回 false

fgets(resource $stream, ?int $length = null): string|false

此处, $stream 参数是使用 fopen() 函数以读取或读/写模式打开的文件的文件指针或句柄,而 $length 是指定要读取的字节数的可选参数。

当读取到“length-1”个字节或遇到新行时,读取操作结束,以先遇到的为准。

Example

以下代码从“hello.txt”文件中读取第一行可用行 −

<?php
   $file = fopen("hello.txt", "r");
   $str = fgets($file);
   echo $str;
   fclose($file);
?>

它将生成以下 output

Hello World

Example

你可以将 fgets() 函数放在一个循环中,以便在到达文件结尾之前读取文件。

<?php
   $file = fopen("hello.txt", "r");
   while(! feof($file)) {
      echo fgets($file). "<br>";
   }
   fclose($file);
?>

它将生成以下 output

Hello World
TutorialsPoint
PHP Tutorials

此处,我们使用了 feof() 函数,如果文件指针处于 EOF,则返回 true;否则,返回 false。

The fgetc() Function

fgetc() 函数返回从文件句柄当前位置读取的单个字符。遇到 EOF 时,它返回 false

fgetc(resource $stream): string|false

此处, $stream 参数是使用 fopen() 函数以读取或读/写模式打开的文件的文件指针或句柄。

Example

以下代码显示从“hello.txt”文件中读取的第一个字符 −

<?php
   $file = fopen("hello.txt", "r");
   $str = fgets($file);
   echo $str;
   fclose($file);
?>

它将生成以下 output

H

Example

你还可以将 fgetc() 函数放在一个循环内,以便逐个字符地读取文件,直到到达 EOF。

<?php
   $file = fopen("hello.txt", "r");
   while(! feof($file)) {
      $char = fgetc($file);
      if ($char == "\n")
      echo "<br>";
      echo $char;
   }
   fclose($file);
?>

它将生成以下 output

Hello World
TutorialsPoint
PHP Tutorials

The fread() Function

PHP 中的 fread() 函数是用于从文件读取数据的二进制安全函数。虽然 fgets() 函数仅从文本文件中读取,但 fread() 函数可以以二进制模式读取文件。

fread(resource $stream, int $length): string|false

此处, $stream 参数是使用 fopen() 函数以二进制读取或读/写模式( rbrb+ )打开的文件的文件指针或句柄。 $length 参数指定要读取的字节数。

如果未给出 $length 参数,PHP 将尝试读取整个文件,直到到达 EOF,但需符合指定的块大小。

Example

以下代码读取一个文本文件 −

<?php
   $name = "hello.txt";
   $file = fopen($name, "r");
   $data = fread($file, filesize($name));
   echo $data;
   fclose($file);
?>

它将生成以下 output

Hello World TutorialsPoint PHP Tutorials

Example

你还可以读取以 rb 模式打开的图像文件等非 ASCII 文件。

<?php
   $name = "welcome.png";
   $file = fopen($name, "rb");
   $data = fread($file, filesize($name));
   var_dump($data);
   fclose($file);
?>

浏览器将“var_dump”信息显示为以下内容 −

php read file

The fscanf() Function

PHP 中的 fscanf() 函数从文件流中读取输入并根据特定格式对其进行解析,从而将其转换为指定类型的变量。每次调用此函数都将从文件中读取一行。

fscanf(resource $stream, string $format, mixed &...$vars): array|int|false|null

此处, $stream 参数是指针,它指向使用 fopen() 函数打开的文件,且为读取模式。同时, $format 为一个字符串,包含下列一个或多个格式说明符 −

  1. %% − 返回一个百分比

  2. %b − Binary number

  3. %c − 根据 ASCII 值设置字符

  4. %f − Floating-point number

  5. %F − Floating-point number

  6. %o − Octal number

  7. %s − String

  8. %d − 有符号十进制数

  9. %e − Scientific notation

  10. %u − 无符号十进制数

  11. %x − 小写字母十六进制数

  12. %X − 大写字母十六进制数

$vars 是一个可选参数,它通过引用指定包含解析值的变量。

假设“employees.txt”文件在与下方 PHP 脚本相同的目录中。文本文件中每一行都有每个员工的 name, email, postsalary ,由制表符分隔。

Example

以下 PHP 脚本使用 fscanf() 函数中的格式说明符读取文件 −

<?php
   $fp = fopen("employees.txt", "r");
   while ($employee_info = fscanf($fp, "%s\t%s\t%s\t%d\n")) {
      list ($name, $email, $post, $salary) = $employee_info;
      echo "<b>Name</b>: $name <b>Email</b>:
	  $email <b>Salary</b>: Rs. $salary <br>";
   }
   fclose($fp);
?>

它将生成以下 output

Name: Ravishankar Email: ravi@gmail.com Salary: Rs. 40000
Name: Kavita Email: kavita@hotmail.com Salary: Rs. 25000
Name: Nandkumar Email: nandu@example.com Salary: Rs. 30000

PHP - Write File

PHP 内置函数库提供了两个函数来执行文件流的写操作。这些函数是 fwrite()fputs()

为了能在文件中写入数据,必须以写模式 (w)、追加模式 (a)、读/写模式 (r+ 或 w+) 或二进制写/追加模式 (rb+、wb+ 或 wa) 打开此文件。

The fputs() Function

fputs() 函数将字符串写入以可写模式打开的文件中。

fputs(resource $stream, string $string, int $length)

此处, $stream 参数是对以可写模式打开的文件句柄。 $string 参数是要写入的数据,而 $length 是可选参数,指定要写入的最大字节数。

fputs() 函数返回写入的字节数,或 false (如果函数执行失败)。

Example

以下代码打开了新文件,其中写入了一个字符串,并返回写入的字节数。

<?php
   $fp = fopen("hello.txt", "w");
   $bytes = fputs($fp, "Hello World\n");
   echo "bytes written: $bytes";
   fclose($fp);
?>

它将生成以下 output

bytes written: 12

Example

如果需要在较早存在的文件中添加文本,必须以追加模式打开此文件( a )。让我们在前面的示例中再向同一文件中添加一个字符串。

<?php
   $fp = fopen("hello.txt", "a");
   $bytes = fputs($fp, "Hello PHP");
   echo "bytes written: $bytes";
   fclose($fp);
?>

如果你在文本编辑器中打开“hello.txt”文件,你应该可以看到其中的这两行。

Example

在以下 PHP 脚本中,一个已存在的文件 (hello.txt) 会在循环中逐行读取,并且每行会被写入到另一个文件 (new.txt)

假设“hello.txt”包含以下文本:

Hello World
TutorialsPoint
PHP Tutorials

以下是创建现有文件副本的 PHP 代码:

<?php
   $file = fopen("hello.txt", "r");
   $newfile = fopen("new.txt", "w");
   while(! feof($file)) {
      $str = fgets($file);
      fputs($newfile, $str);
   }
   fclose($file);
   fclose($newfile);
?>

新创建的“new.txt”文件应具有完全相同的内容。

The fwrite() Function

frwrite() 函数是 fread() 函数的对应函数。它执行二进制安全写操作。

fwrite(resource $stream, string $data, ?int $length = null): int|false

此处, $stream 参数是指向以可写模式打开的文件的资源。要写入该文件的数据提供在 $data 参数中。可以提供可选的 $length 参数来指定要写入的字节数。其应该是 int ,在写入长度字节之后或到达数据的末尾(以先发生的为准)后,写操作会停止。

fwrite() 函数返回写入的字节数,或 false (如果失败,则会同时返回 E_WARNING)。

Example

以下程序打开新文件,执行写操作并显示写入的字节数。

<?php
   $file = fopen("/PhpProject/sample.txt", "w");
   echo fwrite($file, "Hello Tutorialspoint!!!!!");
   fclose($file);
?>

Example

在下面给出的示例代码中,一个现有文件“welcome.png”是以二进制读模式打开的。fread() 函数用于将它的字节读入“$data”变量中,然后将其写入到另一个文件“new.png”:

<?php
   $name = "welcome.png";
   $file = fopen($name, "rb");
   $newfile = fopen("new.png", "wb");
   $size = filesize($name);
   $data = fread($file, $size);
   fwrite($newfile, $data, $size);
   fclose($file);
   fclose($newfile);
?>

运行以上代码。当前目录中现在应有一个现有“welcome.png”文件的副本。

PHP - File Existence

在对文件执行任何处理之前,经常实用的是检查你现在尝试打开的文件是否确实存在。如果不是,程序可能会发出 runtime exception

PHP 的内置函数库在这方面提供了一些实用函数。本章中讨论的某些函数有 −

  1. file_exists() − 测试文件是否存在

  2. is_file() − fopen() 返回的句柄引用的是文件还是目录

  3. is_readable() − 测试你打开的文件是否允许读取数据

  4. is_writable() − 测试文件是否允许写入数据

The file_exists() Function

此函数适用于文件和目录。它检查给定的文件或目录是否存在。

file_exists(string $filename): bool

此函数的唯一参数是一个字符串,代表带有完整路径的文件/目录。此函数将根据文件是否存在返回真或假。

Example

以下程序检查文件 “hello.txt” 是否存在。

<?php
   $filename = 'hello.txt';
   if (file_exists($filename)) {
      $message = "The file $filename exists";
   } else {
      $message = "The file $filename does not exist";
   }
   echo $message;
?>

如果当前目录中存在文件,则消息为 −

The file hello.txt exists

如果没有,则消息为 −

The file hello.txt does not exist

Example

指向文件的字符串可能具有相对路径或绝对路径。假设 “hello.txt” 文件可在当前目录中的 “hello” 子目录中找到。

<?php
   $filename = 'hello/hello.txt';
      if (file_exists($filename)) {
   $message = "The file $filename exists";
   } else {
      $message = "The file $filename does not exist";
   }
   echo $message;
?>

它将生成以下 output

The file hello/hello.txt exists

Example

尝试如下指定绝对路径 −

<?php
   $filename = 'c:/xampp/htdocs/hello.txt';
   if (file_exists($filename)) {
      $message = "The file $filename exists";
   } else {
      $message = "The file $filename does not exist";
   }
   echo $message;
?>

它将生成以下 output

The file c:/xampp/htdocs/hello.txt exists

The is_file() Function

file_exists() 函数为现有文件和目录返回 trueis_file() 函数可帮助您确定是否为文件。

is_file ( string $filename ) : bool

以下示例展示了 is_file() 函数的工作原理 −

<?php
   $filename = 'hello.txt';

   if (is_file($filename)) {
      $message = "$filename is a file";
   } else {
      $message = "$filename is a not a file";
   }
   echo $message;
?>

output 表明它是一个文件 −

hello.txt is a file

现在,将 “$filename” 更改为目录并查看结果 −

<?php
   $filename = hello;

   if (is_file($filename)) {
      $message = "$filename is a file";
   } else {
      $message = "$filename is a not a file";
   }
   echo $message;
?>

现在,您将得知 “hello” 不是文件。

请注意, is_file() 函数接受 $filename ,仅在 $filename 为文件且存在时返回 true

The is_readable() Function

有时,您可能希望事先检查是否可以读取文件。 is_readable() 函数可以确定此事实。

is_readable ( string $filename ) : bool

Example

下面是 is_readable() 函数工作原理的示例 −

<?php
   $filename = 'hello.txt';
   if (is_readable($filename)) {
      $message = "$filename is readable";
   } else {
      $message = "$filename is not readable";
   }
   echo $message;
?>

它将生成以下 output

hello.txt is readable

The is_writable() Function

您可以使用 is_writable() 函数检查文件是否存在以及是否可以在给定文件上执行写操作。

is_writable ( string $filename ) : bool

Example

以下示例展示了 is_writable() 函数的工作原理 −

<?php
   $filename = 'hello.txt';

   if (is_writable($filename)) {
      $message = "$filename is writable";
   } else {
      $message = "$filename is not writable";
   }
   echo $message;
?>

对于普通归档文件,程序指出它是可写的。但是,将其属性更改为 “read_only” 并运行程序。您现在获得 −

hello.txt is writable

PHP - Download File

大多数现代浏览器允许自动下载特定类型的文件,无需任何服务器端代码(例如 PHP 脚本)。例如,zip 文件或 EXE 文件。

如果 HTML 超链接指向 ZIP 或 EXE 文件,浏览器将下载它并弹出一个保存对话框。但是,不会下载文本文件、图像文件等,而是在浏览器中打开,您可将其保存到本地文件系统。

The readfile() Function

要下载此类文件(而不是让浏览器自动打开它们),我们可以使用 PHP 内置函数库中的 readfile() 函数。

readfile(string $filename,
bool $use_include_path = false,
?resource $context = null)
: int|false

此函数读取文件并将其写入输出缓冲区。

第二个参数 $use_include_path 默认情况下为 false,因此将下载当前目录中的文件。如果设置为 true ,将搜索添加到 php.ini 配置的 include_path 设置中的目录以找到要下载的文件。

readfile() 函数返回已读取的字节数,即使已成功完成。

Example

以下 PHP 脚本展示了 readfile() 函数的用法。

要下载文件, Content-Type 响应头应该设置为 application/octect-stream 。此 MIME 类型是二进制文件的默认值。浏览器通常不会执行该文件,甚至不会询问是否应该执行。

此外,将 Content-Disposition 头设置为 attachment 将提示“另存为”对话框弹出。

<?php
   $filePath = 'welcome.png';

   // Set the Content-Type header to application/octet-stream
   header('Content-Type: application/octet-stream');

   // Set the Content-Disposition header to the filename of the downloaded file
   header('Content-Disposition: attachment; filename="'. basename($filePath).'"');

   // Read the contents of the file and output it to the browser.
   readfile($filePath);
?>

将在文档根文件夹中将上述脚本保存为“download.php”。确保要下载的文件存在于同一文件夹中。

启动服务器,并在浏览器中访问 http://localhost/download.php 。你将获得如下所示的“另存为”对话框 -

php download file

你可以选择一个名称并下载该文件。

对于大型文件,你可以从文件流中以一定预定义大小的块中读取它。如果 Content-Disposition 头设置为“attachment”(如前一个示例中),浏览器将提供将其保存在本地文件系统中。

<?php
   $filename = 'welcome.png';

   header('Content-Type: application/octet-stream');
   header('Content-Disposition: attachment; filename="' . basename($filename) . '"');

   $handle = fopen($filename, 'rb');
   $buffer = '';
   $chunkSize = 1024 * 1024;

   ob_start();
   while (!feof($handle)) {
      $buffer = fread($handle, $chunkSize);
      echo $buffer;
      ob_flush();
      flush();
   }
   fclose($handle);
?>

PHP - Copy File

你可以通过三种不同的方式将现有文件复制到新文件中 -

  1. 从一个文件读取一行,并循环写入另一个文件

  2. 将全部内容读入字符串,将字符串写到另一个文件

  3. 使用 PHP 的内置函数库,包括 copy() 函数。

Method 1

在第一种方法中,你可以从现有文件中读取每一行,并写入新文件,直到现有文件到达文件结尾。

在以下 PHP 脚本中,一个已存在的文件 (hello.txt) 会在循环中逐行读取,并且每行会被写入到另一个文件 (new.txt)

我们假设“hello.txt”包含以下文本 -

Hello World
TutorialsPoint
PHP Tutorials

Example

以下是创建现有文件副本的 PHP 代码:

<?php
   $file = fopen("hello.txt", "r");
   $newfile = fopen("new.txt", "w");
   while(! feof($file)) {
      $str = fgets($file);
      fputs($newfile, $str);
   }
   fclose($file);
   fclose($newfile);
?>

新创建的“new.txt”文件应具有完全相同的内容。

Method 2

我们在此处从 PHP 库中使用了两个内置函数 -

file_get_contents(
   string $filename,
   bool $use_include_path = false,
   ?resource $context = null,
   int $offset = 0,
   ?int $length = null
): string|false

此函数将整个文件读入字符串。$filename 参数是一个字符串,它包含要读取的文件的名称。

另一个函数是 -

file_put_contents(
   string $filename,
   mixed $data,
   int $flags = 0,
   ?resource $context = null
): int|false

此函数会 将 $data 中的内容放入 $filename 中。它会返回写入的字节数。

Example

在下面的示例中,我们在字符串 $data 中读取了“hello.txt”中的内容,并将其用作参数写入“test.txt”文件中。

<?php
   $source = "hello.txt";
   $target = "test.txt";
   $data = file_get_contents($source);
   file_put_contents($target, $data);
?>

Method 3

PHP 提供 copy() 函数,专门用于执行复制操作。

copy(string $from, string $to, ?resource $context = null): bool

$from 参数是一个包含现有文件内容的字符串。 $to 参数也是一个字符串,其中包含要创建的新文件名称。如果目标文件已存在,它将被覆盖。

复制操作会根据文件是否成功复制返回 truefalse

Example

让我们使用 copy() 函数将“text.txt”作为“hello.txt”文件的副本。

<?php
   $source = "a.php";
   $target = "a1.php";
   if (!copy($source, $target)) {
      echo "failed to copy $source...\n";
   }
?>

PHP - Append File

在 PHP 中,fopen() 函数返回一个文件指针,用于不同的打开模式,例如“w”表示写入模式,“r”表示读取模式,“r+”或“r+”表示同时读/写操作,以及“a”表示追加模式。

当使用“w”模式参数打开文件时,它总是打开一个新文件。这意味着如果文件已经存在,其内容将丢失。随后的 fwrite() 函数将数据放在文件开始位置。

假设存在一个名为 “new.txt” 的文件,内容如下:

Hello World
TutorialsPoint
PHP Tutorial

以下语句 -

$fp = fopen("new.txt", "w");

删除所有现有数据,然后再写入新内容。

Read/Write Mode

显然,在以“r”模式打开文件时无法添加新数据。然而, “r+”或“w+” mod 在“r/w”模式下打开文件,但在打开文件后一个 fwrite() 语句仍会覆盖内容。

Example

查看以下代码:

<?php
   $fp = fopen("new.txt", "r+");
   fwrite($fp, "PHP-MySQL Tutorial\n");
   fclose($fp);
?>

利用这段代码, “new.txt” 文件的内容现在变为 −

PHP-MySQL Tutorial
lsPoint
PHP Tutorial

为了确保新内容添加到现有文件的末尾,我们需要在写操作前手动将文件指针放置到末尾。(文件的初始指针位置在第 0 个字节)

The fseek() Function

PHP 的 fseek() 函数让您能够将文件指针放置到任何您想要的位置 −

fseek(resource $stream, int $offset, int $whence = SEEK_SET): int

$whence 参数是指从哪里计算偏移量。它的值有 −

  1. SEEK_SET − 将位置设置为等于偏移字节。

  2. SEEK_CUR − 将位置设置为当前位置外加偏移量。

  3. SEEK_END − 将位置设置为文件末尾外加偏移量。

Example

因此,我们需要利用 fseek() 函数将指针移动到末尾,如此以下代码,将新内容添加到末尾。

<?php
   $fp = fopen("new.txt", "r+");
   fseek($fp, 0, SEEK_END);
   fwrite($fp, "\nPHP-MySQL Tutorial\n");
   fclose($fp);
?>

现在检查 “new.txt” 的内容。它将具有以下文本 −

Hello World
TutorialsPoint
PHP Tutorial
PHP-MySQL Tutorial

Append Mode

无需手动将指针移动到末尾,fopen() 函数中的“a”参数会以追加模式打开文件。每个 fwrite() 语句将内容添加到现有内容的末尾,通过自动将指针移动到 SEEK_END 位置。

<?php
   $fp = fopen("new.txt", "a");
   fwrite($fp, "\nPHP-MySQL Tutorial\n");
   fclose($fp);
?>

fopen() 函数允许的模式之一是“r+”模式,使用此模式,文件执行读/追加操作。要读取任何位置的数据,您可以利用 fseek() 将指针置于所需的字节。但是,每次 fwrite() 操作仅在末尾写新内容。

Example

在下面的程序中,文件在“a+”模式下打开。为了读取第一行,我们使文件位置偏移 0——从开头开始。然而, fwrite() 语句仍然在末尾添加新内容,并且不会覆盖后面的一行,就像在“r+”模式打开时那样。

<?php
   $fp = fopen("new.txt", "a+");
   fseek($fp, 0, SEEK_SET);
   $data = fread($fp, 12);
   echo $data;
   fwrite($fp, "PHP-File Handling");
   fclose ($fp);
?>

因此,如果文件在“r+/w+”模式或“a/a+”模式下打开,我们就可以追加数据到现有文件。

PHP - Delete File

PHP 没有 delete 关键字或 delete() 函数。它提供 unlink() 函数代替,此函数被调用时会从文件系统中删除一个文件。它类似于 Unix/C 中的 unlink 函数。

如果无法完成删除操作,则 PHP 会返回 false 并显示一条 E_WARNING 消息。

unlink(string $filename, ?resource $context = null): bool

unlink() 函数的必需字符串参数是一个字符串,该字符串指明要删除的文件。

Example

以下代码演示了 unlink() 函数的简单用法:

<?php
   $file = "my_file.txt";

   if (unlink($file)) {
      echo "The file was deleted successfully.";
   } else {
      echo "The file could not be deleted.";
   }
?>

unlink() 函数还可以删除到某个文件符号链接。但是,删除符号链接并不会删除原始文件。符号链接是既存文件的一个捷径。

在 Windows 中,以管理员权限打开命令提示符,并使用 mlink 命令和 /h 开关来创建到某个文件的符号链接。( /j 开关用于目录的符号链接)

mklink /h hellolink.lnk hello.txt
Hardlink created for hellolink.lnk <<===>> hello.txt

在 Ubuntu Linux 中,要创建到某个文件的符号链接,可使用以下命令:

ln -s /path/to/original_file /path/to/symlink

要创建到某个目录的符号链接,可使用以下命令:

ln -s /path/to/original_directory /path/to/symlink

在 PHP 中,还有一个 symlink() 函数用于此目的。

symlink(string $target, string $link): bool

Example

使用以下代码创建符号链接:

<?php
   $target = 'hello.txt';
   $link = 'hellolink.lnk';
   symlink($target, $link);

   echo readlink($link);
?>

现在,删除上面创建的符号链接:

unlink("hellolink.lnk");

如果查看当前工作目录,则符号链接将被删除,而原始文件保持不变。

How to Rename a File in PHP

您可借助操作系统的控制台中相应命令来更改现有文件的名称。例如,Linux 终端中的“ mv command ”或 Windows 命令提示符中的“ rename command ”可帮助您更改某个文件的名称。

但是,要以编程方式重命名文件,PHP 的内置库中包含一个 rename() 函数。

以下是 rename() 函数的 syntax -

rename(string $from, string $to, ?resource $context = null): bool

$from$to 两个字符串分别是文件的名字,文件已经存在和新的。rename() 函数会尝试将 $from 重命名为 $to ,如果需要的话,它会将其移动到其他目录。

如果你正在重命名 file$to 已存在,那么 $to 将被覆写。如果你正在重命名 directory$to 存在,那么这个函数将抛出一个 warning

将“hello.txt”重命名为“test.txt” -

<?php
   rename("hello.txt", "test.txt");
?>

你也可以使用一个间接的方法来重命名文件。复制一个已存在的文件,并且删除原件。这样也可以将“hello.txt”重命名为“test.txt” -

copy("hello.txt", "test.txt");
unlink("hello.txt");

PHP – Handle CSV File

流行的电子表格程序使用 CSV 文件格式(代表以逗号分隔的值)来将工作表数据导出为纯文本。文件中的每一行代表工作表中的一行,每一列中的值都用逗号分隔。

PHP 的文件系统函数库提供了两个函数 - fgetcsv()fputcsv() - 分别用来从 CSV 文件读取数据到一个数组中,并将数组元素放入 CSV 文件中。

The fgetcsv() Function

getcsv() 函数从文件指针读取一行,并将其解析为 CSV 字段。

fgetcsv(
   resource $stream,
   ?int $length = null,
   string $separator = ",",
   string $enclosure = "\"",
   string $escape = "\\"
): array|false

$stream 参数是一个文件资源的句柄,在 read mode 中打开。用来解析字段的默认分隔符号是逗号,如果你需要,可以指定任何其他符号。

fgetcsv() 函数返回一个包含字段的索引数组。如果函数遇到任何错误,它会返回 false

为了演示 fgetcsv() 函数的使用,将以下文本保存在当前工作目录中,作为“hello.txt”。

Name, Email, Post, Salary
Ravishankar, ravi@gmail.com, Manager, 40000
Kavita, kavita@hotmail.com, Assistant, 25000
Nandkumar, nandu@example.com, Programmer, 30000

Example

下面的 PHP 代码从这个文件读取 CSV 数据,并返回一个数组。然后在 HTML 表格中呈现数组中的字段 -

<?php
   $filename = 'hello.csv';
   $data = [];

   // open the file
   $f = fopen($filename, 'r');

   if ($f === false) {
      die('Cannot open the file ' . $filename);
   }

   // read each line in CSV file at a time
   while (($row = fgetcsv($f)) !== false) {
      $data[] = $row;
   }

   // close the file
   fclose($f);
   echo "<table border=1>";
   foreach ($data as $row) {
      echo "<tr>";
      foreach($row as $val) {
         echo "<td>$val</td>";
      }
      echo "</tr>";
   }
   echo "</table>";
?>

它将生成以下 output

Name

Email

Post

Salary

Ravishankar

ravi@gmail.com

Manager

40000

Kavita

kavita@hotmail.com

Assistant

25000

Nandkumar

nandu@example.com

Programmer

30000

The fputcsv() Function

fputcsv() 函数将一个索引数组及其元素(由逗号分隔)放入 CSV 文件当前文件指针的位置。

fputcsv(
   resource $stream,
   array $fields,
   string $separator = ",",
   string $enclosure = "\"",
   string $escape = "\\",
   string $eol = "\n"
): int|false

目标文件必须以写模式打开。第二个强制参数是一个包含由逗号分隔的字段的数组。就像在 fgetcsv() 函数中,默认分隔符号是逗号。

Example

在下面的代码中,一个由逗号分隔的值组成的二维数组被写入一个 CSV 文件。

<?php
   $data = [
      ["Name", "Email", "Post", "Salary"],
      ["Ravishankar", "ravi@gmail.com", "Manager", "40000"],
      ["Kavita", "kavita@hotmail.com", "Assistant", "25000"],
      ["Nandkumar", "nandu@example.com", "Programmer", "30000"],
   ];
   $filename = 'employee.csv';

   // open csv file for writing
   $f = fopen($filename, 'w');

   if ($f === false) {
      die('Error opening the file ' . $filename);
   }

   // write each row at a time to a file
   foreach ($data as $row) {
      fputcsv($f, $row);
   }

   // close the file
   fclose($f);
?>

在上面程序执行之后,“employee.csv”文件应当被创建在当前工作目录中。

PHP – File Permissions

权限的概念是 Unix/Linux 文件系统核心的内容。权限决定了谁可以访问文件,以及如何访问文件。Linux 中的文件权限受 chmod command 控制,该命令可以在 Linux 终端里面运行。PHP 提供了 chmod() function ,您可以使用它以编程方式处理文件权限。

仅当您在 Linux 操作系统上工作时,PHP 的 chmod() 函数才是有效的。它在 Windows 上不起作用,因为 Windows操作系统的文件权限控制机制不同。

要查看启用的文件权限,请使用 “ ls -l ” 命令获取文件列表(长列表)

mvl@GNVBGL3:~$ ls -l

-rwxr-xr-x 1 mvl mvl 16376 May  5 21:52 a.out
-rw-r--r-- 1 mvl mvl    83 May  5 21:52 hello.cpp
-rwxr-xr-x 1 mvl mvl    43 Oct 11 14:50 hello.php
-rwxr-xr-x 1 mvl mvl    43 May  8 10:01 hello.py
drwxr-xr-x 5 mvl mvl  4096 Apr 20 21:52 myenv

第一列包含每个文件的权限标志。第三列和第四列指出每个文件的所有者和组,然后是大小、日期和时间以及文件名。

权限字符串有十个字符,它们的含义解释如下 −

Position

Meaning

1

“d”,如果是目录,“-”如果是普通文件

2, 3, 4

文件所有者的读、写、执行权限

5, 6, 7

组的读、写、执行权限

8, 9, 10

其他(所有人)的读、写、执行权限

权限字符串中的字符有以下含义:

Value

Meaning

-

Flag is not set.

r

File is readable.

w

文件可写。对于目录,可以创建或删除文件。

x

文件可执行。对于目录,可以列出文件。

如果你考虑上述列表中的第一个条目:

-rwxr-xr-x 1 mvl mvl 16376 May  5 21:52 a.out

“a.out”文件由用户“mvl”和组“mvl”所有。它是一个普通文件,所有者有“读/写/执行”权限,并且组和其他人有“读/执行”权限。

权限标志的二进制和八进制表示可以用下表理解:

Octal Digit

Binary Representation (rwx)

Permission

0

000

none

1

001

execute only

2

010

write only

3

011

write and execute

4

100

read only

5

101

read and execute

6

110

read and write

7

111

读、写和执行(完全权限)

The chmod() Function

chmod() 函数可以更改指定文件的权限。成功时返回 true ,否则在失败时返回 false

chmod(string $filename, int $permissions): bool

chmod() 函数尝试将指定文件( $filename )的模式更改为权限中给定的模式。

第二个参数 $permissions 是一个四位八进制数字的八进制数。第一位始终为零,第二位指定所有者的权限,第三位指定所有者的用户组权限,第四位指定其他人权限。每位数字都是每种类型的权限值的和。

1

Execute Permission

2

Write Permission

4

Read Permission

$permissions 参数的默认值是 0777 ,这意味着目录在启用执行、写和读权限时创建。

Example

请看以下示例:

<?php

   // Read and write for owner, nothing for everybody else
   chmod("/PhpProject/sample.txt", 0600);

   // Read and write for owner, read for everybody else
   chmod("/PhpProject/sample.txt", 0644);

   // Everything for owner, read and execute for everybody else
   chmod("/PhpProject/sample.txt", 0755);

   // Everything for owner, read for owner's group
   chmod("/PhpProject/sample.txt", 0740);
?>

The chown() Function

chown() 函数尝试将文件 filename 的所有者更改为新用户。请注意,只有超级用户可以更改文件的拥有者。

chown(string $filename, string|int $user): bool

Example

请看以下示例:

<?php

   // File name and username to use
   $file_name= "index.php";
   $path = "/PhpProject/backup: " . $file_name ;
   $user_name = "root";

   // Set the user
   chown($path, $user_name);

   // Check the result
   $stat = stat($path);
   print_r(posix_getpwuid(fileowner($path)));
?>

The chgrp() Function

chgrp() 函数尝试将文件 filename 的组更改为组。

chgrp(string $filename, string|int $group): bool

只有 superuser 可以随意更改文件的组;其他用户可以将文件的组更改为该用户所属的任何组。

Example

请看以下示例:

<?php
   $filename = "/PhpProject/sample.txt";
   $format = "%s's Group ID @ %s: %d\n";
   printf($format, $filename, date('r'), filegroup($filename));
   chgrp($filename, "admin");
   clearstatcache();  	// do not cache filegroup() results
   printf($format, $filename, date('r'), filegroup($filename));
?>

它将生成以下 output

/PhpProject/sample.txt's Group ID @ Fri, 13 Oct 2023 07:42:21 +0200: 0
/PhpProject/sample.txt's Group ID @ Fri, 13 Oct 2023 07:42:21 +0200: 0

PHP – Create Directory

计算机文件按层次顺序存储在本地存储设备 (称为 drive ) 中,其中一个目录包含一个或多个文件以及子目录。用于创建和管理目录的各自 DOS 命令在操作系统 Windows、Linux 等等中进行定义。

PHP 提供了目录管理函数来创建目录、更改当前目录和移除某个目录。

本章讨论在 PHP 中使用以下目录函数的情况 -

The mkdir() Function

mkdir() 函数创建一个新目录,它的路径作为函数之一的参数给出

mkdir(
   string $directory,
   int $permissions = 0777,
   bool $recursive = false,
   ?resource $context = null
): bool

Parameters

  1. $directory - 第一个参数 $directory 是必须的。它是一个字符串,其中包含要创建的新目录的绝对路径或相对路径。

  2. $permissions - 第二个参数 $permissions 是一个八进制数字,带有四个八进制数字。第一个数字始终为零,第二个数字指定属主的权限,第三个数字指定属主的用户组,第四个数字指定其他人。

每个数字都是针对每种权限类型的值的和 -

  1. 1 = execute permission

  2. 2 = write permission

  3. 4 = read permission

$permissions 参数的默认值为 0777 ,这意味着创建目录时启用了执行、写入和读取权限。

请注意,在 Windows 操作系统上工作时,$permissions 参数会被忽略。

  1. $recursive - 如果为 true,则指定目录的任何父目录也会被创建,并具有相同的权限。

  2. $context - 这个可选参数是流资源。

mkdir() 函数返回真或假,表示函数是否已成功执行。

Examples

以下是 mkdir() 函数的一些示例。

对 mkdir() 的以下调用在当前工作目录中创建子目录。点表示路径是相对的。

$dir = "./mydir/";
mkdir($dir);

我们可以提供包含要创建的目录的绝对路径的字符串参数。

$dir = "c:/newdir/";
mkdir($dir);

由于 $recursive 参数设置为 true,对 mkdir() 的以下调用包含当前目录内的嵌套目录结构。

$dirs = "./dir1/dir2/dir3/";
mkdir($dirs, 0777, true);

Windows 资源管理器将显示嵌套目录结构,如下所示:

create directory

The chdir() Function

PHP 中的 chdir() 函数对应于 Linux/Windows 中的 chdircd 命令。它会导致根据需要更改当前目录。

chdir(string $directory): bool

此函数的字符串参数是要将当前目录更改到的目录的绝对或相对路径。它返回真或假。

The getcwd() Function

getcwd() 函数的工作方式类似于 Ubuntu Linux 中的 pwd 命令,并返回当前工作目录的路径。

Example

使用以下代码段,PHP 会在更改当前工作目录之前和之后显示当前工作目录。新当前目录中创建了一些文件。使用 scandir() 函数列出文件。

<?php
   echo "current directory: ". getcwd() . PHP_EOL;
   $dir = "./mydir";
   chdir($dir);
   echo "current directory changed to: ". getcwd() .PHP_EOL;

   $fp = fopen("a.txt", "w");
   fwrite($fp, "Hello World");
   fclose($fp);

   copy("a.txt", "b.txt");
   $dir = getcwd();
   foreach(scandir($dir) as $file)
   echo $file . PHP_EOL;
?>

它将生成以下 output

current directory: C:\xampp\php
current directory changed to: C:\xampp\php\mydir
.
..
a.txt
b.txt

The rmdir() Function

rmdir() 函数删除了以参数形式给出的路径的某个目录。要删除的目录必须为空。

$dir = "c:/newdir/";
rmdir($dir) or die("The directory is not present or not empty");

PHP – Listing Files

Windows 命令 DIR 和 Linux 命令 ls 都显示当前目录中的文件列表。可以使用不同的交换机操作这些命令,以便对显示的文件列表应用条件。PHP 提供了一些用于以编程方式列出给定目录中文件的方法。

The readdir() Function

PHP 中的 opendir() 函数类似于 fopen() 函数。它返回目录句柄,以便可以按序列化方式读取目录的内容。

opendir(string $directory, ?resource $context = null): resource|false

此函数打开一个目录句柄,用于后续的 closedir()、readdir() 和 rewinddir() 调用。

readdir() 函数读取 opendir() 函数返回的流句柄中的下一个可用条目。

readdir(?resource $dir_handle = null): string|false

此处, dir_handle 是先前使用 opendir() 打开的目录句柄,如果未指定,则假定为由 opendir() 打开的最后一个链接。

closedir() 函数类似于 fclose() 函数。它关闭目录句柄。

closedir(?resource $dir_handle = null): void

该函数关闭 dir_handle 指示的目录流。该流必须先前由 opendir() 打开。

Example

以下 PHP 代码从当前登录目录中一次读取一个文件。

<?php
   $dir = getcwd();

   // Open a known directory, and proceed to read its contents
   if (is_dir($dir)) {
      if ($dh = opendir($dir)) {
         while (($file = readdir($dh)) !== false) {
            echo "filename:" . $file . "\n";
         }
         closedir($dh);
      }
   }
?>

The scandir() Function

scandir() 函数检索给定目录中的文件和子目录。

scandir(string $directory,
int $sorting_order = SCANDIR_SORT_ASCENDING,
?resource $context = null): array|false

“sorting_order” 默认按升序排列。如果将此可选参数设置为 SCANDIR_SORT_DESCENDING,则排序顺序变为按降序排列。如果它设置为 SCANDIR_SORT_NONE,则结果将变为未排序。

Example

使用以下 PHP 代码,scandir() 函数返回给定目录中的文件数组。

<?php
   $dir = "c:/xampp/php/mydir/";

   $files = scandir($dir);
   var_dump($files);
?>

它将生成以下 output

array(4) {
   [0]=>
   string(1) "."
   [1]=>
   string(2) ".."
   [2]=>
   string(5) "a.txt"
   [3]=>
   string(5) "b.txt"
}

你可以使用 foreach 循环遍历 scandir() 函数返回的数组。

<?php
   $dir = "c:/xampp/php/mydir/";

   $files = scandir($dir);
   foreach ($files as $file)
   echo $file . PHP_EOL;
?>

它将生成以下 output

.
..
a.txt
b.txt

Object Oriented Programming in PHP

我们可以想象我们的宇宙是由不同的物体组成的,如太阳、地球、月亮等。类似地,我们可以想象我们的汽车是由不同的物体组成的,如车轮、方向盘、齿轮等。同样,还存在面向对象编程概念,该概念将所有内容都假设为对象,并使用不同的对象实现软件。

Object Oriented Concepts

在我们详细介绍之前,让我们定义与面向对象编程相关的术语。

  1. Class − 这是一个由程序员定义的数据类型,它包括本地函数和本地数据。可以将类视作一个模板,用于创建同一类型的(或类)对象的许多实例。

  2. Object - 由类定义的数据结构的单个实例。定义一个类一次,然后创建属于它的许多对象。对象也被称为实例。

  3. Member Variable − 这些是类内定义的变量。该数据对外不可见,可通过成员函数访问。一旦创建了对象,这些变量就会被调用为对象的属性。

  4. Member function − 这些是类内定义的函数,用于访问对象数据。

  5. Inheritance − 当一个类继承父类的现有函数时,该类被称为继承。在此,子类将继承父类的一些或全部成员函数和变量。

  6. Parent class − 被另一个类继承的类。这也被称为基类或超类。

  7. Child Class − 从另一个类继承的类。这也称为子类或派生类。

  8. Polymorphism − 这是一个面向对象的概念,同一个函数可用于不同的目的。例如,函数名称保持不变,但是它可以接受不同数量的参数并执行不同的任务。

  9. Overloading − 一种类型的多态,其中一些或全部操作符具有不同的实现,具体取决于它们的争论类型。同样,函数也可以通过实现不同而重载。

  10. Data Abstraction − 数据的任何表示形式,其中实现细节是隐藏的(抽象的)。

  11. Encapsulation − 指一个概念,即我们将所有数据和成员函数封装在一起以形成一个对象。

  12. Constructor − 指一个特殊类型的函数,当从类中进行对象形成时,该函数会自动被调用。

  13. Destructor − 指一个特殊类型的函数,当一个对象被删除或超出范围时,该函数会自动被调用。

Defining PHP Classes

在 PHP 中定义新类的通用格式如下 −

<?php
   class phpClass {
      var $var1;
      var $var2 = "constant string";

      function myfunc ($arg1, $arg2) {
         [..]
      }
      [..]
   }
?>

下面是每一行的说明 −

  1. 特殊格式 class ,后跟要定义的类的名称。

  2. 一个大括号,包围任意数量的变量声明和函数定义。

  3. 变量声明以特殊格式 var 开头,后跟一个常规的 $ 变量名;它们还可以将初始赋值设为常量值。

  4. 函数定义看起来很像独立的 PHP 函数,但它是类的局部函数,用于设置和访问对象数据。

Example

下面是一个示例,定义了一个 Books 类型的类 −

<?php
   class Books {
      /* Member variables */
      var $price;
      var $title;

      /* Member functions */
      function setPrice($par){
         $this->price = $par;
      }

      function getPrice(){
         echo $this->price ."<br/>";
      }

      function setTitle($par){
         $this->title = $par;
      }

      function getTitle(){
         echo $this->title ." <br/>";
      }
   }
?>

变量 $this 是一个特殊变量,它引用同个对象,即它自身。

Creating Objects in PHP

一旦定义了类,您就可以创建任意多的该类类型的对象。以下是如何使用 new 操作符创建对象的示例。

$physics = new Books;
$maths = new Books;
$chemistry = new Books;

在这里,我们创建了三个对象,这些对象相互独立且单独存在。下一步,我们将看到如何访问成员函数和处理成员变量。

Calling Member Functions

创建对象之后,您将能够调用与该对象相关联的成员函数。一个成员函数将只能处理相关对象的成员变量。

下面的示例演示了如何通过调用成员函数为这三本书设置标题和价格。

$physics->setTitle( "Physics for High School" );
$chemistry->setTitle( "Advanced Chemistry" );
$maths->setTitle( "Algebra" );

$physics->setPrice( 10 );
$chemistry->setPrice( 15 );
$maths->setPrice( 7 );

现在可以调用另一个成员函数来获取上述示例中设置的值 -

$physics->getTitle();
$chemistry->getTitle();
$maths->getTitle();
$physics->getPrice();
$chemistry->getPrice();
$maths->getPrice();

这会产生以下结果 −

Physics for High School
Advanced Chemistry
Algebra
10
15
7

Constructor Functions

构造函数是一种特殊类型的函数,它在创建对象时会自动调用。因此,通过构造函数初始化许多内容,我们可以充分利用此行为。

PHP 提供了一个名为 __construct() 的特殊函数来定义一个构造函数。您可以将任意数量的参数传递到构造函数中。

以下示例将为 Books 类创建一个构造函数,它将在创建对象时初始化该书的价格和标题。

function __construct( $par1, $par2 ) {
   $this->title = $par1;
   $this->price = $par2;
}

现在我们无需单独调用 set 函数来设置价格和标题。我们只能在创建对象时初始化这两个成员变量。查看以下示例 -

$physics = new Books( "Physics for High School", 10 );
$maths = new Books ( "Advanced Chemistry", 15 );
$chemistry = new Books ("Algebra", 7 );

/* Get those set values */
$physics->getTitle();
$chemistry->getTitle();
$maths->getTitle();

$physics->getPrice();
$chemistry->getPrice();
$maths->getPrice();

这会产生以下结果 −

Physics for High School
Advanced Chemistry
Algebra
10
15
7

Destructor

像构造函数一样,您可以使用函数 __destruct() 定义一个析构函数。您可以在析构函数中释放所有资源。

Inheritance

PHP 类定义可以使用 extends 子句从父类定义中继承,语法如下:

class Child extends Parent {
   <definition body>
}

继承的效果是子类(或子类或派生类)具有以下特征 -

  1. 自动具有父类的所有成员变量声明。

  2. 自动具有与父类相同的所有成员函数,这些函数(默认情况下)将按照它们在父类中的工作方式工作。

以下示例继承 Books 类并根据要求添加更多功能。

class Novel extends Books {
   var $publisher;

   function setPublisher($par){
      $this->publisher = $par;
   }

   function getPublisher(){
      echo $this->publisher. "<br />";
   }
}

现在,除了继承的函数之外,Novel 类还保留了两个其他成员函数。

Function Overriding

子类中的函数定义覆盖了父类中同名定义。在子类中,我们可以修改从父类继承的函数的定义。

在以下示例中,getPrice 和 getTitle 函数被覆盖以返回一些值。

function getPrice() {
   echo $this->price . "<br/>";
   return $this->price;
}

function getTitle(){
   echo $this->title . "<br/>";
   return $this->title;
}

Public Members

除非您另行指明,否则类的属性和方法均为公共的。也就是说,它们可以在三种可能的情况下进行访问 -

  1. 从声明它的类外部

  2. 从声明它的类中

  3. 从实现声明它的类的另一个类中

到目前为止,我们已经看到了所有成员作为公共成员。如果您希望限制类成员的可访问性,则可以将类成员定义为 privateprotected

Private members

通过将成员设为私有,你可以限制其对声明它的类的可访问性。私有成员无法从继承声明它的类的类中引用,也无法从类外部访问。

可以使用成员前面的 private 关键字将类成员设为私有。

class MyClass {
   private $car = "skoda";
   $driver = "SRK";

   function __construct($par) {

      // Statements here run every time
      // an instance of the class
      // is created.
   }

   function myPublicFunction() {
      return("I'm visible!");
   }

   private function myPrivateFunction() {
      return("I'm  not visible outside!");
   }
}

当 MyClass 类使用 extends 被另一个类继承时,myPublicFunction() 将可见,$driver 也将可见。扩展类不会意识到或访问 myPrivateFunction 和 $car,因为它们声明为私有。

Protected members

受保护的属性或方法在其声明所在的类以及该类的扩展类中都可以访问。受保护的成员在除了这两种类之外的类中不可用。可以使用成员前面的 protected 关键字将类成员设为受保护。

以下是 MyClass 的不同版本 −

class MyClass {
   protected $car = "skoda";
   $driver = "SRK";

   function __construct($par) {
      // Statements here run every time
      // an instance of the class
      // is created.
   }

   function myPublicFunction() {
      return("I'm visible!");
   }

   protected function myPrivateFunction() {
      return("I'm  visible in child class!");
   }
}

Interfaces

接口的定义是为了向实现者提供通用的函数名称。不同的实现者可以根据其要求来实现这些接口。你可以说,接口是开发人员实现的骨架。

从 PHP5 起,可以像这样定义接口 −

interface Mail {
   public function sendMail();
}

然后,如果另一个类实现了该接口,如下所示 −

class Report implements Mail {
   // sendMail() Definition goes here
}

Constants

常量有点像变量,因为它含有值,但实际上更像函数,因为常量是不可变的。一旦声明常量,它就不会改变。

声明常量很简单,在 MyClass 的此版本中就是如此 −

class MyClass {
   const requiredMargin = 1.7;

   function __construct($incomingValue) {

      // Statements here run every time
      // an instance of the class
      // is created.
   }
}

在此类中,requiredMargin 是一个常量。它使用关键字 const 声明,在任何情况下都不得将其更改为 1.7 以外的任何值。请注意,与变量名称不同,常量的名称没有前导 $。

Abstract Classes

抽象类是不可实例化的,只能继承。使用关键字 abstract 声明抽象类,如下所示 −

从抽象类继承时,父类的类声明中标记为 abstract 的所有方法都必须由子类定义;此外,这些方法必须使用相同的可见性定义。

abstract class MyAbstractClass {
   abstract function myAbstractFunction() {
   }
}

请注意,抽象类中的函数定义也必须以前导关键字 abstract 为前缀。在非抽象类中不能有抽象函数定义。

Static Keyword

将类成员或方法声明为 static 使它们可以在不需要实例化类的情况下对其进行访问。声明为 static 的成员无法通过实例化的类对象进行访问(虽然静态方法可以访问)。

尝试使用以下示例 −

<?php
   class Foo {
      public static $my_static = 'foo';

      public function staticValue() {
         return self::$my_static;
      }
   }

   print Foo::$my_static . "\n";
   $foo = new Foo();

   print $foo->staticValue() . "\n";
?>

Final Keyword

PHP 5 引入了 final 关键字,它通过使用 final 作为定义前缀来阻止子类覆盖方法。如果类本身被定义为 final,则无法使用其扩展。

以下示例导致致命错误:无法覆盖 final 方法 BaseClass::moreTesting()

<?php

   class BaseClass {
      public function test() {
         echo "BaseClass::test() called<br>";
      }

      final public function moreTesting() {
         echo "BaseClass::moreTesting() called<br>";
      }
   }

   class ChildClass extends BaseClass {
      public function moreTesting() {
         echo "ChildClass::moreTesting() called<br>";
      }
   }
?>

Calling parent constructors

让我们通过显式地调用父类的构造函数,然后再执行实例化子类时除了需要的所有其他操作之外的任何操作来编写它,而不是为子类编写一个全新的构造函数。这里有一个简单的示例 −

class Name {
   var $_firstName;
   var $_lastName;

   function Name($first_name, $last_name) {
      $this->_firstName = $first_name;
      $this->_lastName = $last_name;
   }

   function toString() {
      return($this->_lastName .", " .$this->_firstName);
   }
}
class NameSub1 extends Name {
   var $_middleInitial;

   function NameSub1($first_name, $middle_initial, $last_name) {
      Name::Name($first_name, $last_name);
      $this->_middleInitial = $middle_initial;
   }

   function toString() {
      return(Name::toString() . " " . $this->_middleInitial);
   }
}
In this example, we have a parent class (Name), which has a two-argument constructor, and a subclass (NameSub1), which has a three-argument constructor. The constructor of NameSub1 functions by calling its parent constructor explicitly using the

syntax (passing two of its arguments along) and then setting an additional field. Similarly, NameSub1 defines its non constructor toString() function in terms of the parent function that it overrides.

NOTE − 构造函数可以使用与类名称相同的名称来定义。它在上面的示例中被定义。

PHP – Classes and Objects

类和对象的概念对于 PHP 的面向对象编程方法至关重要。 class 是其对象的模板描述。它包括处理属性的属性和函数。 object 是其类的实例。它的特点是类中定义的属性和函数。

classes and objects

Defining a Class in PHP

PHP 有一个用于定义类的关键词 “ class ”。同样,PHP 提供了关键词 “ new ” 来声明任何给定类的对象。

在 PHP 中定义新类的通用格式如下 −

<?php
   class phpClass {
      var $var1;
      var $var2 = "constant string";

      function myfunc ($arg1, $arg2) {
         [..]
      }
      [..]
   }
?>

关键词 class 后跟您想要定义的类的名称。类名称遵循与 PHP 变量相同的命名约定。后跟一对花括号,其中包含任意数量的变量声明(属性)和函数定义。

变量声明以另一个保留关键字 var 开始,后跟一个常规 $variable 名称;它们还可以对常量值进行初始赋值。

函数定义看起来很像独立的 PHP 函数,但它们是类中的本地函数,并且将用于设置和访问对象数据。类中的函数也称为方法。

Example

这里有一个定义 Book 类型类的示例 −

class Book {

   /* Member variables */
   var $price;
   var $title;

   /* Member functions */
   function setPrice($par){
      $this->price = $par;
   }

   function getPrice(){
      echo $this->price ."<br/>";
   }

   function setTitle($par){
      $this->title = $par;
   }

   function getTitle(){
      echo $this->title ." <br/>";
   }
}

当从对象上下文中调用方法时,伪变量 $this 可用。 $this 指的是调用对象。

Book 类有两个 member variables (或属性): $title$price 。成员变量(有时也称为实例变量)通常对每个对象具有不同的值;就像每本书的标题和价格都不同一样。

Book 类有函数(在类中定义的函数称为 methods )setTitle() 和 setPrice()。这些函数与对象和参数一起调用,用于分别设置标题和价格成员变量的值。

Book 类还有 getTitle()getPrice() 方法。调用时,它们会返回其引用已传递的对象的标题和价格。

一旦定义了一个类,您就可以使用 new 运算符声明一个或多个对象。

$b1 = new Book;
$b2 = new Book;

new 运算符为每个对象的成员变量和方法分配所需的内存。在这里,我们创建了两个对象,这些对象彼此独立,并且它们将分别存在。

每个对象都可以通过 “ ” 运算符访问其成员变量和方法。例如, b1 对象的 $title 属性为 “ $b1→title ”,要调用 setTitle() 方法,请使用 “ $b1→setTitle() ” 语句。

要设置 b1 对象的标题和价格,

$b1->setTitle("PHP Programming");
$b1->setPrice(450);

同样,以下语句获取 b1 书的标题和价格 −

echo $b1->getPrice();
echo $b1->getTitle();

Example

下面给出了一个完整的 PHP 脚本,该脚本定义 Book 类、声明两个对象和调用成员函数。

<?php
   class Book {

      /* Member variables */
      var $price;
      var $title;

      /* Member functions */
      function setPrice($par){
         $this->price = $par;
      }

      function getPrice(){
         echo $this->price ."\n";
      }

      function setTitle($par){
         $this->title = $par;
      }

      function getTitle(){
         echo $this->title ."\n";
      }
   }

   $b1 = new Book;
   $b2 =new Book;

   $b1->setTitle("PHP Programming");
   $b1->setPrice(450);
   $b2->setTitle("PHP Fundamentals");
   $b2->setPrice(275);
   $b1->getTitle();
   $b1->getPrice();
   $b2->getTitle();
   $b2->getPrice();
?>

它将生成以下 output

PHP Programming
450
PHP Fundamentals
275

PHP – Constructor and Destructor

与大多数面向对象语言一样,您还可以在 PHP 中的类中定义一个构造函数。当您使用 new 运算符声明一个对象时,它的成员变量不会分配任何值。构造函数用于在声明时初始化每个新对象。PHP 还支持具有析构函数,该析构函数会从内存中销毁对象,因为它不再有任何引用。

The __construct() Function

PHP 提供了一个用于初始化对象的 __construct() 函数。

__construct(mixed ...$values = ""): void

类内部的构造函数方法在每个新创建的对象上自动调用。请注意,定义构造函数不是强制性的。但是,如果存在,它适用于在使用对象之前它可能需要的任何初始化。

您可以向构造函数传递任意多个参数。__construct() 函数没有任何返回值。

让我们在前一章中使用的 Book 类中定义一个构造函数

<?php
   class Book {

      /* Member variables */
      var $price;
      var $title;

      /*Constructor*/
      function __construct(){
         $this->title = "PHP Fundamentals";
         $this->price = 275;
      }

      /* Member functions */
      function getPrice() {
         echo "Price: $this->price \n";
      }

      function getTitle(){
         echo "Title: $this->title \n";
      }
   }

   $b1 = new Book;
   $b1->getTitle();
   $b1->getPrice();
?>

它将生成以下 output

Title: PHP Fundamentals
Price: 275

Parameterized Constructor

$b1 的成员变量已经初始化,而无需调用 setTitle()setPrice() 方法,因为构造函数在对象声明后立即被调用。但是,此构造函数将针对每个对象调用,因此每个对象都具有 titleprice 属性的相同值。

要使用不同的值初始化每个对象,请使用带参数定义 @{s1} 函数。

@{s2} 函数的定义更改为以下内容 −

function __construct($param1, $param2) {
   $this->title = $param1;
   $this->price = $param2;
}

要初始化对象,请在声明中将值传递给括号内的参数。

$b1 = new Book("PHP Fundamentals", 375);

Example

现在,每个对象都可以对成员变量具有不同的值。

<?php
   class Book {

      /* Member variables */
      var $price;
      var $title;

      /*Constructor*/
      function __construct($param1, $param2) {
         $this->title = $param1;
         $this->price = $param2;
      }

      /* Member functions */
      function getPrice(){
         echo "Price: $this->price \n";
      }

      function getTitle(){
         echo "Title: $this->title \n";
      }
   }

   $b1 = new Book("PHP Fundamentals", 375);
   $b2 = new Book("PHP Programming", 450);

   $b1->getTitle();
   $b1->getPrice();
   $b2->getTitle();
   $b2->getPrice();
?>

它将生成以下 output

Title: PHP Fundamentals
Price: 375
Title: PHP Programming
Price: 450

Constructor Overloading

方法重载是面向对象编程中的一个重要概念,其中一个类可能具有多个构造函数定义,每个定义具有不同的参数数量。然而,PHP 不支持方法重载。可以通过在构造函数中使用带默认值的参数来克服此限制。

将 __construct() 函数更改为以下内容:

function __construct($param1="PHP Basics", $param2=380) {
   $this->title = $param1;
   $this->price = $param2;
}

现在,声明一个不带参数的对象,而另一个带参数。不带参数的对象将用默认参数初始化,带参数的对象将用传递的值初始化。

$b1 = new Book();
$b2 = new Book("PHP Programming", 450);

它将生成以下 output

Title: PHP Basics
Price: 380
Title: PHP Programming
Price: 450

Type Declaration in Constructor

由于 PHP(7.0 及更高版本)允许对函数参数使用标量类型声明,因此可以将 __construct() 函数定义为:

function __construct(string $param1="PHP Basics", int $param2=380) {
   $this->title = $param1;
   $this->price = $param2;
}

在 PHP 的早期版本中,允许使用类的名称来定义构造函数,但此功能自 PHP 8.0 起已弃用。

The __destruct() Function

PHP 还有一个 __destructor() 函数。它实现了一个析构函数概念,与其他面向对象语言(如 C++)中的概念类似。只要不存在对特定对象的引用,就会调用析构函数方法。

__destruct(): void

_destruct() 函数没有任何参数,也没有任何返回值。_destruct() 函数在任何对象超出作用域时都会自动调用这一事实可以通过在函数中放置 var_dump($this) 来验证。

如上所述, $this 携带对调用对象的引用;转储显示,成员变量被设置为 NULL

在 Book 类中添加析构函数,如下所示:

function __destruct() {
   var_dump($this);
   echo "object destroyed";
}

当程序退出时,将显示以下 output

object(Book)#1 (2) {
   ["price"]=>
   NULL
   ["title"]=>
   NULL
}
object destroyed

PHP – Access Modifiers

在 PHP 中,关键字 public, privateprotected 被称为 access modifiers 。这些关键字控制类属性和方法的可访问性或可见性的范围。其中一个关键字在声明成员变量和定义成员函数时添加为前缀。

PHP 代码是否可以自由地访问类成员,或者被限制获取,或者有条件地访问,是由这些关键字决定的 -

  1. Public − 类成员从任何地方都可以访问,即使在类作用域外,但只可以使用对象引用。

  2. Private − 类成员可以在类中访问。它防止外部类访问成员,即使参考了类实例。

  3. Protected − 成员只能在类及其子类中访问,其他地方都不能访问。

数据封装原则是面向对象编程方法的基础。它指的是将对象的成员数据或属性置于类外部环境的访问范围之外,只允许通过类中可用的方法或函数进行受控访问。

要实现封装,类的成员数据被设为 private ,方法被设为 public

access modifiers 1

Public Members

在 PHP 中,类成员(成员变量和其他成员函数)默认情况下是公开的。

Example

在下面的程序中,对象的成员变量 title 和 price 在类的外部可以自由访问,因为它们默认情况下是公开的,除非另行指定。

<?php
   class Book {
      /* Member variables */
      var $price;
      var $title;

      /*Constructor*/
      function __construct(string $param1="PHP Basics", int $param2=380) {
         $this->title = $param1;
         $this->price = $param2;
      }

      function getPrice() {
         echo "Title: $this->price \n";
      }

      function getTitle() {
         echo "Price: $this->title \n";
      }
   }
   $b1 = new Book();
   echo "Title : $b1->title Price: $b1->price";
?>

它将生成以下 output

Title : PHP Basics Price: 380

Private Members

如上所述,封装原则要求不得直接访问成员变量。只有方法应具有对数据成员的访问权。因此,我们需要将成员变量设为私有,并将方法设为公有。

<?php
   class Book {
      /* Member variables */
      private $price;
      private $title;

      /*Constructor*/
      function __construct(string $param1="PHP Basics", int $param2=380) {
         $this->title = $param1;
         $this->price = $param2;
      }

      public function getPrice() {
         echo "Price: $this->price \n";
      }

      public function getTitle() {
         echo "Title: $this->title \n;";
      }
   }
   $b1 = new Book();
   $b1->getTitle();
   $b1->getPrice();
   echo "Title : $b1->title Price: $b1->price";
?>

Output

现在,getTitle() 和 getPrice() 函数是公共的,能够访问私有成员变量 title 和 price。但是,如果尝试直接显示标题和价格,会遇到错误,因为它们不是公共的。

Title: PHP Basics
Price: 380
Fatal error: Uncaught Error: Cannot access private property
Book::$title in hello.php:31

Protected Members

针对类成员指定受保护的访问权在类继承的情况下有效。我们知道可以从类的外围访问公有成员,并且不能从类的外围访问私有成员。

protected 关键字允许访问同一类的对象和继承类中的对象,但禁止访问其他环境。

让我们在 Book 类示例中将标题成员设置为受保护的,将价格保留为私有的。

class Book {
   /* Member variables */
   private $price;
   protected $title;
   # rest of the code kept as it is
}
$b1 = new Book();
$b1->getTitle();
$b1->getPrice();

PHP 允许访问两个成员变量,因为该对象属于同一个类。

让我们添加一个 mybook 类,它继承了 Book 类 −

class mybook extends Book {
   # no additional members defined
}

它的对象仍能访问成员变量,因为子类继承了父类的公有和受保护的成员。

但是,将 mybook 类作为一个独立的类(不扩展 Book 类)并定义一个 getmytitle() 函数,该函数尝试访问 Book 类的受保护标题成员变量。

class mybook {
   public function getmytitle($b) {
      echo "Title: $b->title <br/>";
   }
}
$b1 = new mybook();
$b = new Book();
$b1->getmytitle($b);

由于 getmytitle() 函数尝试打印 Book 对象的标题,因此一个显示 Cannot access protected property Book::$title 的错误消息被引发。

Example

尝试运行以下代码 −

<?php
   class Book {
      private $price;
      protected $title;
      function __construct(string $param1="PHP Basics", int $param2=380) {
         $this->title = $param1;
         $this->price = $param2;
      }
      public function getPrice(){
         echo "Price: $this->price <br/>";
      }
      public function getTitle(){
         echo "Title: $this->title <br/>";
      }
   }
   class mybook {
      public function getmytitle($b) {
         echo "Title: $b->title <br/>";
      }
   }
   $b1 = new mybook();
   $b = new Book();
   $b1->getmytitle($b);
?>

它将生成以下 output

PHP Fatal error:  Uncaught Error: Cannot access protected property
   Book::$title in /home/cg/root/97848/main.php:18

因此,可以看到受保护的成员只能被同一类和继承类的对象访问。对于所有其他环境,受保护的成员不可访问。

可访问性规则可以由下表总结:

access modifiers 2

PHP – Inheritance

继承是面向对象编程方法论的基本原则之一。继承是一种软件建模方法,它允许扩展现有类以构建新类,而不是从头开始构建新类。

PHP 提供了所有功能在其对象模型中实现继承。在 PHP 软件开发中纳入继承会产生代码再利用,消除冗余的代码重复及逻辑组织。

想象一下你需要设计一个新类,这个类的大部分功能已经在一个现有类中得到明确定义。继承允许你扩展现有类,添加或移除其功能,并开发一个新类。事实上,PHP 有“extends”关键词来建立现有类和新类之间的继承关系。

class newclass extends oldclass {
   ...
   ...
}

当一个新类(以后将被称为继承类、子类、子类,等等)与一个现有类(将被称为基类、超类、父类,等等)拥有“是”关系时,继承就会出现。

php inheritence

在 PHP 中,当通过扩展另一个类来定义一个新类时,子类会继承来自父类的公共和受保护的方法、属性和常量。你可以自由重写继承方法的功能,否则它将按照父类中定义的那样保留其功能。

Example

请看以下示例:

<?php
   class myclass {
      public function hello() {
         echo "Hello from the parent class" . PHP_EOL;
      }
      public  function thanks() {
         echo "Thank you from parent class" . PHP_EOL;
      }
   }
   class newclass extends myclass {
      public function thanks() {
         echo "Thank you from the child class" . PHP_EOL;
      }
   }

   # object of parent class
   $obj1 = new myclass;
   $obj1->hello();
   $obj1->thanks();

   # object of child class
   $obj2 = new newclass;
   $obj2->hello();
   $obj2->thanks();
?>

它将生成以下 output

Hello from the parent class
Thank you from parent class
Hello from the parent class
Thank you from the child class

如前所述,子类继承父类的公共和受保护成员(属性和方法)。子类可以引入其他属性或方法。

在下面的示例中,我们使用 Book class 作为父类。在这里,我们创建一个 ebook class 来扩展 Book 类。新类有一个其他属性 - format (表示电子书的文件格式 - EPUB,PDF,MOBI 等)。电子书类定义了两个新方法来初始化和输出电子书数据,分别是 getebook()dispebook()

Example

完整的继承示例代码如下所示:

<?php
   class Book {

      /* Member variables */
      protected int $price;
      protected string $title;

      public function getbook(string $param1, int $param2) {
         $this->title = $param1;
         $this->price = $param2;
      }
      public function dispbook() {
         echo "Title: $this->title Price: $this->price \n";
      }
   }

   class ebook extends Book {
      private string $format;
      public function getebook(string $param1, int $param2, string $param3) {
         $this->title = $param1;
         $this->price = $param2;
         $this->format = $param3;
      }
      public function dispebook() {
         echo "Title: $this->title Price: $this->price\n";
         echo "Format: $this->format \n";
      }
   }
   $eb = new ebook;
   $eb->getebook("PHP Fundamentals", 450, "EPUB");
   $eb->dispebook();
?>

浏览器 output 如下所示:

Title: PHP Fundamentals Price: 450
Format: EPUB

如果你仔细查看 getebook() 函数,前两个赋值语句实际上是 getebook() 函数,而电子书类已经继承了它。因此,我们可以使用 parent 关键字和范围解析运算符调用它。

用以下代码更改 getebook() 函数代码:

public function getebook(string $param1, int $param2, string $param3) {
   parent::getbook($param1, $param2);
   $this->format = $param3;
}

同样,dispebook() 函数中的第一个 echo 语句被一个调用替换,后者位于父类中调用 dispbook() 函数:

public function dispebook() {
   parent::dispbook();
   echo "Format: $this->format<br/>";
}

Constructor in Inheritance

父类构造函数中的构造函数由子类继承,但是如果子类定义了一个构造函数,则无法在子类中直接调用它。

为了运行一个父构造函数,需要在子构造函数内调用 parent::__construct()

Example

请看以下示例:

<?php
   class myclass{
      public function __construct(){
         echo "This is parent constructor". PHP_EOL;
      }
   }
   class newclass extends myclass {
      public function __construct(){
         parent::__construct();
         echo "This is child class destructor" . PHP_EOL;
      }
   }
   $obj = new newclass();
?>

它将生成以下 output

This is parent constructor
This is child class destructor

然而,如果子类没有构造函数,那么它可以从父类继承构造函数,就像一个普通的类方法(如果它不是声明为私有的)。

Example

请看以下示例:

<?php
   class myclass{
      public function __construct(){
         echo "This is parent constructor". PHP_EOL;
      }
   }
   class newclass extends myclass{ }
   $obj = new newclass();
?>

它将生成以下 output

This is parent constructor

PHP 不允许通过扩展多个父类来开发一个类。你可以有 hierarchical inheritance ,其中类 B 扩展类 A,类 C 扩展类 B,以此类推。但是 PHP 不支持 multiple inheritance ,其中类 C 试图同时扩展类 A 和类 B。然而,我们可以扩展一个类并实现一个或多个 interfaces 。我们将在后续章节之一中学习关于接口的内容。

PHP – Class Constants

PHP 允许将类中的标识符定义为具有常量值的“类常量”,它在每个类基础上保持不变。为了与类中的变量或属性区分开来,该常量的名称没有前缀通常的“$”符号,并由“const”限定符定义。请注意,PHP 程序还可以使用 define() 函数创建全局常量。

常量的默认可见性是公共的,尽管可以在定义中使用其他修饰符。常量的值必须是一个表达式,而不是变量、函数调用或属性。常量值通过作用域解析运算符通过类名进行访问。在方法中,可以通过 self 变量引用它。

class SomeClass {
   const CONSTANT = 'constant value';
}
echo SomeClass::CONSTANT;

Constant names are case sensitive 。传统上,常量的名称使用大写字母。

Example

此示例显示了如何定义和访问类常量:

<?php
   class square {
      const PI=M_PI;
      var $side=5;
      function area() {
         $area=$this->side**2*self::PI;
         return $area;
      }
   }
   $s1=new square();
   echo "PI=". square::PI . "\n";
   echo "area=" . $s1->area();
?>

它将生成以下 output

PI=3.1415926535898
area=78.539816339745

Class Constant as Expression

在这个示例中,类常量被分配一个表达式 -

<?php
   const X = 22;
   const Y=7;

   class square {
      const PI=X/Y;
      var $side=5;
      function area() {
         $area=$this->side**2*self::PI;
         return $area;
      }
   }
   $s1=new square();
   echo "PI=". square::PI . "\n";
   echo "area=" . $s1->area();
?>

它将生成以下 output

PI=3.1428571428571
area=78.571428571429

Class Constant Visibility Modifiers

请看以下示例:

<?php
   class example {
      const X=10;
      private const Y=20;
   }
   $s1=new example();
   echo "public=". example::X. "\n";
   echo "private=" . $s1->Y ."\n";
   echo "private=" . $example::Y ."\n";
?>

它将生成以下 output

public=10
PHP Notice:  Undefined property: example::$Y in  line 11

private=
PHP Fatal error:  Uncaught Error: Cannot access private const example::Y

PHP – Abstract Classes

PHP 中的保留字列表包括“abstract”关键字。当用“abstract”关键字定义一个类时,它不能被实例化,即,你不能声明这样的类的对象。抽象类可以由另一个类扩展。

abstract class myclass {
   // class body
}

如上所述,你可以 cannot declare an object of this class 。因此,下面的语句 -

$obj = new myclass;

将导致一个 error 消息,如下所示 -

PHP Fatal error:  Uncaught Error: Cannot instantiate abstract class myclass

一个抽象类可能包含属性、常量或方法。类成员可以是 public、private 或 protected 类型的。一个类中的一个或更多方法也可以被定义为抽象的。

如果一个类中的任何方法是抽象的,类本身必须是一个抽象类。换句话说,一个普通的类不能有在其中定义的抽象方法。

这会产生一个 error -

class myclass {
   abstract function myabsmethod($arg1, $arg2);
   function mymethod() #this is a normal method {
      echo "Hello";
   }
}

error message 将被显示为 -

PHP Fatal error:  Class myclass contains 1 abstract method
and must therefore be declared abstract

你可以使用一个抽象类作为一个父类并用一个子类扩展它。但是,子类必须为父类中的每一个抽象方法提供具体的实现,否则会遇到错误。

Example

在以下代码中, myclass 是一个 abstract classmyabsmethod() 作为其 abstract method 。它派生的类是 mynewclass ,但它没有实现其父类中的抽象方法。

<?php
   abstract class myclass {
      abstract function myabsmethod($arg1, $arg2);
      function mymethod() {
         echo "Hello";
      }
   }
   class newclass extends myclass {
      function newmethod() {
         echo "World";
      }
   }
   $m1 = new newclass;
   $m1->mymethod();
?>

在这种情况下 error message -

PHP Fatal error:  Class newclass contains 1 abstract method and must
therefore be declared abstract or implement the remaining
methods (myclass::myabsmethod)

它表明新类应该实现抽象方法或者应该被声明为抽象类。

Example

在以下 PHP 脚本中,我们有 marks 作为抽象类,其中 percent() 是其中一个抽象方法。另一个 student 类扩展了 marks 类并实现了其 percent() 方法。

<?php
   abstract class marks {
      protected int $m1, $m2, $m3;
      abstract public function percent(): float;
   }

   class student extends marks {
      public function __construct($x, $y, $z) {
         $this->m1 = $x;
         $this->m2 = $y;
         $this->m3 = $z;
      }
      public function percent(): float {
         return ($this->m1+$this->m2+$this->m3)*100/300;
      }
   }

   $s1 = new student(50, 60, 70);
   echo "Percentage of marks: ". $s1->percent() . PHP_EOL;
?>

它将生成以下 output

Percentage of marks: 60

Difference between Interface and Abstract Class in PHP

PHP 中抽象类的概念与接口非常相似。但是,接口和抽象类之间有几个不同之处。

Abstract class

Interface

用 abstract 关键字定义抽象类

用 interface 关键字定义接口

抽象类不能被实例化

Interface cannot be instantiated.

抽象类可能具有普通和抽象方法

接口必须声明具有参数和返回类型的 method 不是任何主体。

抽象类由子类扩展,后者必须实现所有抽象方法

接口必须由另一个类实现,该类必须提供接口中所有方法的功能。

可以具有公共、私有或受保护的属性

不能在接口中声明属性

PHP – Interfaces

正如类是其对象的一个模板一样,PHP 中的 interface 可称为类模板。我们知道当一个类被实例化时,该类中定义的属性和方法对它可用。类似地,PHP 中的接口声明了方法及其参数和返回值。这些方法没有任何方法体,即在接口中没有定义任何功能。

一个 concrete 类必须实现接口中的方法。换句话说,当一个类实现一个接口时,它必须为接口中的所有方法提供功能。

接口的定义方式与类的定义方式相同,只是使用了关键字 interface 来代替类。

interface myinterface {
   public function myfunction(int $arg1, int $arg2);
   public function mymethod(string $arg1, int $arg2);
}

注意,接口中的方法没有任何功能。这些方法的定义必须由实现此接口的类提供。

当定义一个子类时,我们使用关键字 extends 。在这种情况下,该类必须使用关键字 implements

必须定义接口中声明的所有方法,参数和返回值的数量和类型均相同。

class myclass implements myinterface {
   public function myfunction(int $arg1, int $arg2) {
      ## implementation of myfunction;
   }
   public function mymethod(string $arg1, int $arg2) {
      # implementation of mymethod;
   }
}

Note 在接口中声明的所有方法都必须为公共方法。

Example

让我们定义一个名为 shape 的接口。形状具有一定的面积。你有不同几何形状的形状,如矩形、圆形等,每个形状都有一个面积,使用不同的公式计算。因此形状接口声明了一个方法 area(),该方法返回一个浮点值。

interface shape {
   public function area(): float;
}

接下来,我们将定义一个实现形状接口的圆形类,为了实现,该类必须提供接口中函数的具体实现。此处,圆形类中的 area() 函数计算给定半径的圆的面积。

class circle implements shape {
   var $radius;
   public function __construct($arg1) {
      $this->radius = $arg1;
   }
   public function area(): float {
      return pow($this->radius,2)*pi();
   }
}

现在我们可以声明一个圆形类的对象并调用 area() 方法。

$cir = new circle(5);
echo "Radius : " . $cir->radius .  " Area of Circle: " . $cir->area(). PHP_EOL;

一个接口可以由任意数量的类(它们可能彼此无关)实现,只要实现类提供接口中每个方法的功能即可。

这里有一个实现形状的 Square 类。area() 方法返回边属性的平方。

class square implements shape {
   var $side;
   public function __construct($arg1) {
      $this->side = $arg1;
   }
   public function area(): float {
      return pow($this->side, 2);
   }
}

类似地,创建一个 Square 对象并调用 area() 方法。

Example

以下是形状接口的完整代码,由圆形和 Square 类实现 −

<?php
   interface shape {
      public function area(): float;
   }

   class square implements shape {
      var $side;
      public function __construct($arg1) {
         $this->side = $arg1;
      }
      public function area(): float {
         return pow($this->side, 2);
      }
   }
   class circle implements shape {
      var $radius;
      public function __construct($arg1) {
         $this->radius = $arg1;
      }
      public function area(): float {
         return pow($this->radius,2)*pi();
      }
   }

   $sq = new square(5);
   echo "Side: " . $sq->side .  " Area of Square: ". $sq->area() . PHP_EOL;

   $cir = new circle(5);
   echo "Radius: " . $cir->radius .  " Area of Circle: " . $cir->area(). PHP_EOL;
?>

它将生成以下 output

Side: 5 Area of Square: 25
Radius: 5 Area of Circle: 78.539816339745

Multiple Inheritance in PHP

PHP 无法建立扩展两个父类的子类。换句话说,该语句 −

class child extends parent1, parent2

不受支持。但是,PHP 支持扩展一个父类并实现一个或多个接口的子类。

我们来看看下面的示例,该示例显示了一个扩展另一个类并实现一个接口的类。

首先,父类标记。它具有三个实例变量或属性 $m1、$m2、$m3,分别表示三个科目中的分数。提供了一个 constructor 来初始化对象。

class marks {
   protected int $m1, $m2, $m3;
   public function __construct($x, $y, $z) {
      $this->m1 = $x;
      $this->m2 = $y;
      $this->m3 = $z;
   }
}

我们现在提供一个名为 percent 的接口,它声明了一个方法 percent(),它应该返回一个浮点数,但没有函数体。

interface percent {
   public function percent(): float;
}

我们现在开发一个类来扩展 marks 类并在接口中为 percent() 方法提供实现。

class student extends marks implements percent {
   public function percent(): float {
      return ($this->m1+$this->m2+$this->m3)*100/300;
   }
}

student 类继承了父构造函数,但提供了 parent() 方法的实现,该方法返回分数的百分比。

Example

完整代码如下所示:

<?php
   class marks {
      protected int $m1, $m2, $m3;
      public function __construct($x, $y, $z) {
         $this->m1 = $x;
         $this->m2 = $y;
         $this->m3 = $z;
      }
   }
   interface percent {
      public function percent(): float;
   }

   class student extends marks implements percent {
      public function percent(): float {
         return ($this->m1+$this->m2+$this->m3)*100/300;
      }
   }

   $s1 = new student(50, 60, 70);
   echo "Percentage of marks: ". $s1->percent() . PHP_EOL;
?>

它将生成以下 output

Percentage of marks: 60

PHP 中的接口定义了一个方法框架,用于类提供自己的不同但具体的实现。

PHP – Traits

在 PHP 中,一个类只能从一个父类继承,多重继承在 PHP 中没有定义。PHP 中的 Traits 被引入来克服此限制。你可以在一个 Trait 中定义一个或多个方法,它们可以自由地重复用于各种独立的类。

Syntax

"trait" 关键字按以下语法使用 −

trait mytrait {
   function method1() {
      /*function body*/
   }

   function method2() {
      /*function body*/
   }
}

为了能够调用 Trait 中的方法,需要使用 use 关键字将其提供给另一个类。

Example

Trait 类似于一个类,但只用于以细粒度和一致的方式对功能进行分组。无法单独实例化 Trait。

<?php
   trait mytrait {
      public function hello() {
         echo "Hello World from " . __TRAIT__ . "";
      }
   }
   class myclass {
      use mytrait;
   }
   $obj = new myclass();
   $obj->hello();
?>

它将生成以下 output

Hello World from mytrait

Example

一个 Trait 可以用在多个类中。以下示例有一个带有 avg() 函数 int 的 mytrait。它在 marks 类中使用。percent() 方法在内部从 Trait 调用 avg() 函数。

请看以下示例:

<?php
   trait mytrait {
      function avg($x, $y) {
         return ($x+$y)/2;
      }
   }
   class marks {
      use mytrait;
      private int $m1, $m2;
      function __construct($x, $y) {
         $this->m1 = $x;
         $this->m2 = $y;
      }
      function percent():float {
         return $this->avg($this->m1, $this->m2);
      }
   }
   $obj = new marks(50, 60);
   echo "percentage: " . $obj->percent();
?>

它将生成以下 output

percentage: 55

Using Multiple Traits

一个类可以使用多个 Trait。这里我们有两个 Trait,每个 Trait 都带有一个函数,分别对两个数字进行加法和乘法。两者都在第三个类中使用。

<?php
   trait addition {
      function add($x, $y) {
         return $x+$y;
      }
   }

   trait multiplication {
      function multiply($x, $y) {
         return $x*$y;
      }
   }

   class numbers {
      use addition, multiplication;
      private int $m1, $m2;
      function __construct($x, $y) {
         $this->m1 = $x;
         $this->m2 = $y;
      }
      function calculate():array {
         $arr = [$this->add($this->m1, $this->m2), $this->multiply($this->m1, $this->m2)];
         return $arr;
      }
   }

   $obj = new numbers(50, 60);
   $res = $obj->calculate();
   echo "Addition: " . $res[0] . PHP_EOL;
   echo "Multiplication: " . $res[1] . PHP_EOL;
?>

它将生成以下 output

Addition: 110
Multiplication: 3000

Overriding Trait Function

当一个类使用某个 Trait 时,其函数对它可用,就像子类继承父类方法一样。Trait 函数也可以被覆盖。

<?php
   trait mytrait {
      public function sayHello() {
         echo 'Hello World!';
      }
   }

   class myclass {
      use mytrait;
      public function sayHello() {
         echo 'Hello PHP!';
      }
   }

   $o = new myclass();
   $o->sayHello();
?>

它将生成以下 output

Hello PHP!

The "insteadof" Keyword

有时,两个以上的 Trait 可能会具有相同名称的函数。因此,在类中使用它们会导致模棱两可的情况。PHP 提供 insteadof 关键字来告知解析器你要使用哪个 Trait 函数。

<?php
   trait mytrait {
      public function sayHello() {
         echo 'Hello World!';
      }
   }

   trait newtrait {
      public function sayHello() {
         echo 'Hello PHP!';
      }
   }

   class myclass {
      use mytrait, newtrait{
         newtrait::sayHello insteadof mytrait;
      }
   }

   $o = new myclass();
   $o->sayHello();
?>

它将生成以下 output

Hello PHP!

Aliasing a Trait Function

如果你希望能够从这两个 Trait 中调用函数,即使它们具有同名的函数,解决方法是为其中一个指定别名。

Example

在以下示例中,我们将 mytrait 中的 sayHello() 称为 hello() −

<?php
   trait mytrait {
      public function sayHello() {
         echo 'Hello World!' . PHP_EOL;
      }
   }

   trait newtrait {
      public function sayHello() {
         echo 'Hello PHP!' . PHP_EOL;
      }
   }

   class myclass {
      use mytrait, newtrait{
         mytrait::sayHello as hello;
         newtrait::sayHello insteadof mytrait;
      }
   }

   $o = new myclass();
   $o->hello();
   $o->sayHello();
?>

它将生成以下 output

Hello World!
Hello PHP!

PHP – Static Methods

PHP 中的 "static" 关键字用于在 PHP 类中定义静态属性和静态方法。需要注意的是,static 关键字也用于定义静态变量和静态匿名函数。本章讨论 PHP 类中的静态方法。

在类定义中,用 static 限定符声明的函数成为其静态方法。

class myclass {
   public static function myStaticMethod() {
      // ...
}

您无需创建类的实例即可调用该类的静态方法。通过作用域解析运算符,根据类名称来调用该静态方法。静态方法调用的语法为 −

myclass::myStaticMethod();

由于无需创建类的实例即可调用静态方法,因此伪变量 $this 在静态方法内部不可用。允许由对象调用一个静态方法,尽管将一个实例方法作为静态方法调用会引发错误。

Example

请看以下示例:

<?php
   class myclass {

      /* Member variables */
      static int $var1 = 0;
      public static function mystaticmethod() {
         echo "This is a static method".  PHP_EOL;
      }
      public function myinstancemethod() {
         echo "This is an instance method".  PHP_EOL;
      }
   }

   myclass::mystaticmethod();
   $obj = new myclass;
   $obj->myinstancemethod();
   $obj->mystaticmethod();
   myclass::myinstancemethod();
?>

它将生成以下 output

This is a static method
This is an instance method
This is a static method
PHP Fatal error:  Uncaught Error: Non-static method
myclass::myinstancemethod() cannot be called statically

The "self" Keyword in Static Method

如果您需要从在同一类中定义的实例方法内部调用静态方法,那么必须使用引用类名称的 self 关键字,然后是作用域解析运算符(如 self::mystaticmethod)

<?php
   class myclass {

      /* Member variables */
      static int $var1 = 0;
      public static function mystaticmethod() {
         echo "This is a static method".  PHP_EOL;
      }
      public function myinstancemethod() {
         echo "This is an instance method".  PHP_EOL;
         echo "calling static method from instance method" . PHP_EOL;
         self::mystaticmethod();
      }
   }

   $obj = new myclass;
   $obj->myinstancemethod();
?>

它将生成以下 output

This is an instance method
calling static method from instance method
This is a static method

Using the "parent" Keyword

在继承的情况下,通过引用“parent”关键字,可以根据派生类的对象或从派生类的实例方法内部调用在基类中定义的静态方法。

Example

请看以下示例:

<?php
   class myclass {

      /* Member variables */
      static int $var1 = 0;
      public static function mystaticmethod() {
         echo "This is a static method".  PHP_EOL;
      }
      public function myinstancemethod() {
         echo "This is an instance method".  PHP_EOL;
         echo "calling static method from instance method" . PHP_EOL;
         self::mystaticmethod();
      }
   }

   class mynewclass extends myclass {
      public function myfunction() {
         echo "This an instance method of the derived class" . PHP_EOL;
         echo "Calling static method of the parent class" . PHP_EOL;
         parent::mystaticmethod();
      }
   }
   $obj = new mynewclass;
   mynewclass::mystaticmethod();
   $obj->myfunction();
?>

它将生成以下 output

This is a static method
This an instance method of the derived class
Calling static method of the parent class
This is a static method

Static Method Inside Another Class

完全可以从一个类中调用另一个类中的静态方法。您必须用其类名称和作用域解析运算符限定其名称。

Example

请看以下示例:

<?php
   class myclass {

      /* Member variables */
      static int $var1 = 0;
      public static function mystaticmethod() {
         echo "This is a static method".  PHP_EOL;
      }
   }

   #this is not a derived class
   class mynewclass {
      public function myfunction() {
         echo "This an instance method" . PHP_EOL;
         echo "Calling static method of the another class" . PHP_EOL;
         myclass::mystaticmethod();
      }
   }
   $obj = new mynewclass;
   $obj->myfunction();
?>

它将生成以下 output

This an instance method
Calling static method of another class
This is a static method

由于 $this 伪变量对于静态方法不可用,因此对象实例变量无法在静态方法内部访问。它只能处理该类的静态属性。

Example

请看以下示例:

<?php
   class myclass {

      /* Member variables */
      static int $var1 = 0;
      function __construct() {
         self::$var1++;
         echo "object number ". self::$var1 . PHP_EOL;
      }
      public static function mystaticmethod() {
         echo "Number of objects available: " . self::$var1 . PHP_EOL;
      }
   }

   for ($i=1; $i<=3; $i++) {
      $obj = new myclass;
   }
   myclass::mystaticmethod();
?>

它将生成以下 output

object number 1
object number 2
object number 3
Number of objects available: 3

PHP – Static Properties

PHP 中的“static”关键字用于在 PHP 类中定义静态属性和静态方法。可能注意的是,static 关键字也用于定义静态变量和静态匿名函数。阅读本章以了解 PHP 类中的静态属性。

在类定义中,用静态限定声明的变量将成为其静态属性。static 关键字可以在访问修饰符之前或之后出现。

static private $var1;
public static $var2;

如果您想使用类型提示,该类型一定不能在 static 关键字之前。

static private string $var1;
public static float $var2;

静态属性在类中的值无法通过其对象(使用 → 运算符)访问。这样做会产生一条指出 Accessing static property myclass::$var1 as non static 的通知。相反,可以使用由“::”符号表示的范围解析运算符访问静态属性。

Example

请看以下示例:

<?php
   class myclass {
      static string $var1 = "My Class";
      function __construct() {
         echo "New object declared" . PHP_EOL;
      }
   }
   $obj = new myclass;
   echo "accessing static property with scope resolution operator: " . myclass::$var1 . PHP_EOL;
   echo "accessing static property with -> operator: ". $obj->var1 . PHP_EOL;
?>

它将生成以下 output

New object declared
accessing static property with scope resolution operator: My Class
PHP Notice:  Accessing static property myclass::$var1 as non static in hello.php on line 14

The "self" Keyword

要从方法内部访问静态属性,请使用 self 关键字引用当前类。在以下示例中,该类具有一个整型静态属性,每当声明一个新对象时都会对其进行递增。

<?php
   class myclass {

      /* Member variables */
      static int $var1 = 0;
      function __construct(){
         self::$var1++;
         echo "object number ". self::$var1 . PHP_EOL;
      }
   }
   for ($i=1; $i<=3; $i++) {
      $obj = new myclass;
   }
?>

它将生成以下 output

object number 1
object number 2
object number 3

The "parent" Keyword

可以将基类的静态属性通过引用 parent 关键字用在继承类的函数中。您需要使用“parent::static_property”语法。

Example

查看以下示例 −

<?php
   class myclass {

      /* Member variables */
      static int $var1 = 0;
      function __construct() {
         self::$var1++;
         echo "object number ". self::$var1 . PHP_EOL;
      }
   }

   class newclass extends myclass{
      function getstatic() {
         echo "Static property in parent class: " . parent::$var1 . PHP_EOL;
      }
   }
   $obj = new newclass;
   $obj->getstatic();
?>

它将生成以下 output

object number 1
Static property in parent class: 1

PHP - Namespaces

我们经常将文件组织在不同的文件夹中。通常情况下,一个文件夹包含与某个目标、应用程序或类别相关联的文件。一个文件夹不能包含两个具有相同名称的文件,尽管不同的文件夹可能具有一个名称相同的文件,因此每个文件路径都是不同的。

PHP 中的命名空间理念有点类似。在 PHP 中,命名空间允许在不同上下文中使用相同名称的类或函数或常量,而不会出现任何冲突,从而封装这些项。

PHP 命名空间是根据它们的关联性对类/函数等进行的逻辑分组。正如同名的文件可以存在于两个不同的文件夹中一样,命名空间中也可以定义一个特定名称的类。此外,由于我们指定文件的完整路径来获取访问权限,因此我们需要指定类及其命名空间的完整名称。

随着应用程序规模的不断增大,包括许多类和函数定义,为每个类/函数提供一个唯一的名称可能会变得繁琐并且不够优雅。使用命名空间可让您以一种简洁的方式组织此类代码块。例如,如果我们需要声明一个 calculate() 函数来计算面积和税费,我们可以创建两个命名空间 area 和 tax,并在其中使用 calculate() 而不必将它们定义为类似 calculate_area() 和 calculate_tax() 的内容。

Advantages of Namespace

下面列出了一些使用 PHP 中的命名空间的优点 −

  1. 命名空间有助于避免某人使用第三方类/函数/常量定义的类/函数/常量之间的名称冲突。

  2. 命名空间提供了对 Extra_Long_Names 进行别名(或缩短)的能力,从而提高了源代码的可读性。

  3. PHP 命名空间提供了一种对相关的类、接口、函数和常量进行分组的方法。命名空间名称不区分大小写。

Defining a Namespace

PHP 的名称空间关键字用于定义新的命名空间。

namespace myspace;

包含命名空间的 “.php” 文件必须在文件顶部声明命名空间,然后再声明任何其他内容(声明指令除外)。在命名空间中声明类、函数和常量会影响其访问权限。

一个 PHP 脚本可以除了定义命名空间之外,还包含其他代码。为了加载在相同代码中定义的命名空间,PHP 具有“use”关键字。

use myspace;

Example

在以下 “hello.php” 脚本中,我们在 myspace 命名空间中定义了一个 hello() 函数,并在当前脚本中加载该命名空间之后对其进行调用。

<?php
   namespace myspace;
   function hello() {
      echo "Hello World";
   }
   use myspace;
   myspace\hello();
?>

它将生成以下 output

Hello World

请注意,您必须用名称空间完整的名称限定 hello() 函数,其中包括名称空间 - myspace\hello()。

Include Namespace

可以有一个脚本包含名称空间声明,以及在其中使用 include 语句加载该名称空间的另一个脚本。

a.php

<?php
   namespace myspace {
      function hello() {
         echo "Hello World in myspace";
      }
   }
?>

b.php

<?php
   include 'a.php';
   myspace\hello();
?>

它将生成以下 output

Hello World in myspace

在当前的脚本(如上所述的“b.php”)中,可能还有一个函数与 include 文件中函数名称相同。附加名称空间的完全限定函数,帮助解析器解决名称冲突。

Example

请看以下示例:

<?php
   include 'a.php';
   function hello() {
      echo "Hello World from current namespace";
   }
   hello();
   myspace\hello();
?>

它将生成以下 output

Hello World from current namespace
Hello World in myspace

Example

如上所述,名称空间声明必须在最上面,紧跟在 <?php 标签的后面。否则,解析器会抛出致命错误。

<?php
   echo "hello"
   namespace myspace;
   function hello() {
      echo "Hello World";
   }
   use myspace;
   myspace\hello();
?>

它将生成以下 output

PHP Parse error:  syntax error, unexpected token "namespace",
expecting "," or ";" in /home/cg/root/67771/main.php on line 4

上面的错误信息明确指出,在名称空间声明之前,只允许出现“declare 语句”。

<?php
   declare (strict_types=1);
   namespace myspace;
   function hello() {
      echo "Hello World";
   }
   use myspace;
   myspace\hello();
?>

Relative Namespace

可以通过相对于名称空间的路径引用当前名称空间中的对象,如函数、类和常量。

在下面的示例中,“b.php”包含一个带有 hello() 函数和 TEMP 常量的名称空间 space1\myspace。这些对象也在“a.php”中定义的名称空间 space1 中被定义。

显然,当“b.php”被包含在“a.php”时,“myspace”是“space1”的子空间。因此,通过对其相对名称空间(也是 TEMP 常量)加上前缀来调用来自“myspace”的 hello()。

b.php

<?php
   namespace space1\myspace;
   const TEMP = 10;
   function hello() {
      echo "Hello from current namespace:" . __NAMESPACE__ . ;
   }
?>

a.php

<?php
   namespace space1;
   include 'b.php';
   function hello() {
      echo "Hello from current namespace:" . __NAMESPACE__ . ;
   }
   const TEMP = 100;
   hello();            // current namespace
   myspace\hello();   // sub namespace

   echo "TEMP : " . TEMP . " in " . __NAMESPACE__ . ;
   echo "TEMP : " . myspace\TEMP  . " \\in space1\\myspace\n";
?>

它将生成以下 output

Hello from current namespace:space1
Hello from current namespace:space1\myspace
TEMP : 100 in space1
TEMP : 10 in space1\myspace

Absolute Namespace

也可以通过附加绝对名称空间路径来访问任何名称空间中的函数/常量。例如,“b.php”中的 hello() 是“\space\myspace\hello()”。

a.php

<?php
   namespace space1;
   include 'b.php';
   function hello() {
      echo "Hello from current namespace:" . __NAMESPACE__ . ;
   }
   const TEMP = 100;
   \space1\hello();	             //current namespace
   \space1\myspace\hello();	    //sub namespace

   echo "TEMP: " . \space1\TEMP . " in " . __NAMESPACE__ . ;
   echo "TEMP: " . \space1\myspace\TEMP  . " in space1\\myspace\n";
?>

NAMESPACE 是 PHP 中的预定义常量,用于返回当前名称空间的名称。

Namespace Rules

通过遵循以下规则,可以解决不同名称空间之间出现的函数/类/常量名称冲突:

  1. 不带名称空间分隔符符号(/)的名称空间标识符表示其正在引用当前名称空间。这是一个不合格的名称。

  2. 如果它包含分隔符符号,如 myspace\space1,则解析为 myspace 下的子名称空间 space1。这种类型命名是相对名称空间。

  3. 完全限定名称空间的名称以“\”字符开头。例如,“\myspace”或“\myspace\space1”。

  4. 完全限定名称解析为绝对名称空间。例如,\myspace\space1 解析为 myspace\space1 名称空间。

  5. 如果名称出现在全局名称空间中,“namespace\”前缀会被移除。例如,“namespace\space1”解析为 space1。

  6. 然而,如果它出现在另一个名称空间内,则其处理方式有所不同。例如,如果 namespace\space1 在 myspace 中,则它等同于“myspace\space1”。

  7. 限定名称中的名称的第一段根据当前类/名称空间导入表进行翻译。

  8. 如果没有导入规则适用,则在名称前加上当前名称空间。

  9. 类名类型名称根据类/名称空间导入表进行翻译,函数名称根据函数导入表进行翻译,常量根据常量导入表进行翻译。

  10. 对于不合格名称,如果未应用导入规则并且名称指向函数或常量,且代码在全局命名空间之外,则该名称在运行时解析。首先,它从当前名称空间查找函数,然后尝试查找并调用全局函数。

PHP - Object Iteration

一个 foreach 循环可用于遍历 PHP 类的对象的公开可见的所有成员。此功能在 PHP 5 及其以后版本中提供。您当然可以访问实例方法中的私有属性列表。PHP 还定义了可用于此目的的 Iterator 接口。

Using foreach Loop

在下面的示例中,类的公开属性使用 foreach 循环列出。

Example

<?php
   class myclass {
      private $var;
      protected $var1;
      public $x, $y, $z;
      public function __construct() {
         $this->var="Hello World";
         $this->var1=array(1,2,3);
         $this->x=100;
         $this->y=200;
         $this->z=300;
      }
   }
   $obj = new myclass();
   foreach($obj as $key => $value) {
      print "$key => $value\n";
   }
?>

它将生成以下 output

x => 100
y => 200
z => 300

请注意,只有公共成员才能在类外访问。如果类包含一个方法,则所有成员(公有、私有或受保护的)都可以从内部通过 foreach 循环进行遍历。

让我们在上面的 myclass 中添加一个迭代方法。

public function iterate() {
   foreach ($this as $k=>$v) {
      if (is_array($v)) {
         var_dump($v);
         echo PHP_EOL;
      } else {
         echo "$k : $v". PHP_EOL;
      }
   }
}

调用此实例方法以获取所有成员的列表。

它将生成以下 output

var : Hello World
array(3) {
   [0]=>
   int(1)
   [1]=>
   int(2)
   [2]=>
   int(3)
}
x : 100
y : 200
z : 300

Using Iterator Interface

PHP 提供 Iterator 接口,用于可自身在内部进行迭代的外部迭代器或对象。它定义了下面需要在用户定义类中实现的抽象方法。

interface Iterator extends Traversable {
   /* Methods */
   public current(): mixed
   public key(): mixed
   public next(): void
   public rewind(): void
   public valid(): bool
}
  1. rewind() 方法将 Iterator 倒回到第一个元素。这是开始 foreach 循环时调用的第一个方法。它不会在 foreach 循环之后执行。

  2. current() 方法返回当前元素。

  3. key() 方法在 foreach 循环的每次迭代中返回当前元素的键。

  4. next() 方法在每次 foreach 循环之后调用,并向前移动到下一个元素。

  5. valid() 方法检查当前位置是否有效。

Example

下面的示例通过实现 Iterator 接口演示对象迭代

<?php
   class myclass implements Iterator {
      private $arr = array('a','b','c');

      public function rewind():void {
         echo "rewinding\n";
         reset($this->arr);
      }

      public function current() {
         $var = current($this->arr);
         echo "current: $var\n";
         return $var;
      }

      public function key() {
         $var = key($this->arr);
         echo "key: $var\n";
         return $var;
      }

      public function next() : void {
         $var = next($this->arr);
         echo "next: $var\n";
         # return $var;
      }

      public function valid() : bool {
         $key = key($this->arr);
         $var = ($key !== NULL && $key !== FALSE);
         echo "valid: $var\n";
         return $var;
      }
   }

   $obj = new myclass();

   foreach ($obj as $k => $v) {
      print "$k: $v\n";
   }
?>

它将生成以下 output

rewinding
valid: 1
current: a
key: 0
0: a
next: b
valid: 1
current: b
key: 1
1: b
next: c
valid: 1
current: c
key: 2
2: c
next:

PHP - Encapsulation

PHP 实现了 encapsulation ,这是 OOP 的一个重要原则,带有访问控制关键字 public, privateprotected

封装是指将对象的数据成员或属性远离类外部环境获取的方式,仅允许通过类中可用的方法或函数进行受控访问。

下图展示了面向对象编程方法中封装的原则。

php encapsulation 1

PHP 的关键字列表包含以下关键字,这些关键字决定了 PHP 中对象实例的属性和方法的可访问性 −

  1. Public − 类成员可以在任何地方访问,即使是在类的作用域之外,但只能通过对象引用访问。

  2. Private − 类成员可以在类本身内访问。它防止成员在类实例的引用下从类外访问。

  3. Protected − 成员只能在类和其子类内访问,在其他任何地方都不能访问。

这三个关键字“ public, privateprotected ”通常称为访问修饰符。它们也被称为可见性模式,因为它们决定了某类成员可以使用的范围。

Public Members

在 PHP 中,类成员(成员变量和其他成员函数)默认情况下是公开的。

Example

在下面的程序中,对象的成员变量 title 和 price 在类的外部可以自由访问,因为它们默认情况下是公开的,除非另行指定。

<?php
   class Person {

      /* Member variables */
      var $name;
      var $age;

      /*Constructor*/
      function __construct(string $param1="Ravi", int $param2=28) {
         $this->name = $param1;
         $this->age = $param2;
      }

      function getName() {
         echo "Name: $this->name" . PHP_EOL;;
      }
      function getAge() {
         echo "Age: $this->age" . PHP_EOL;;
      }
   }
   $b1 = new Person();
   $b1->getName();
   $b1->getAge();
   echo "Name : $b1->name Age: $b1->age" . PHP_EOL;
?>

它将生成以下 output

Name: Ravi
Age: 28
Name : Ravi Age: 28

Note 由于默认情况下类成员的所有属性都为公有,因此如果需要,可以明确地宣告它们为公有。结果,可以从类的外围调用实例方法 getName() 和 getAge()。

由于属性 name 和 age 也是公有的,因此也可以从类外访问它们,这与封装原则相违背。

Private Members

如上所述,封装原则要求不得直接访问成员变量。只有方法应具有对数据成员的访问权。因此,我们需要将成员变量设为私有,并将方法设为公有。

Example

让我们将 name 和 age 属性的宣告改为私有,并运行以下 PHP 脚本:

<?php
   class Person {

      /* Member variables */
      private $name;
      private $age;

      /*Constructor*/
      function __construct(string $param1="Ravi", int $param2=28) {
         $this->name = $param1;
         $this->age = $param2;
      }

      public function getName() {
         echo "Name: $this->name" . PHP_EOL;;
      }

      public function getAge(){
         echo "Age: $this->age" . PHP_EOL;;
      }
   }

   $b1 = new Person();
   $b1->getName();
   $b1->getAge();
   echo "Name : $b1->name Age: $b1->age" . PHP_EOL;
?>

它将生成以下 output

Name: Ravi
Age: 28
PHP Fatal error:  Uncaught Error: Cannot access private property Person::$name in person.php:27

该错误消息表明我们不能从公有范围访问私有属性。

Protected Members

针对类成员指定受保护的访问权在类继承的情况下有效。我们知道可以从类的外围访问公有成员,并且不能从类的外围访问私有成员。

protected 关键字允许访问同一类的对象和继承类中的对象,但禁止访问其他环境。

Example

让我们继承 person 类并定义一个学生类。我们将 name 属性的私有级别更改为受保护级别。此学生类具有一个新的公有方法 getDetails(),它将打印 name 和 age 属性的值。

Person class

<?php
class Person {

   /* Member variables */
   protected $name;
   private $age;

   /*Constructor*/
   function __construct(string $param1="Ravi", int $param2=28) {
      $this->name = $param1;
      $this->age = $param2;
   }

   public function getName(){
      echo "Name: $this->name" . PHP_EOL;;
   }

   public function getAge() {
      echo "Age: $this->age" . PHP_EOL;;
   }
}

Student class

class student extends Person {
   public function getDetails() {
      echo "My Name: $this->name" . PHP_EOL;
      echo "My age: $this->age" . PHP_EOL;
   }
}
$s1 = new student();
$s1->getDetails();
?>

它将生成以下 output

My Name: Ravi
PHP Warning:  Undefined property: student::$age in person.php on line 28
My age:

下表说明了 PHP 中类成员的可访问性规则:

php encapsulation 2

PHP - The "Final" Keyword

PHP 中的 “final” 关键字用于类定义、类中的方法,以及类常量属性的定义。

A Class with "final" Keyword

我们来看一下如何使用 “final” 关键字创建类 -

final class myclass {
   /*class members*/
}

类定义中的 “final” 关键字防止此类被扩展。换句话说,您不能将 final 类用作父类。如果您尝试这样做,PHP 解析器会抛出一个错误

<?php
   final class myclass {

      /* class body */
   }
   class newclass extends myclass {

      /* class body */
   }
?>

当您运行此代码时,它将显示 error -

PHP Fatal error:  Class newclass may not inherit from final class (myclass)

Method with "final" Keyword

下面是使用 “final” 关键字创建方法的方式 -

class myclass {
   final function myfunction() {

      /* function body */
   }
}

final 关键字给方法定义加上前缀,可以防止在子类中覆盖它。具有 final 方法的类可以扩展,但子类不能覆盖它。

Example

请看以下示例:

<?php
   class myclass {
      final public function hello() {
         echo "Hello World!";
      }
   }
   class newclass extends myclass {
      public function hello() {
         echo "Hello PHP!";
      }
   }
?>

当您运行此代码时,它将显示 error -

PHP Fatal error:  Cannot override final method myclass::hello() in hello.php

Constant with "final" Keyword

还可以使用 final 关键字在类中声明常量,从 PHP 8.1.0 开始。

final public const NAME = "My Class";

如果您尝试在子类中覆盖父类的最终常量,将会遇到错误。

<?php
   class myclass {
      final public const NAME = "My Class";
      final public function hello() {
         echo "Hello World!";
      }
   }

   class newclass extends myclass {
      public const NAME = "New Class";
   }
?>

当您运行此代码时,它将显示 error -

Fatal error: newclass::NAME cannot override final constant myclass::NAME

Example

以下 PHP 脚本包含父类 ellipse,其中 PI 常量和 area() 方法均声明为 final。它们由 circle 类继承。area() 函数计算圆的面积。

<?php
   class ellipse {
      final public const PI=22/7;
      private float $a, $b;
      public function __construct($x, $y) {
         $this->a = $x;
         $this->b = $y;
      }
      final public function area() : float {
         return self::PI*$this->a*$this->b;
      }
   }
   class circle extends ellipse {
      public function __construct(float $x) {
         parent::__construct($x, $x);
      }
   }
   $c1 = new circle(5);
   echo "Area: " . $c1->area() . PHP_EOL;
?>

它将生成以下 output

Area: 78.571428571429

请注意,类的实例变量或属性不能声明为 final。

PHP - Overloading

在 C++ 或 Java 中,此术语表示一个类可以多次定义名称相同但参数和/或返回类型不同的类方法。在 PHP 中,“重载”一词有不同的解释。它是一个可以使用该术语动态创建属性和方法的功能。PHP 的魔术方法(以双下划线开头的名称方法)用于设置动态属性和方法。

在处理未声明或在当前范围内不可见的属性或方法时,会调用用于重载目的的魔术方法。

Property Overloading

PHP 的魔术方法示例包括 _construct()、_destruct()、__tostring() 等。PHP 使用下列魔术方法对属性进行重载。

public __set ( string $name , mixed $value ) : void
public __get ( string $name ) : mixed
public __isset ( string $name ) : bool
public __unset ( string $name ) : void

在此,

  1. __set() 用于向受保护的、私有的或不存在的不可访问属性写入数据。

  2. __get() 从不可访问属性读取数据。

  3. __isset() 对不可访问属性调用 isset() 或 empty()。

  4. 在不可访问的属性上调用 unset() 时调用 __unset()

上面使用的 $name 参数是要设置或检索的属性的名称。__set() 方法的 $value 参数指定要分配给属性的值。

_isset() 方法检查某个属性是否已经设置。 _unset() 方法移除属性。

Property overloading 仅在 object context 中起作用。在任何 static context 中,这些魔术方法都不会被触发。因此它们不应该被声明为 static。

Example

在下面的代码中,设置和检索了一个名为 myprop 的动态属性,该属性未在类中声明。

<?php
   class myclass {
      public function __set($name, $value) {
         echo "setting $name property to $value \n";
         $this->$name = $value;
      }

      public function __get($name) {
         echo "value of $name property is ";
         return $this->$name;
      }
   }

   $obj = new myclass();

   # This calls __set() method
   $obj->myproperty="Hello World!";

   # This call __get() method
   echo "Retrieving myproperty: " . $obj->myproperty . PHP_EOL;
?>

它将生成以下 output

setting myproperty property to Hello World!
Retrieving myproperty: Hello World!

_set()_get() 魔术方法还设置和检索了一个声明为私有的属性。在 myclass 内部添加以下语句(在函数定义之前):

private $myproperty;

您可以在 myclass 中定义 __isset() 方法来检查属性 −

public function __isset($name) {
   return isset($this->$name);
}

使用此语句检查属性是否已设置 −

var_dump (isset($obj->myproperty));

在这种情况下,它返回 true

使用在 myclass 中定义的 __unset() 方法取消动态创建的属性 −

public function __unset($name) {
   unset($this->$name);
}

以下代码会返回 false

var_dump (isset($obj->myproperty));

Method Overloading

用于动态设置方法的两种魔术方法是 _call()_callStatic()

public __call (string $name , array $arguments) : mixed
public static __callStatic (string $name , array $arguments) : mixed

当在对象上下文中调用不可访问(未定义或私有)方法时,触发 _call()。另一方面,当在静态上下文中调用不可访问的方法时,触发 _callStatic()。

Example

以下示例演示了 PHP 中的方法重载

<?php
   class myclass {
      public function __call($name, $args) {

         // Value of $name is case sensitive.
         echo "Calling object method $name with " . implode(" ", $args). "\n";
      }
      public static function __callStatic($name, $args) {
         echo "Calling static method $name with " . implode(" ", $args). "\n";
      }
   }
   $obj = new myclass();

   # This invokes __call() magic method
   $obj->mymethod("Hello World!");

   # This invokes __callStatic() method
   myclass::mymethod("Hello World!");
?>

它将生成以下 output

Calling object method mymethod with Hello World!
Calling static method mymethod with Hello World!

请注意,“ ”运算符的使用表示该方法是 instance method ,“::”运算符表示该方法是 static method

PHP - Cloning Objects

诸如“$obj1 = $obj2”的 PHP 语句只是创建对内存中同一对象的另一个引用。因此,属性的更改同时反映在原始对象和复制的对象中。PHP 中的 clone 关键字创建对象的浅拷贝。

$obj2 = $obj1

原始对象中的更改不会反映在浅拷贝中。

Example

请看以下示例:

<?php
   class foo {
      var $var1 = 'Hello';
   }
   $x = new foo();
   $y = $x;		# reference copy
   echo $x->var1 . " " . $y->var1 . PHP_EOL;

   $x->var1 = "Hello World";
   echo $x->var1 . " " . $y->var1 . PHP_EOL;
?>

它将生成以下 output

Hello Hello
Hello World Hello World

在第一种情况下, $y 只是 $x 的引用副本。因此, var1 属性的任何更改都会反映在两者中。

但是,如果我们将 $y 声明为 $x 的克隆,则原始对象中的任何更改都不会反映在其浅拷贝中。

Example

请看以下示例:

<?php
   class foo {
      var $var1 = 'Hello World';
   }

   $x = new foo();

   # shallow copy
   $y = clone $x;
   echo $x->var1 . " " . $y->var1 . PHP_EOL;

   $x->var1 = "Hello PHP";
   echo $x->var1 . " " . $y->var1 . PHP_EOL;
?>

它将生成以下 output

Hello World Hello World
Hello PHP Hello World

Example

在以下代码中, myclass 的属性之一是作为地址类对象的属性。myclass 的一个对象被赋值复制。其嵌入地址对象的任何值的变化会反映在两个对象中,但是名称属性的变化不会体现在克隆对象中。

<?php
   class address {
      var $city="Nanded";
      var $pin="431601";
      function setaddr($arg1, $arg2) {
         $this->city=$arg1;
         $this->pin=$arg2;
      }
   }
   class myclass {
      var $name="Raja";
      var $obj;
      function setname($arg) {
         $this->name=$arg;
      }
   }

   $obj1=new myclass();
   $obj1->obj=new address();
   echo "original object\n";
   print_r($obj1);
   echo "\n";

   $obj2=$obj1;		# reference copy
   $obj1->setname("Ravi");
   $obj1->obj->setaddr("Mumbai", "400001");
   echo "after change: Original object\n";
   print_r($obj1);
   echo "\nCopied object\n";
   print_r($obj2);
?>

它将生成以下 output

original object
myclass Object
(
   [name] => Raja
   [obj] => address Object
   (
      [city] => Nanded
      [pin] => 431601
   )
)

after change: Original object
myclass Object
(
   [name] => Ravi
   [obj] => address Object
   (
      [city] => Mumbai
      [pin] => 400001
   )
)

Copied object
myclass Object
(
   [name] => Ravi
   [obj] => address Object
   (
      [city] => Mumbai
      [pin] => 400001
   )
)

Using the "clone" Keyword

在浅表副本中,任何是对其他变量引用的原始对象的属性都将保持引用。clone 关键字不会复制复制对象的包含对象。

我们现在创建 myclass 对象的克隆,以便 $obj2$obj1 的克隆。我们将 $obj1 的 name 属性从 Raja 更改为 Ravi ,然后修改嵌入地址对象。属性更改不会反映在其克隆中,但是引用的地址对象将更改。

Example

请看以下示例:

<?php
   class address {
      var $city="Nanded";
      var $pin="431601";
      function setaddr($arg1, $arg2) {
         $this->city=$arg1;
         $this->pin=$arg2;
      }
   }
   class myclass {
      var $name="Raja";
      var $obj;
      function setname($arg) {
         $this->name=$arg;
      }
   }
   $obj1=new myclass();
   $obj1->obj=new address();
   echo "original object\n";
   print_r($obj1);
   echo "\n";

   $obj2=clone $obj1;		# clone copy
   $obj1->setname("Ravi");
   $obj1->obj->setaddr("Mumbai", "400001");
   echo "after change: Original object\n";
   print_r($obj1);
   echo "\nCopied object\n";
   print_r($obj2);
?>

它将生成以下 output

original object
myclass Object
(
   [name] => Raja
   [obj] => address Object
   (
      [city] => Nanded
      [pin] => 431601
   )
)

after change: Original object
myclass Object
(
   [name] => Ravi
   [obj] => address Object
   (
      [city] => Mumbai
      [pin] => 400001
   )
)

Copied object
myclass Object
(
   [name] => Raja
   [obj] => address Object
   (
      [city] => Mumbai
      [pin] => 400001
   )
)

Using __clone() Method

clone 关键字创建对象的浅表副本。克隆对象后,PHP 将对所有对象的属性执行浅表副本。是对其他变量引用的任何属性都将保持引用。因此,对原始对象执行的任何更改也将出现在克隆对象中。

如果您希望防止复制的对象自动更新,则需要使用 __clone() 方法创建对象的深表副本。它是 PHP 中的魔术方法之一。

一旦克隆完成,如果定义了 _clone() 方法,系统就会调用新创建对象的 _clone() 方法,以允许需要更改的任何必要属性。

Example

在上述示例中,我们有一个 myclass 对象,其中一个属性 $obj 保存对地址类的对象的引用。要实现深表副本,我们会覆盖 myclass 中的 __clone() 魔术方法。

<?php
   class address {
      var $city="Nanded";
      var $pin="431601";
      function setaddr($arg1, $arg2) {
         $this->city=$arg1;
         $this->pin=$arg2;
      }
   }
   class myclass {
      var $name="Raja";
      var $obj;
      function setname($arg) {
         $this->name=$arg;
      }
      public function __clone() {
         $this->obj = clone $this->obj ;
      }
   }
   $obj1=new myclass();
   $obj1->obj=new address();
   echo "original object\n";
   print_r($obj1);
   echo "\n";

   $obj2=clone $obj1;		# cloned deep copy
   $obj1->setname("Ravi");
   $obj1->obj->setaddr("Mumbai", "400001");
   echo "after change: Original object\n";
   print_r($obj1);
   echo "\nCloned object\n";
   print_r($obj2);
?>

您现在会看到原始对象(我们更改地址属性)中的更改不会反映在克隆对象中,如下面的 output 所示。

original object
myclass Object
(
   [name] => Raja
   [obj] => address Object
   (
      [city] => Nanded
      [pin] => 431601
   )
)

after change: Original object
myclass Object
(
   [name] => Ravi
   [obj] => address Object
   (
      [city] => Mumbai
      [pin] => 400001
   )
)

Cloned object
myclass Object
(
   [name] => Raja
   [obj] => address Object
   (
      [city] => Nanded
      [pin] => 431601
   )
)

PHP - Anonymous Classes

版本 7.0 的发布是 PHP 语言演化中的一个重要里程碑,那时引入了许多新功能。PHP 7.0 版本中还提供了匿名类功能。

正如术语“匿名”所暗示的那样,它是一个无(程序员声明的)名的类。通常的做法是用某个标识符定义一个类,以便可以重复使用它。另一方面,匿名类仅供一次性使用。

$obj = new class() {
   /* class body */
};

除了该类没有名称之外,它与普通命名类类似,因为它可以包含属性和方法。它的功能与命名类对象的功能没有区别。

在类不需要文档时,以及类在执行期间仅使用一次时,匿名类可能会在一个已命名的类上使用。当需要创建简单的一次性对象时,匿名类非常有用。

Example

在以下代码中,匿名类被实例化并存储在 $obj 对象中。该类包括 addition() 和 division() 方法的定义,这些方法用 $obj 对象调用。

<?php
   $obj = new class(10) {
      private int $x;
      function __construct($x) {
         $this->x = $x;
      }

      public function addition($x) {
         return $this->x+$x;
      }
      public function division($x) {
         return $this->x/$x;
      }
   };

   echo "Addition: " . $obj->addition(20) . PHP_EOL;
   echo "Division: " . $obj->division(20) . PHP_EOL;
?>

它将生成以下 output

Addition: 30
Division: 0.5

Anonymous Class as a Child Class

匿名类可以执行普通类可以执行的所有操作。它可以扩展另一个类、实现一个接口甚至使用一个特性。

Example

在以下示例中,匿名类是一个子类,它扩展了一个已经存在的父类。

<?php
   class myclass {
      public function hello() {
         echo "Hello World!" . PHP_EOL;
      }
   }
   $obj = new class("Neena") extends myclass {
      private string $nm;
      function __construct($x) {
         $this->nm = $x;
      }
      public function greeting() {
         parent::hello();
         echo "Welcome " . $this->nm . PHP_EOL;
      }
   };
   $obj->greeting();
?>

它将生成以下 output

Hello World!
Welcome Neena

Example

尽管匿名类没有任何用户定义的名称,但 PHP 会为其分配内部名称,该名称可以使用内置的 get_class() 函数获得,如下所示:

<?php
   $obj = new class() {
      function greeting() {
         echo "Hello World" . PHP_EOL;
      }
   };
   $obj->greeting();
   echo "Name of class: " . get_class($obj);
?>

它将生成以下 output

Hello World
Name of class: class@anonymousC:\xampp\htdocs\hello.php:2$0

PHP 解析器随机分配内部名称。

PHP - Web Concepts

PHP 是一种服务器端脚本语言,用于创建动态网页。它是 Web 开发中最流行的编程语言之一。本章旨在让您熟悉使用 PHP 进行 Web 应用程序开发的某些重要概念。

基于 Web 的应用程序是网页的集合。网页主要是用 HTML 标记创建的。HTML 包含用于定义页面元素(如文本、图像、表格等)外观的不同 HTML 标记。因此,HTML 本质上创建了一个静态网页。

Web 应用托管在安装了 PHP 模块的 HTTP 服务器上。浏览器作为 http 客户端,遵循 HTTP 协议来与服务器建立通信。

php web concepts

How to Add Dynamic Content on a Webpage?

要向网页添加动态内容,可以使用两种方式。

JavaScript 是一种客户端脚本语言,它可以访问 HTML 文档对象模型并在客户端浏览器上呈现动态内容。JavaScript 代码可以嵌入到 HTML 页面中。

浏览器可以通过 HTML 表单元素收集用户数据,然后将其发送到 HTTP 服务器进行处理。PHP 是一种广泛使用的服务器端处理语言。PHP 脚本也可以嵌入到 HTML 页面中。

Example

在下面的脚本中,嵌入到 HTML 中的 JavaScript 代码根据客户端浏览器呈现当前日期,而 PHP 代码则根据脚本托管的服务器显示当前日期。

<!DOCTYPE html>
<html>
<body>
   <script type="text/JavaScript">
      document.write("Client's date :"+Date()+"\n");
   </script>
   <?php
      date_default_timezone_set("Asia/Calcutta");
      echo "server's date is " . date("Y-m-d") . "\n";
      echo "The time is " . date("h:i:sa");
   ?>
</body>
</html>

PHP can intercept and process the data from HTML forms 。这使你可以收集你的用户的信息。下一章将讨论 PHP 表单处理。

PHP can be used to interact with databases ,例如 MySQL 和 PostgreSQL。这使你能够存储和检索你的数据库中的数据,并动态填充网页或为 Web 应用程序提供动力。PHP 包括用于数据库处理的 mysql、mysqli 和 PDO 扩展。

PHP can handle the data received from the client 使用 HTTP GET 和 POST 方法。我们将在后面的章节详细讨论 PHP 如何处理 GET/POST 方法。

HTTP is a stateless protocol 。不过,它允许在服务器和客户端分别维护会话和 cookie。PHP 可用于创建和管理会话和 cookie。当用户浏览你的网站时,会话允许你跟踪各个用户,而 cookie 允许你将信息存储在用户的计算机上以供日后使用。在后续章节中,我们将学习 PHP 如何处理会话和 cookie。

PHP can be used to upload files to your web server 。这使你能够创建允许用户上传文件(例如图片、视频或文档)的 Web 应用程序。

You can use PHP to create a login page for your website 。当用户输入他们的用户名和密码时,PHP 可以检查数据库以查看用户是否有效。如果用户有效,PHP 可以让用户登录并将其重定向到你的网站的主页。

Identifying Browser & Platform

PHP 创建了一些可以在用于设置 PHP 环境的 phpinfo.php 页面中看到的 environment variables

PHP 设置的环境变量之一是 HTTP_USER_AGENT ,它标识用户的浏览器和操作系统。

PHP 提供了一个 getenv() 函数来访问所有环境变量的值。HTTP_USER_AGENT 环境变量中包含的信息可用于根据浏览器创建适当的动态内容。

Example

下面的示例展示了如何识别客户端浏览器和操作系统。

NOTE − preg_match() 函数在 PHP Regular expression 会话中讨论。

<?php
   function getBrowser() {
      $u_agent = $_SERVER['HTTP_USER_AGENT'];
      $bname = 'Unknown';
      $platform = 'Unknown';
      $version = "";

      //First get the platform
      if (preg_match('/linux/i', $u_agent)) {
         $platform = 'linux';
      } elseif (preg_match('/macintosh|mac os x/i', $u_agent)) {
         $platform = 'mac';
      } elseif (preg_match('/windows|win32/i', $u_agent)) {
         $platform = 'windows';
      }

      // Next get the name of the useragent yes seperately and for good reason
      if(preg_match('/MSIE/i',$u_agent) && !preg_match('/Opera/i',$u_agent)) {
         $bname = 'Internet Explorer';
         $ub = "MSIE";
      } elseif(preg_match('/Firefox/i',$u_agent)) {
         $bname = 'Mozilla Firefox';
         $ub = "Firefox";
      } elseif(preg_match('/Chrome/i',$u_agent)) {
         $bname = 'Google Chrome';
         $ub = "Chrome";
      } elseif(preg_match('/Safari/i',$u_agent)) {
         $bname = 'Apple Safari';
         $ub = "Safari";
      } elseif(preg_match('/Opera/i',$u_agent)) {
         $bname = 'Opera';
         $ub = "Opera";
      } elseif(preg_match('/Netscape/i',$u_agent)) {
         $bname = 'Netscape';
         $ub = "Netscape";
      }

      // finally get the correct version number
      $known = array('Version', $ub, 'other');
      $pattern = '#(?<browser>' . join('|', $known) . ')
         [/ ]+(?<version>[0-9.|a-zA-Z.]*)#';

      if (!preg_match_all($pattern, $u_agent, $matches)) {
         // we have no matching number just continue
      }

      // see how many we have
      $i = count($matches['browser']);

      if ($i != 1) {
         //we will have two since we are not using 'other' argument yet

         //see if version is before or after the name
         if (strripos($u_agent,"Version") < strripos($u_agent,$ub)){
            $version= $matches['version'][0];
         } else {
            $version= $matches['version'][1];
         }
      } else {
         $version= $matches['version'][0];
      }

      // check if we have a number
      if ($version == null || $version == "") {$version = "?";}
         return array(
            'userAgent' => $u_agent,
            'name'      => $bname,
            'version'   => $version,
            'platform'  => $platform,
            'pattern'   => $pattern
         );
   }

   // now try it
   $ua = getBrowser();
   $yourbrowser = "Your browser: " . $ua['name'] . " " . $ua['version'] .
   " on " .$ua['platform'] . " reports: <br >" . $ua['userAgent'];

   print_r($yourbrowser);
?>

这在我的机器上产生以下结果。根据你使用的计算机,此结果可能有所不同。

它将产生以下结果 −

Your browser: Google Chrome 54.0.2840.99 on windows reports:
Mozilla/5.0 (Windows NT 6.3; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko)
   Chrome/54.0.2840.99 Safari/537.36

Display Images Randomly

PHP rand() 函数用于生成随机数。此函数可以生成指定范围内内的数。应设置随机数生成器的种子,以防止生成规则的数字模式。这是通过使用 srand() 函数来实现的,该函数指定种子号作为其参数。

Example

以下示例展示了如何每次从四张图片中显示不同的图片 −

<?php
   srand( microtime() * 1000000 );
   $num = rand( 1, 4 );

   switch( $num ) {
      case 1: $image_file = "/php/images/php_image_sample_1.jpg";
         break;

      case 2: $image_file = "/php/images/php_image_sample_2.jpg";
         break;

      case 3: $image_file = "/php/images/php_image_sample_3.jpg";
         break;

      case 4: $image_file = "/php/images/php_image_sample_4.jpg";
         break;
   }
   echo "Random Image : <img src=$image_file />";
?>

它将产生以下结果 −

php image sample 3

Using HTML Forms

处理 HTML 表单和 PHP 时需要注意的最重要一点是 HTML 页面中的任何表单元素都将自动对你的 PHP 脚本可用。

Example

通过将源代码放入 test.php 脚本中,尝试以下示例。

<?php
   if( $_POST["name"] || $_POST["age"] ) {
      if (preg_match("/[^A-Za-z'-]/",$_POST['name'] )) {
         die ("invalid name and name should be alpha");
      }

      echo "Welcome ". $_POST['name']. "<br />";
      echo "You are ". $_POST['age']. " years old.";

      exit();
   }
?>
<form action = "<?php <b>$_PHP_SELF</b> ?>" method = "POST">
   Name: <input type = "text" name = "name" />
   Age: <input type = "text" name = "age" />
   <input type = "submit" />
</form>

它将产生以下结果 −

forms
  1. PHP 默认变量 $_PHP_SELF 用于 PHP 脚本名称,当你点击“提交”按钮时,将调用相同的 PHP 脚本,并将产生以下结果 −

  2. method = "POST" 用于向服务器脚本发布用户数据。有两种向服务器脚本发布数据的方法,将在 PHP GET & POST 章节中讨论。

Browser Redirection

PHP header() 函数向浏览器提供原始的 HTTP 标头,可用于将其重定向到其他位置。重定向脚本应位于页面的最顶部,以防页面任何其他部分加载。

目标由 Location: 标头指定为 header() 函数的参数。在调用此函数后,可以使用 exit() 函数来停止解析代码的其余部分。

Example

以下示例演示如何将浏览器请求重定向到另一个网页。通过将源代码放入 test.php 脚本中,尝试此示例。

<?php
   if( $_POST["location"] ) {
      $location = $_POST["location"];
      header( "Location:$location" );

      exit();
   }
?>
<p>Choose a site to visit :</p>
<form action = "<?php <b>$_SERVER['PHP_SELF']</b> ?>" method ="POST">
   <select name = "location">.

      <option value = "http://www.tutorialspoint.com">
         Tutorialspoint.com
      </option>

      <option value = "http://www.google.com">
         Google Search Page
      </option>

   </select>
   <input type = "submit" />
</form>

它将产生以下结果 −

browser redirection

PHP - Form Handling

HTML Forms 在 PHP Web 应用程序中扮演着重要的角色。虽然纯粹由 HTML 编写的网页是一个静态网页,但 HTML 表单组件是一个重要的特性,有助于实现交互性和呈现动态内容。PHP 的表单处理功能可以在处理之前验证从用户收集的数据。

HTML 表单是各种表单控件的集合,例如文本字段、复选框、单选按钮等,用户可以使用这些表单控件进行交互、输入或选择某些数据,这些数据可以由 JavaScript(客户端处理)在本地处理,也可以借助 PHP 等服务器端编程脚本发送到远程服务器进行处理。

一个或多个表单控件元素被放在 <form> 和 </form> 标记内。 form element 的特点是具有不同的属性,例如名称、操作和方法。

<form [attributes]>
   Form controls
</form>

Form Attributes

在 HTML 表单元素的众多属性中,经常需要和定义以下属性 −

Action Attribute

表示处理表单提交的 URL 的字符串。例如, http://example.com/test.php 。若要将表单数据提交至定义 HTML 表单的相同 PHP 脚本,请使用 PHP_SELF 服务器变量 −

<form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">

Enctype Attribute

指定在将表单数据发送到服务器之前对其进行编码的方法。可能的值为 −

  1. application/x-www-form-urlencoded − 默认值。

  2. multipart/form-data − 如果表单包含带有类型=文件的 <input> 元素,请使用此方法。

  3. text/plain − 对于调试目的很有用。

Method Attribute

表示提交表单所用 HTTP 方法的字符串。以下方法是 method 属性的可能值 −

  1. post − POST 方法;表单数据作为请求正文发送。

  2. get (default) − GET;表单数据附加到带有“?”分隔符的操作 URL。在表单没有副作用时使用此方法。

  3. dialog − 当表单位于 <dialog> 内部时,关闭该会话框并触发提交事件,而无需提交数据或清除表单。

Name Attribute

表单的名称。该值不能是空字符串,且如果同一 HTML 文档中存在多个表单,则它必须是唯一的。

Target Attribute

一个指示提交表单后显示响应的位置的字符串。应为下列选项之一:

  1. _self (default) − 加载到与当前浏览上下文相同的上下文。

  2. _blank − 加载到一个新的未命名浏览上下文中。

  3. _parent − 加载到当前浏览上下文的父上下文中。

  4. _top − 加载到顶级浏览上下文中(当前上下文的祖先且没有父上下文)。

因此,在一个 PHP Web 应用程序中使用的典型 HTML 表单如下所示:

<form name="form1" action="<?php echo $_SERVER['PHP_SELF'];?>" action="POST">
   Form controls
</form>

Form Elements

HTML 表单设计为不同类型的控件或元素。用户可以与这些控件交互,以输入数据或从呈现的可用选项中进行选择。下面描述了一些元素:

Input Element

input 元素表示一个数据域,允许用户输入和/或编辑数据。

input 元素的 type 属性控制数据。input 元素可以是以下类型:

用于输入单行文本的文本域。

<input type="text" name="employee">

一个屏蔽输入字符的单行文本域。

<input type="password" name="pwd"><br>

一个可复选的矩形框,是从预定义列表中获取的一个或多个值。

<input type="checkbox" id="s1" name="sport1" value="Cricket">
<label for="s1">I like Cricket</label><br>
<input type="checkbox" id="s2" name="sport2" value="Football">
<label for="s2">I like Football</label><br>
<input type="checkbox" id="s3" name="sport3" value="Tennis">
<label for="s3">I like Tennis</label><br><br>

此类型呈现一个带有两种状态(开或关)的可圆形单击按钮,通常是单选按钮组中的一个按钮。

<input type="radio" id="g1" name="gender" value="Male">
<label for="g1">Male</label><br>
<input type="radio" id="g2" name="female" value="Female">
<label for="g2">Female</label><br>

input 类型呈现一个标有标题文件的按钮,允许用户从客户端文件系统选择一个文件,通常要上载到服务器。表单的 enctype 属性必须设置为“multipart/form-data”。

<input type="file" name="file">

一个单行文本域,经过自定义以接受一个符合有效电子邮件 ID 的字符串。

一个单行文本域,经过自定义以接受一个符合有效 URL 的字符串。

此 input 元素呈现一个按钮,单击此按钮时,它会启动将表单数据提交到当前表单的 action 属性中指定的 URL。

<input type="submit" name="Submit">

Select Element

Select 元素表示用于在一组选项中进行选择的控件。每个选项都由 Select Control 的 option 属性定义。例如 −

<select name="Subjects" id="subject">
   <option value="Physics">Physics</option>
   <option value="Chemistry">Chemistry</option>
   <option value="Maths">Maths</option>
   <option value="English">English</option>
</select>

Form Example

让我们使用这些表单元素来设计一个 HTML 表单并将其发送到 PHP_SELF 脚本

<html>
<body>
   <form method = "post" action = "<?php
      echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
      <table>
         <tr>
            <td>Name:</td>
            <td><input type = "text" name = "name"></td>
         </tr>
         <tr>
            <td>E-mail: </td>
            <td><input type = "email" name = "email"></td>
         </tr>
         <tr>
            <td>Website:</td>
            <td><input type = "url" name = "website"></td>
         </tr>
         <tr>
            <td>Classes:</td>
            <td><textarea name = "comment" rows = "5" cols = "40"></textarea></td>
         </tr>
         <tr>
            <td>Gender:</td>
            <td>
               <input type = "radio" name = "gender" value = "female">Female
               <input type = "radio" name = "gender" value = "male">Male
            </td>
         </tr>
         <td>
            <input type = "submit" name = "submit" value = "Submit">
         </td>
      </table>
   </form>
   <?php
      $name = $email = $gender = $comment = $site = "";

      if ($_SERVER["REQUEST_METHOD"] == "POST") {
         $name = $_POST["name"];
         $email = $_POST["email"];
         $name = $_POST["name"];
         $comment = $_POST["comment"];
         $gender = $_POST["gender"];
         $site = $_POST["website"];
      }
      echo "<h2>Your given values are as:</h2>";
      echo $name;
      echo "<br>";

      echo $email;
      echo "<br>";

      echo $site;
      echo "<br>";

      echo $comment;
      echo "<br>";

      echo $gender;
   ?>
</body>
</html>

它将生成以下 output

php form handling

PHP - Form Validation

术语“表单验证”指的是确定用户在各种表单元素中输入的数据是否可用于进一步处理的过程。在后续处理之前验证数据可避免可能的异常和运行时错误。

验证可以在客户端和服务器端进行。当客户端提交表单时,表单数据会被服务器上运行的 PHP 脚本截取。可以使用 PHP 中的各种函数进行服务器端表单验证。

Client-side Validation

根据 HTML5 规范,新的输入控件具有内置验证。例如,类型为“电子邮件”的输入元素,即使是文本字段,也经过了定制,以接受与电子邮件地址协议一致的字符串。

在将数据提交至服务器之前验证。对于其他输入类型(如 URL、数字等)也是如此。

Example

下面给出一个包含数字类型、电子邮件类型和 URL 类型的输入元素的 HTML 表单。如果您输入的不是按所需格式,那么在您尝试提交表单时会闪烁一个合适的错误信息。

<h1>Input Validation</h1>
<form>
   <p><Label for "name">Enter your name</label>
   <input type = "text" id="name" name="name"></p>
   <p><label for="age">Enter age</label>
   <input type = "text" id = "age" name="age"></p>
   <p><label for="email">Enter your email:</label>
   <input type="text" id="email" name="email"></p>
   <p><label for="URL">Enter your website<label>
   <input type = "text" id="URL" name="url"></p>
   <input type="submit">
</form>

数字类型文本字段在右侧显示了向上/向下计数器箭头。只接受数字,可以增量或减量。

php form validation 1

如果电子邮件字段中的数据无效,您将收到如下错误信息。

php form validation 2

同样,任何不正确的 URL 格式也会显示如下所示的错误 −

php form validation 3

Validation Functions

带有PHP的服务器端验证出现在两种情况下,一种是表单数据通过客户端验证,另一种是客户端根本没有验证。

在上面示例中使用的 HTML 表单中,让我们删除所有特殊输入类型并使用文本类型的全部文本字段。通过 POST 方法将表单提交到服务器上的 hello.php。

<form action="hello.php" method="POST">
   <p><Label for "name">Enter your name</label>
   <input type = "text" id="name" name="name"></p>
   <p><label for="age">Enter age</label>
   <input type = "text" id = "age" name="age"></p>
   <p><label for="email">Enter your email:</label>
   <input type="text" id="email" name="email"></p>
   <p><label for="URL">Enter your website<label>
   <input type = "text" id="URL" name="url"></p>
   <input type="submit">
</form>

Form is Empty

如果用户(可能是无意中)单击了提交按钮,你可以要求 PHP 重新显示表单。你需要检查 $_POST 数组是否已使用 isset() 函数初始化。如果没有,则 header() 函数会将控件重定向回表单。

<?php
   if ($_SERVER["REQUEST_METHOD"] == "POST") {
      if (isset($_POST)) {
         header("Location: hello.html", true, 301);
         exit();
      }
      // form processing if the form is not empty
   }
?>

Example

你还可以检查在提交表单时是否有任何字段为空。

<?php
   if ($_SERVER["REQUEST_METHOD"] == "POST") {
      foreach($_POST as $k=>$v) {
         if (empty($v)==true) {
            echo "One or more fields are empty \n";
            echo "<a href = 'hello.html'>Click here to go back </a>";
            exit;
         }
         else
         echo "$k => $v \n";
      }
   }
?>

Age field is non-numeric

在 HTML 表单中,名称的输入字段为文本类型,因此它可以接受任何字符。然而,我们希望它具有数字性,这可以通过 is_numeric() 函数来保证。

<?php
   if (is_numeric($_POST["age"])==false) {
      echo "Age cannot be non-numeric \n";
      echo "<a href = 'hello.html'>Click here to go back</a>";
   }
?>

PHP 还有 is_string() 函数,用于检查字段是否包含字符串。另外两个函数 trim() 和 htmlspecialchars() 也对表单验证有用。

  1. trim() − 从字符串的开头和结尾移除空白

  2. htmlspecialchars() − 将特殊字符转换成 HTML 实体,以防止跨站点脚本(XSS)攻击。

PHP - Form Email/URL

PHP 为验证表单数据项(它们是字符串,但预期是电子邮件 ID 或 URL 的表示)提供了两种选择。检查表单元素是否包含电子邮件/URL 的一种方法是使用 RegEx (regular expressions) ,另一种更方便的方法是使用 filter_var() 函数。让我们应用这两种方法,并验证由表单提交给 PHP 脚本的电子邮件和 URL。

本章中使用的 HTML 表单如下 −

<h1>Email and URL Validation</h1>
<form action="hello.php" method="POST">
   <p><label for="email">Enter your email:</label>
   <input type="text" id="email" name="email"></p>
   <p><label for="URL">Enter your website<label>
   <input type = "text" id="URL" name="url"></p>
   <input type="submit">
</form>

Validation with Regex

PHP 的内置函数库包括执行正则表达式匹配的 preg_match() function

preg_match(
   string $pattern,
   string $subject,
   array &$matches = null,
   int $flags = 0,
   int $offset = 0
): int|false

此函数在 subject 中搜索与 pattern 中给出的正则表达式匹配的部分。如果 pattern 与给定的 subject 匹配, preg_match() 返回 1;如果它不匹配,则返回 0;如果失败,则返回 false

有效的电子邮件 ID 应满足以下正则表达式 −

"/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix"

同样,有效的 URL 应满足以下正则表达式 −

"/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i"

如果字符串是有效的电子邮件 ID,则以下函数返回“1”或“0”。

function checkemail($str) {
   return (!preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE;
}

Example

让我们使用 checkmail() function ,借助以下 PHP 代码,来检查上面 HTML 中的电子邮件字段是否有效 −

<?php
   function checkemail($str) {
      return (!preg_match("/^([a-z0-9\+_\-]+)(\.[a-z0-9\+_\-]+)*@
         ([a-z0-9\-]+\.)+[a-z]{2,6}$/ix", $str)) ? FALSE : TRUE;
   }
   if ($_SERVER["REQUEST_METHOD"] == "POST") {
      $email = $_POST['email'];
      if(!checkemail($email)){
         echo "Invalid email address.";
      } else {
         echo "Valid email address.";
      }
   }
?>

HTML 表单如下呈现 −

php form email url

通过在电子邮件字段中输入有效/无效的电子邮件字符串来测试 PHP 代码。

以下 checkURL() function 检查字符串是否表示有效的 URL 或无效的 URL,并返回“1 或“0”。

function checkURL($str) {
   return (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)
      [-a-z0-9+&@#\/%?=~_|!:,.;]*[-a-z0-9+&@#\/%=~_|]/i", $str)) ? FALSE : TRUE;
}

Example

从 $_POST 数组中提取的 URL 字段作为参数提供给上述函数。

<?php
   function checkURL($str) {
      return (!preg_match("/\b(?:(?:https?|ftp):\/\/|www\.)[-a-z0-9+&@#\/%?=~_|!:,.;]
         *[-a-z0-9+&@#\/%=~_|]/i", $str)) ? FALSE : TRUE;
   }
   if ($_SERVER["REQUEST_METHOD"] == "POST") {
      $url = $_POST['url'];
      if(!checkURL($url)){
         echo "Invalid URL.";
      } else {
         echo "Valid URL.";
      }
   }
?>

您可以通过在上面表单的 URL 字段中输入 URL 字符串来测试上面的代码。

Using filter_var() function

内置的 filter_var() 函数使用指定的过滤器过滤变量。

filter_var(mixed $value, int $filter = FILTER_DEFAULT, array|int $options = 0): mixed

根据 $filter 参数的值作为枚举过滤器 ID,将检查 $value 参数,如果过滤器失败,则该函数返回过滤后的数据或 false。

有各种 predefined filter ID constants 可用 −

Sr.No

ID & Description

1

FILTER_VALIDATE_BOOL 返回 true 以表示“1”、“true”、“on”和“yes”。否则返回 false。

2

FILTER_VALIDATE_DOMAIN 验证域名标签长度是否有效。

3

FILTER_VALIDATE_EMAIL 验证值是否有效的电子邮件地址。

4

FILTER_VALIDATE_IP 验证值是否有效的 IP 地址

5

FILTER_VALIDATE_URL Validates value as URL

Example

以下 PHP 脚本验证了以上 HTML 提交的电子邮件和 URL 数据 −

<?php
   if ($_SERVER["REQUEST_METHOD"] == "POST") {
      $email = $_POST['email'];
      $url = $_POST['url'];

      if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
         echo "Invalid email format and please re-enter valid email\n";
      }
      else
      echo "Email entered is in valid format\n";

      if (!filter_var($url, FILTER_VALIDATE_URL)) {
         echo "Invalid URL format and please re-enter valid URL\n";
      }
      else
      echo "URL entered is in valid format\n";
   }
?>

你可以通过输入有效的/无效的电子邮件/URL 来测试以上脚本的性能。

PHP - Complete Form

本章将表单验证和提取 HTML 表单数据的所有概念放入 PHP 代码中。下面给出的完整表单处理代码分三个部分:开始时的 PHP 代码部分,当表单提交时寻找任何验证错误;HTML 表单,带有各种元素,例如文本字段、单选按钮、选择控件、复选框等。第三部分又是一段 PHP 代码,它呈现用户输入的数据。

PHP Error Tracking

捕获错误的代码位于整个脚本的开头。显然,这将在每次加载页面时执行。如果在表单提交后加载,则以下片段检查每个元素是否为空,电子邮件字段是否格式化良好,以及复选框是否被单击(表示用户同意条款)。

<?php

   // define variables and set to empty values
   $nameErr = $emailErr = $genderErr = $websiteErr = "";
   $name = $email = $gender = $class = $course = $subject = "";

   if ($_SERVER["REQUEST_METHOD"] == "POST") {
      if (empty($_POST["name"])) {
         $nameErr = "Name is required";
      } else {
         $name = test_input($_POST["name"]);
      }

      if (empty($_POST["email"])) {
         $emailErr = "Email is required";
      } else {
         $email = test_input($_POST["email"]);

         // check if e-mail address is well-formed
         if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
            $emailErr = "Invalid email format";
         }
      }

      if (empty($_POST["course"])) {
         $course = "";
      } else {
         $course = test_input($_POST["course"]);
      }

      if (empty($_POST["class"])) {
         $class = "";
      } else {
         $class = test_input($_POST["class"]);
      }

      if (empty($_POST["gender"])) {
         $genderErr = "Gender is required";
      } else {
         $gender = test_input($_POST["gender"]);
      }

      if (empty($_POST["subject"])) {
         $subjectErr = "You must select one or more subjects";
      } else {
         $subject = $_POST["subject"];
      }
   }

   function test_input($data) {
      $data = trim($data);
      $data = stripslashes($data);
      $data = htmlspecialchars($data);
      return $data;
   }
?>

HTML Form

呈现条目表单的 HTML 脚本遵循错误捕获代码。表单设计中采用了多种元素。

<h2>Absolute Classes Registration Form</h2>
<p><span class = "error">* required field.</span></p>
<form method = "POST" action = "<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
   <table>
      <tr>
         <td>Name:</td>
         <td>
            <input type = "text" name = "name">
            <span class = "error">* <?php echo $nameErr;?></span>
         </td>
      </tr>
      <tr>
         <td>E-mail: </td>
         <td>
            <input type = "text" name = "email">
            <span class = "error">* <?php echo $emailErr;?></span>
         </td>
      </tr>
      <tr>
         <td>Time:</td>
         <td>
            <input type = "text" name = "course">
            <span class = "error"><?php echo $websiteErr;?></span>
         </td>
      </tr>
      <tr>
         <td>Classes:</td>
         <td><textarea name = "class" rows = "5" cols = "40"></textarea></td>
      </tr>
      <tr>
         <td>Gender:</td>
         <td>
            <input type = "radio" name = "gender" value = "female">Female
            <input type = "radio" name = "gender" value = "male">Male
            <span class = "error">* <?php echo $genderErr;?></span>
         </td>
      </tr>
      <tr>
         <td>Select:</td>
         <td>
            <select name = "subject[]" size = "4" multiple>
               <option value = "Android">C</option>
               <option value = "Java">Java</option>
               <option value = "C#">C#</option>
               <option value = "Data Base">C++</option>
               <option value = "Hadoop">PHP</option>
               <option value = "VB script">Python</option>
            </select>
         </td>
      </tr>
      <tr>
         <td>Agree</td>
         <td><input type = "checkbox" name = "checked" value = "1"></td>
         <?php if(!isset($_POST['checked'])){ ?>
            <span class = "error">* <?php echo "You must agree to terms";?></span>
         <?php } ?>
      </tr>
      <tr>
         <td>
            <input type = "submit" name = "submit" value = "Submit">
         </td>
      </tr>
   </table>
</form>

请注意,表单数据已提交回同一个脚本,因此表单的 action 属性设置为 $_SERVER["PHP_SELF"] 超全局。此部分还包含某些内联 PHP 代码,这些代码在各个表单控件旁边闪烁错误消息——例如,如果名称字段在提交表单时为空,则在名称文本框旁边立即显示名称必需的消息。

Display Form Data

脚本的第三部分又是一段 PHP 代码,它回显用户提交的每个表单字段的值。

<?php
   if ($_SERVER["REQUEST_METHOD"] == "POST") {
      echo "<h2>Your given values are as :</h2>";
      echo ("<p><b>Name</b> : $name</p>");
      echo ("<p><b>Email address</b> : $email</p>");
      echo ("<p><b>Preffered class time</b> : $course</p>");
      echo ("<p><b>Class info</b> : $class </p>");
      echo ("<p><b>Gender</b> : $gender</p>");
      echo "<p><b>Subjcts Chosen:</b><p>";
      if (!empty($subject)) {
         echo "<ul>";
         for($i = 0; $i < count($subject); $i++) {
            echo "<li>$subject[$i]</u/li>";
         }
         echo "</ul>";
      }
   }
?>

当脚本从服务器的文档根目录运行时,此为表单中填写的示例数据 −

php complete form 1

当提交时, output 呈现如下所示 −

php complete form 2

Example

处理 HTML 表单的 PHP 的完整代码如下所示 −

<html>
<head>
   <style>
      .error {color: #FF0000;}
   </style>
</head>
<body>
   <?php

      // define variables and set to empty values
      $nameErr = $emailErr = $genderErr = $websiteErr = "";
      $name = $email = $gender = $class = $course = $subject = "";

      if ($_SERVER["REQUEST_METHOD"] == "POST") {
         if (empty($_POST["name"])) {
            $nameErr = "Name is required";
         }else {
            $name = test_input($_POST["name"]);
         }

         if (empty($_POST["email"])) {
            $emailErr = "Email is required";
         } else {
            $email = test_input($_POST["email"]);

            // check if e-mail address is well-formed
            if (!filter_var($email, FILTER_VALIDATE_EMAIL)) {
               $emailErr = "Invalid email format";
            }
         }

         if (empty($_POST["course"])) {
            $course = "";
         } else {
            $course = test_input($_POST["course"]);
         }

         if (empty($_POST["class"])) {
            $class = "";
         } else {
            $class = test_input($_POST["class"]);
         }

         if (empty($_POST["gender"])) {
            $genderErr = "Gender is required";
         } else {
            $gender = test_input($_POST["gender"]);
         }

         if (empty($_POST["subject"])) {
            $subjectErr = "You must select one or more subjects";
         } else {
            $subject = $_POST["subject"];
         }
      }

      function test_input($data) {
         $data = trim($data);
         $data = stripslashes($data);
         $data = htmlspecialchars($data);
         return $data;
      }
   ?>
   <h2>Absolute Classes Registration Form</h2>
   <p><span class = "error">* required field.</span></p>
   <form method = "POST" action = "<?php echo htmlspecialchars($_SERVER["PHP_SELF"]);?>">
      <table>
         <tr>
            <td>Name:</td>
            <td>
               <input type = "text" name = "name">
               <span class = "error">* <?php echo $nameErr;?></span>
            </td>
         </tr>
         <tr>
            <td>E-mail: </td>
            <td>
               <input type = "text" name = "email">
               <span class = "error">* <?php echo $emailErr;?></span>
            </td>
         </tr>
         <tr>
            <td>Time:</td>
            <td>
               <input type = "text" name = "course">
               <span class = "error"><?php echo $websiteErr;?></span>
            </td>
         </tr>
         <tr>
            <td>Classes:</td>
            <td><textarea name = "class" rows = "5" cols = "40"></textarea></td>
         </tr>
         <tr>
            <td>Gender:</td>
            <td>
               <input type = "radio" name = "gender" value = "female">Female
               <input type = "radio" name = "gender" value = "male">Male
               <span class = "error">* <?php echo $genderErr;?></span>
            </td>
         </tr>
         <tr>
            <td>Select:</td>
            <td>
               <select name = "subject[]" size = "4" multiple>
                  <option value = "C">C</option>
                  <option value = "Java">Java</option>
                  <option value = "C#">C#</option>
                  <option value = "c++">C++</option>
                  <option value = "PHP">PHP</option>
                  <option value = "Python">Python</option>
               </select>
            </td>
         </tr>
         <tr>
            <td>Agree</td>
            <td><input type = "checkbox" name = "checked" value = "1"></td>
            <?php if(!isset($_POST['checked'])){ ?>
               <span class = "error">* <?php echo "You must agree to terms";?></span>
            <?php } ?>
         </tr>
         <tr>
            <td>
               <input type = "submit" name = "submit" value = "Submit">
            </td>
         </tr>
      </table>
   </form>
   <?php
      if ($_SERVER["REQUEST_METHOD"] == "POST") {
         echo "<h2>Your given values are as :</h2>";
         echo ("<p><b>Name</b> : $name</p>");
         echo ("<p><b>Email address</b> : $email</p>");
         echo ("<p><b>Preffered class time</b> : $course</p>");
         echo ("<p><b>Class info</b> : $class </p>");
         echo ("<p><b>Gender</b> : $gender</p>");
         echo "<p><b>Subjcts Chosen:</b><p>";
         if (!empty($subject)) {
            echo "<ul>";
            for($i = 0; $i < count($subject); $i++) {
               echo "<li>$subject[$i]</u/li>";
            }
            echo "</ul>";
         }
      }
   ?>
</body>
</html>

它将生成以下 output

complete form

PHP - File Inclusion

你可以在服务器执行之前将一个 PHP 文件的内容包含到另一个 PHP 文件中。有两个 PHP 函数可用于将一个 PHP 文件包含到另一个 PHP 文件中。

  1. The include() Function

  2. The require() Function

这是 PHP 的一个优点,它有助于创建可以在多个页面中重复使用的函数、页眉、页脚或元素。这将有助于开发人员毫不费力地轻松更改整个网站的布局。如果有任何更改需求,则无需更改数千个文件,只需要更改包含的文件即可。

The include() Function

include() 函数获取指定文件中所有的文本并且将其复制到使用 include 函数的文件中。如果加载文件时有任何问题,则 include() 函数会生成警告,但是脚本将继续执行。

假设你要为网站创建一个通用菜单。然后创建一个包含以下内容的文件 menu.php。

<a href="http://www.tutorialspoint.com/index.htm">Home</a>
<a href="http://www.tutorialspoint.com/ebxml">ebXML</a>
<a href="http://www.tutorialspoint.com/ajax">AJAX</a>
<a href="http://www.tutorialspoint.com/perl">PERL</a>

现在创建尽可能多的页面,并添加此文件以创建页眉。例如,现在你的 test.php 文件可以包含以下内容。

<?php <b>include("menu.php");</b> ?>
<p>This is an example to show how to include PHP file!</p>

它将产生以下结果 −

include

The require() Function

require() 函数获取指定文件中所有的文本并且将其复制到使用 include 函数的文件中。如果加载文件时有任何问题,则 require() 函数会生成致命错误并停止脚本执行。

因此 require() 和 include() 之间的区别在于它们如何处理错误条件。建议使用 require() 函数,而不要使用 include() 函数,因为如果缺少文件或文件命名错误,脚本不应继续执行。

你可以尝试使用以上示例结合 require() 函数,它会生成相同的结果。但是,如果将尝试以下两个示例,其中文件不存在,你将会得到不同的结果。

<?php include("xxmenu.php"); ?>
<p>This is an example to show how to include wrong PHP file!</p>

这会产生以下结果 −

This is an example to show how to include wrong PHP file!

现在我们尝试使用 require() 函数来执行相同的示例。

<?php <b>require("xxmenu.php");</b> ?>
<p>This is an example to show how to include wrong PHP file!</p>

这次文件执行停止,没有显示任何东西。

NOTE − 你可能会得到普通警告消息或致命错误消息,或者根本没有消息。这取决于你的 PHP 服务器配置。

PHP - GET & POST

由于 PHP 主要用于 Web 应用程序开发,因此浏览器客户端发送的数据主要与 GET 和 POST 类型的 HTTP 请求方法有关。HTTP 协议还定义了向服务器发送请求的其他方法。除了 GET 和 POST 方法之外,还有 PUT、DELETE、HEAD 和 OPTIONS 方法。在本章中,我们主要研究 PHP 如何处理 GET 和 POST 方法。

The GET Method

GET 方法发送编码的用户信息,并将其附加到页面请求。页面和编码信息由 ? 字符分隔。

http://www.test.com/index.htm?name1=value1&name2=value2
  1. GET 方法生成一个较长的字符串,它显示在服务器日志中和浏览器的 Location: 方框中。

  2. GET 方法只能发送最多 1024 个字符。

  3. 如果你要向服务器发送密码或其他敏感信息,请切勿使用 GET 方法。

  4. GET 不能用于向服务器发送二进制数据,例如图像或 word 文档。

  5. 通过 QUERY_STRING 环境变量可以访问 GET 方法发送的数据。

  6. PHP 提供了 $_GET 关联数组来使用 GET 方法访问所有发送的信息。

通过将源代码放入 test.php 脚本中,尝试以下示例。

<?php
   if( $_GET["name"] || $_GET["age"] ) {
      echo "Welcome ". $_GET['name']. "<br />";
      echo "You are ". $_GET['age']. " years old.";

      exit();
   }
?>
<form action = "<?php <b>$_PHP_SELF</b> ?>" method = "GET">
   Name: <input type = "text" name = "name" />
   Age: <input type = "text" name = "age" />
   <input type = "submit" />
</form>

它将产生以下结果 −

forms

The POST Method

POST 方法通过 HTTP 标头传输信息。该信息已被编码,就像 GET 方法中所描述的那样,并放入名为 QUERY_STRING 的标头中。

  1. POST 方法对要发送的数据量没有任何限制。

  2. POST 方法可用于发送 ASCII 和二进制数据。

  3. POST 方法发送的数据会通过 HTTP 标头,因此安全性取决于 HTTP 协议。通过使用安全 HTTP,你可以确保你的信息安全。

  4. PHP 提供了 $_POST 关联数组来使用 POST 方法访问所有发送的信息。

通过将源代码放入 test.php 脚本中,尝试以下示例。

<?php
   if( $_POST["name"] || $_POST["age"] ) {
      if (preg_match("/[^A-Za-z'-]/",$_POST['name'] )) {
         die ("invalid name and name should be alpha");
      }
      echo "Welcome ". $_POST['name']. "<br />";
      echo "You are ". $_POST['age']. " years old.";

      exit();
   }
?>
<form action = "<?php <b>$_PHP_SELF</b> ?>" method = "POST">
   Name: <input type = "text" name = "name" />
   Age: <input type = "text" name = "age" />
   <input type = "submit" />
</form>

它将产生以下结果 −

forms

Difference between GET and POST

GET 方法和 POST 方法之间的主要区别在于,虽然附加到 URL 的请求参数在浏览器的 URL 中公开出来,但 POST 数据包含在消息正文中,并且不会在 URL 中显示出来。因此,GET 方法不应用于将敏感数据发送到服务器。

其次,GET 方法中的请求数据不能超过 2048 个字符,只能由 ASCII 字符组成,而使用 POST 方法时,对请求数据没有限制,也可以是二进制的(POST 数据的默认最大大小由 php.ini 文件中的 post_max_size 设置决定)

PHP 提供了以下三个 superglobals 来检索和处理请求参数 −

  1. $_GET − 用于使用 GET 方法访问所有发送信息的一个关联数组。

  2. $_POST − 用于使用 POST 方法访问所有发送信息的一个关联数组。

  3. $_REQUEST − 用于获取通过 GET 和 POST 方法发送的表单数据的结果的一个关联数组。

$_GET Array

你可以在查询字符串中以直接附加到 URL 的形式传递请求参数。

将以下 PHP 脚本保存在文档根文件夹 ( htdocs ) 中,并将其命名为“hello.php” −

<?php
   echo "First name: " . $_REQUEST['first_name'] . " " .
      "Last Name: " . $_REQUEST['last_name'] . "";
?>

在浏览器窗口中输入 http://localhost/hello.php?first_name=Amar&last_name=Sharma 作为 URL(确保 PHP 服务器正在运行)。

$_GET 数组通过请求填充,输出显示如下 −

First name: Amar Last Name: Sharma

如果 HTML 表单数据的方法属性为 GET,您也可以使用该数据填充 $_GET 数组。

使用以下 HTML 表单收集数据并将其发送到“hello.php”。在文档根目录下,将以下脚本另存为“hello.html” −

<form action="hello.php" method="get">
   First Name: <input type="text" name="first_name"/>  <br/>
   Last Name: <input type="text" name="last_name" />
   <input type="submit" value="Submit" />
</form>

在浏览器中,输入 URL“http://localhost/hello.html” −

php get post

您应该会在浏览器窗口中获取类似 output 的内容。

$_POST Array

使用 POST 请求向服务器发送数据的最简单方法是将 HTML 表单的方法属性指定为 POST。假设浏览器中的 URL 为“http://localhost/hello.php”,那么在 HTML 表单“hello.html”中将 method=POST 设置为前面的示例 −

<form action="hello.php" method="post">
   First Name: <input type="text" name="first_name"/>  <br/>
   Last Name: <input type="text" name="last_name" />
   <input type="submit" value="Submit" />
</form>

“hello.php”脚本(位于文档根目录文件夹中)在 $_POST 数组中检索表单数据并将其作为 HTTP 响应呈现给浏览器 −

<?php
   echo "First name: " . $_POST['first_name'] . " " .
      "Last Name: " . $_POST['last_name'] . "";
?>

在浏览器中打开 "http://localhost/hello.html" 。输入的数据将由服务器检索,然后像前面的示例一样呈现在客户端。

PHP - File Uploading

典型 PHP Web 应用程序所需的一个常见功能是允许用户上传文件。在 PHP 中从客户端上传文件非常容易。在本章中,我们将学习如何针对文件上传过程使用 PHP 脚本。

上传文件的过程遵循以下步骤 −

  1. 用户打开包含 HTML 表单的页面,其中包含文本文件、浏览按钮和提交按钮。

  2. 用户单击浏览按钮,并从本地 PC 中选择要上传的文件。

  3. 系统会在文本文件中显示所选文件的完整路径,然后用户单击提交按钮。

  4. 所选文件将发送到服务器上的临时目录。

  5. 表单操作属性中指定为表单处理器的 PHP 脚本将检查文件是否已到达,然后将文件复制到目标目录中。

  6. PHP 脚本向用户确认成功。

为了执行此活动,我们必须首先确保“php.ini”中启用了与文件上传相关的配置设置。

打开“php.ini”文件并确保以下设置已启用,方法是在 file_uploads、upload_tmp_dir、upload_max_filesize 和 max_file_uploads 参数中删除前导分号 (;) 符号 −

;;;;;;;;;;;;;;;;
; File Uploads ;
;;;;;;;;;;;;;;;;

; Whether to allow HTTP file uploads.
; http://php.net/file-uploads
file_uploads=On

; Temporary directory for HTTP uploaded files (will use system
; default if not specified).
; http://php.net/upload-tmp-dir
upload_tmp_dir="C:\xampp\tmp"

; Maximum allowed size for uploaded files.
; http://php.net/upload-max-filesize
upload_max_filesize=40M

; Maximum number of files that can be uploaded via a single request
max_file_uploads=20

临时位置和最终位置的文件夹必须设置有允许文件写入的权限。如果任一位置设置为只读,那么进程将失败。

Creating a File Upload Form

下一步,我们需要设计一个用于文件上传的 HTML 表单。该表单的 method 属性必须为 POST,enctype 必须为 multipart/form-data。使用 file 作为 input 类型,以便让用户浏览并选择要上传的文件。

<h2>File Upload Form</h2>
<form method = "POST" action = "uploadfile.php" enctype="multipart/form-data">
   <label for="file">File name:</label>
   <input type="file" name="uploadfile" />
   <input type="submit" name="submit" value="Upload" />
</form>

Creating an Upload Script

uploadfile.php 脚本接收已上传的文件。文件数据收集在超级全局变量 $_FILES 中。获取已上传文件的名称、文件类型、大小和 tmp_name 属性。

move_uploaded_file() 函数将所选文件复制到文档文件夹中。

<?php
   echo "<b>File to be uploaded: </b>" . $_FILES["uploadfile"]["name"] . "<br>";
   echo "<b>Type: </b>" . $_FILES["uploadfile"]["type"] . "<br>";
   echo "<b>File Size: </b>" . $_FILES["uploadfile"]["size"]/1024 . "<br>";
   echo "<b>Store in: </b>" . $_FILES["uploadfile"]["tmp_name"] . "<br>";

   if (file_exists($_FILES["uploadfile"]["name"])){
      echo "<h3>The file already exists</h3>";
   } else {
      move_uploaded_file($_FILES["uploadfile"]["tmp_name"], $_FILES["uploadfile"]["name"]);
      echo "<h3>File Successfully Uploaded</h3>";
   }
?>

假设 myform.php 和 uploadfile.php 这两个文件都存储在文档文件夹中。

在浏览器中打开 “myform.php” - ([role="bare"]http://localhost/myform.php)

php file uploading 1

单击 File 按钮,浏览到待上传的目标文件,并单击 Upload 按钮。

服务器返回以下消息 -

php file uploading 2

PHP - Cookies

万维网由 HTTP 协议驱动,该协议是一种无状态协议。Cookie 机制帮助服务器维护以前请求的信息。PHP 透明支持 HTTP cookie。

  1. 当客户端首次发送其请求时,服务器随其响应一起包含一个小数据段,作为 cookie。PHP 提供了 setcookie() 方法,用于在响应中注入 cookie。

  2. 此 cookie 数据以文本文件形式存储在客户端计算机中。在同一客户端的后续访问中,这些 cookie 将作为 request 标头的组成部分包含在内。

  3. 服务器使用客户端请求中存在的所有 cookie 来填充 PHP 超级全局变量 “$_COOKIE”。

本章将教您如何设置 cookie、如何访问 cookie 以及如何删除 cookie。

Cookie 通常设置在 HTTP 头中(尽管 JavaScript 也可以直接在浏览器上设置 cookie)。设置 cookie 的 PHP 脚本可能会发送类似以下内容的头:

HTTP/1.1 200 OK
Date: Fri, 04 Feb 2000 21:03:38 GMT
Server: Apache/1.3.9 (UNIX) PHP/4.0b3
Set-Cookie: name=xyz; expires=Friday, 04-Feb-07 22:03:38 GMT;
                 path=/; domain=tutorialspoint.com
Connection: close
Content-Type: text/html

如您所见,Set-Cookie 标头包含一个名称值对、一个 GMT 日期、一个路径和一个域名。名称和值将经过 URL 编码。expires 字段是指示浏览器在给定时间和日期后“忘记”Cookie 的指令。

如果浏览器配置为存储 cookie,它会将此信息保留至到期日期。如果用户将浏览器指向与 cookie 路径和域名匹配的任何页面,它将重新发送 cookie 至服务器浏览器头可能类似以下内容:

GET / HTTP/1.0
Connection: Keep-Alive
User-Agent: Mozilla/4.6 (X11; I; Linux 2.2.6-15apmac ppc)
Host: zink.demon.co.uk:1126
Accept: image/gif, */*
Accept-Encoding: gzip
Accept-Language: en
Accept-Charset: iso-8859-1,*,utf-8
Cookie: name=xyz

随后,PHP 脚本可以访问环境变量 $_COOKIE 或 $HTTP_COOKIE_VARS[]中的 cookie,其中包含所有 cookie 名称和值。可以使用 $HTTP_COOKIE_VARS["name"] 访问上述 cookie。

PHP 包含 setcookie 函数,用于创建要随 HTTP 响应一起发送给客户端的 cookie 对象。

setcookie(name, value, expire, path, domain, security);

Parameters

以下是所有参数的详细信息-

  1. Name -这将设置 cookie 的名称,并存储在名为 HTTP_COOKIE_VARS 的环境变量中。在访问 cookie 时使用此变量。

  2. Value -这将设置命名变量的值,并且是您实际上要存储的内容。

  3. Expiry − 此处指定了自 1970 年 1 月 1 日格林威治时间 00:00:00 起的秒数中的未来时间。在此时间之后,Cookie 将变得不可访问。如果未设置此参数,则会在关闭 Web 浏览器时自动使 Cookie 过期。

  4. Path − 此处指定了 Cookie 生效的目录。单个正斜杠字符允许 Cookie 对所有目录生效。

  5. Domain − 在非常大的域中,此可用于指定域名,并且必须包含至少两个句点才有效。所有 Cookie 仅对创建它们的 host 和域有效。

  6. Security − 此处可将其设置为 1,以指定只应通过使用 HTTPS 进行安全传输以发送 Cookie,否则将其设置为 0 表示可以通过常规 HTTP 发送 Cookie。

Example

下面给出的 PHP 脚本会检查 Cookie 名称为 username 已经设置,如果已被设置,则会取回其值。如果未设置,则会设置一个新的 Cookie username

<?php
   if (isset($_COOKIE['username'])) {
      echo "<h2>Cookie username already set:" . $_COOKIE['username'] . "</h2>";
   } else {
      setcookie("username", "MohanKumar");
      echo "<h2>Cookie username is now set</h2>";
   }
?>

从 Apache 服务器的文档根文件夹运行此脚本。您应会看到此消息 −

Cookie username is now set

如果重新执行此脚本,则现在已设置 Cookie。

Cookie username already set: MohanKumar

浏览器的开发者工具是非常有用的工具。您可通过该工具设置、取回、删除 Cookie。由上述程序设置的 Cookie 可在浏览器的开发者工具的“应用程序”选项卡下查看。

php cookies

如下面的 foreach 循环会取回所有 Cookie −

<?php
   $arr=$_COOKIE;
   foreach ($arr as $key=>$val);
   echo "<h2>$key=>$val </h2>";
?>

以下脚本包含一个 HTML 表单。它会将表单数据发送至 setcookie.php 脚本,该脚本会使用从 $_POST 数组取回的数据设置 Cookie。

以下代码会呈现 HTML 表单 −

<form action="setcookie.php" method="POST">
   <input type="text" name="name">
   <input type="text" name="age">
   <input type="submit" name="Submit">
</form>

SetCookie.php 会读取表单数据并设置 Cookie。

if (isset($_POST["submit"]) {
   setcookie("name", $_POST["name"]);
   setcookie("age", $_POST["age"]);
}

我们可通过另一个 getcookie.php 代码取回所设置的 Cookie。

if (isset($_COOKIE["name"])
echo "Cookie: name => " . $_COOKIE["name"]. "<br>";
if (isset($_COOKIE["age"])
echo "Cookie: age => " . $_COOKIE["age"]. "<br>";

Accessing Cookies with PHP

PHP 提供了许多访问 Cookie 的方法。最简单的方法是使用 $_COOKIE 或 $HTTP_COOKIE_VARS 变量。以下示例将访问上述示例中设置的所有 Cookie。

<?php
   echo $_COOKIE["name"]. "<br />";

   /* is equivalent to */
   echo $HTTP_COOKIE_VARS["name"]. "<br />";

   echo $_COOKIE["age"] . "<br />";

   /* is equivalent to */
   echo $HTTP_COOKIE_VARS["age"] . "<br />";
?>

您可以使用 isset() 函数检查 Cookie 是否已经设置。

<?php
   if( isset($_COOKIE["name"]))
      echo "Welcome " . $_COOKIE["name"] . "<br />";

   else
      echo "Sorry... Not recognized" . "<br />";
?>

Deleting the Cookies

要删除 Cookie,请使用在浏览器已经过期的日期设置 Cookie,以便浏览器触发 Cookie 删除机制。

Example

请看以下示例:

<?php
   setcookie("username", "", time() - 3600);
   echo "<h2>Cookie username is now removed</h2>";
?>

浏览器会显示以下响应 −

Cookie username is now removed

您还可以通过在 Cookie 名称中使用数组符号来设置数组 Cookie。

setcookie("user[three]", "Guest");
setcookie("user[two]", "user");
setcookie("user[one]", "admin");

如果 Cookie 名称包含句点 (.),则 PHP 会将它们替换为下划线 (_)。

虽然 Cookie 概念的主要目的是帮助 Web 开发者提供更为个性化、更为便捷的用户体验,但它可能会对您的隐私和个人信息构成风险。

在某些情况下,如果你不接受应用的 cookies,应用可能会拒绝你完全访问。在这种情况下,建议定期清理浏览器缓存中的 cookie 相关数据。

PHP - Sessions

Web 会话是从用户与服务器建立连接到连接终止之间的时间。与 cookies 一起,会话变量使数据可以在整个网站的各个页面中访问。

在会话期间,网站维护有关用户操作和偏好的信息。会话数据填充在超全局关联数组 $_SESSION 中。

要在 PHP 中启动一个新会话,你需要调用 session_start() 函数。

Starting a Session

为了启用对会话数据的访问,必须调用 session_start() 函数。 session_start() 基于通过 GET 或 POST 请求或通过 cookie 传递的会话标识符,创建一个会话或恢复当前会话。

session_start(array $options = []): bool

如果会话成功启动,此函数返回 true ;否则返回 false

PHP 首先为该特定会话创建一个唯一标识符,该标识符是由 32 个十六进制数字组成的随机字符串。

session_id() 函数设置或检索唯一会话 ID。

session_id(?string $id = null): string|false

如果未给定 $id 参数,PHP 将生成一个随机会话 ID。你也可以指定自己的 ID。该函数返回当前会话的会话 ID,如果没有当前会话,则返回空字符串。如果失败,它将返回 false

Example

请看以下示例:

<?php
   // Starting the session
   session_start();
   $id = session_id();
   echo "Session Id: ".$id ;
?>

浏览器会将一个随机字符串显示为 output

Session Id: mi3976f8ssethe9f04vq1ag6it

名为 PHPSESSID 的 cookie 会自动发送到用户的计算机,以存储唯一的会话标识符字符串。

php sessions 1

会话在服务器的临时目录中创建一个文件,其中存储已注册的会话变量及其值。此数据在该访问期间将对网站上的所有页面可用。

临时文件的位置由“php.ini”文件中的一个名为“session.save_path”的设置确定。

Handling Session Variables

会话变量存储在关联数组 $_SESSION[] 中。在会话的生命周期内可以访问这些变量。

要创建新的会话变量,在 $_SESSION 数组中添加一个键值对 −

$_SESSION[ "var"]=value;

要回读会话变量的值,可以使用 echo/print 语句、或 var_dump() 或 print_r() 函数。

echo $_SESSION[ "var"];

要获取当前会话中所有会话变量的列表,可以使用 foreach 循环遍历 $_SESSION −

foreach ($_SESSION as $key=>$val)
echo $key . "=>" . $val;

Example

以下示例启动一个会话,然后注册一个名为 counter 的变量,该变量在会话期间每次访问页面时都会递增。

使用 isset() function 检查会话变量是否已设置。

以下 PHP 脚本在首次运行时启动会话,并设置一个名为 counter 的会话变量。当客户端再次访问同一 URL 时,由于会话变量已设置,因此计数器会增加。

<?php
   session_start();
   if( isset( $_SESSION['counter'] ) ) {
      $_SESSION['counter'] += 1;
   } else {
      $_SESSION['counter'] = 1;
   }
   $msg = "Number of visits in this session: ".  $_SESSION['counter'];
?>
<?php
   echo "$msg";
?>

多次刷新浏览器以模拟重复访问。浏览器显示计数器 −

Number of visits in this session: 5

Destroying a PHP Session

PHP 会话可以被 session_destroy() 函数销毁。此函数不需要任何参数,并且一次调用可以销毁所有会话变量。如果您想销毁单个会话变量,则可以使用 unset() 函数取消设置会话变量。

以下是 unset a single variable 的示例 −

<?php
   unset($_SESSION['counter']);
?>

以下是将会 destroy all the session variables 的调用 −

<?php
   session_destroy();
?>

如果您可以在 php.ini 文件中将 session.auto_start 变量设置为 1,则当用户访问您的网站时,您不需要调用 start_session() 函数来启动会话。

Example

以下 PHP 脚本呈现一个 HTML 表单。表单数据用于创建三个会话变量。超链接将浏览器带到另一个页面,该页面读回会话变量。

<html>
<body>
   <form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
      <h3>User's ID: <input type="text" name="ID"/></h3>
      <h3>User's Name: <input type="text" name="name"/></h3>
      <h3>User Type: <input type="text" name="type"/></h3>
      <input type="submit" value="Submit" />
   </form>

   <?php
      session_start();
      if ($_SERVER["REQUEST_METHOD"] == "POST") {
         $_SESSION['ID'] = $_POST['ID'];
         $_SESSION['Name'] = $_POST['name'];
         $_SESSION['type'] = $_POST['type'];

         echo "<h2>Following Session variables Created</h2>";
         foreach ($_SESSION as $key=>$val) {
            echo "<h3>" . $key . "=>" . $val . "</h3>";
         }
         echo "<a href='test.php'><b>Click Here</b></a>";
      }
   ?>
</body>
</html>

将此代码作为“hello.php”保存在文档根目录文件夹中,并在客户端浏览器中打开它。

php sessions 2

Submit 按钮。浏览器将显示已创建的会话变量 −

php sessions 3

浏览器通过遵循所示的链接导航到另一个页面。它读回会话变量。

php sessions 4

PHP - Session Options

从 PHP 7 开始, session_start() 函数接受一个选项数组来覆盖在“php.ini”中设置的会话配置指令。在“php.ini”中的 [session] 会话定义了各种选项的默认值。

如果提供了选项,它们将采用将覆盖当前设置的会话配置指令的关联选项数组的形式。键不应包含“session.”前缀。

Example

例如,您可以使用 session_start() 函数的参数定义的两个会话选项来启动 HTTP 会话 −

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

Configurable Options of an HTTP Session

PHP 中 HTTP 会话的一些可配置选项如下 −

session.name

它指定用作 cookie 名称的会话名称。它应只包含字母数字字符。默认为 PHPSESSID。

session.save_handler

它定义用于存储和检索与会话关联的数据的处理程序的名称。默认为文件。

session.auto_start

它指定会话模块是否在请求启动时自动启动会话。默认为 0(已禁用)。

它指定发送到浏览器的 cookie 的生命周期(以秒为单位)。值 0 表示“直到浏览器关闭”。默认为 0。

session.cache_limiter

它指定会话页面使用的缓存控制方法。它可以是以下值之一:nocache、private、private_no_expire 或 public。默认为 nocache。

session.sid_length

它允许您指定会话 ID 字符串的长度。会话 ID 长度可在 22 到 256 之间。默认值为 32。

session.upload_progress.enabled

它启用上传进度跟踪,填充 $_SESSION 变量。默认值为 1,已启用。

session.lazy_write

将此值设为 1 时,这意味着仅当会话数据发生更改时才将其重写。默认值为 1,已启用。

PHP - Sending Emails

发送电子邮件是 PHP 提供支持的典型 Web 应用程序的常见需求功能之一。你会希望通过 PHP 应用程序本身(而非不同的邮件服务)向你的注册用户发送包含通知、更新和其他通信的电子邮件。你可以通过采用本章中描述的技术向你的 PHP 应用程序添加此功能。

PHP 内置有一个 mail() 函数,可用于发送电子邮件。但是,你需要正确配置“php.ini”设置,才能使用它。首先,你必须知道你正在使用的网络托管平台的 SMTP 域名。例如,如果你的网站托管在 GoDaddy 托管服务上,则 SMTP 域名是“smtp.secureserver.net”,你应该在配置中使用它。

如果你使用 GoDaddy 的基于 Windows 的托管,你应该确保在 php.ini 文件中启用了两个指令。第一个指令称为 SMTP,它定义你的电子邮件服务器地址。第二个指令称为 sendmail_from,它定义你的自己电子邮件地址。

用于 Windows 的配置看起来应该像这样:

[mail function]
; For Win32 only.
SMTP = smtp.secureserver.net

; For win32 only
sendmail_from = webmaster@tutorialspoint.com

Linux 用户只需让 PHP 知道其 sendmail 应用程序的位置即可。应将路径和任何所需的 switch 指定给 sendmail_path 指令。

用于 Linux 的配置看起来应该像这样:

[mail function]
; For Win32 only.
SMTP =

; For win32 only
sendmail_from =

; For Unix only
sendmail_path = /usr/sbin/sendmail -t -i

PHP 中的 mail() 函数需要三个强制性参数,这些参数指定收件人的电子邮件地址、邮件主题和实际邮件,此外还有另外两个可选参数。

mail( to, subject, message, headers, parameters );

Parameters

  1. to − 必需。指定电子邮件的接收者/收件人

  2. subject − 必需。指定电子邮件的主题。此参数不能包含任何换行符

  3. message − 必需。定义要发送的邮件。每一行都应该用 LF (\n) 分隔。行数不得超过 70 个字符

  4. headers − 可选。指定其他标头,例如发件人、抄送和密件抄送。应该用 CRLF (\r\n) 分隔其他标头

  5. parameters − 可选。指定发送邮件程序的其他参数

多个收件人可指定为 mail() 函数的第一个参数,用逗号分隔。

Sending HTML Email

当你使用 PHP 发送文本消息时,所有内容都将被视为纯文本。即使你将 HTML 标记包含在文本消息中,它也将显示为纯文本,并且 HTML 标记不会根据 HTML 语法进行格式化。但 PHP 提供了将 HTML 邮件作为实际 HTML 邮件发送的选项。

发送邮件时,你可以指定一个 Mime 版本、内容类型和字符集来发送 HTML 邮件。

Example

以下示例显示了如何将 HTML 邮件发送至“ xyz@somedomain.com ”,并抄送给“ afgh@somedomain.com ”。你可以以这样的方式编写此程序,使其接收来自用户的全部内容,然后发送电子邮件。

它应当接收来自用户的全部内容,然后发送一封电子邮件。

<?php
   $to = "xyz@somedomain.com";
   $subject = "This is subject";

   $message = "<b>This is HTML message.</b>";
   $message .= "<h1>This is headline.</h1>";

   $header = "From:abc@somedomain.com \r\n";
   $header .= "Cc:afgh@somedomain.com \r\n";
   $header .= "MIME-Version: 1.0\r\n";
   $header .= "Content-type: text/html\r\n";

   $retval = mail ($to,$subject,$message,$header);

   if( $retval == true ) {
      echo "Message sent successfully...";
   }else {
      echo "Message could not be sent...";
   }
?>

它将生成以下 output

Message could not be sent...
sh: 1: /usr/sbin/sendmail: not found

Sending Email from Localhost

上面的 PHP mail() 调用方法可能无法在你的 localhost 上运行。在这种情况中,有一种替代方案可用于发送电子邮件。你可以使用 PHPMailer 从 localhost 使用 SMTP 发送电子邮件。

PHPMailer 是一个开源库,用于连接 SMTP 来发送电子邮件。你可以从 PEAR 或 Composer 存储库下载它,或从 https://github.com/PHPMailer/PHPMailer 下载它。从这里下载 ZIP 文件,并将 PHPMailer 文件夹的内容复制到 PHP 配置中指定的某个 include_path 目录中,并手动加载每个类文件。

Example

使用以下 PHP 脚本通过 PHPMailer 库发送电子邮件:

<?php
   use PHPMailer\PHPMailer\PHPMailer;
   use PHPMailer\PHPMailer\SMTP;
   use PHPMailer\PHPMailer\Exception;

   require_once __DIR__ . '/vendor/phpmailer/src/Exception.php';
   require_once __DIR__ . '/vendor/phpmailer/src/PHPMailer.php';
   require_once __DIR__ . '/vendor/phpmailer/src/SMTP.php';
   require 'vendor/autoload.php';

   $mail = new PHPMailer;
   if(isset($_POST['send'])){

      // getting post values
      $fname=$_POST['fname'];
      $toemail=$_POST['toemail'];
      $subject=$_POST['subject'];
      $message=$_POST['message'];
      $mail->isSMTP();					      // Set mailer to use SMTP
      $mail->Host = 'smtp.gmail.com';
      $mail->SMTPAuth = true;
      $mail->Username = 'myID@gmail.com';	// SMTP username
      $mail->Password = 'mypassword'; 		// SMTP password

      // Enable TLS encryption, 'ssl' also accepted
      $mail->SMTPSecure = 'tls';
      $mail->Port = 587;
      $mail->setFrom(myID@gmail.com', 'My_Name');
      $mail->addReplyTo(myID@gmail.com', 'My_Name');
      $mail->addAddress($toemail);   	  // Add a recipient
      $mail->isHTML(true);                // Set email format to HTML
      $bodyContent=$message;
      $mail->Subject =$subject;
      $body = 'Dear'.$fname;
      $body .='<p>'.$message.'</p>';
      $mail->Body = $body;

      if(!$mail->send()) {
         echo 'Message could not be sent.';
         echo 'Mailer Error: ' . $mail->ErrorInfo;
      } else {
         echo 'Message has been sent';
      }
   }
?>

使用以下 HTML 表单编写邮件消息。表单提交给上述 phpmail.php 脚本

<h1>PHP - Sending Email</h1>
<form action="PHPmailer.php" method="post">
   <label for="inputName">Name</label>
   <input type="text" id="inputName" name="fname" required>

   <label for="inputEmail">Email</label>
   <input type="email" id="inputEmail" name="toemail" required>

   <label for="inputSubject">Subject</label>
   <input type="text" id="inputSubject" name="subject" required>

   <label for="inputMessage">Message</label>
   <textarea id="inputMessage" name="message" rows="5" required></textarea>

   <button type="submit" name="send">Send</button>
</form>

Sending Attachments with Email

要发送具有混合内容的电子邮件,您应将 Content-type 头设为 multipart/mixed。然后,可以在边界中指定文本和附件部分。

一个边界以两个连字符开始,后跟一个唯一数字,该数字不能出现在电子邮件的消息部分中。PHP 函数 md5() 用于创建一个 32 位十六进制数以创建唯一数字。表示电子邮件最终部分的最终边界也必须以两个连字符结束。

Example

请看以下示例:

<?php

   // request variables
   $from = $_REQUEST["from"];
   $emaila = $_REQUEST["emaila"];
   $filea = $_REQUEST["filea"];

   if ($filea) {
      function mail_attachment ($from , $to, $subject, $message, $attachment){
         $fileatt = $attachment; 		// Path to the file
         $fileatt_type = "application/octet-stream"; // File Type

         $start = strrpos($attachment, '/') == -1 ?
         strrpos($attachment, '//') : strrpos($attachment, '/')+1;

         // Filename that will be used for the file as the attachment
         $fileatt_name = substr($attachment, $start,
         strlen($attachment));

         $email_from = $from; 		// Who the email is from
         $subject = "New Attachment Message";

         $email_subject =  $subject; // The Subject of the email
         $email_txt = $message;     // Message that the email has in it
         $email_to = $to; 	 	   // Who the email is to

         $headers = "From: ".$email_from;
         $file = fopen($fileatt,'rb');
         $data = fread($file,filesize($fileatt));
         fclose($file);

         $msg_txt="\n\n You have recieved a new attachment message from $from";
         $semi_rand = md5(time());
         $mime_boundary = "==Multipart_Boundary_x{$semi_rand}x";
         $headers .= "\nMIME-Version: 1.0\n" . "Content-Type: multipart/mixed;\n" . "
         boundary=\"{$mime_boundary}\"";

         $email_txt .= $msg_txt;

         $email_message .= "This is a multi-part message in MIME format.\n\n" .
         "--{$mime_boundary}\n" . "Content-Type:text/html;
         charset = \"iso-8859-1\"\n" . "Content-Transfer-Encoding: 7bit\n\n" .
         $email_txt . "\n\n";

         $data = chunk_split(base64_encode($data));

         $email_message .= "--{$mime_boundary}\n" . "Content-Type: {$fileatt_type};\n" .
         " name = \"{$fileatt_name}\"\n" . //"Content-Disposition: attachment;\n" .
         //" filename = \"{$fileatt_name}\"\n" . "Content-Transfer-Encoding:
         "base64\n\n" . $data . "\n\n" . "--{$mime_boundary}--\n";

         $ok = mail($email_to, $email_subject, $email_message, $headers);

         if($ok) {
            echo "File Sent Successfully.";
            // delete a file after attachment sent.
            unlink($attachment);
         } else {
            die("Sorry but the email could not be sent. Please go back and try again!");
         }
      }
      move_uploaded_file($_FILES["filea"]["tmp_name"],
      'temp/'.basename($_FILES['filea']['name']));

      mail_attachment("$from", "youremailaddress@gmail.com",
      "subject", "message", ("temp/".$_FILES["filea"]["name"]));
   }
?>
<html>
<head>
   <script language = "javascript" type = "text/javascript">
      function CheckData45() {
         with(document.filepost) {
            if(filea.value ! = "") {
               document.getElementById('one').innerText = "Attaching File ... Please Wait";
            }
         }
      }
   </script>
</head>
<body>
   <table width = "100%" height = "100%" border = "0"
      cellpadding = "0" cellspacing = "0">
      <tr>
         <td align = "center">
            <form name = "filepost" method = "post"
               action = "file.php" enctype = "multipart/form-data" id = "file">
               <table width = "300" border = "0" cellspacing = "0"
                  cellpadding = "0">
                  <tr valign = "bottom">
                     <td height = "20">Your Name:</td>
                  </tr>
                  <tr>
                     <td><input name = "from" type = "text" id = "from" size = "30"></td>
                  </tr>
                  <tr valign = "bottom">
                     <td height = "20">Your Email Address:</td>
                  </tr>
                  <tr>
                     <td class = "frmtxt2"><input name = "emaila" type = "text" id = "emaila" size = "30"></td>
                  </tr>
                  <tr>
                     <td height = "20" valign = "bottom">Attach File:</td>
                  </tr>
                  <tr valign = "bottom">
                     <td valign = "bottom"><input name = "filea" type = "file" id = "filea" size = "16"></td>
                  </tr>
                  <tr>
                     <td height = "40" valign = "middle">
                        <input name = "Reset2" type = "reset" id = "Reset2" value = "Reset">
                        <input name = "Submit2" type = "submit" value = "Submit" onClick = "return CheckData45()">
                     </td>
                  </tr>
               </table>
            </form>
            <center>
               <table width = "400">
                  <tr>
                     <td id = "one"></td>
                  </tr>
               </table>
            </center>
         </td>
      </tr>
   </table>
</body>
</html>

它将生成以下 output

php sending emails

PHP - Sanitize Input

在 PHP 中,重要的是要确保在服务器端代码处理输入数据之前,通过删除任何不需要的字符来正确清理输入数据。通常,用户通过 HTML 表单向 PHP Web 应用程序输入其数据。如果表单数据包含任何不需要的字符,可能会造成损害,因此必须执行适当的清理操作。

输入清理可以使用 PHP 中以下一个或多个函数的帮助进行。

The htmlspecialchars() Function

此函数将特殊字符转换为 HTML 实体。

htmlspecialchars(
   string $string,
   int $flags = ENT_QUOTES | ENT_SUBSTITUTE | ENT_HTML401,
   ?string $encoding = null,
   bool $double_encode = true
): string

在 HTML 中,某些字符有着特殊的意义。这个 htmlspecialchars() 函数用于对 HTML 实体中的特殊字符进行编码。当您希望将用户输入显示为 HTML 时,这将非常有用,而且希望防止脚本注入攻击。

以下 special characters 按下述所示方式翻译 −

Character

Replaced by

& (ampersand)

&

" (double quote)

", unless ENT_NOQUOTES is set

' (single quote)

' (for ENT_HTML401 ) or ' (for ENT_XML1, ENT_XHTML or ENT_HTML5 ), but only when ENT_QUOTES is set

< (less than)

<

> (greater than)

>

Flag Constants

flags 参数是一个或多个以下标志的位掩码,它们指定如何处理引号、无效的代码单元序列和使用的文档类型。

Sr.No

Constant & Description

1

ENT_COMPAT 将转换双引号,而忽略单引号。

2

ENT_QUOTES 将转换双引号和单引号。

3

ENT_NOQUOTES 将保留双引号和单引号不变。

4

ENT_IGNORE 舍弃无效的代码单元序列,而不是返回一个空字符串。

5

ENT_SUBSTITUTE 用 Unicode Replacement Character U+FFFD (UTF-8) 或 � 替换无效的代码单元序列

6

ENT_DISALLOWED 用 Unicode Replacement Character U+FFFD (UTF-8) 或 �(否则)替换给定文档类型的无效代码点,而不是保持原样。这可能会很有用。

7

ENT_HTML401 将代码作为 HTML 4.01 处理。

8

ENT_XML1 将代码作为 XML 1 处理。

9

ENT_XHTML Handle code as XHTML.

10

ENT_HTML5 将代码作为 HTML 5 处理。

Example

请看以下示例:

<?php
   $str = 'Welcome To "PHP Tutorial" by <b>TutorialsPoint</b>';
   echo htmlspecialchars($str);
?>

它将生成以下 output

Welcome To "PHP Tutorial" by <b>TutorialsPoint</b>

The strip_tags() Function

strip_tags() 函数从给定的字符串中删除所有 HTML 和 PHP 标记。

strip_tags(string $string, array|string|null $allowed_tags = null): string

当您希望确保用户输入不包含任何潜在的恶意标记时,这个函数非常有用。

allowed_tags 参数是一个可选的第二个参数,用于指定不应删除的标记。这些标记可以以字符串的形式给出,也可以作为数组给出。

Example

请看以下示例:

<?php
   $text = '<p>Hello World</p><!-- Comment -->
      <a href="/test.html">Click Here</a>';
   echo strip_tags($text);
   echo "\n";

   // Allow <p> and <a>
   echo strip_tags($text, '<p><a>');
?>

它将生成以下 output

Hello World
      Click Here
Hello World


      Click Here

The addslashes() Function

addslashes() 函数向字符串添加反斜杠。

addslashes(string $string): string

此函数返回一个字符串,在需要转义的字符前面添加反斜杠。这些字符为 −

  1. Single Quote (')

  2. Double Quote (")

  3. Backslash (\)

  4. NUL (The NUL Byte)

在向数据库中存储用户输入且希望防止 SQL 注入攻击时,请使用此函数。

Example

请看以下示例:

<?php
   $text = "Newton's Laws";
   $str = addslashes($text);

   // prints the escaped string
   echo($str);
?>

它将生成以下 output

Newton\'s Laws

The filter_var() Function

借助特定的过滤器标记,可以使用 filter_var() 函数来净化用户输入。

filter_var(mixed $value, int $filter =
   FILTER_DEFAULT, array|int $options = 0): mixed

$value 参数是要净化其值的一个变量。$filter 参数是任何预定义的过滤器常量。

Sr.No

ID & Description

1

FILTER_SANITIZE_EMAIL 移除除字母数字和 !#$%&'*+-=?^_`{ 之外的所有字符。

}~@.[].

2

FILTER_SANITIZE_ENCODED URL 编码字符串,可以选择清除或编码特殊字符。

3

FILTER_SANITIZE_ADD_SLASHES 应用 addslashes()。(在 PHP 7.3.0 及以上版本中可用)。

4

FILTER_SANITIZE_NUMBER_FLOAT 移除除数字、+- 和选择性地移除 .,eE 之外的所有字符。

5

FILTER_SANITIZE_NUMBER_INT 移除除数字、加号和减号之外的所有字符。

6

FILTER_SANITIZE_SPECIAL_CHARS HTML 编码 '"<>& 字符和 ASCII 值小于 32 的字符,可以选择清除或编码其他特殊字符。

7

FILTER_SANITIZE_FULL_SPECIAL_CHARS 等同于用已设置的 ENT_QUOTES 调用 htmlspecialchars()。通过设置 FILTER_FLAG_NO_ ENCODE_QUOTES 可以禁用编码引号。

8

FILTER_SANITIZE_URL 移除除字母数字和 $-_.+!*'(),{} 之外的所有字符。

\\^~[]`<>#%";/?:@&=.

9

FILTER_UNSAFE_RAW

Example

下列代码展示了净化电子邮件数据的方式 -

<?php
   $a = 'abc def@xyz.com';

   $sa = filter_var($a, FILTER_SANITIZE_EMAIL);
   echo "$sa";
?>

它将生成以下 output

abcdef@xyz.com

Example

下列代码展示了净化 URL 的方式 -

<?php
   $a = "http://example.c o m";

   $sa = filter_var($a, FILTER_SANITIZE_URL);
   echo "$sa";
?>

它将生成以下 output

http://example.com

PHP - Post-Redirect-Get (PRG)

在 PHP 中,PRG 代表“Post/Redirect/Get”。这是一种常用的技术,设计用于防止提交表单之后再次提交该表单。您可以在 PHP 中轻松实施此技术以避免重复提交表单。

通常,HTML 表单使用 POST 方法向服务器发送数据。服务器脚本获取数据以进行进一步处理,如在后端数据库中添加新记录或运行查询以获取数据。如果用户意外地刷新浏览器,则有可能再次重新提交相同的表单数据,可能导致数据完整性丢失。PHP 中的 PRG 方法帮助您避免这种陷阱。

Example

首先,我们考虑以下 PHP 脚本,它渲染一个简单的 HTML 表单,并使用 POST 方法将其提交回自身。当用户填写数据并提交时,后端脚本会获取数据,渲染结果,然后返回以再次显示空白表单。

<?php
   if (isset($_POST["submit"])) {
      if ($_SERVER["REQUEST_METHOD"] == "POST")
         echo "First name: " . $_REQUEST['first_name'] . " " . "Last Name: " . $_REQUEST['last_name'] . "";
   }
?>

<html>
<body>
   <form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
      First Name: <input type="text" name="first_name">  <br/>
      Last Name: <input type="text" name="last_name" />
      <button type="submit" name="submit">Submit</button>
   </form>
</body>
</html>

假设服务器正在运行,则将上述脚本放置在文档根文件夹中并在浏览器中访问。

填写数据并提交。浏览器会回显结果,然后重新渲染表单。现在,如果您尝试刷新浏览器页面,将会弹出一个警告,如下所示 −

php prg 1

如果您按 Continue ,则会再次发布相同数据。

可以使用以下图形理解问题 −

php prg 2

在 PHP 脚本中执行以下步骤以避免问题 −

  1. HTML 表单之前的 PHP 脚本启动一个新会话。

  2. 检查表单是否已用 POST 方法提交。

  3. 如果是,请将表单数据存储到会话变量中

  4. 将浏览器重定向到结果页面。在我们的示例中,即为同一页面。使用 exit 命令停止此脚本,确保不会再执行更多代码。

  5. 如果 PHP 发现请求方法不是 POST,则会检查会话变量是否已设置。如果是,则会与刚复制的表单一同呈现。

  6. 现在,即使刷新了表单,您也已成功避免了重新提交的可能性。

Example

下面是使用 PRG 技术的 PHP 代码−

<?php
   session_start();
   if (isset($_POST["submit"])) {
      $_SESSION['fname'] = $_POST['first_name'];
      $_SESSION['lname'] = $_POST['last_name'];
      header("Location: hello.php");
      exit;
   }
   if (isset($_SESSION["fname"])) {
      echo "First name: " . $_SESSION['fname'] . " " . "Last Name: " . $_SESSION['lname'] . "";
      unset($_SESSION["fname"]); unset($_SESSION["lname"]);
   }
?>

<html>
<body>
   <form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
      First Name: <input type="text" name="first_name">  <br />
      Last Name: <input type="text" name="last_name" />
      <button type="submit" name="submit">Submit</button>
   </form>
</body>
</html>

PHP - Flash Messages

在 PHP Web 应用程序中, Message flashing 指的是使某些消息在浏览器窗口中弹出,以便用户接收应用程序反馈的技术。能够向用户提供与其交互的有意义的反馈是一项重要的设计原则,可以提供更好的用户体验。

在 PHP Web 应用程序中,我们可以使用会话数据不定期地针对特定操作、通知或警告等内容发出成功或失败的闪存消息,以便向用户随时通报相关信息。

flash message 使您能在一页上创建消息,然后在另一页上显示一次此消息。如要从一页向另一页传输消息,请使用 $_SESSION 超全局变量。

首先,请按如下方式向 $_SESSION 数组添加一个变量 -

<?php
   session_start();
   $_SESSION['flash_message'] = "Hello World";
?>

稍后,导航到另一页,然后从 $_SESSION 变量中检索闪存消息并将其分配给一个变量。随后,您可以显示消息,然后从 $_SESSION 中删除该消息 -

<?php
   session_start();
   if(isset($_SESSION['flash_message'])) {
      $message = $_SESSION['flash_message'];
      unset($_SESSION['flash_message']);
      echo $message;
   }
?>

为了概括处理闪存消息的基本思路,我们将编写一个将消息添加到 $_SESSION 中的函数 -

session_start();
function create_flash_message(string $name, string $message): void {

   // remove existing message with the name
   if (isset($_SESSION[FLASH][$name])) {
      unset($_SESSION[FLASH][$name]);
   }
   // add the message to the session
   $_SESSION[FLASH][$name] = ['message' => $message];
}

让我们也编写另一个函数,该函数回读一条消息、在浏览器上闪烁并从 $_SESSION 中移除此消息。

function display_flash_message(string $name): void {
   if (!isset($_SESSION[FLASH][$name])) {
      return;
   }

   // get message from the session
   $flash_message = $_SESSION[FLASH][$name];

   // delete the flash message
   unset($_SESSION[FLASH][$name]);

   // display the flash message
   echo format_flash_message($flash_message);
}

format_flash_message() 函数通过适当的 CSS 规则对获得的字符串应用所需的格式设置。

如果应用程序闪现了多条消息,则可以使用以下示例检索并闪现所有这些消息 -

function display_all_flash_messages(): void {
   if (!isset($_SESSION[FLASH])) {
      return;
   }

   // get flash messages
   $flash_messages = $_SESSION[FLASH];

   // remove all the flash messages
   unset($_SESSION[FLASH]);

   // show all flash messages
   foreach ($flash_messages as $flash_message) {
      echo format_flash_message($flash_message);
   }
}

使用以下 flash() function 创建、设置格式并闪现消息

function flash(string $name = '', string $message = ''): void {
   if ($name !== '' && $message !== '') {
      create_flash_message($name, $message);
   }
   elseif ($name !== '' && $message === '') {
      display_flash_message($name);		// display a flash message
   } elseif ($name === '' && $message === '' ) {
      display_all_flash_messages(); 	// display all flash message
   }
}

如要实现上述方法,请在第一页上调用 flash() function

flash('first', 'Hello World');

导航到另一页并调用 flash() 函数来检索并显示消息 -

flash('first');

闪存消息的使用机制通常用于注册页面,以便在用户注册后将他们重定向到登录页面并显示一条欢迎消息。

PHP - AJAX Introduction

由 PHP 提供支持的 Web 应用程序通常使用 AJAX,两者联合起来可用来创建动态且交互式的 Web 应用程序。AJAX 代表 Asynchronous Javascript and XML 。它允许网页异步更新,而无需重新加载整个页面。

在 AJAX 应用程序中,Web 浏览器与服务器端 PHP 脚本之间的数据交换是异步的。PHP 是一种服务器端脚本语言,可用于生成动态内容并处理数据。

由于我们可以使用 JavaScript 执行后台服务器调用并检索所需数据,并且可以在不强制页面完全重新加载的情况下更新网页的请求部分,所以 AJAX 在 Web 应用程序与 Web 服务器之间创建了一层附加层(称为 AJAX 引擎)。它缩短了页面刷新时间,并且为用户提供了迅速而灵敏的体验。

php ajax introduction

What is Required to Run AJAX?

AJAX 使用的技术已经在所有现代浏览器中实现。因此,客户端不需要任何额外的模块来运行 AJAX 应用程序。AJAX 使用的技术有 −

  1. {s0} − 它是 AJAX 的重要部分。它允许你创建客户端功能。或者我们可以说它用于创建 AJAX 应用程序。

  2. {s1} − 它用于在 Web 服务器和客户端之间交换数据。

  3. {s2} − 它用于在 Web 浏览器和 Web 服务器之间执行异步数据交换。

  4. {s3} − 它用于向网页文本提供标记和样式。

  5. {s4} − 它用于动态地与网页布局和内容进行交互并更改它们。

在 PHP 中使用 AJAX,将需要使用 JavaScript 中的 XMLHttpRequest 对象向 PHP 服务器发送请求。然后 PHP 服务器将处理请求并返回响应,通常以 JSON 或 XML 的形式。随后 JavaScript 代码能够分析响应并相应地更新网页。

JavaScript 中的 XMLHttpRequest 对象是基于浏览器的 API,允许开发者向服务器发出 HTTP 请求而无需刷新该页面。这是 AJAX 编程的基础,这允许动态且互动的 Web 应用。

XMLHttpRequest 对象可以用来 −

  1. 从服务器中检索数据,如 JSON、XML 或 HTML。

  2. 向服务器发送数据,如表单数据或文件上传。

  3. 无需重新加载即可更新网页。

  4. 创建聊天应用程序和其他交互式功能。

要使用 XMLHttpRequest 对象,首先需要创建一个新实例。然后,可以使用 open() 方法指定 HTTP 方法和请求 URL。下一步,可以设置任何请求头(如果需要的话)。最后,可以使用 send() 方法发送请求。

Example

以下是如何使用 XMLHttpRequest 对象从服务器检索数据的简单 JavaScript 代码 −

// Create a new XMLHttpRequest object
var xhr = new XMLHttpRequest();

// Set the HTTP method and request URL
xhr.open("GET", "test.php");

// Send the request
xhr.send();

// Listen for the onload event to be fired
xhr.onload = function() {

   // Check the status code to ensure the request was successful
   if (xhr.status === 200) {

      // Get the response data.
      var users = JSON.parse(xhr.responseText);

      // Do something with the user data.
   } else {
      // Handle the error
   }
};

服务器上的 PHP 脚本从 AJAX 请求中检索数据并发送回响应。

// Get the request data.
$name = $_GET["name"];

// Create a response object.
$response = new stdClass();
$response->message = "Hello, $name!";

// Send the response back to the client.
header("Content-Type: application/json");
echo json_encode($response);

AJAX 是术语异步 JavaScript 和 XML 的缩写。Ajax 用于构建快速而动态的网页。下面的示例演示了如何使用 AJAX 函数与后端 PHP 脚本交互,以便在网页上提供一个搜索字段。

Step 1

将以下脚本另存为“example.php”−

<html>
<head>
   <style>
      span {
         color: green;
      }
   </style>
   <script>
      function showHint(str) {
         if (str.length == 0) {
            document.getElementById("txtHint").innerHTML = "";
            return;
         } else {
            var xmlhttp = new XMLHttpRequest();
            xmlhttp.onreadystatechange = function() {
               if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
                  document.getElementById("txtHint").innerHTML = xmlhttp.responseText;
               }
            }
            xmlhttp.open("GET", "hello.php?q=" + str, true);
            xmlhttp.send();
         }
      }
   </script>
</head>
<body>
   <p><b>Search your favourite tutorials:</b></p>
   <form>
      <input type = "text" onkeyup = "showHint(this.value)">
   </form>
   <p>Entered Course name: <span id="txtHint"></span></p>
</body>
</html>

此代码本质上是一个 HTML 脚本,该脚本呈现一个带有文本字段的 HTML 表单。在其 onkeyup 事件中,调用 showHint() JavaScript 函数。函数向服务器上的另一个 PHP 脚本发送 HTTP GET 请求。

Step 2

把以下脚本另存为“php_ajax.php”−

<?php
   // Array with names
   $a[] = "Android";
   $a[] = "B programming language";
   $a[] = "C programming language";
   $a[] = "D programming language";
   $a[] = "euphoria";
   $a[] = "F#";
   $a[] = "GWT";
   $a[] = "HTML5";
   $a[] = "ibatis";
   $a[] = "Java";
   $a[] = "K programming language";
   $a[] = "Lisp";
   $a[] = "Microsoft technologies";
   $a[] = "Networking";
   $a[] = "Open Source";
   $a[] = "Prototype";
   $a[] = "QC";
   $a[] = "Restful web services";
   $a[] = "Scrum";
   $a[] = "Testing";
   $a[] = "UML";
   $a[] = "VB Script";
   $a[] = "Web Technologies";
   $a[] = "Xerox Technology";
   $a[] = "YQL";
   $a[] = "ZOPL";

   $q = $_REQUEST["q"];
   $hint = "";

   if ($q !== "") {
      $q = strtolower($q);
      $len = strlen($q);

      foreach($a as $name) {
         if (stristr($q, substr($name, 0, $len))) {
            if ($hint === "") {
               $hint = $name;
            } else {
               $hint .= ", $name";
            }
         }
      }
   }
   echo $hint === "" ? "Please enter a valid course name" : $hint;
?>

Step 3

我们将通过输入网址 http://localhost/example.php 在浏览器中打开 example.php 来启动此应用程序

在搜索字段中每次击键时,一个 GET 请求都会发送到服务器。服务器脚本从 $_REQUEST 数组中读取字符并搜索与其匹配的课程名称。匹配的值显示在文本字段下方的浏览器中。

php ajax search

PHP - AJAX XML Parser

使用 PHP 和 AJAX,我们可以解析本地目录和服务器上的 XML 文档。以下示例演示了如何用网络浏览器解析 XML。

客户端脚本呈现了一个 HTML 表单,并定义了一个 JavaScript 函数,用于通过 XMLHttpRequest 对象向服务器发送 HTTP 请求。

在服务器上,一个 PHP 脚本从所需的 XML 文档加载 DOM 对象,从 $_REQUEST 变量中获取所选课程,并将已选课程的详细信息呈现为对客户端的响应。

Step 1

以下 XML 文档存储在 XAMPP 服务器的文档根目录中。

<?xml version = "1.0" encoding = "utf-8"?>
<CATALOG>

   <SUBJECT>
      <COURSE>Android</COURSE>
      <COUNTRY>India</COUNTRY>
      <COMPANY>TutorialsPoint</COMPANY>
      <PRICE>$10</PRICE>
      <YEAR>2015</YEAR>
   </SUBJECT>

   <SUBJECT>
      <COURSE>Html</COURSE>
      <COUNTRY>India</COUNTRY>
      <COMPANY>TutorialsPoint</COMPANY>
      <PRICE>$15</PRICE>
      <YEAR>2015</YEAR>
   </SUBJECT>

   <SUBJECT>
      <COURSE>Java</COURSE>
      <COUNTRY>India</COUNTRY>
      <COMPANY>TutorialsPoint</COMPANY>
      <PRICE>$20</PRICE>
      <YEAR>2015</YEAR>
   </SUBJECT>

   <SUBJECT>
      <COURSE>Microsoft</COURSE>
      <COUNTRY>India</COUNTRY>
      <COMPANY>TutorialsPoint</COMPANY>
      <PRICE>$25</PRICE>
      <YEAR>2015</YEAR>
   </SUBJECT>

</CATALOG>

Step 2

下面的 AJAX 代码有一个 HTML 表单和一个 JavaScript 函数,通过 XMLHttpRequest 对象提出 HTTP 请求。

<html>
<head>
   <script>
      function showCD(str) {
         if (str == "") {
            document.getElementById("txtHint").innerHTML = "";
            return;
         }

         if (window.XMLHttpRequest) {

            // code for IE7+, Firefox, Chrome, Opera, Safari
            xmlhttp = new XMLHttpRequest();
         } else {

            // code for IE6, IE5
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
         }

         xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
               document.getElementById("txtHint").innerHTML = xmlhttp.responseText;
            }
         }
         xmlhttp.open("GET","hello.php?q="+str,true);
         xmlhttp.send();
      }
   </script>
</head>
<body>
   <form>
      Select a Course:
      <select name = "cds" onchange = "showCD(this.value)">
         <option value = "">Select a course:</option>
         <option value = "Android">Android </option>
         <option value = "Html">HTML</option>
         <option value = "Java">Java</option>
         <option value = "Microsoft">MS technologies</option>
      </select>
   </form>
   <div id = "txtHint"><b>Course info will be listed here...</b></div>
</body>
</html>

Step 3

搜索 XML 文档的服务器端 PHP 脚本如下 −

<?php
   $q = $_GET["q"];

   $xmlDoc = new DOMDocument();
   $xmlDoc->load("test.xml");

   $x = $xmlDoc->getElementsByTagName('COURSE');

   for ($i = 0; $i<=$x->length-1; $i++) {
      if ($x->item($i)->nodeType == 1) {
         if ($x->item($i)->childNodes->item(0)->nodeValue == $q) {
            $y = ($x->item($i)->parentNode);
         }
      }
   }

   $cd = ($y->childNodes);

   for ($i = 0;$i<$cd->length;$i++) {
      if ($cd->item($i)->nodeType == 1) {
         echo("<b>" . $cd->item($i)->nodeName . ":</b> ");
         echo($cd->item($i)->childNodes->item(0)->nodeValue);
         echo("<br>");
      }
   }
?>

访问“http://localhost/example.php”来让用户选择课程。在选择后,相关详细信息从服务器中获取并显示如下 −

php ajax xml parser

自动完成功能是一种预测机制,当用户在提供的搜索框中输入数据时显示输入建议。它也被称为实时搜索,因为它对用户的输入作出反应。在本例中,我们将使用 PHP 中的 AJAX 和 XML 解析器来演示自动完成文本框的使用。

此应用程序有三个主要部分 −

  1. The XML Document

  2. JavaScript Code

  3. XML Parser in PHP

现在让我们详细讨论这三个部分 −

The XML Document

将以下 XML 脚本另存为文档根目录中的“ autocomplete.xml

<?xml version = "1.0" encoding = "utf-8"?>
<pages>

   <link>
      <title>android</title>
      <url>https://www.tutorialspoint.com/android/index.htm</url>
   </link>

   <link>
      <title>Java</title>
      <url>https://www.tutorialspoint.com/java/index.htm</url>
   </link>

   <link>
      <title>CSS </title>
      <url>https://www.tutorialspoint.com/css/index.htm</url>
   </link>

   <link>
      <title>angularjs</title>
      <url>https://www.tutorialspoint.com/angularjs/index.htm </url>
   </link>

   <link>
      <title>hadoop</title>
      <url>https://www.tutorialspoint.com/hadoop/index.htm </url>
   </link>

   <link>
      <title>swift</title>
      <url>https://www.tutorialspoint.com/swift/index.htm </url>
   </link>

   <link>
      <title>ruby</title>
      <url>https://www.tutorialspoint.com/ruby/index.htm </url>
   </link>

   <link>
      <title>nodejs</title>
      <url>https://www.tutorialspoint.com/nodejs/index.htm </url>
   </link>

</pages>

JavaScript Code

以下脚本为用户呈现一个文本字段,用于输入他选择的课程名称。每次击键时,都会调用一个 JavaScript 函数,并将输入值以 GET 方法传给服务器端 PHP 脚本。服务器响应将异步呈现。

将此代码另存为“ index.php ”。

<html>
<head>
   <script>
      function showResult(str) {
         if (str.length == 0) {
            document.getElementById("livesearch").innerHTML = "";
            document.getElementById("livesearch").style.border = "0px";
            return;
         }

         if (window.XMLHttpRequest) {
            xmlhttp = new XMLHttpRequest();
         } else {
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
         }

         xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
               document.getElementById("livesearch").innerHTML = xmlhttp.responseText;
               document.getElementById("livesearch").style.border = "1px solid #A5ACB2";
            }
         }

         xmlhttp.open("GET","livesearch.php?q="+str,true);
         xmlhttp.send();
      }
   </script>
</head>
<body>
   <form>
      <h2>Enter Course Name</h2>
      <input type = "text" size = "30" onkeyup = "showResult(this.value)">
      <div id = "livesearch"></div>
      <a href = "https://www.tutorialspoint.com">More Details</a>
   </form>
</body>
</html>

XML Parser in PHP

这是服务器上的 PHP 脚本。它解析给定的 XML 源文档,读取输入字段中输入的字符,在已解析的 XNL 对象中进行搜索,然后将响应发送回。

将以下代码另存为“livesearch.php”。

<?php
   $xml_doc = new DOMDocument();
   $xml_doc->load('autocomplete.xml');

   $x=$xml_doc->getElementsByTagName('link');

   $q = $_GET['q'];
   $result = '';
   foreach($x as $node) {
      if (stripos("{$node->nodeValue}", $q) !== false) {
         $result .= "{$node->nodeValue}";
      }
   }

   // Set $response to "No records found." in case no hint was found
   // or the values of the matching values
   if ($result == '')
      $result = 'No records found.';

   // show the results or "No records found."
   echo $result;
?>

在 XAMPP 服务器运行的情况下,访问“http://localhost/index.php”,浏览器会显示一个输入文本字段。对于在其中键入的每个字符,相关的建议都会出现在其下面。

php ajax auto search

PHP - AJAX RSS Feed Example

Really Simple Syndication (RSS)

RSS(Really Simple Syndication 的缩写)可用于发布网站的经常更新信息,如音频、视频、图像等。我们可以使用 AJAX 和 PHP 将 RSS 提要集成到网站中。此代码演示了如何在我们的站点中显示 RSS 提要。

Index.html

索引页应如下所述 −

<html>
<head>
   <script>
      function showRSS(str) {
         if (str.length == 0) {
            document.getElementById("output").innerHTML = "";
            return;
         }

         if (window.XMLHttpRequest) {
            xmlhttp = new XMLHttpRequest();
         } else {
            xmlhttp = new ActiveXObject("Microsoft.XMLHTTP");
         }
         xmlhttp.onreadystatechange = function() {
            if (xmlhttp.readyState == 4 && xmlhttp.status == 200) {
               document.getElementById("output").innerHTML = xmlhttp.responseText;
            }
         }

         xmlhttp.open("GET","rss.php?q="+str,true);
         xmlhttp.send();
      }
   </script>
</head>
<body>
   <p>Please Select an option to get RSS:</p>
   <form>
      <select onchange = "showRSS(this.value)">
         <option value = "">Select an RSS-feed:</option>
         <option value = "cnn">CNN</option>
         <option value = "bbc">BBC News</option>
         <option value = "pc">PC World</option>
      </select>
   </form>
   <br>
   <div id = "output">RSS-feeds</div>
</body>
</html>

rss.php

“rss.php”中包含有关如何访问 RSS Feeds RSS 提要并将 RSS 提要返回到网页的语法。

<?php
   $q = $_GET["q"];

   if($q == "cnn") {
      $xml = ("http://rss.cnn.com/rss/cnn_topstories.rss");
   } elseif($q == "bbc") {
      $xml = ("http://newsrss.bbc.co.uk/rss/newsonline_world_edition/americas/rss.xml");
   } elseif($q = "pcw"){
      $xml = ("http://www.pcworld.com/index.rss");
   }

   $xmlDoc = new DOMDocument();
   $xmlDoc->load($xml);

   $channel = $xmlDoc->getElementsByTagName('channel')->item(0);

   $channel_title = $channel->getElementsByTagName('title')
   ->item(0)->childNodes->item(0)->nodeValue;

   $channel_link = $channel->getElementsByTagName('link')
   ->item(0)->childNodes->item(0)->nodeValue;

   $channel_desc = $channel->getElementsByTagName('description')
   ->item(0)->childNodes->item(0)->nodeValue;

   echo("<p><a href = '" . $channel_link . "'>" .
      $channel_title . "</a>");
   echo("<br>");
   echo($channel_desc . "</p>");

   $x = $xmlDoc->getElementsByTagName('item');

   for ($i = 0; $i<=2; $i++) {
      $item_title = $x->item($i)->getElementsByTagName('title')
      ->item(0)->childNodes->item(0)->nodeValue;

      $item_link = $x->item($i)->getElementsByTagName('link')
      ->item(0)->childNodes->item(0)->nodeValue;

      $item_desc = $x->item($i)->getElementsByTagName('description')
      ->item(0)->childNodes->item(0)->nodeValue;

      echo ("<p><a href = '" . $item_link . "'>" . $item_title . "</a>");
      echo ("<br>");
      echo ($item_desc . "</p>");
   }
?>

它将生成如下输出:

php rss feed example

PHP - XML Introduction

借助 PHP 的内置函数和库,我们可以处理 XML 数据的处理。XML(eXtensible Markup Language 的缩写)是一种用于结构化文档交换的数据格式,特别是在网络上。

XML 是一种流行的文件格式,用于存储数据的序列化,将其传输到另一个位置并在目的地重建它。

在本章中,我们将学习使用 PHP 进行 XML 处理的基础知识。

Features of XML

XML 的一个特点是它既可读,又可机器读。XML 的规范由万维网联盟定义和标准化。PHP 解析器可以在 XML 数据上执行读/写操作。

XML Tags

与 HTML 类似,XML 文档也是借助 tags 组成的。然而,你可以定义自己的标签,这不像 HTML,在其中你需要使用预定义的标签才能编写 HTML 文档。

HTML 标签本质上应用于文本、图像、多媒体资源等的格式化属性。XML 标签为数据元素定义用户指定的属性。

XML Document

XML 文档具有标签的层次结构,这些标签定义文档中数据的元素和属性。每个 XML 文档都包含一个根元素,它封装了其他元素。元素可以具有属性,这些属性提供有关元素的其他信息或特性。元素中的数据通过开始和结束标签来封装。

Example

以下是典型 XML 文档的示例 −

<?xml version = '1.0' encoding = 'UTF-8'?>
<note>
   <Course>Android</Course>
   <Subject>Android</Subject>
   <Company>TutorialsPoint</Company>
   <Price>$10</Price>
</note>

Types of XML Parsers

在 PHP 中,有两种类型的 XML 解析器 −

  1. Tree based parsers

  2. Event based parsers

Tree-based Parsers

使用这种类型的解析器,PHP 将在内存中加载整个 XML 文档,并将 XML 文档转换为树结构。它分析整个文档,并为树元素提供访问权限。

For smaller documents, tree-based parser works well ,但对于大型 XML 文档,它会导致重大的性能问题。 SimpleXML parserDOM XML parser 是基于树的解析器的示例

Simple XML Parser

简单 XML 解析器也称为基于树的 XML 解析器,它将解析简单的 XML 文件。简单 XML 解析器将调用 simplexml_load_file() 方法以从特定路径获取 xml 的访问权限。

DOM Parser

DOM 解析器也称为复杂节点解析器,用于解析高度复杂的 XML 文件。它用作修改 XML 文件的界面。DOM 解析器已使用 UTF-8 字符编码进行编码。

Event-based Parsers

基于事件的解析器不会在内存中加载整个 XML 文档。相反,它一次读取一个节点。解析器允许你实时交互。一旦你移到下一个节点,以前的那个节点就会从内存中移除。

由于没有涉及内存过载,因此这种类型的解析器适用于大型 XML 文档,并且解析文档的速度比任何基于树的解析器都要快。XMLReader 和 XML Expat Parser 是基于事件的解析器的示例。

XML Parser

XML 解析基于 SAX 解析。它比所有上述解析器都要快。它将创建 XML 文件并解析 XML。XML 解析器已由 ISO-8859-1、US-ASCII 和 UTF-8 字符编码编码。

XML Reader

XML 阅读器解析也称为 Pull XML 解析。它用于以更快的速度读取 XML 文件。它可以与具有 XML 验证的高复杂 XML 文档配合使用。

PHP - Simple XML Parser

PHP 的 SimpleXML 扩展提供了非常简单易用的工具集,用于将 XML 转换为可以使用普通属性选择器和数组迭代器进行处理的对象。它是一个基于树的解析器,适用于简单的 XML 文件,但是在处理更大且复杂的 XML 文档时可能会遇到问题。

SimpleXML 扩展中定义了以下函数:

simplexml_load_file

simplexml_load_file() 函数将 XML 文件解释为一个对象:

simplexml_load_file(
   string $filename,
   ?string $class_name = SimpleXMLElement::class,
   int $options = 0,
   string $namespace_or_prefix = "",
   bool $is_prefix = false
): SimpleXMLElement|false

给定文件中的格式良好的 XML 文档将转换为一个对象。

filename 参数是一个表示要解析的 XML 文件的字符串。class_name 是一个可选参数。它指定函数将返回其对象的类。该函数返回一个 SimpleXMLElement 类对象,其中属性包含 XML 文档中保存的数据,或者在失败时返回 false

Example

请看以下示例:

<?php
   $xml = simplexml_load_file("test.xml") or die("Error: Cannot create object");
   print_r($xml);
?>

它将生成以下 output

SimpleXMLElement Object
(
   [Course] => Android
   [Subject] => Android
   [Company] => TutorialsPoint
   [Price] => $10
)

simplexml_load_string

simplexml_load_string() 函数将 XML 文件解释为一个对象。

simplexml_load_string(
   string $filename,
   ?string $class_name = SimpleXMLElement::class,
   int $options = 0,
   string $namespace_or_prefix = "",
   bool $is_prefix = false
): SimpleXMLElement|false

给定字符串中的格式良好的 XML 文档将转换为一个对象。

$data 参数是一个表示要解析的 XML 文档的字符串。 class_name 是一个可选参数。它指定函数将返回其对象的类。该函数返回一个 SimpleXMLElement 类对象,其中属性包含 XML 文档中保存的数据,或者在失败时返回 false

Example

请看以下示例:

<?php
   $data = "<?xml version = '1.0' encoding = 'UTF-8'?>
   <note>
      <Course>Android</Course>
      <Subject>Android</Subject>
      <Company>TutorialsPoint</Company>
      <Price>$10</Price>
   </note>";
   $xml = simplexml_load_string($data) or die("Error: Cannot create object");
   print_r($xml);
?>

它将生成以下 output

SimpleXMLElement Object
(
   [Course] => Android
   [Subject] => Android
   [Company] => TutorialsPoint
   [Price] => $10
)

simplexml_import_dom

simplexml_import_dom() 函数从 DOM 节点构造一个 SimpleXMLElement 对象。

simplexml_import_dom(SimpleXMLElement|DOMNode $node, ?string
   $class_name = SimpleXMLElement::class): ?SimpleXMLElement

该函数获取 DOM 文档的一个节点,并将其转化为一个 SimpleXML 节点。然后,这个新对象可以用作原生 SimpleXML 元素。

node 参数是一个 DOM Element 节点。可以给出可选的 class_name,以便 simplexml_import_dom() 返回 SimpleXMLElement 类的指定子类的对象。该函数返回的值是一个 SimpleXMLElement 或 (在失败时) null。

Example

请看以下示例:

<?php
   $dom = new DOMDocument;
   $dom->loadXML('<books><book><title>PHP Handbook</title></book></books>');
   if (!$dom) {
      echo 'Error while parsing the document';
      exit;
   }

   $s = simplexml_import_dom($dom);
   echo $s->book[0]->title;
?>

它将生成以下 output

PHP Handbook

Get the Node Values

以下代码演示了如何从 XML 文件获取节点值,XML 应如下所示:

<?xml version = "1.0" encoding = "utf-8"?>
<tutorialspoint>
   <course category = "JAVA">
      <title lang = "en">Java</title>
      <tutor>Gopal</tutor>
      <duration></duration>
      <price>$30</price>
   </course>

   <course category = "HADOOP">
      <title lang = "en">Hadoop</title>.
      <tutor>Satish</tutor>
      <duration>3</duration>
      <price>$50</price>
   </course>

   <course category = "HTML">
      <title lang = "en">html</title>
      <tutor>raju</tutor>
      <duration>5</duration>
      <price>$50</price>
   </course>

   <course category = "WEB">
      <title lang = "en">Web Technologies</title>
      <tutor>Javed</tutor>
      <duration>10</duration>
      <price>$60</price>
   </course>
</tutorialspoint>

Example

PHP 代码应如下所示:

<?php
   $xml = simplexml_load_file("books.xml") or die("Error: Cannot create object");

   foreach($xml->children() as $books) {
      echo $books->title . "<br> ";
      echo $books->tutor . "<br> ";
      echo $books->duration . "<br> ";
      echo $books->price . "<hr>";
   }
?>

它将生成以下 output

Java
Gopal

$30
________________________________________
Hadoop
Satish
3
$50
________________________________________
html
raju
5
$50
________________________________________
Web Technologies
Javed
10
$60
________________________________________

PHP - SAX Parser Example

PHP 在 php.ini 设置文件中默认启用了 XML 解析器扩展。该解析器实现了 SAX API,这是一种基于事件的解析算法。

基于事件的解析器不会在内存中加载整个 XML 文档。相反,它一次读取一个节点。解析器允许你实时交互。一旦你移到下一个节点,以前的那个节点就会从内存中移除。

基于 SAX 的解析机制比基于树的解析器更快。PHP 库包含用于处理 XML 事件的函数,如本章所述。

解析 XML 文档的第一步是让一个解析器对象使用 xml_parse_create() 函数。

xml_parser_create(?string $encoding = null): XMLParser

此函数创建一个新的 XML 解析器,并返回一个 XMLParser 对象供其他 XML 函数使用。

xml_parse() 函数开始解析 XML 文档

xml_parse(XMLParser $parser, string $data, bool $is_final = false): int

xml_parse() 解析 XML 文档。已配置事件的处理程序将按需要多次调用。

XMLParser 扩展提供不同的事件处理程序函数。

xml_set_element_handler()

此函数设置 XML 解析器的元素处理程序函数。每当 XML 解析器遇到开始或结束标记时,就会发出元素事件。有单独的处理程序来处理开始标记和结束标记。

xml_set_element_handler(XMLParser $parser, callable $start_handler,
   callable $end_handler): true

当打开新的 XML 元素时,调用 start_handler() 函数。当关闭 XML 元素时,调用 end_handler() 函数。

xml_set_character_data_handler()

此函数设置 XML 解析器 parser 的字符数据处理程序函数。字符数据大概包括 XML 文档中所有非标记内容,包括标记之间的空格。

xml_set_character_data_handler(XMLParser $parser, callable $handler): true

xml_set_processing_instruction_handler()

此函数设置 XML 解析器 parser 的处理指令 (PI) 处理程序函数。<?php ?> 是一个处理指令,其中 php 称为“PI 目标”。它们的处理是特定于应用程序的。

xml_set_processing_instruction_handler(XMLParser $parser, callable $handler): true

processing instruction 具有以下格式 -

<?target
   data
?>

xml_set_default_handler()

此函数设置 XML 解析器 parser 的默认处理程序函数。未转交给其他处理程序的所有内容都转交给默认处理程序。您将在默认处理程序中获得 XML 和文档类型声明等内容。

xml_set_default_handler(XMLParser $parser, callable $handler): true

Example

以下示例演示了用于解析 XML 文档的 SAX API 的使用。我们将使用 SAX.xml 如下所示 -

<?xml version = "1.0" encoding = "utf-8"?>
<tutors>
   <course>
      <name>Android</name>
      <country>India</country>
      <email>contact@tutorialspoint.com</email>
      <phone>123456789</phone>
   </course>

   <course>
      <name>Java</name>
      <country>India</country>
      <email>contact@tutorialspoint.com</email>
      <phone>123456789</phone>
   </course>

   <course>
      <name>HTML</name>
      <country>India</country>
      <email>contact@tutorialspoint.com</email>
      <phone>123456789</phone>
   </course>
</tutors>

Example

以下是解析上述文档的 PHP 代码。它打开 XML 文件并调用 xml_parse() 函数,直至文件结束。事件处理程序将数据存储在 tutors 数组中。然后,按元素顺序回显该数组。

<?php

   // Reading XML using the SAX(Simple API for XML) parser
   $tutors   = array();
   $elements   = null;

   // Called to this function when tags are opened
   function startElements($parser, $name, $attrs) {
      global $tutors, $elements;
      if(!empty($name)) {
         if ($name == 'COURSE') {

            // creating an array to store information
            $tutors []= array();
         }
         $elements = $name;
      }
   }

   // Called to this function when tags are closed
   function endElements($parser, $name) {
      global $elements;

      if(!empty($name)) {
         $elements = null;
      }
   }

   // Called on the text between the start and end of the tags
   function characterData($parser, $data) {
      global $tutors, $elements;
      if(!empty($data)) {
         if ($elements == 'NAME' || $elements == 'COUNTRY' ||  $elements == 'EMAIL' ||  $elements == 'PHONE') {
            $tutors[count($tutors)-1][$elements] = trim($data);
         }
      }
   }

   $parser = xml_parser_create();
   xml_set_element_handler($parser, "startElements", "endElements");
   xml_set_character_data_handler($parser, "characterData");

   // open xml file
   if (!($handle = fopen('sax.xml', "r"))) {
      die("could not open XML input");
   }

   while($data = fread($handle, 4096)) {
      xml_parse($parser, $data);
   }

   xml_parser_free($parser);
   $i = 1;

   foreach($tutors as $course) {
      echo "course No - ".$i. '<br/>';
      echo "course Name - ".$course['NAME'].'<br/>';
      echo "Country - ".$course['COUNTRY'].'<br/>';
      echo "Email - ".$course['EMAIL'].'<br/>';
      echo "Phone - ".$course['PHONE'].'<hr/>';
      $i++;
   }
?>

上述代码给出了以下输出 -

course No - 1
course Name - Android
Country - India
Email - contact@tutorialspoint.com
Phone - 123456789
________________________________________
course No - 2
course Name - Java
Country - India
Email - contact@tutorialspoint.com
Phone - 123456789
________________________________________
course No - 3
course Name - HTML
Country - India
Email - contact@tutorialspoint.com
Phone - 123456789
________________________________________

PHP - DOM Parser Example

PHP 中的 DOM 扩展提供广泛的功能,我们可借此对 XML 和 HTML 文档执行各种操作。我们可以动态构造一个 DOM 对象,从一个 HTML 文件或包含 HTML 标记树的字符串加载一个 DOM 文档。我们还可以将 DOM 文档保存到 XML 文件中,或者从 XML 文档中提取 DOM 树。

DOMDocument 类是 DOM 扩展中定义的最重要类之一。

$obj = new DOMDocument($version = "1.0", $encoding = "")

它表示整个 HTML 或 XML 文档;用作文档树的根。DOMDocument 类包括许多静态方法的定义,其中一些如下 -

Sr.No

Methods & Description

1

createElement Create new element node

2

createAttribute Create new attribute

3

createTextNode Create new text node

4

getElementById 搜索具有特定 id 的元素

5

getElementsByTagName 搜索具有给定本地标记名称的所有元素

6

load 从文件中加载 XML

7

loadHTML 从字符串加载 HTML

8

loadHTMLFile 从文件中加载 HTML

9

loadXML 从字符串加载 XML

10

save 将内部 XML 树转储回文件

11

saveHTML 使用 HTML 格式将内部文档转储到字符串中

12

saveHTMLFile 使用 HTML 格式将内部文档转储到文件中

13

saveXML 将内部 XML 树转存储回字符串

Example

让我们对以下 HTML 文件使用此示例 −

<html>
<head>
   <title>Tutorialspoint</title>
</head>
<body>
   <h2>Course details</h2>
   <table border = "0">
      <tbody>
         <tr>
            <td>Android</td>
            <td>Gopal</td>
            <td>Sairam</td>
         </tr>
         <tr>
            <td>Hadoop</td>
            <td>Gopal</td>
            <td>Satish</td>
         </tr>
         <tr>
            <td>HTML</td>
            <td>Gopal</td>
            <td>Raju</td>
         </tr>
         <tr>
            <td>Web technologies</td>
            <td>Gopal</td>
            <td>Javed</td>
         </tr>
         <tr>
            <td>Graphic</td>
            <td>Gopal</td>
            <td>Satish</td>
         </tr>
         <tr>
            <td>Writer</td>
            <td>Kiran</td>
            <td>Amith</td>
         </tr>
         <tr>
            <td>Writer</td>
            <td>Kiran</td>
            <td>Vineeth</td>
         </tr>
      </tbody>
   </table>
</body>
</html>

我们现在将通过在以下 PHP 代码中调用 loadHTMLFile() 方法从上述 HTML 文件中提取文档对象模型 −

<?php

   /*** a new dom object ***/
   $dom = new domDocument;

   /*** load the html into the object ***/
   $dom->loadHTMLFile("hello.html");

   /*** discard white space ***/
   $dom->preserveWhiteSpace = false;

   /*** the table by its tag name ***/
   $tables = $dom->getElementsByTagName('table');

   /*** get all rows from the table ***/
   $rows = $tables[0]->getElementsByTagName('tr');

   /*** loop over the table rows ***/
   foreach ($rows as $row) {

      /*** get each column by tag name ***/
      $cols = $row->getElementsByTagName('td');

      /*** echo the values ***/
      echo 'Designation: '.$cols->item(0)->nodeValue.'<br />';
      echo 'Manager: '.$cols->item(1)->nodeValue.'<br />';
      echo 'Team: '.$cols->item(2)->nodeValue;
      echo '<hr />';
   }

?>

它将生成以下 output

Designation: Android
Manager: Gopal
Team: Sairam
________________________________________
Designation: Hadoop
Manager: Gopal
Team: Satish
________________________________________
Designation: HTML
Manager: Gopal
Team: Raju
________________________________________
Designation: Web technologies
Manager: Gopal
Team: Javed
________________________________________
Designation: Graphic
Manager: Gopal
Team: Satish
________________________________________
Designation: Writer
Manager: Kiran
Team: Amith
________________________________________
Designation: Writer
Manager: Kiran
Team: Vineeth
________________________________________

PHP - Login Example

一个典型的 PHP 网络应用程序在登录之前将对用户进行认证,通过询问他的凭据,诸如 usernamepassword 。然后根据服务器上可用的用户数据对凭据进行检查。在这个例子中,用户数据是用关联数组的形式提供的。以下 PHP 登录脚本在下面进行了说明 −

HTML Form

该代码的 HTML 部分给出了一个简单的 HTML 表单,它接受用户名和密码,并且将数据发布到自身。

<form action = "<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post">
   <div>
      <label for="username">Username:</label>
      <input type="text" name="username" id="name">
   </div>
   <div>
      <label for="password">Password:</label>
      <input type="password" name="password" id="password">
   </div>
   <section style="margin-left:2rem;">
      <button type="submit" name="login">Login</button>
   </section>
</form>

PHP Authentication

PHP 脚本解析 POST 数据,并且检查用户名是否存在于用户数组中。如果存在,则它进一步检查密码是否与数组中已注册的用户相符

<?php
   if (array_key_exists($user, $users)) {
      if ($users[$_POST['username']]==$_POST['password']) {
         $_SESSION['valid'] = true;
         $_SESSION['timeout'] = time();
         $_SESSION['username'] = $_POST['username'];
         $msg = "You have entered correct username and password";
      } else {
         $msg = "You have entered wrong Password";
      }
   } else {
      $msg = "You have entered wrong user name";
   }
?>

将用户名和相应的消息添加到 $_SESSION 数组中。用户将看到相应的消息,提示他输入的凭据是否正确。

The Complete Code

以下是完整代码——

Login.php

<?php
   ob_start();
   session_start();
?>
<html lang = "en">
<head>
   <meta charset="UTF-8">
   <meta name="viewport" content="width=device-width, initial-scale=1.0">
   <link rel="stylesheet" href="loginstyle.css">
   <title>Login</title>
</head>
<body>
   <h2 style="margin-left:10rem; margin-top:5rem;">Enter Username and Password</h2>
   <?php
      $msg = '';
      $users = ['user'=>"test", "manager"=>"secret", "guest"=>"abc123"];

      if (isset($_POST['login']) && !empty($_POST['username'])
      && !empty($_POST['password'])) {
         $user=$_POST['username'];
         if (array_key_exists($user, $users)){
            if ($users[$_POST['username']]==$_POST['password']){
               $_SESSION['valid'] = true;
               $_SESSION['timeout'] = time();
               $_SESSION['username'] = $_POST['username'];
               $msg = "You have entered correct username and password";
            }
            else {
               $msg = "You have entered wrong Password";
            }
         }
         else {
            $msg = "You have entered wrong user name";
         }
      }
   ?>

   <h4 style="margin-left:10rem; color:red;"><?php echo $msg; ?></h4>
   <br/><br/>
   <form action = "<?php echo htmlspecialchars($_SERVER['PHP_SELF']); ?>" method="post">
      <div>
         <label for="username">Username:</label>
         <input type="text" name="username" id="name">
      </div>
      <div>
         <label for="password">Password:</label>
         <input type="password" name="password" id="password">
      </div>
      <section style="margin-left:2rem;">
         <button type="submit" name="login">Login</button>
      </section>
   </form>

   <p style="margin-left: 2rem;">
      <a href = "logout.php" tite = "Logout">Click here to clean Session.</a>
   </p>
   </div>
</body>
</html>

Logout.php

要注销,用户点击 logout.php 的链接

<?php
   session_start();
   unset($_SESSION["username"]);
   unset($_SESSION["password"]);

   echo '<h4>You have cleaned session</h4>';
   header('Refresh: 2; URL = login.php');
?>

通过输入 “http://localhost/login.php” 启动应用程序。以下是 different scenarios

Correct Username and Password

php login example 1

Incorrect Password

php login example 2

Incorrect Username

php login example 3

当用户单击底部的链接时,会话变量将被删除,且登录屏幕将重新出现。

PHP - Facebook Login

可以使用社交媒体登录(也称为 SSO)要求用户登录 Web 应用程序。这样用户无需创建一个新帐户。相反,用户可以使用其现有的社交媒体帐户信息登录。一些社交媒体登录的示例包括:谷歌、Facebook、LinkedIn、Apple。

在本章中,我们将说明如何使用 Facebook 证书激活登录 PHP 应用程序。

添加 Facebook 登录功能的第一步是创建一个 Facebook 应用程序。访问 https://developers.facebook.com/apps/creation/ 并使用您的 Facebook 帐户登录。

php facebook login 1

接下来,输入要创建的 Facebook 应用程序的名称 −

php facebook login 2

进入应用程序设置并获取应用程序 ID 和密钥 −

php facebook login 3

将平台选为网站 −

php facebook login 4

接下来,您需要在 PHP 中设置 Facebook SDK。从“https://packagist.org/packages/facebook/php-sdk”下载适用于 PHP 的 Facebook SDK 或使用 composer : composer require “facebook/graph-sdk-v5”。将 SDK 文件解压到您的 PHP 应用程序可访问的目录中。

要在 PHP 代码中配置 Facebook SDK,请在您的 PHP 文件中包含 Facebook SDK 自动加载器:require_once DIR . '/vendor/autoload.php';

设置您的应用程序访问令牌和应用程序密钥 −

$app_id = 'YOUR_APP_ID';
$app_secret = 'YOUR_APP_SECRET';

接下来,创建 Facebook 登录按钮。创建 HTML 按钮并添加 Facebook 登录 JavaScript SDK 以触发登录流程 −

<button id="facebook-login-button">Login with Facebook</button>

包含 Facebook JavaScript SDK −

<script src="https://connect.facebook.net/en_US/sdk.js#xfbml=1&version=v13.0&appId=YOUR_APP_ID&autoLogApp=true" async defer></script>

创建一个 PHP 脚本来处理 Facebook 登录回调 −

<?php
   session_start();

   $fb = new Facebook\Facebook([
      'app_id' => $app_id,
      'app_secret' => $app_secret,
      'default_graph_version' => 'v13.0',
   ]);

   $helper = $fb->getRedirectLoginHelper();
   $accessToken = $helper->getAccessToken();

   if ($accessToken) {
      // User is logged in, handle their data
      $user = $fb->get('/me', ['fields' => 'id,name,email']);
      $_SESSION['user_data'] = $user;
      header('Location: profile.php');
   } else {
      // User is not logged in, redirect to login page
      $loginUrl = $helper->getLoginUrl(['scope' => 'public_profile,email']);
      header('Location: ' . $loginUrl);
   }
?>

成功登录后,将用户数据存储在会话中,并重定向到受保护页面。在受保护页面上,查看会话中的用户数据以验证访问。

PHP - Paypal Integration

PayPal 是一个付款处理系统。我们可以使用 PHP 来将 PayPal 与网站集成。

PayPal Integration File System

PayPal 集成文件系统包含四个文件,如下所示 -

  1. constants.php − 这个文件包含 API 用户名、密码和签名。

  2. CallerService.php − 这个文件包含用于调用 PayPal 服务的 PayPal 服务。

  3. confirmation.php − 这个文件包含执行付款处理所需的最少字段的表单,它将返回付款成功或失败。

  4. PayPal_entry.php − 此页面用于将用户数据发送到 PayPal。它充当 PayPal 与用户表单之间的适配器。

用户需要从这里下载一个 PayPal SDK 文件并具体解压一个 zip 文件。zip 文件包含四个 PHP 文件。我们不需要更改“constants.php”以外的任何文件。

constants.php

“constants.php”文件包含以下代码 -

<?php
   define('API_USERNAME', 'YOUR USER NAME HERE');
   define('API_PASSWORD', 'YOUR PASSWORD HERE');
   define('API_SIGNATURE', 'YOUR API SIGNATURE HERE');
   define('API_ENDPOINT', 'https://api-3t.paypal.com/nvp');
   define('USE_PROXY',FALSE);
   define('PROXY_HOST', '127.0.0.1');
   define('PROXY_PORT', '808');
   define('PAYPAL_URL', 'https://www.PayPal.com/webscr&cmd=_express-checkout&token=');
   define('VERSION', '53.0');
?>

用户将在上方语法中声明放置在“constants.php”中的用户名、密码和签名。

这是一个实验示例,所以最后金额将被添加到沙盒账户。

PHP - MySQL Login

MySQL 是 PHP 支持的 Web 应用程序的后端数据库的热门选择。在本章中,我们将学习如何为 PHP 应用程序开发一个登录页面,该页面验证给定的用户名和密码。

您应该有一个安装了 PHP 和 MySQL 的 Web 服务器,以便对本章中讨论的示例进行实验。可以轻松安装适用于您操作系统的 Apache、PHP 和 MySQL(MariaDB)的捆绑二进制文件 XAMPP。

在运行示例代码之前,您应该有一个名为 mydb 的 MySQL 数据库,其中必须有一个名为 admin 的表。您可以使用以下 SQL 脚本创建表并插入测试数据

use mydb;

CREATE TABLE `admin` (
   `username` varchar(10) NOT NULL,
   `passcode` varchar(10) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

INSERT INTO `admin` (`username`, `passcode`) VALUES
('guest', 'abc123'),
('manager', 'secret'),
('user', 'test');

ALTER TABLE `admin`
   ADD PRIMARY KEY (`username`);
COMMIT;

PHP 登录应用程序的第一部分是建立数据库连接对象。我们使用 myqli API 来获得连接对象。将以下代码保存为 “config.php”

Config.php

<?php
   define('DB_SERVER', 'localhost');
   define('DB_USERNAME', 'root');
   define('DB_PASSWORD', '');
   define('DB_DATABASE', 'mydb');
   $db = mysqli_connect(DB_SERVER,DB_USERNAME,DB_PASSWORD,DB_DATABASE);
?>

此 PHP 脚本在登录脚本中调用。它向用户提供一个 HTML 表单,用于输入用户名和密码。如果提交了表单,PHP 会运行一个 SELECT 查询,以检索 admin 表中用户名和密码与用户输入匹配的行。

$myusername = mysqli_real_escape_string($db,$_POST['username']);
$mypassword = mysqli_real_escape_string($db,$_POST['password']);

$sql = "SELECT * FROM admin WHERE username = '$myusername' and passcode = '$mypassword'";

$result = mysqli_query($db,$sql);
$row = mysqli_num_rows($result);

如果行数为 1,则表示输入的用户名和密码匹配。用户名保存到 $_SESSION 变量,浏览器会定向到 welcome.php 脚本。

Login.php

将以下代码保存为 “login.php” −

<?php
   include("config.php");
   session_start();
   $error='';
   if($_SERVER["REQUEST_METHOD"] == "POST") {

      // username and password sent from form
      $myusername = mysqli_real_escape_string($db,$_POST['username']);
      $mypassword = mysqli_real_escape_string($db,$_POST['password']);

      $sql = "SELECT * FROM admin WHERE username = '$myusername' and passcode = '$mypassword'";

      $result = mysqli_query($db,$sql);
      $row = mysqli_num_rows($result);
      $count = mysqli_num_rows($result);

      if($count == 1) {

         // session_register("myusername");
         $_SESSION['login_user'] = $myusername;
         header("location: welcome.php");
      } else {
         $error = "Your Login Name or Password is invalid";
      }
   }
?>
<html>
<head>
   <title>Login Page</title>
   <style type = "text/css">
      body {
         font-family:Arial, Helvetica, sans-serif;
         font-size:14px;
      }
      label {
         font-weight:bold;
         width:100px;
         font-size:14px;
      }
      .box {
         border:#666666 solid 1px;
      }
   </style>
</head>
<body bgcolor = "#FFFFFF">
   <div align = "center">
      <div style = "width:300px; border: solid 1px #333333; " align = "left">
         <div style = "background-color:#333333; color:#FFFFFF; padding:3px;"><b>Login</b></div>
         <div style = "margin:30px">
            <form action = "" method = "post">
               <label>UserName  :</label><input type = "text" name = "username" class = "box"/><br /><br />
               <label>Password  :</label><input type = "password" name = "password" class = "box" /><br/><br />
               <input type = "submit" value = " Submit "/><br />
            </form>
            <div style = "font-size:11px; color:#cc0000; margin-top:10px"><?php echo $error; ?></div>
         </div>
      </div>
   </div>
</body>
</html>

Welcome.php

当用户通过身份验证时,会调用 “welcome.php” 脚本。它读取会话变量以显示欢迎消息。

<?php
   include('session.php');
?>
<html>
<head>
   <title>Welcome </title>
</head>
<body>
   <h1>Welcome <?php echo $login_session; ?></h1>
   <h2><a href = "logout.php">Sign Out</a></h2>
</body>
</html>

Logout.php

最后,退出脚本删除并销毁会话,并将用户重定向到登录页面。

<?php
   session_start();

   if(session_destroy()) {
      header("Location: login.php");
   }
?>

要启动登录应用程序,请访问 “http://localhost/login.php”

php mysql login 1

输入用户名和密码。在按下提交按钮后,这些输入与 admin 表中的行进行比对。成功后,您会收到以下消息 −

php mysql login 2

如果查询没有提取到任何匹配的行,则会显示以下错误消息 −

php mysql login 3

PHP & MySQL

PHP 几乎可以与所有数据库软件一起使用,包括 Oracle 和 Sybase,但最常用的是免费提供的 MySQL 数据库。

What you should already have ?

  1. 您已经学习了 MySQL 教程以了解 MySQL 基础知识。

  2. 下载并安装了最新版本的 MySQL。

  3. 使用密码 guest123 创建了数据库用户 guest

  4. 如果您尚未创建数据库,则需要 root 用户及其密码才能创建数据库。

我们已将本章分为以下几个部分 −

  1. * Connecting to MySQL database* − 学习如何使用 PHP 打开和关闭 MySQL 数据库连接。

  2. * Create MySQL Database Using PHP* −本部分说明如何使用 PHP 创建 MySQL 数据库和表。

  3. * Delete MySQL Database Using PHP* −本部分说明如何使用 PHP 删除 MySQL 数据库和表。

  4. * Insert Data To MySQL Database* −创建数据库和表后,就会希望将数据插入创建的表中。本会话将带你实际演练数据插入过程。

  5. * Retrieve Data From MySQL Database* −了解如何使用 PHP 从 MySQL 数据库中检索记录。

  6. * Using Paging through PHP* −本部分说明如何将查询结果显示到多个页面以及如何创建导航链接。

  7. * Updating Data Into MySQL Database* −本部分说明如何使用 PHP 更新 MySQL 数据库中的现有记录。

  8. * Deleting Data From MySQL Database* −本部分说明如何使用 PHP 删除或清除 MySQL 数据库中的现有记录。

  9. * Using PHP To Backup MySQL Database* −了解备份 MySQL 数据库的不同方法,以便于安全目的。

PHP.INI File Configuration

在计算机上安装 PHP 软件后,就会在安装目录中创建 php.ini。对于 XAMPP,php.ini 位于 c:\xamm\php 文件夹中。这是一个重要的配置文件,它控制着性能并设置所有与 PHP 相关的参数。

phpinfo() 函数显示一个不同的参数列表及其 PHP、Aache、MySQL 和 Web 服务器安装的其他部分的当前值。

运行以下代码以显示设置,其中一个设置显示“php.ini”文件的路径:

<?php
   echo phpinfo();
?>

Loaded Configuration File

查找指明php.ini 文件所在位置的已加载配置文件设置

C:\xampp\php\php.ini

PHP 行为的不同方面由大量的参数(称为指令)配置。“php.ini”文件以分号(;)符号开头的多数行开头 - 表示该行已注释。未注释的行实际上是有效的指令及其值。换句话说,要激活并为特定指令指定值,请删除前导分号。

directive = value

指令名称区分大小写。指令是在变量中用于配置 PHP 或 PHP 扩展。请注意,没有名称验证,因此如果没有找到预期的指令,将使用默认值,它可以是字符串、数字、PHP 常量(例如 E_ALL 或 M_PI)、其中一个 INI 常量(开、关、真、假、是、否和无)。

实际上,C:\XAMPP\PHP 文件夹包含两个 INI 文件,一个用于生产环境,另一个用于开发环境。

php.ini-development.ini 与它的生产版本非常相似,除了在错误方面更加详细。在开发阶段,将其复制为 php.ini 以便能够跟踪代码中的错误。一旦代码准备就绪,可以使用 php.ini-production.ini 文件作为有效的 php.ini 文件,这在很大程度上抑制了错误消息。

php.ini 中的指令分为不同的类别,如错误处理、数据处理、路径和目录、文件上传、PHP 扩展和模块设置。

以下是“php.ini”文件中一些重要指令的列表:

short_open_tag = Off

简写标签看起来像这样:<? ?>。如果您想要使用 XML 功能,则必须将此选项设置为“关”。

safe_mode = Off

如果设置为开,您可能使用 --enable-safe-mode 标志编译了 PHP。安全模式最适用于 CGI 用途。请参见本章前面的“CGI 编译时选项”部分中的说明。

safe_mode_exec_dir = [DIR]

此选项仅在安全模式开启时才相关;它也可以在 Unix 构建过程中使用 --with-exec-dir 标志设置。处于安全模式的 PHP 仅会从该目录中执行外部二进制文件。默认值为 /usr/local/bin。这与提供正常的 PHP/HTML 网页无关。

safe_mode_allowed_env_vars = [PHP_]

此选项设置用户在安全模式下可以更改的环境变量。默认值仅为以“PHP_”为前缀的变量。如果此指令为空,则大部分变量均可更改。

safe_mode_protected_env_vars = [LD_LIBRARY_PATH]

此选项设置用户在安全模式下不可更改的环境变量,即使 safe_mode_allowed_env_vars 设置为宽松的模式。

disable_functions = [function1, function2…​]

PHP4 配置的一个受欢迎的补充,也是在 PHP5 中延续的一个补充,就是出于安全性考虑禁用选定功能的能力。以前,这需要手动编辑 PHP 所基于的 C 代码。文件系统、系统和网络功能可能应该首先启用,因为允许通过 HTTP 编写文件和更改系统从来都不是一个安全的想法。

max_execution_time = 30

函数 set_time_limit() 在安全模式下不可用,因此这是在安全模式下使脚本超时的主要方法。在 Windows 中,您必须根据消耗的最大内存而非时间中止执行。如果您使用 Apache,也可以使用 Apache 超时设置来超时,但这也会应用于网站上的非 PHP 文件。

error_reporting = E_ALL & ~E_NOTICE

默认值为 E_ALL & ~E_NOTICE,所有错误,不包括通知。开发服务器应至少设置为默认值;仅正式服务器才能考虑使用较低的值。

error_prepend_string = [""]

与它的配套设置 error_append_string 一起使用时,此设置允许您使错误消息与其他文本的不同颜色,或满足您的其他要求。

warn_plus_overloading = Off

此设置在将 + 运算符用于字符串(比如表单值)时会发出警告。

variables_order = EGPCS

此配置设置取代了 gpc_order。这两个设置现在与其 register_globals 一起弃用。它设置了不同变量的顺序:环境、GET、POST、COOKIE 和 SERVER(也称为内置)。您可以更改此顺序。

变量将按照从左到右的顺序逐个覆盖,最右边的每次都赢得比赛。这意味着,如果您保留默认设置并碰巧为环境变量、POST 变量和 COOKIE 变量使用了相同名称,那么在进程结束时,COOKIE 变量将拥有该名称。实际生活中,这种情况很少发生。

register_globals = Off

此设置允许您决定是否将 EGPCS 变量注册为全局变量。此设置现在已弃用,从 PHP4.2 开始,此标志默认设置为关。请改用超级全局数组。本书中的所有主要代码列表都使用超级全局数组。

magic_quotes_gpc = On

此设置转义传入 GET/POST/COOKIE 数据中的引号。如果您使用许多可能会提交给自己或其他表单并在表单值中显示的表单,您可能需要将此指令设置为开,或者准备对字符串类型数据使用 addslashes()。

magic_quotes_runtime = Off

此设置转义传入数据库和文本字符串中的引号。记住,SQL 在存储字符串时会对单引号和撇号添加斜杠,在返回时不会去除。如果此设置关闭,您需要在从 SQL 数据库输出任何类型的字符串数据时使用 stripslashes()。如果将 magic_quotes_sybase 设置为开,则此设置必须关闭。

magic_quotes_sybase = Off

此设置不对传入数据库和文本字符串中的单引号使用反斜杠,而是使用 Sybase 样式的单引号。如果将 magic_quotes_runtime 设置为开,则此设置必须关闭。

auto-prepend-file = [path/to/file]

如果此处指定了路径,PHP 必须在每个 PHP 文件的开头自动对其 include()。包含路径限制适用。

auto-append-file = [path/to/file]

如果此处指定了路径,PHP 必须在每个 PHP 文件的末尾对其 include(),除非您使用 exit() 函数转义。包括路径限制适用。

include_path = [DIR]

如果您设置此值,您将只能从这些目录包含或需要文件。包含目录通常位于您的文档根目录下;如果您在安全模式下运行,则这是强制性的。将其设置为。,以便包含与您的脚本所在的相同目录中的文件。多个目录使用冒号分隔:.:/usr/local/apache/htdocs:/usr/local/lib。

doc_root = [DIR]

如果您使用 Apache,您已经在 httpd.conf 中为该服务器或虚拟主机设置了文档根目录。如果您在使用安全模式或希望仅启用您网站的一部分的 PHP(例如,仅在 Web 根目录的一个子目录中),请在此处设置此值。

file_uploads = [on/off]

如果您要使用 PHP 脚本上传文件,请打开此标志。

upload_tmp_dir = [DIR]

除非您了解 HTTP 上传的影响,否则不要对这一行进行注释!

session.save-handler = files

除了极少数情况下,您一般不会希望更改此设置。因此请不要动它。

ignore_user_abort = [On/Off]

如果网站访问者单击浏览器的停止按钮,此设置将控制会发生的事情。默认设置为“开”,这意味着该脚本将继续运行到完成或超时。如果该设置被更改为“关”,该脚本将中止。此设置只在模块模式下工作,而不在 CGI 中工作。

mysql.default_host = hostname

如果未指定其他主机,则在连接到数据库服务器时要使用的默认服务器主机。

mysql.default_user = username

如果未指定其他名称,则在连接到数据库服务器时要使用的默认用户名。

mysql.default_password = password

如果未指定其他密码,则在连接到数据库服务器时要使用的默认密码。

PHP - Array Destructuring

在 PHP 中,数组解构一词指的是将数组元素提取到单个变量中的机制。它也可以称为解包数组。PHP 的 list() 构造函数用来解构给定的数组,并在一条语句中将其项目分配给变量列表。

list($var1, $var2, $var3, . . . ) = array(val1, val2, val3, . . .);

结果, val1 被分配到 $var1, val2$var2 等等。即使因为括号,您可能认为 list() 是一个函数,但它不是,因为它没有返回值。PHP 将字符串视为一个数组,但是它无法用 list() 解包。此外,list() 中的括号不能是空的。

除了 list(),您还可以使用方括号 [] 作为解构数组的快捷方式。

[$var1, $var2, $var3, . . . ] = array(val1, val2, val3, . . .);

Example

请看以下示例:

<?php
   $marks = array(50, 56, 70);
   list($p, $c, $m) = $marks;
   echo "Physics: $p  Chemistry: $c  Maths: $m" . PHP_EOL;

   # shortcut notation
   [$p, $c, $m] = $marks;
   echo "Physics: $p  Chemistry: $c  Maths: $m" . PHP_EOL;
?>

它将生成以下 output

Physics: 50  Chemistry: 56  Maths: 70
Physics: 50  Chemistry: 56  Maths: 70

Destructuring an Associative Array

在 PHP 7.1.0 之前,list() 只在从 0 开始的数字索引的数字数组上工作。PHP 7.1 数组解构也适用于关联数组。

让我们尝试对以下关联数组进行解构(或拆包),一个具有非数字索引的数组。

$marks = array('p'=>50, 'c'=>56, 'm'=>70);

要对这个数组进行解构,list() 语句将每个数组键与一个独立变量相关联。

list('p'=>$p, 'c'=>$c, 'm'=>$m) = $marks;

此外,您还可以使用 [] 替代解构符号。

['p'=>$p, 'c'=>$c, 'm'=>$m] = $marks;

尝试并执行以下 PHP 脚本 −

<?php
   $marks = array('p'=>50, 'c'=>56, 'm'=>70);
   list('p'=>$p, 'c'=>$c, 'm'=>$m) = $marks;
   echo "Physics: $p  Chemistry: $c  Maths: $m" . PHP_EOL;

   # shortcut notation
   ['p'=>$p, 'c'=>$c, 'm'=>$m] = $marks;
   echo "Physics: $p  Chemistry: $c  Maths: $m" . PHP_EOL;
?>

Skipping Array Elements

对于索引数组,您可以跳过其某些元素,只将其他元素分配给必需的变量

<?php
   $marks = array(50, 56, 70);
   list($p, , $m) = $marks;
   echo "Physics: $p  Maths: $m" . PHP_EOL;

   # shortcut notation
   [$p, , $m] = $marks;
   echo "Physics: $p  Maths: $m" . PHP_EOL;
?>

对于关联数组,由于索引不是从 0 开始递增的,因此在分配时不必遵循元素的顺序。

<?php
   $marks = array('p'=>50, 'c'=>56, 'm'=>70);
   list('c'=>$c, 'p'=>$p, 'm'=>$m) = $marks;
   echo "Physics: $p  Chemistry: $c  Maths: $m" . PHP_EOL;

   ['c'=>$c, 'm'=>$m, 'p'=>$p] = $marks;		# shortcut notation
   echo "Physics: $p  Chemistry: $c  Maths: $m" . PHP_EOL;
?>

Destructuring a Nested Array

您还可以将数组解构的概念扩展到嵌套数组。在以下示例中,嵌套在其内部的子数组是一个索引数组。

<?php
   $marks = ['marks' => [50, 60, 70]];
   ['marks' => [$p, $c, $m]] = $marks;
   echo "Physics: $p  Chemistry: $c  Maths: $m" . PHP_EOL;
?>

即使嵌套数组也是关联数组,解构也同样有效。

<?php
   $marks = ['marks' => ['p'=>50, 'c'=>60, 'm'=>70]];
   ['marks' => ['p'=>$p, 'c'=>$c, 'm'=>$m]] = $marks;
   echo "Physics: $p  Chemistry: $c  Maths: $m" . PHP_EOL;
?>

PHP - Coding Standard

每家公司都基于其最佳实践遵循自己的编码规范。编码规范是必需的,因为可能会有许多开发者在研究不同的模块,因此,如果他们开始发明自己的规范,那么源代码将变得非常难以管理,并且在未来难以维护该源代码。

以下是人们应该使用编码规范的部分原因:

  1. 你的同伴程序员必须理解你生成的代码。编码规范可作为团队全体人员解读代码的蓝图。

  2. 通过一致的编码实现的简单性和清晰性让你避免了常见错误。

  3. 如果你在一段时间后修改你的代码,那么该代码变得容易理解。

  4. 遵循统一编码规范会让软件的质量更高。

在使用 PHP 编码时可以遵循一些准则。

Indenting and Line Length

使用 4 个空格的缩进,不要使用任何制表符,因为不同的计算机对制表符使用不同的设置。建议将行长度保持在大约 75-85 个字符以内,以便于更好地阅读代码。

Control Structures

这些内容包括 if、for、while、switch 等。控制语句在控制关键字和开括号之间应该有一个空格,以区别于函数调用。强烈建议你始终使用大括号,即使在技术上它们是可选项的情况下也是如此。

Examples

if ((condition1) || (condition2)) {
   action1;
} elseif ((condition3) && (condition4)) {
   action2;
} else {
   default action;
}

你可以按如下方式编写 switch 语句:

switch (condition) {
   case 1:
      action1;
      break;

   case 2:
      action2;
      break;

   default:
      defaultaction;
      break;
}

Function Calls

函数调用时不应该在函数名称、开括号和第一个参数之间使用空格;在逗号和每个参数之间使用空格;在最后一个参数、闭括号和分号之间不使用空格。以下是一个示例:

$var = foo($bar, $baz, $quux);

Function Definitions

函数声明遵循“BSD/Allman 样式”:

function fooFunction($arg1, $arg2 = '') {
   if (condition) {
      statement;
   }
   return $val;
}

Comments

C 风格注释 (/* */) 和标准 C++ 注释 (//) 都可以。允许使用 Perl/shell 风格注释 (#),但不鼓励这样做。

PHP Code Tags

始终使用 <?php ?> 来分隔 PHP 代码,而不是 <? ?> 简写。这是 PHP 合规性要求,也是在不同的操作系统和设置上包含 PHP 代码的最可移植方式。

Variable Names

  1. 全部使用小写字母

  2. 使用“_”作为单词分隔符。

  3. 全局变量应该以“g”为前缀。

  4. 全局常量应该全部大写,并使用“_”作为分隔符。

  5. 静态变量可以预先加上“s”。

Make Functions Reentrant

函数不应保留防止函数重入的静态变量。

Alignment of Declaration Blocks

声明块应对齐。

One Statement Per Line

除了语句紧密相关之外,每行只能有一个语句。

Short Methods or Functions

方法应限制在单个代码页中。

在编写 PHP 程序时,应考虑很多要点。总的来说,意图应始终一致,并且仅在遵循编码标准时才有可能。如果你喜欢不同的东西,你可以设计自己的标准。

PHP - Regular Expressions

正则表达式本身不过是字符的序列或模式。它们为模式匹配功能提供基础。

使用正则表达式,可以在另一个字符串中搜索特定字符串,可以用另一个字符串替换一个字符串,还可以将一个字符串拆分成许多块。

PHP 提供特定于两组正则表达式函数的函数,每个函数都对应一定类型的正则表达式。您可以根据您的喜好使用其中任何一个。

  1. POSIX Regular Expressions

  2. PERL Style Regular Expressions

POSIX Regular Expressions

POSIX 正则表达式的结构与典型算术表达式的结构并无不同:将各种元素(运算符)组合起来以形成更复杂的表达式。

最简单的正则表达式是匹配单个字符的正则表达式,如 g,在诸如 g、haggle 或 bag 等字符串中。

让我们对 POSIX 正则表达式中使用的几个概念进行解释。之后,我们将向您介绍正则表达式相关函数。

Brackets

括号 ([]) 在正则表达式中使用时具有特殊的含义。它们用于查找字符范围。

Sr.No

Expression & Description

1

[0-9] 它匹配 0 到 9 之间的任何十进制数字。

2

[a-z] 它匹配小写字母 a 到小写字母 z 的任何字符。

3

[A-Z] 它匹配大写字母 A 到大写字母 Z 的任何字符。

4

[a-Z] 它匹配小写字母 a 到大写字母 Z 的任何字符。

上面显示的范围是通用的;您还可以使用范围 [0-3] 以匹配从 0 到 3 的任何十进制数字,或使用范围 [b-v] 以匹配从 b 到 v 的任何小写字母。

Quantifiers

用方括号括起来的字符序列和单个字符出现的频率或位置可以用特殊字符表示。每个特殊字符都有一个特定含义。+、*、?、{int. range} 和 $ 标志都出现在字符序列之后。

Sr.No

Expression & Description

1

p+ 它匹配包含至少一个 p 的任何字符串。

2

p *匹配包含零个或更多个 p 的任何字符串。

3

p? 它匹配包含零个或一个 p 的任何字符串。

4

p{*N }*它匹配包含 N p 序列的任何字符串

5

p{2,3} 匹配包含两个或三个 p 序列的任何字符串。

6

p{2, } 匹配包含至少两个 p 序列的任何字符串。

7

p$ 匹配末尾有 p 的任何字符串。

8

*^*p 它匹配以 p 开头的任何字符串。

Examples

以下示例将阐明您对匹配字符的概念。

Sr.No

Expression & Description

1

[^a-zA-Z] 它匹配不包含从 a 到 z 和 A 到 Z 的任何字符的任何字符串。

2

p.p 它匹配包含 p、紧接着任何字符以及再紧接着另一个 p 的任何字符串。

3

^.{2}$ 匹配包含正好两个字符的任何字符串。

4

&lt;b&gt;(. )</b>*匹配以 <b> 和 </b> 括起的任何字符串。

5

p(hp) *它匹配包含一个 p,后跟零个或多个 php 序列的任何字符串。

Predefined Character Ranges

为了方便你的编程,提供了几个预定义的字符范围,也称为字符类。字符类指定了一整个字符范围,例如,字母表或整数集 -

Sr.No

Expression & Description

1

[id=":alpha:"] 它匹配包含字母 aA 到 zZ 的任何字符串。

2

[id=":digit:"] 它匹配包含数字数字 0 到 9 的任何字符串。

3

[id=":alnum:"] 它匹配包含字母数字 aA 到 zZ 和 0 到 9 的任何字符串。

4

[id=":space:"] 它匹配包含空格的任何字符串。

PHP’s Regexp POSIX Functions

PHP 目前提供七个函数用于使用 POSIX 风格的正则表达式搜索字符串 -

Sr.No

Function & Description

1

ereg() ereg() 函数在字符串指定模式指定的字符串中搜索,如果找到该模式,返回 true,否则返回 false。

2

ereg_replace() ereg_replace() 函数搜索 pattern 指定的字符串并用 replacement 替换 pattern(如果找到的话)。

3

eregi() eregi() 函数在字符串指定模式指定的字符串中搜索。搜索不区分大小写。

4

eregi_replace() eregi_replace() 函数的操作与 ereg_replace() 完全相同,但对 pattern 在字符串中的搜索不区分大小写。

5

split() split() 函数将一个字符串分解成多个元素,每个元素的边界基于 pattern 在字符串中出现的位置。

6

spliti() spliti() 函数的操作与其同级 split() 完全相同,但它不区分大小写。

7

sql_regcase() sql_regcase() 函数可被视为一个实用程序函数,将输入参数字符串中的每个字符转换为包含两个字符的括号表达式。

PERL Style Regular Expressions

Perl 风格的正则表达式类似于 POSIX 对应表达式。POSIX 语法几乎可以与 Perl 风格的正则表达式函数互换使用。事实上,你可以使用先前 POSIX 部分中介绍的任何限定符。

让我们对 PERL 正则表达式中使用的一些概念进行说明。之后,我们会向你介绍与正则表达式相关的函数。

Meta characters

元字符只是一个字母字符,前置反斜杠,作用是给组合赋予一个特殊含义。

例如,你可以使用“\d”元字符搜索大额资金: /([\d]+)000/ ,此处 \d 将搜索任何数字字符的字符串。

以下是可以用于 PERL 风格正则表达式中的元字符列表。

Character		Description
.              a single character
\s             a whitespace character (space, tab, newline)
\S             non-whitespace character
\d             a digit (0-9)
\D             a non-digit
\w             a word character (a-z, A-Z, 0-9, _)
\W             a non-word character
[aeiou]        matches a single character in the given set
[^aeiou]       matches a single character outside the given set
(foo|bar|baz)  matches any of the alternatives specified

Modifiers

有几个修饰符可用,它们可以使你和正则表达式的合作更容易,比如区分大小写、在多行中搜索等。

Modifier	Description
i 	Makes the match case insensitive
m 	Specifies that if the string has newline or carriage
	return characters, the ^ and $ operators will now
	match against a newline boundary, instead of a
	string boundary
o 	Evaluates the expression only once
s 	Allows use of . to match a newline character
x 	Allows you to use white space in the expression for clarity
g 	Globally finds all matches
cg 	Allows a search to continue even after a global match fails

PHP’s Regexp PERL Compatible Functions

PHP 提供以下函数,用于使用 Perl 兼容正则表达式搜索字符串 −

Sr.No

Function & Description

1

preg_match() preg_match() 函数用于在字符串中搜索模式,如果模式存在则返回 true,否则返回 false。

2

preg_match_all() preg_match_all() 函数匹配字符串中模式的所有出现。

3

preg_replace() preg_replace() 函数的工作方式类似于 ereg_replace(),不同之处在于可以在模式和替换输入参数中使用正则表达式。

4

preg_split() preg_split() 函数的工作方式完全类似于 split(),不同之处在于可以接受正则表达式作为模式的输入参数。

5

preg_grep() preg_grep() 函数搜索 input_array 的所有元素,返回与 regexp 模式匹配的所有元素。

6

preg_ quote() 引用正则表达式字符

PHP - Error Handling

在 PHP 中处理错误是指在 PHP 代码中做出规定来有效识别和恢复程序可能遇到的运行时错误。在 PHP 中,错误的处理方法有 -

  1. The die() function

  2. The Error Handler Function

The die() Function

die() 函数是 PHP 中 exit() 的别名。当遇到它们时,这两个函数都会导致当前 PHP 脚本终止。如果在括号中指定了一个可选字符串,它将在程序终止前输出。

die("message");

Example

以下代码是 die() 在 PHP 脚本中的典型用法。如果 PHP 找不到文件,它将显示“File not found”消息,否则它会继续将其打开以进行后续处理。

<?php
   if(!file_exists("nosuchfile.txt")) {
      die("File not found");
   } else {
      $file = fopen("nosuchfile","r");
      print "Opend file sucessfully";

      // Rest of the code here.
      fclose($file);
   }
?>

它将生成以下 output

File not found

使用上述技术,当您的程序发生错误时,您可以随时停止程序并显示更具意义且用户友好的消息,而不是让 PHP 生成致命错误消息。

The Error Handler Function

使用 die() 处理错误被认为是一种笨拙且糟糕的程序设计,因为它会导致网站用户的体验很差。PHP 提供了一个更优雅的替代方法,您可以使用它定义一个自定义函数并指定它来处理错误。

set_error_handler() 函数具有以下参数 -

set_error_handler(?callable $callback, int $error_levels = E_ALL): ?callable

第一个参数是用户定义的函数,每当遇到错误时都会自动调用该函数。

自定义错误处理回调函数应具有以下参数 -

handler(
   int $errno,
   string $errstr,
   string $errfile = ?,
   int $errline = ?,
   array $errcontext = ?
): bool

Parameters

Parameter

Importance

Description

errno

Required

它指定用户定义错误的错误级别。它必须是数值。

errstr

Required

它指定用户定义错误的错误消息。

errfile

Optional

它指定发生错误的文件名。

errline

Optional

它指定发生错误的行号。

errcontext

Optional

它指定一个在发生错误时包含正在使用的变量及其值的数组。

如果回调函数返回 false,将调用默认错误。

$errno 是一个对应于预定义错误级别的整数。

Sr.No

Constant & Description

Value

1

E_ERROR (int) 无法恢复的致命运行时错误。脚本的执行将停止。

1

2

E_WARNING (int) 运行时警告(非致命错误)。脚本的执行不会停止。

2

3

E_PARSE (int) 编译时解析错误。解析错误只应由解析器生成。

4

4

E_NOTICE (int) 运行时通知。在脚本的正常运行过程中可能发生某些表示错误的内容。

8

5

E_CORE_ERROR (int)PHP 在初始启动过程中发生的致命错误。这就像一个 E_ERROR

16

6

E_CORE_WARNING (int)PHP 在初始启动过程中发生的警告(非致命错误)。这就像一个 E_WARNING

32

7

E_COMPILE_ERROR (int)致命的编译时错误。这就像一个 E_ERROR

64

8

E_COMPILE_WARNING (int)编译时的警告(非致命错误)。这就像一个 E_WARNING

128

9

E_USER_ERROR (int)用户生成错误信息。这就像一个 E_ERROR ,由 PHP 代码中使用 PHP 函数 trigger_error() 生成的。

256

10

E_USER_WARNING (int)用户生成警告信息。这就像一个 E_WARNING ,由 PHP 代码中使用函数 trigger_error() 生成的。

512

11

E_USER_NOTICE (int)用户生成通知信息。这就像一个 E_NOTICE ,由 PHP 代码中使用函数 trigger_error() 生成的。

1024

12

E_STRICT (int)启用后,PHP 会建议对你代码进行更改,以确保代码具有最佳互操作性和前向兼容性。

2048

13

E_RECOVERABLE_ERROR (int)可捕获的致命错误。如果错误未被用户定义的处理程序捕获,则应用程序将中止,就像一个 E_ERROR 一样。

4096

14

E_DEPRECATED (int)运行时通知。启用后,可以接收有关将来版本中无法工作的代码的警告。

8192

15

E_USER_DEPRECATED (int)用户生成警告信息。这就像一个 E_DEPRECATED ,由 PHP 代码中使用函数 trigger_error() 生成的。

16384

16

E_ALL (int)所有错误、警告和通知。

32767

Example

请看以下示例:

<?php
   error_reporting(E_ERROR);

   function myerrorhandler($errno, $errstr) {
      echo "error No: $errno Error message: $errstr" . PHP_EOL;
      echo "Terminating PHP script";
      die();
   }

   set_error_handler("myerrorhandler");

   $f = fopen("nosuchfile.txt", "r");
   echo "file opened successfully";
   // rest of the code
   fclose($f);
?>

它将生成以下 output

error No: 2 Error message: fopen(nosuchfile.txt): Failed to open stream: No
such file or directory
Terminating PHP script

PHP 的错误类层次结构始于 throwable 接口。PHP 中所有预定义的 Error 类都继承自 Error 类。

The ArithmeticError Class

ArithmeticError class 继承自 Error class 。在执行某些数学运算(例如以负数执行按位移位运算)时,可能会发生这种类型的错误。

Example

请看以下示例:

<?php
   try {
      $a = 10;
      $b = -3;
      $result = $a << $b;
   }
   catch (ArithmeticError $e) {
      echo $e->getMessage();
   }
?>

它将生成以下 output

Bit shift by negative number

当调用 intdiv() 函数导致的值超出整数的合法边界时,也会引发此错误。

Example

请看以下示例:

<?php
   try {
      $a = PHP_INT_MIN;
      $b = -1;
      $result = intdiv($a, $b);
      echo $result;
   }
   catch (ArithmeticError $e) {
      echo $e->getMessage();
   }
?>

它将生成以下 output

Division of PHP_INT_MIN by -1 is not an integer

DivisionByZeroError

DivisionByZeroError 类是 ArithmeticError 类的子类。当除法运算中的分母值为零时,会发生此类型的错误。

Example: Modulo by Zero

来看一下以下示例:

<?php
   try {
      $a = 10;
      $b = 0;
      $result = $a%$b;
      echo $result;
   }
   catch (DivisionByZeroError $e) {
      echo $e->getMessage();
   }
?>

它将生成以下 output

Modulo by zero

当模运算符(%)的第二个运算符为 0,且 intdiv() 函数的第二个参数为 0 时,也会发生这种情况。

Example: Division by Zero

请看以下示例:

<?php
   try {
      $a = 10;
      $b = 0;
      $result = $a/$b;
      echo $result;
   }
   catch (DivisionByZeroError $e) {
      echo $e->getMessage();
   }
?>

它将生成以下 output

Division by zero

ArgumentCountError

当传递给用户定义函数或方法的参数少于其定义中的参数时,PHP 解析器会引发 ArgumentCountError。

Example

请看以下示例:

<?php
   function add($x, $y) {
      return $x+$y;
   }
   try {
      echo add(10);
   }
   catch (ArgumentCountError $e) {
      echo $e->getMessage();
   }
?>

它将生成以下 output

Too few arguments to function add(), 1 passed in C:\xampp\php\test.php on line 9 and exactly 2 expected

TypeError

当实际参数类型和形式参数类型不匹配、返回类型不匹配声明的返回类型时,会引发此错误。

Example

请看以下示例:

<?php
   function add(int $first, int $second) {
      echo "addition: " . $first + second;
   }

   try {
      add('first', 'second');
   }
   catch (TypeError $e) {
      echo $e->getMessage(), "";
   }
?>

它将生成以下 output

add(): Argument #1 ($first) must be of type int, string given,
   called in /home/cg/root/63814/main.php on line 7

当 PHP 的内置函数传递的参数数量不正确时,也会引发 TypeError。但是,必须一开始就设置“strict_types=1”指令。

Example

请看以下示例:

<?php
   declare(strict_types=1);
   try {
      echo pow(100,2,3);
   }
   catch (TypeError $e) {
      echo $e->getMessage(), "";
   }
?>

它将生成以下 output

pow() expects exactly 2 parameters, 3 given

Exceptions Handling in PHP

PHP 具有一个类似于其他编程语言的异常模型。异常很重要,并提供了对错误处理的更好控制。

让我们解释一下与异常相关的新的关键字。

  1. Try − 使用异常的函数应位于“try”块中。如果异常未触发,则代码将照常继续。但是,如果异常触发,则会“抛出”异常。

  2. Throw − 这是触发异常的方法。每个“投掷”都必须至少有一个“捕获”。

  3. Catch − “catch”块检索异常并创建一个包含异常信息的对象。

当抛出异常时,语句后面的代码不会执行,并且 PHP 将尝试查找第一个匹配的 catch 块。如果未捕获异常,则会使用“未捕获异常”发出 PHP 致命错误……

  1. 可以在 PHP 中抛出并捕获(“捕获”)异常。代码可以包围在 try 块中。

  2. 每个 try 必须至少有一个相应的 catch 块。可以使用多个 catch 块来捕获不同类别的异常。

  3. 可以在 catch 块中抛出(或重新抛出)异常。

Example

以下是代码片,复制并将此代码粘贴到文件中并验证结果。

<?php
   try {
      $error = 'Always throw this error';
      throw new Exception($error);

      // Code following an exception is not executed.
      echo 'Never executed';
   }catch (Exception $e) {
      echo 'Caught exception: ',  $e->getMessage(), "";
   }

   // Continue execution
   echo 'Hello World';
?>

在上面的示例中,$e→getMessage 函数用于获取错误消息。有以下函数可以从 Exception 类中使用。

  1. getMessage() − 异常消息

  2. getCode() − 异常代码

  3. getFile() − source filename

  4. getLine() − source line

  5. getTrace() − backtrace() 的 n 个数组

  6. getTraceAsString() − 跟踪的格式化字符串

Creating Custom Exception Handler

您可以定义您自己的自定义异常处理程序。使用以下函数设置用户定义的异常处理程序函数。

string set_exception_handler ( callback $exception_handler )

这里 exception_handler 是在发生未捕获异常时要调用的函数的名称。必须在调用 set_exception_handler() 之前定义此函数。

Example

请看以下示例:

<?php
   function exception_handler($exception) {
      echo "Uncaught exception: " , $exception->getMessage(), "\n";
   }

   set_exception_handler('exception_handler');
   throw new Exception('Uncaught Exception');

   echo "Not Executed";
?>

PHP Error Handling Functions 查看错误处理函数的完整列表

PHP Try…Catch

在 PHP 中,提供了关键字 try, catch, throwfinally 来处理异常。如果错误是程序自身无法处理的意外程序结果,则必须使用 die() 终止程序或设置自定义错误处理程序。

另一方面,异常是指可以通过某种方式处理的意外情况,在异常从正常流中抛出后,程序可以继续运行。

可以通过 PHP 代码中的 catch 关键字抛出异常,并使用该关键字捕获异常。可能容易出现异常的代码块被 try 块包围。每个 try 至少必须有一个对应的 catch 或 finally 块。

Try, Throw, Catch, and Finally

与异常相关的四个关键字具有以下作用 −

  1. Try − 将可能发生异常的代码块放在“try”块中。如果未触发异常,则代码继续执行。但是,如果确实发生了异常,则会“抛出”异常。执行暂停,并且 PHP 查找匹配的“catch”块。如果未捕获异常,则 PHP 会发出致命错误。

  2. Throw − 以下是如何触发异常。每个“throw”至少必须有一个“catch”或“finally”块。

  3. Catch − 一个检索异常并在对象中创建包含异常信息的块。可以使用多个 catch 块来捕获不同的异常。

  4. Finally − 在 finally 块中的代码始终在 throw 或 catch 块之后执行。

Example

以下是一个异常处理技术的示例。该代码在浏览器上渲染两个文本字段,并要求用户输入两个数字以执行它们的除法。如果第二个数字(分母)为 0,则会抛出异常,程序进入 catch 块并打印异常消息。否则,将显示除法的结果。

<html>
<body>
   <form action="<?php echo $_SERVER['PHP_SELF'];?>" method="post">
      <h3>First No: <input type="text" name="first"/></h3>
      <h3>Second No: <input type="text" name="second"/></h3>
      <input type="submit" value="Submit" />
   </form>

   <?php
      if ($_SERVER["REQUEST_METHOD"] == "POST") {
         $x = $_POST['first'];
         $y = $_POST['second'];
         echo "$x $y";
         try {
            if ($y == 0) {
               throw new Exception("Division by Zero");
            }
            $z = $x/$y;
            echo "<h3>x = $x y = $y Division = $z<br>";
         }
         catch (Exception $e) {
            echo "<h3> Exception: " . $e->getMessage();
         }
      }
   ?>
</body>
</html>

它将生成以下 output

Case 1: x = 10 y = 5 Division = 2

Case 2: x = 10 y = 0
Exception: Division by Zero

The Exception Class

PHP 抛出一个 Exception class 对象。在 PHP 中,Exception 类是用户异常的基础。它实现可抛出的接口。

该类定义以下方法 −

getMessage()

此函数将异常消息作为字符串返回 −

final public Exception::getMessage(): string

getCode()

此函数返回异常代码作为 Exception 中的 int

final public Exception::getCode(): int

看看以下 example

try {
   throw new Exception("Some error message", 30);
}
catch(Exception $e) {
   echo "The exception code is: " . $e->getCode();
}

getFile()

此函数返回创建异常的文件名

final public Exception::getFile(): string

看看以下 example

try {
   if ($y == 0) {
      throw new Exception("Division by Zero");
   }
   $z = $x/$y;
   echo "<h3>x = $x y = $y Division = $z<br>";
}
catch (Exception $e) {
   echo "<h3> Exception: " . $e->getMessage(). " in " . $e->getFile();
}

它将生成以下 output

Exception: Division by Zero in C:\xampp\htdocs\hello.php

getLine()

此函数返回创建异常的行号

final public Exception::getLine(): int

Example

请看以下示例:

<?php
   if ($_SERVER["REQUEST_METHOD"] == "POST") {
      $x = $_POST['first'];
      $y = $_POST['second'];
      echo "$x $y";
      try {
         if ($y == 0) {
            throw new Exception("Division by Zero");
         }
         $z = $x/$y;
         echo "<h3>x = $x y = $y Division = $z<br>";
      }
      catch (Exception $e) {
         echo "<h3> Exception: " . $e->getMessage(). " in " . $e->getLine() . " of " . $e->getFile();
      }
   }
?>

它将生成以下 output

Exception: Division by Zero in 21 of C:\xampp\htdocs\hello.php

Multiple Catch Blocks

PHP 允许一系列 catch 块跟随 try 块来处理不同的异常情况。可以采用多个 catch 块来处理预定义的异常和错误,以及用户定义的异常。

Example

以下示例使用 catch 块来处理 DivisioByZeroError、TypeError、ArgumentCountError 和 InvalidArgumentException 条件。还有一个 catch 块来处理常规的 Exception。

<?php
   declare(strict_types=1);
   function divide(int $a, int $b) : int {
      return $a / $b;
   }
   $a=10;
   $b=0;
   try {
   if (!$b) {
      throw new DivisionByZeroError('Division by zero.');
      if (is_int($a)==FALSE || is_int($b)==FALSE)
      throw new InvalidArgumentException("Invalid type of arguments");
      $result=divide($a, $b);
      echo $result;
   }

   // if argument types not matching
   catch (TypeError $x) {
      echo $x->getMessage();
   }

   // if denominator is 0
   catch (DivisionByZeroError $y) {
      echo $y->getMessage();
   }

   // if number of arguments not equal to 2
   catch (ArgumentCountError $z) {
      echo $z->getMessage();
   }

   // if argument types not matching
   catch (InvalidArgumentException $i) {
      echo $i->getMessage();
   }

   // any uncaught exception
   catch (Exception $ex) {
      echo $ex->getMessage();
   }
?>

首先,由于分母为 0,因此将显示“除以 0”错误 −

Division by 0

设置 $b=3 ,它将导致 TypeError,因为期望除数函数返回整数,但是除法结果为 float

divide(): Return value must be of type int, float returned

如果仅将一个变量传递给除数函数,通过更改 $res=divide($a); ,这将导致 ArgumentCountError

Too few arguments to function divide(), 1 passed in C:\xampp\htdocs\hello.php on line 16 and exactly 2 expected

如果其中一个参数不是整数,则是 InvalidArgumentException 的情况。将 $b 更改为字符串 −

Invalid type of arguments

The Finally Block

finally 块也可能在 catch 块后面或代替 catch 块指定。无论是否抛出异常, finally 块内的代码都将在 trycatch 块之后始终执行,并且在恢复正常执行之前执行。

try {
   if ($y == 0) {
      throw new Exception("Division by Zero");
   }
   $z = $x/$y;
   echo "<h3>x = $x y = $y Division = $z </h3><br>";
}
catch (Exception $e) {
   echo "<h3> Exception: " . $e->getMessage(). "</h3>";
}
finally {
   echo "<h3>End of try - catch - finally</h3>";
}

它将生成如下输出:

Case 1 −

x = 10 y = 5 Division = 2
End of try - catch – finally

Case 2 −

X=10 y=0
Exception: Division by Zero
End of try - catch – finally

Finally With Return

try 块或 catch 块(或两者)包含 return 语句时,有 finally 块的特殊行为。通常, return 语句会导致程序控制权返回到调用位置。但是,对于具有 return 的 try/catch 块的函数, finally 块中的语句将在返回之前首先执行。

Example

在以下示例中,div() 函数有一个“try-catch-finally”构造。没有异常的 try 块返回除法结果。如果发生异常,则 catch 块返回错误消息。但是,无论哪种情况, finally 块中的语句都将首先执行。

<?php
   function div($x, $y) {
      try {
         if ($y==0)
         throw new Exception("Division by 0");
         else
         $res=$x/$y;;
         return $res;
      }
      catch (Exception $e) {
         return $e->getMessage();
      }
      finally {
         echo "This block is always executed\n";
      }
   }
   $x=10;
   $y=0;
   echo div($x,$y);
?>

它将生成以下 output

This block is always executed
Division by 0

PHP - Bugs Debugging

PHP 代码中的故障是指程序中导致意外结果或崩溃的错误。在用户这样做之前寻找错误的过程中的系统方法称为调试。本章给出了在 PHP 代码中跟踪错误的一些重要提示。

程序很少在第一次工作时就正确运行。您的程序中会出现很多问题,导致 PHP 解释器生成错误消息。您可以选择这些错误消息的去向。消息可以连同其他程序输出一起发送到网络浏览器。它们还可以包含在“Web 服务器错误日志”中。

要使错误消息显示在浏览器中,将“display_errors”配置指令设置为 ON。确保在“php.ini”文件中启用了以下设置。

display_errors=On
display_startup_errors=On

您还可以使用 ini_set() function 覆盖“pnp.ini”配置 −

ini_set('display_errors', 1)
ini_set('display_startup_errors', 1)

要将错误发送到 Web 服务器错误日志中,请将“log_errors”设置为 ON。如果您同时想要这两个地方都有错误消息,则可以将两者都设置为 On。

PHP 定义了一些 constants ,可用于设置 error_reporting 的值,以只报告特定类型的错误 −

  1. E_ALL(针对除了严格注释以外的所有错误)

  2. E_PARSE (parse errors)

  3. E_ERROR (fatal errors)

  4. E_WARNING (warnings)

  5. E_NOTICE (notices)

  6. E_STRICT (strict notices)

在编写 PHP 程序时,最好使用 PHP 感知编辑器,例如 BBEdit 或 Emacs。这些编辑器的一个特色功能是语法高亮显示。它会根据程序中不同部分的内容更改这些部分的颜色。例如,字符串为粉色,if 和 while 等关键词为蓝色,注释为灰色,变量为黑色。

Microsoft 的 VS Code 也是编辑 PHP 代码的不错选择。如果您安装 VS Code 扩展 Intelephense,在编辑器窗口中输入 PHP 语句时,将获得类型提示和错误消息。

另一个功能是引号和括号匹配,它有助于确保您的引号和括号处于平衡状态。当您键入“}”之类的闭合定界符时,编辑器将高亮显示它匹配的开“{”。

Points to Check while Debugging a Code

在调试程序代码时,需要验证以下几点 −

Missing Semicolons

每条 PHP 语句都以分号 (;) 结束。PHP 不会停止读取语句,直到它到达分号。如果您在行的末尾省略分号,PHP 将继续在下一行读取该语句。

Not Enough Equal Signs

当您询问比较语句中的两个值是否相等时,您需要两个等号 (==)。使用一个等号是一个常见的错误。

Misspelled Variable Names

如果您拼写错误了一个变量,那么 PHP 将其理解为一个新变量。请记住:对于 PHP 来说,$test 并不是与 $Test 相同的变量。

Missing Dollar Signs

变量名中缺少美元符号确实很难看出来,但至少它通常会导致一条错误消息,以便您知道在哪里查找问题。

Troubling Quotes

引号可能太多、太少或类型错误。因此,检查引号是否数量平衡。

Missing Parentheses and curly brackets

它们应该始终成对出现。

Array Index

PHP 中的数组是一个项的集合,每个项都分配了一个从 0 开始的增量索引。

此外,正确处理所有错误并将所有跟踪消息定向到系统日志文件中,以便在发生任何问题时将其记录到系统日志文件中,这样您就可以调试该问题。

PHP For C Developers

如果您有 C 编程的先验知识,学习 PHP 会变得容易得多,尤其是在基础方面。尽管 PHP 与 C 非常相似,但它捆绑了许多特定于 Web 的库,所有这些库都直接连接到您偏爱的 Web 服务器。

考虑 PHP 的最简单方法是将其视为可以嵌入 HTML 文档中经过解释的 C。PHP 脚本也可以从命令行执行,很像 C 程序。

语句和函数定义的语法应该很熟悉,但变量总是以 $ 作为前缀,函数不需要单独的原型。

让我们看一下 PHP 和 C 中的一些异同 −

Similarities Between C and PHP

与 C 类似,PHP 代码不区分空格,语句以分号终止。

函数调用具有相同的结构

my_function(expression1, expression2) {
   Statements;
}

大括号用于将多个语句放入块中。

PHP 支持 C 和 C++ 样式的注释 (/* */ 和 //),还支持 Perl 和 shell 脚本样式 (#)。

Operators − 赋值运算符 (=, =, *= 等等)、布尔运算符 (&&, ||, !) 、比较运算符 (<,>, ⇐, >=, ==, !=) 以及基本算术运算符(, -, *, /, %)在 PHP 中的行为与 C 中的行为相同。

Control Structures − 基本控制结构 (if, switch, while, for) 的行为如同在 C 中,包括 break 和 continue。一个值得注意的区别是,PHP 中的 switch 可以接受字符串作为 case 标识符。

PHP 还具有 foreach 循环结构,用于遍历诸如数组的集合。

Function Names − 在您浏览文档时,您会看到许多看似与 C 函数相同的函数名称。

Differences Between C and PHP

Dollar Sign − 所有变量名称均以 $ 为前缀。无需在赋值前声明变量,并且它们没有固有类型。PHP 是一种动态类型语言,而 C 是一种静态类型语言。

Types − PHP 只有两种数值类型:整数(对应于 C 中的 long)和 double(对应于 C 中的 double)。在 PHP 中,float 等同于 double。字符串的长度是任意的。PHP 中没有单独的 char 类型,如在 C 中的情况。

Type Conversion − C 是一种强类型语言,因为变量的类型必须在使用前声明,并且在编译时检查类型。而 PHP 是一种弱类型语言,在编译时不检查类型,类型错误通常不会在运行时发生。相反,变量和值会根据需要自动跨类型转换。

Arrays − 数组具有与 C 数组语法表面上相似的语法,但它们的实现方式完全不同。在 C 中,数组是相似数据类型的集合。在 PHP 数组中,项可以是不同类型的。PHP 数组实际上是关联数组或哈希,索引可以是数字或字符串。它们无需预先声明或分配。

No Struct Type − C 中的 struct 关键字用于定义新的数据类型。PHP 中没有 struct 关键字或其等效项,部分原因是数组和对象类型一起使它变得不必要。PHP 数组的元素不必是一致的类型。

No Pointers − 指针是 C 中的一个重要概念。PHP 中没有指针可用,尽管无类型变量扮演着类似的角色。与 C 不同,PHP 支持变量引用。您还可以在某种程度上模拟函数指针,方法是函数名称可以存储在变量中并使用变量而不是文字名称进行调用。

No Prototypes − 无需在定义其实现之前声明函数,只要可在当前代码文件或包含的文件的某个位置找到该定义。相反,C 函数必须在使用之前定义。

No main() − 在 C 程序中,main() 函数是入口点,无论它出现在代码的哪个位置。而 PHP 程序从脚本中的第一个语句开始执行

Memory Management − PHP 引擎实际上是一个垃圾回收环境(引用计数),并且在小型脚本中无需执行任何取消分配。您应该自由分配新结构——例如新的字符串和对象实例。在 PHP5 中,可以为对象定义析构函数,但 C/C++ 中没有 free 或 delete 关键字。在释放内存之前,当对对象的最后一个引用消失时,调用析构函数。

Compilation and Linking − PHP 是解释性语言。因此,不会创建 PHP 脚本的编译版本。C 程序先被编译以获取目标代码,然后链接到必需的库以构建一个可执行文件。PHP 脚本没有单独的编译步骤。PHP 脚本无法变成自执行文件。

Permissiveness − 总的来说,PHP 比 C 更宽容(尤其是在其类型系统中),因此它会让您摆脱新的错误类型。意外结果比错误更常见。

PHP For PERL Developers

PERL 是一种动态类型、高级且通用的编程语言。通常认为 PERL 是实用抽取和报告语言的缩写。而 PHP 也是一种通用脚本语言。最初 PHP 曾是“个人主页”的缩写,但如今它已被公认为一个递归缩写“PHP:超文本预处理器”。

本章节概述了 PHP 与 Perl 之间的主要相似性和差异。这将帮助 Perl 开发人员非常快速地了解 PHP 并避免常见错误。

Similarities between PERL and PHP

Perl 和 PHP 均为脚本语言。它们不用于提前在执行之前构建本机独立可执行文件。

早期的 PHP 版本受到 Perl 的启发。PHP 的基本语法与 Perl 非常相似。两者都与 C 共享许多语法特性。它们的代码对空白不敏感,每条语句都以分号结尾。

PHP 和 Perl 都使用大括号将多个语句组织成一个单一代码块。函数调用以函数名开头,后跟用括号括起来并用逗号分隔的实际参数,在两种情况下都一样。

  1. PHP 中的所有变量看起来都像 Perl 中的标量变量:一个带有美元符号 ($) 前缀的名称。

  2. 由于这两种语言都是动态类型的,因此你无需在使用 PHP 和 Perl 变量之前声明其类型。

  3. 在 PHP 中,和 Perl 一样,变量除了当前持有的值之外没有固有类型。你可以在同一类型变量中存储数字或字符串。

  4. PHP 和 Perl 对双引号字符串("string")的解释比单引号字符串('string')更多。

Differences between PERL and PHP

PHP 可以嵌入 HTML 中。虽然可以从命令行运行 PHP 脚本,但它更常用作 Web 服务器上的服务器端脚本语言,并用于生成网页。

如果你习惯了用 Perl 编写 CGI 脚本,则 PHP 中的主要区别在于你不再需要使用 print 或 heredoc 语句显式打印大块静态 HTML,而只需在 PHP 代码块之外编写 HTML 本身。

No @ or % variables − PHP 仅有一种变量,它以美元符号 ($) 开头。该语言中的任何数据类型都可以存储在(标量或复合)这些变量中。在 Perl 中,数组变量以 @ 符号为前缀。此外,哈希变量以 % 符号为前缀。

与 Perl 不同,PHP 有一种称为数组的单一数据类型,该类型可以是 indexed arrayassociative array ,与 hash in PERL 类似。

Function calls in PHP 看起来很像 subroutine calls in PERL 。另一方面,PHP 中的函数定义通常需要某种形式的正式参数列表,就像 C 或 Java 中一样,这与 Perl 不同。

Perl 中的 Scope of variables 默认情况下是全局的。这意味着顶级变量在子例程中是可见的。通常,这会导致在函数中滥用全局变量。在 PHP 中,函数定义中变量的范围默认情况下是局部的。

PHP 中的 No module system 亦是如此。在 PHP 中,普通代码文件与用作导入库的代码文件之间没有真正区别。

Break and continue 而不是 next and last − PHP 更像是 C 语言,并且使用 break 和 continue,而不是像 Perl 中的 next 和 last 语句。

No elsif − 一个次要拼写差异:Perl 的 elsif 是 PHP 的 elseif。

除了 Perl 样式 (#) single-line comments 之外,PHP 还提供 C 样式 multiline comments (/* comment */)和 Java 样式单行注释(// comment)。

Regular expressions − PHP 没有针对正则表达式特定于内置语法,但在其“Perl 兼容”正则表达式函数中具有相同的大部分功能。

PHP – Frameworks

PHP生态系统中有很多Web框架。一些流行的PHP Web框架包括Laravel、Yii、CakePHP 等。尽管可以通过核心PHP构建Web应用程序,但开发人员越来越倾向于使用Web框架来快速开发应用程序。

What are Software Frameworks?

在计算机编程中, software framework 是库和类的集合,它提供了通用的功能,使开发人员能够更多地专注于应用程序逻辑,而不是为例行程序但繁琐的低级流程编写代码。

框架提供了一个可重复使用的软件环境,该环境能快速构建一个最小的工作模板应用程序。然后,开发人员可以修改这些模块以获得额外功能。

每个框架都是为了帮助开发者构建一定类型应用程序而构建的。例如, web frameworks (有时也被称为“Web应用程序框架”)用于开发包括Web服务、Web资源和Web API在内的Web应用程序。

在本章中,我们简要概述了其中一些流行的PHP frmeworks。

FuelPHP

FuelPHP ( https://fuelphp.com/ ) 基于模型视图控制器,并拥有创新插件。FuelPHP 支持基于路由的理论,您可以在其中直接路由到较近的输入uri,使闭包成为控制器并使其控制进一步执行。

php frameworks 1

CakePHP

CakePHP ( https://cakephp.org/ ) 是以简单的方式构建简单而强大的Web应用程序的极好来源。PHP中内置的一些强大功能包括输入验证、SQL注入预防,它们可以使您的应用程序保持安全。

php frameworks 2

FlightPHP

FlightPHP ( https://flightphp.com/ ) 对于创建RESTful Web服务非常有帮助,并且它在MIT许可证下。

php frameworks 3

Symfony

Symfony适用于专业开发人员,他们可以利用PHP组件(如Drupal、PHPBB、laravel、eX、OROCRM和piwik)来构建网站。

php frameworks 4

yiiFramework

YiiFramework ( https://www.yiiframework.com/ ) 基于具有高端安全性的Web 2.0。它包括输入验证、输出过滤和SQL注入。

php frameworks 5

Laravel

Laravel ( https://laravel.com/ ) 最适用于RESRful路由和轻量级blading引擎。Laravel已与某些经过良好测试且可靠的代码模块集成在一起。

php frameworks 6

Zend

Zend ( https://framework.zend.com/ ) 是一个现代框架,用于执行高端Web应用程序。它基于加密和安全编码工具工作。Zend Framework是专业PHP包的集合,安装量超过5.7亿次。

它可用于使用PHP 5.6+开发Web应用程序和服务,并使用广泛的语言功能提供100%面向对象代码。

php frameworks 7

Codeigniter

对于需要简单而优雅的工具包来创建创新的Web应用程序的开发人员来说,Codeigniter可以轻松开发较小的占用空间。

php frameworks 8

Phalcon PHP

Pholcon ( https://phalcon.io/en-us ) 是一个基于MVC并与创新架构集成以提高执行速度的PHP框架。

php frameworks 9

PHPixie

PHPixie ( https://phpixie.com/ ) 基于MVC,专为快速和可靠地开发网站而设计。

php frameworks 10

Agavi

Agavi是一个强大且可扩展的PHP5应用程序框架,遵循MVC模型。Agavi可以帮助PHP开发人员编写简洁且可维护的代码。

Core PHP vs Frameworks

PHP是目前最流行的用于Web应用程序开发的服务器端编程语言,近75%的网站使用PHP(以其核心形式或可用的各种PHP框架之一)构建。为了在使用“核心PHP”或框架进行Web开发之间做出选择,我们需要了解两者之间的优缺点。

简单来说,用核心PHP开发Web应用程序就像通过在纸上写下每个步骤来手动解决数学问题一样。另一方面,使用框架类似于使用计算器等工具来解决问题。正如计算器一样,框架是用于快速开发应用程序的有用工具。

Core PHP vs Frameworks – Pros and Cons

Web 框架(尤其是 PHP 框架)是一组一个或多个 PHP 库和类。它提供通用功能,从而允许开发人员更加专注于应用程序逻辑,而不是编写草稿代码。它提供可重用的软件环境,可以快速构建一个最小的工作模板应用程序。

纯粹使用核心 PHP 开发 Web 应用程序具有自己的优点和缺点−

  1. 它为开发人员提供了更好的控制和灵活性。

  2. 同时,对于一个仅使用核心 PHP 开发的大型应用程序可能会变得难以管理和维护。

现在,让我们来看看使用 PHP 框架的优缺点−

  1. Symfony、Laravel 或 Yii 等 PHP 框架提供了一种更加标准化的 Web 应用程序开发方式。由于框架处理了大部分例行且重复的部分,因此开发人员可以更加专注于应用程序逻辑。因此,花在调试上的时间减少了。

  2. 另一方面,与核心 PHP 相比,该框架不那么灵活。应用程序的框架模板已随时可用,而开发人员只能在框架定义的范围内自定义功能。

The MVC Architecture

大多数 Web 应用程序框架使用 MVC (模型、视图和控制器) architecture ,这通过将逻辑与样式分离,极大程度地简化了编写高质量、强大的代码。

php core php vs frameworks

如果您希望为应用程序开发使用核心 PHP 特性,您可以在对象导向方法或模块化方法中自由选择,这取决于哪种方法更适合您。

Built-in Security Measures

PHP 框架提供 built-in security measures 以纳入 Web 应用程序中。

  1. 如果您选择使用核心 PHP 来开发应用程序,则必须明确提供安全措施。

  2. 然而,大多数框架都有一些外部依赖性,与作为一个独立的解决方案的核心 PHP 应用程序相比,这可能会使应用程序相当容易受到攻击。

框架基于应用程序 may be a little slow 在性能方面,与核心 PHP 应用程序相比,特别是对于较小的应用程序。

Comparison: Core PHP vs Frameworks

两者的比较可以总结如下−

  1. 对于较小的应用程序,核心 PHP 比框架更合适。

  2. 框架提供快速开发和代码重用。

  3. Frameworks are less flexible.

  4. 使用核心 PHP 特性,开发人员拥有完全的控制权。

  5. 对于大型应用程序,MVC 体系结构是有帮助的。

  6. 框架提供集成的授权和身份验证支持。在核心 PHP 应用程序中,需要明确定义安全规则。

PHP – Design Patterns

在软件工程理论中,“设计模式”一词通常是指可重复使用的解决方案,该解决方案可用作模板,以便开发应用来解决常见问题。你可以将软件设计模式视为开发软件解决方案时的正规最佳实践。

大多数标准设计模式在使用 PHP 开发应用时可以非常有效地实现。在本章中,我们将了解如何在开发 PHP 应用时应用一些流行设计模式。

Singleton Pattern

当你希望将某个类的对象实例化限制为仅一个实例时,单例设计模式很有用。名称“单例模式”源自数学中的单例概念。单例模式确保只有一个实例,在整个应用中可以全局访问它。

单例模式的典型应用是创建数据库连接对象,该对象必须在应用的生命周期中创建一次。

Example

在以下代码中,DataBaseConnector 类只能实例化一次,否则将发出不允许重复对象的消息。

<?php
   class DataBaseConnector {
      private static $obj;
      private final function __construct() {
         echo __CLASS__ . " object created for first time ". PHP_EOL;
      }
      public static function getConnect() {
         if (!isset(self::$obj)) {
            self::$obj = new DataBaseConnector();
            return self::$obj;
         } else {
            echo "connection object could not be created again" . PHP_EOL;
         }
      }
   }

   $obj1 = DataBaseConnector::getConnect();
   $obj2 = DataBaseConnector::getConnect();

   var_dump($obj1 == $obj2);
?>

它将生成如下输出:

DataBaseConnector object created for first time
connection object could not be created again
bool(false)

Factory Pattern

这是最常用的设计模式之一。在此模式中,你并不直接声明所需类的对象,而是提供了另一个类,其静态方法创建所需对象。

Example

以下示例演示了工厂设计模式的工作原理 −

<?php
   class Automobile {
      private $bikeMake;
      private $bikeModel;

      public function __construct($make, $model) {
         $this->bikeMake = $make;
         $this->bikeModel = $model;
      }

      public function getMakeAndModel() {
         return $this->bikeMake . ' ' . $this->bikeModel;
      }
   }

   class AutomobileFactory {
      public static function create($make, $model) {
         return new Automobile($make, $model);
      }
   }

   $pulsar = AutomobileFactory::create('ktm', 'Pulsar');
   print_r($pulsar->getMakeAndModel());
?>

它将生成如下输出:

ktm Pulsar

Strategy Pattern

策略模式推荐使用以下方法:封装特定的算法族,允许负责实例化特定算法的客户端类。实现该模式的类不了解实际的实现。

Example

以下代码演示了策略模式的使用。我们有一个接口,其 case() 方法由两个不同的类以不同的方式实现。testdata 类的对象通过自己的 process() 方法间接调用各自的 case() 方法。

<?php
   interface example {
      public function case($str);
   }

   class ucase implements example {
      public function case($str) {
         return strtoupper($str);
      }
   }

   class lcase implements example {
      public function case($str) {
         return strtolower($str);
      }
   }

   class testdata {
      private $data;

      public function __construct($input) {
         $this->data = $input;
      }
      public function process(example $type) {
         return $this->data = $type->case($this->data);
      }
   }
   $str = "hello";
   $obj = new testdata($str);
   echo $obj->process(new ucase) . PHP_EOL;
   $str = "HELLO";
   echo $obj->process(new lcase);
?>

它将生成以下 output

HELLO
Hello

MVC Design Pattern

MVC(代表模型、视图和控制器)是一种非常流行的软件架构模式。大多数 PHP 网络(例如 Laravel、Symfony 等)都实现了 MVC 架构。

应用中每个层的角色分离如下 −

  1. Model − 指数据结构。在本例中指数据库。

  2. View − 指用户界面。指 HTML 和 CSS。

  3. Controller − 执行处理的“中间件”。接受来自视图的输入,并使用模型。不言而喻,指 PHP 脚本和库本身。

视图充当 GUI,模型充当后端,而控制器则充当适配器。在这里,三个部分相互连接。它会传递数据并在彼此之间访问数据。

Example

让我们在以下示例中用纯 PHP、JavaScript 和 HTML 实现 MVC 设计模式 −

应用的表示层是 view.php,它呈现 HTML 表单。用户将数据提交给控制器脚本。控制器返回的结果使用一些 JavaScript 在网页上呈现。

<!DOCTYPE html>
<html>
<head>
   <title>View (User Interface)</title>
   <link rel="stylesheet" href="style.css">
</head>
<body>
   <form id="mysearch" action="controller.php" method="POST">
      <input type="text" id = "nm" name="search" required>
      <input type="submit" value="Search">
   </form>
   <div id="results"></div>
   <script>
      let results = document.getElementById("results");
      results.innerHTML = "";
   </script>
   <?php
      session_start();
      if (isset($_SESSION['result'])) {
         $arr=$_SESSION['result'];

         foreach ($arr as $obj) {?>
            <script>
               results.innerHTML += "<div><?php echo $obj['id'] . "-" .
			      $obj['name'] . "</div>"; ?>";
            </script>
            <?php
         }
      }
   ?>
</body>
</html>

控制器脚本需要 model.php,并使用数据库对象,调用 select 方法从数据库中获取数据。结果存储在当前会话中,以便在视图页面上访问它。

<?php
   session_start();
   require "model.php";
   $results = $_DB->select(
      "SELECT * FROM `users` WHERE `name` LIKE ?",
      ["%{$_POST["search"]}%"]
   );
   $_SESSION['search'] = $_POST['search'];
   $_SESSION['result'] = $results;
   Header("Location: view.php", true);
?>

应用的模型层在“model.php”中编码。它使用 PDO 扩展与名为 mydb 的 mysql 数据库建立连接。

<?php
   class DB {
      public $error = "";
      private $pdo = null;
      private $stmt = null;
      var $dsn="localhost";
      var $dbName="myDB";
      var $username="root";
      var $password="";
      function __construct () {
         $this->pdo = new PDO("mysql:host=$this->dsn;dbname=$this->
		    dbName",$this->username,$this->password);
      }
      function __destruct () {
         if ($this->stmt!==null) { $this->stmt = null; }
         if ($this->pdo!==null) { $this->pdo = null; }
      }
      function select ($sql, $data=null) {
         $this->stmt = $this->pdo->prepare($sql);
         $this->stmt->execute($data);
         return $this->stmt->fetchAll();
      }
   }
   $_DB = new DB();
?>

后端 mydb 数据库必须有一个包含 ID 和 NAME 字段的 users 表。

-- Table structure for table `users`
--
CREATE TABLE `users` (
   `id` bigint(20) NOT NULL,
   `name` varchar(255) NOT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci;

--
-- Dumping data for table `users`
--
INSERT INTO `users` (`id`, `name`) VALUES
(21, 'Ahmad Shaikh'),
(24, 'Akshay Wadkar'),
(26, 'Bridget Wooten'),
(10, 'Coby Kelleigh'),
(20, 'Dashan Shah'),
(12, 'Elizabeth Taylor'),
(41, 'Issac Newton'),
(34, 'Julia Roberts'),
(31, 'Junior Mahmood'),
(32, 'Kailas Bende'),
(47, 'Karan Sharma'),
(16, 'Kenneth Sanders'),
(28, 'Kirstie Thomas'),
(33, 'Lawrence Murphy'),
(14, 'Leah Shan'),
(51, 'Marcus Best'),
(29, 'Maya Pande'),
(50, 'Nathaniel Khan'),
(6, 'Richard Breann'),
(54, 'Rowan Avalos'),
(3, 'Rusty Terry'),
(37, 'Sacha Gross'),
(27, 'Sally Castillo'),
(11, 'Sarah Sanders'),
(18, 'Seth Sonnel'),
(38, 'Shannon Peterson'),
(25, 'Shayan Clements'),
(49, 'Shoaib Vickers'),
(43, 'Simran Kaur'),
(35, 'Sulaiman Gilmour'),
(44, 'Taran Morin'),
(48, 'Taran Morin'),
(22, 'Thelma Kim'),
(8, 'Tillie Sharalyn'),
(36, 'Virgil Collier');

在浏览器中访问 "http://localhost/view.php" 以启动应用程序。输入与包含必需字母的名称相对应的搜索词。

php design patterns

PHP – Filters

重要的是,在 PHP 应用程序中处理之前,验证以客户端请求的形式接收的输入数据。为了执行输入验证,PHP 中的 filter 扩展程序提供了一些 filter 函数,并由预定义的 filter 常量和标志支持。PHP 库的 filter 扩展程序还有助于通过 GET 或 POST 方法净化接收的输入。

filter 扩展程序是一项强大的功能,有助于防止安全漏洞,例如 SQL 注入和跨站脚本攻击。扩展程序有两种类型的过滤器 −

Validation Filters

验证过滤器检查数据是否符合某些标准。例如,您想确保用户正确地输入了 HTML 表单中的电子邮件字段。FILTER_VALIDATE_EMAIL 将确定数据是否有效的电子邮件地址。但是,验证过滤器不会更改数据本身。

Sanitization Filters

清理是指从输入中删除不需要的字符的过程。因此,它可以通过删除不需要的字符来更改数据。例如,传入 FILTER_SANITIZE_EMAIL 将删除不适合包含在电子邮件地址中的字符,而不会执行验证。

Filter Flags

PHP 中的 filter 扩展程序定义了许多 filter flags 如下所示 −

Sr.No

ID & Description

1

FILTER_FLAG_STRIP_LOW 移除数值 <32 的字符。

2

FILTER_FLAG_STRIP_HIGH 移除数值 >127 的字符。

3

FILTER_FLAG_STRIP_BACKTICK Strips backtick characters.

4

FILTER_FLAG_ALLOW_FRACTION 允许数字中使用句点 (.) 作为小数分隔符。

5

FILTER_FLAG_ALLOW_THOUSAND 允许数字中使用逗号 (,) 作为千分位分隔符。

6

FILTER_FLAG_ALLOW_SCIENTIFIC 允许在数字中使用 e 或 E 表示科学记数法。

7

FILTER_FLAG_NO_ENCODE_QUOTES 如果存在此标志,则单引号 (') 和双引号 (") 将不会被编码。

8

FILTER_FLAG_ENCODE_LOW 编码数值 <32 的所有字符。

9

FILTER_FLAG_ENCODE_HIGH 编码数值 >127 的所有字符。

10

FILTER_FLAG_ENCODE_AMP Encodes ampersands (&).

11

FILTER_NULL_ON_FAILURE 对于无法识别的值,返回 null

12

FILTER_FLAG_ALLOW_OCTAL 将以零 (0) 开头的输入视为八进制数。

13

FILTER_FLAG_ALLOW_HEX 将以 0x 或 0X 开头的输入视为十六进制数。

14

FILTER_FLAG_EMAIL_UNICODE 允许电子邮件地址的本地部分包含 Unicode 字符。

15

FILTER_FLAG_IPV4 允许 IP 地址采用 IPv4 格式。

16

FILTER_FLAG_IPV6 允许 IP 地址采用 IPv6 格式。

17

FILTER_FLAG_NO_PRIV_RANGE 验证以下专用 IPv4 范围时失败:10.0.0.0/8、172.16.0.0/12 和 192.168.0.0/16。

18

FILTER_FLAG_NO_RES_RANGE 验证以下保留 IPv4 范围时失败:0.0.0.0/8、169.254.0.0/16、127.0.0.0/8 和 240.0.0.0/4 验证以下保留 IPv6 范围时失败:::1/128、::/128、::ffff:0:0/96 和 fe80::/10。

19

FILTER_FLAG_GLOBAL_RANGE 验证非全局 IPv4/IPv6 范围时失败

20

FILTER_FLAG_SCHEME_REQUIRED 要求 URL 包含方案部分。

21

FILTER_FLAG_HOST_REQUIRED 要求 URL 包含主机部分。

22

FILTER_FLAG_PATH_REQUIRED 要求 URL 包含路径部分。

23

FILTER_FLAG_QUERY_REQUIRED 要求 URL 包含查询字符串。

24

FILTER_REQUIRE_SCALAR 要求该值是标量类型。

25

FILTER_REQUIRE_ARRAY 要求该值是数组。

26

FILTER_FORCE_ARRAY 如果该值是标量类型,则它将被视为数组,其标量值作为唯一的元素。

Filter Functions

过滤器扩展包括以下内容: filter functions

Sr.No

ID & Description

1

filter_has_var() 检查是否存在指定类型的变量

2

filter_id() 返回属于命名过滤器的过滤器 ID

3

filter_input_array() 获取外部变量并可以选择对其进行筛选

4

filter_input () 按名称获取特定外部变量并对其进行筛选

5

filter_list() 返回所有受支持过滤器列表

6

filter_var_array() 获取多个变量并可以选择对其进行筛选

7

filter_var() 使用指定过滤器筛选变量

Predefined Constants

以上函数使用一个名为 input_type 的参数,它是用来表示向 PHP 脚本提供输入用于筛选目的的预定义枚举常量之一。

Constant

Types

INPUT_POST (int)

POST Variables

INPUT_GET (int)

GET Variables

INPUT_COOKIE (int)

COOKIE Variables

INPUT_ENV (int)

ENV Variables

INPUT_SERVER (int)

SERVER Variables

INPUT_SESSION (int)

SESSION Variables

INPUT_REQUEST (int)

REQUEST Variables

filter_has_var() function

filter_has_var() 函数检查指定类型变量是否存在。

filter_has_var(int $input_type, string $var_name): bool

input_type 是预定义常量之一,如 INPUT_GET、INPUT_POST、INPUT_COOKIE、INPUT_SERVER 或 INPUT_ENV;var_name 参数是用于检查的变量名称。该函数在成功时返回 true,失败时返回 false。

Example

访问 XAMPP 服务器上的以下 PHP 脚本。

<?php
   if (!filter_has_var(INPUT_GET, "email")) {
      echo("Email not found");
   } else {
      echo("Email found");
   }
?>

它将生成以下 output

Email found

filter_input() function

filter_input() 函数通过名称获取特定外部变量并根据应用的过滤器常量过滤它

filter_input(
   int $type,
   string $var_name,
   int $filter = FILTER_DEFAULT,
   array|int $options = 0
): mixed

type 参数是常量之一,如 INPUT_GET、INPUT_POST、INPUT_COOKIE、INPUT_SERVER 或 INPUT_ENV。第二个参数是 var_name,这是用于获取的变量名称。你可以使用要应用的过滤器。使用任何预定义筛选标志。如果省略,则使用 FILTER_DEFAULT

该函数在成功时返回所请求变量的值,如果过滤器失败则返回 false,如果未设置 var_name 变量则返回 null。

Example

请看以下示例:

<?php
   if (!filter_input(INPUT_GET, "email", FILTER_VALIDATE_EMAIL)) {
      echo("Email is not valid");
   } else {
      echo("Email is valid");
   }
?>

它将生成以下 output

Email is valid
Email is not valid

你还可以针对通过 POST 方法接收的输入使用 INPUT_POST 类型 −

<?php
   if (!filter_input(INPUT_POST, "email", FILTER_VALIDATE_EMAIL)) {
      echo("Email is not valid");
   } else {
      echo("Email is valid");
   }
?>

要使用 POST 请求传递数据,打开命令提示符,并使用以下 CURL 命令

curl -X POST -d "{\"email\": \"a@b.com\"}" http://localhost/hello.php

filter_list() function

filter_list() 函数返回所有受支持的过滤器的列表

filter_list(): array

Example

该函数返回所有受支持的过滤器的名称数组,如果没有这样的过滤器,则返回空数组。

<?php
   print_r(filter_list());
?>

它将生成以下 output

Array
(
   [0] => int
   [1] => boolean
   [2] => float
   [3] => validate_regexp
   [4] => validate_domain
   [5] => validate_url
   [6] => validate_email
   [7] => validate_ip
   [8] => validate_mac
   [9] => string
   [10] => stripped
   [11] => encoded
   [12] => special_chars
   [13] => full_special_chars
   [14] => unsafe_raw
   [15] => email
   [16] => url
   [17] => number_int
   [18] => number_float
   [19] => add_slashes
   [20] => callback
)

filter_input_array() function

filter_input_array() 获取外部变量,并可选地对其进行筛选。

filter_input_array(int $type, array|int $options = FILTER_DEFAULT,
   bool $add_empty = true): array|false|null

此函数用于在不重复调用 filter_input() 的情况下检索多个值。

type 参数是 INPUT_GET、INPUT_POST、INPUT_COOKIE、INPUT_SERVER 或 INPUT_ENV 之一。

options 参数是用于定义参数的数组。有效键是包含变量名称的字符串,有效值是过滤器类型或选择性指定过滤器、标志和选项的数组。此参数也可以是用于保存过滤器常量的整数。然后输入数组中的所有值都将通过该过滤器进行筛选。

此函数在成功时返回一个包含请求变量值数组。如果由 type 指定的输入数组未填充,则在未给出 FILTER_NULL_ON_FAILURE 标志的情况下函数返回 null,否则返回 false。对于其他失败,则返回 false。

Example

要在 HTTP 请求中包含数组,我们在“hello.html”中使用以下 HTML 表单,并通过 POST 方法发送。

<!DOCTYPE html>
<html>
<body>
   <h1>Filter Input Array</h1>
   <form action="hello.php" method="POST">
      <p><label for="email">Enter your email:</label>
      <input type="text" id="email" name="email"></p>
      <p><label for="age">Enter your age<label>
      <input type = "text" id="age" name="age"></p>
      <input type="submit">
   </form>
</body>
</html>

验证输入数组的 PHP 脚本如下所示 −

<?php
   $filters = array (
      "age" => array ("filter"=>FILTER_VALIDATE_INT,
         "options"=>array("min_range"=>20,"max_range"=>40) ),
      "email" => FILTER_VALIDATE_EMAIL
   );
   print_r(filter_input_array(INPUT_POST, $filters));
?>

打开 HTML 表单,并将年龄填为 30, * abc@example.com* 作为电子邮件,结果将是一个数组,验证这两个输入 −

Array ( [age] => 30 [email] => abc@example.com )

尝试给出无效的输入,如“age=15”。输出数组将显示 age 密钥的 null 值

Array ( [age] => [email] => abc@example.com )

PHP – JSON

PHP 的标准发行版默认启用 JSON 支持。PHP 扩展实现 JavaScript 对象表示法 (JSON) 数据交换格式。PHP 解析器中的 JSON 扩展处理 JSON 数据。

JSON(JavaScript 对象表示法)是一种轻量级、基于文本、与语言无关的数据交换格式。JSON 为便携式表示结构化数据定义了一组较小的格式化规则。它是一种基于文本的数据格式,对于人类和机器来说都很容易读取。

PHP 版本 5.2 及更高版本中的 JSON 扩展提供了许多预定义的常量、JSON 相关函数以及 JsonException 类。

PHP JSON Functions

PHP 具有以下 JSON 函数 −

json_encode()

此函数返回一个字符串,其中包含所提供值的 JSON 表示形式。如果参数是数组或对象,则会递归序列化。

json_encode(mixed $value, int $flags = 0, int $depth = 512): string|false

json_decode()

此函数采用 JSON 编码的字符串,并将其转换为 PHP 值。

json_decode(
   string $json,
   ?bool $associative = null,
   int $depth = 512,
   int $flags = 0
): mixed

当此函数的关联参数为 true 时,JSON 对象将作为关联数组返回;当为 false 时,JSON 对象将作为对象返回。

编码/解码操作受所提供标志的影响。预定义常量及其整数值如下 −

Predefined Constant

Values

JSON_HEX_TAG

1

JSON_HEX_AMP

2

JSON_HEX_APOS

4

JSON_HEX_QUOT

8

JSON_FORCE_OBJECT

16

JSON_NUMERIC_CHECK

32

JSON_UNESCAPED_SLASHES

64

JSON_PRETTY_PRINT

128

JSON_UNESCAPED_UNICODE

256

json_last_error_msg()

此函数返回最近 json_encode() 或 json_decode() 调用的错误字符串。

json_last_error_msg(): string

如果没有发生错误,则返回“No error”消息。

json_last_error()

此函数返回一个整数。

json_last_error(): int

该函数返回一个整数,对应于以下常量之一 −

Sr.No

Constant & Meaning

1

JSON_ERROR_NONE No error has occurred

2

JSON_ERROR_DEPTH 已超过最大栈深度

3

JSON_ERROR_STATE_MISMATCH Invalid or malformed JSON

4

JSON_ERROR_CTRL_CHAR 控制字符错误,可能编码不正确

5

JSON_ERROR_SYNTAX Syntax error

6

JSON_ERROR_UTF8 错误格式的 UTF-8 字符,可能编码不正确

7

JSON_ERROR_RECURSION 要进行编码的值中存在一个或多个递归引用

8

JSON_ERROR_INF_OR_NAN 要进行编码的值中存在一个或多个 NANINF

9

*JSON_ERROR_UNSUPPORTED_TYPE*给出不能被编码的类型的值

10

JSON_ERROR_INVALID_PROPERTY_NAME 给出不能被编码的属性名

11

JSON_ERROR_UTF16 格式错误的 UTF-16 个字符,可能编码不正确

Example

以下 PHP 代码将给定的数组编码为 JSON 表示,并将 JSON 字符串解码回 PHP 数组。

<?php
   $arr = array('a' => 1, 'b' => 2, 'c' => 3, 'd' => 4, 'e' => 5);
   $encoded = json_encode($arr);
   echo "The initial array: " . PHP_EOL;
   var_dump($arr);
   echo "Encoded JSON: $encoded" . PHP_EOL;

   $decoded = json_decode($encoded);
   echo "Array obtained after decoding: " . PHP_EOL;
   var_dump($decoded);
?>

它将生成以下 output

The initial array:
array(5) {
   ["a"]=>
   int(1)
   ["b"]=>
   int(2)
   ["c"]=>
   int(3)
   ["d"]=>
   int(4)
   ["e"]=>
   int(5)
}
Encoded JSON: {"a":1,"b":2,"c":3,"d":4,"e":5}
Array obtained after decoding:
object(stdClass)#1 (5) {
   ["a"]=>
   int(1)
   ["b"]=>
   int(2)
   ["c"]=>
   int(3)
   ["d"]=>
   int(4)
   ["e"]=>
   int(5)
}

PHP – Exceptions

在 7 之前的版本中,PHP 解析器在响应各种条件时曾经报告错误。每个错误曾经都是一个预定义类型。PHP7 已经更改了错误报告的机制。与传统的错误报告不同,现在大多数错误都是通过抛出错误异常来报告的。

PHP 中的异常处理机制与许多其他语言类似,并且使用 try, catch, throwfinally 关键字实现。

The Throwable Interface

PHP 中的异常实现了 Throwable interface 。Throwable 接口充当任何可通过 throw 语句引发对象的基类,包括 Error 和 Exception 对象。

用户定义的类不能直接实现 Throwable 接口。相反,要声明一个用户定义的异常类,必须扩展 Exception class

带有潜在异常的 PHP 代码被 try 块包围。如果找到异常对象,则抛出该对象,以方便捕获潜在的异常。每个 try 必须至少有一个对应的 catchfinally 块。此外,对应于 try 块可能有多个 catch/finally 块。

try {

   // throw errors in the try-block
   // if an error occurs we can throw an exception
   throw new Exception('this is an error.');
}
catch(Exception $e) {

   // catch the throws in the catch-block
   // do something with the exception object, eg.
   // display its message
   echo 'Error message: ' .$e->getMessage();
}

如果抛出了异常并且没有 catch 块,那么异常会“冒泡”出现,直到找到一个匹配的 catch 块。如果调用堆栈一直向下绕回到全局范围而没有遇到一个匹配的 catch 块,那么将调用一个全局异常处理程序(如果已设置),否则程序将以一个致命错误终止。

set_exception_handler

如果异常没有在 try/catch 块中被捕获,则此函数将设置默认异常处理程序。在回调函数执行之后,程序执行将停止。

set_exception_handler(?callable $callback): ?callable

当一个未捕获的异常发生时,$callback 参数是要被调用的函数的名称。在调用 set_exception_handler() 之前必须定义此函数。此处理程序函数需要接受一个参数,该参数将是抛出的异常对象。

此函数将返回以前定义的异常处理程序的名称,或者在出错时返回 NULL。如果之前没有定义处理程序,那么也将返回 NULL。

Example

请看以下示例:

<?php
   function handler($ex) {
      echo "Uncaught exception is : " , $ex->getMessage(), "\n";
   }

   set_exception_handler('handler');
   throw new Exception('Not Found Exception');
   echo "not included Executed\n";
?>

它将生成以下 output

Uncaught exception is : Not Found Exception

SPL Exceptions

标准 PHP 库包含预定义的异常 −

Sr.No

Predefined Exceptions

1

LogicException 表示程序逻辑中错误的异常。

2

BadFunctionCallException 如果回调函数引用了一个未定义的函数或者缺少一些参数则抛出的异常。

3

BadMethodCallException 如果回调函数引用了一个未定义的方法或者缺少一些参数则抛出的异常。

4

DomainException 如果一个值不遵守一个定义的有效数据域则抛出的异常。

5

InvalidArgumentException 如果一个参数不是期望的类型而抛出的异常。

6

LengthException 如果长度无效则抛出的异常。

7

OutOfRangeException 如果请求了一个非法索引则抛出的异常。

8

RuntimeException 如果出现了一个只可在运行时发现的错误而抛出的异常。

9

OutOfBoundsException 如果一个值不是一个有效键值则抛出的异常。

10

OverflowException 当向一个完整的容器中添加元素时抛出的异常。

11

RangeException 在程序执行期间向外抛出异常,用于指示范围错误。非上下溢出式的算术错误。

12

UnderflowException 当对空容器执行无效操作时向外抛出异常,例如,移除元素时。

13

如果值与一组值不符时,将会抛出异常。

User-defined Exception

你可以定义一个扩展了基本 Exception 类的自定义异常类。下面的脚本定义了一个称为 myException 的自定义异常类。如果 $num 的值小于 0 或者大于 100,则会抛出此类型的异常。

Example

Exception 类的 getMessage() 方法返回错误消息,而 getLine() 方法返回出现异常的代码行。

<?php
   class myException extends Exception {
      function message() {
         return "error : ". $this->getMessage(). "in line no". $this->getLine();
      }
   }
   $num=125;
   try {
      if ($num>100 || $num<0)
      throw new myException("$num is invalid number");
      else
      echo "$num is a valid number";
   }
   catch (myException $m) {
      echo $m->message();
   }
?>

使用 $num=125$num=90 运行上述代码,可获得一条错误消息和一条有效的数字消息 −

error : 125 is invalid number in line no 10

PHP – Special Types

PHP 的两种数据类型 resourceNULL - 被归类为 special types 。资源类型的对象是指外部资源,例如数据库连接、文件流等。另一方面,NULL 数据类型是一个未分配任何数据的变量。在本章中,我们将详细了解这些类型。

Resource Type

PHP 程序经常需要与外部环境交互,例如数据库或磁盘文件等。这些在 PHP 中被视为资源。资源是一种特殊的数据类型,它指向任何此类外部资源。PHP 使用相关函数来创建这些资源。例如,fopen() 函数会打开一个磁盘文件,并将其引用存储在资源变量中。

PHP 的 Zend 引擎使用引用计数系统。因此,垃圾回收器会自动销毁引用计数为零的资源,并且无需手动释放资源数据类型所使用的内存。

不同的 PHP 内置函数返回各自的资源变量。随后,PHP 使用它们与相应的外部环境进行交互。例如,fopen() 函数返回一个文件资源,该资源用作文件句柄,并且通过此资源变量来促进对文件的读/写操作。

下表总结了返回资源变量的不同函数 −

Resource Type

Built-in functions

Definition

Produced

Sold

bzip2

bzopen()

bzclose()

Bzip2 file

curl

curl_init()

curl_close()

Curl session

ftp

ftp_connect(),

ftp_close()

FTP stream

mssql link

mssql_connect()

mssql_close()

链接到 Microsoft SQL Server 数据库

mysql link

mysql_connect()

mysql_close()

Link to MySQL database

mysql result

mysql_db_query(),

mysql_free_result()

MySQL result

oci8 connection

oci_connect()

oci_close()

Connection to Oracle Database

ODBC link

odbc_connect()

odbc_close()

Link to ODBC database

pdf document

pdf_new()

pdf_close()

PDF document

stream

opendir()

closedir()

Dir handle

stream

fopen(), tmpfile()

fclose()

File handle

socket

socket_create()

Socket_close()

Socket handle

xml

xml_parser_create()

xml_parser_free()

XML parser

zlib

gzopen()

gzclose()

gz-compressed file

zlib.deflate

deflate_init()

None()

incremental deflate context

zlib.inflate

inflate_init()

None()

incremental inflate context

PHP 具有 get_resource_type() 函数,该函数返回变量的资源类型。

get_resource_type ( resource $handle ) : string

其中 $handle 是要获取其类型的资源变量。此函数返回一个对应于资源类型的字符串。

还有一个 get_resource_id() 函数,它为给定的资源提供一个整数标识符。

get_resource_id(resource $resource): int

Example

此函数提供了一种类型安全的方式来为给定的资源生成整数标识符。

<?php
   $fp = fopen("hello.php", "r");
   $resource = get_resource_type($fp);
   $id = get_resource_id($fp);
   echo "The resource type is : $resource The resource ID is : $id";
?>

它将生成以下 output

The resource type is : stream The resource ID is : 5

NULL type

在 PHP 中,没有值的变量称为 null 数据类型。这样的变量有一个值被定义为 NULL。变量可以显式分配 NULL 或使用 unset() 函数将其值设置为 null。

$var=NULL;

可以将其他类型的变量强制转换为 null,尽管从 PHP 7.2 开始已弃用将 null 强制转换为其他类型。在早期版本中,使用 (unset)$var 语法完成强制转换

Example

以下示例显示如何将 NULL 分配给变量

<?php
   $var=NULL;
   var_dump($var);
?>

它将生成以下 output

NULL

Example

以下示例将 null 变量执行到其他主变量 −

<?php
   $var = NULL;
   var_dump( (int)   $var);
   var_dump((float)$var);
   var_dump((bool)  $var) ;
   var_dump( (boolean) $var);
?>

它将生成以下 output

int(0)
float(0)
bool(false)
bool(false)

PHP – Hashing

“哈希” 一词表示一种对数据(特别是文本)进行加密以获得固定长度值的技术。PHP 库包含许多函数,可以通过应用不同的哈希算法(例如 md5、SHA2、HMAC 等)对数据执行哈希。获得的加密值称为原始密钥的哈希。

哈希处理是一个单向过程,从某种意义上说,无法对哈希进行反转,因而无法获取原始键。

Applications of Hashing

哈希技术被有效用于以下目的:

Password Authentication

我们通常会注册各种在线应用程序,例如 gmail、Facebook 等。您需要填写一个表格,您在其中为在线帐户创建密码。服务器会对您的密码进行哈希,哈希值存储在数据库中。当您登录时,提交的密码会被哈希,并与数据库中的密码进行比较。这让你的密码不会被盗用。

Data Integrity

哈希的一个重要用途是验证数据没有被篡改。当您从互联网下载文件时,它会显示给您哈希值,您可以用此哈希值来与下载的文件进行对比,确保文件没有被破坏。

The Process of Hashing

可以由下图查看哈希处理过程:

php hashing

Hashing Algorithms in PHP

PHP 支持多个哈希算法:

  1. MD5 - MD5 是一种 128 位的哈希函数,广泛用于软件中,用于验证传输文件的完整性。128 位的哈希值通常表示为 32 位十六进制数。例如,“frog”这个单词总是生成哈希值“8b1a9953c4611296a827abf8c47804d7”

  2. SHA - SHA 的全称是安全散列算法,由美国国家标准与技术研究院(NIST)制定的一系列标准。SHA 是 MD5 的改进版本,用于哈希数据和证书。SHA-1 和 SHA-2 是该算法的不同版本。SHA-1 是一个 160 位的哈希算法。SHA-2 实际上是一个哈希“系列”,有各种长度,其中最受欢迎的是 256 位。

  3. HMAC - HMAC(基于哈希的消息认证码)是一种加密认证技术,使用哈希函数和密钥。

  4. HKDF - HKDF 是一个简单的密钥派生函数 (KDF),基于 HMAC 消息认证码。

  5. PBKDF2 - PBKDF2(基于密码的密钥派生函数 2)是一种哈希算法,可根据密码创建加密密钥。

Hash Functions in PHP

PHP 库包含多个哈希函数:

The hash_algos Function

此函数返回一个数字索引数组,其中包含受支持哈希算法的列表。

hash_algos(): array

The hash_file Function

该函数返回一个字符串,其中包含计算出的消息摘要,小写十六进制。

hash_file(
   string $algo,
   string $filename,
   bool $binary = false,
   array $options = []
): string|false

algo 参数是所选哈希算法的类型(即 “md5”、“sha256”、“haval160,4”等)。 filename 是描述待哈希文件位置的 URL;支持 fopen 包装器。

Example

请看以下示例:

<?php
   /* Create a file to calculate hash of */
   $fp=fopen("Hello.txt", "w");
   $bytes = fputs($fp, "The quick brown fox jumped over the lazy dog.");
   fclose($fp);
   echo hash_file('md5', "Hello.txt");
?>

它将生成以下 output

5c6ffbdd40d9556b73a21e63c3e0e904

The hash() Function

hash() 函数生成哈希值(消息摘要):

hash(
   string $algo,
   string $data,
   bool $binary = false,
   array $options = []
): string

algo 参数是所选哈希算法的类型(即 “md5”、“sha256”、“haval160,4”等)。 data 参数是要进行哈希处理的消息。如果 binary 参数为 true ,它将输出原始二进制数据;“false” 输出小写十六进制。

Example

该函数返回一个字符串,其中包含计算出的消息摘要,小写十六进制。

<?php
   echo "Using SHA256 algorithm:" . hash('sha256', 'The quick brown fox jumped over the lazy dog.'). PHP_EOL;
   echo "Using MD5 algorithm:",hash('md5', 'The quick brown fox jumped over the lazy dog.'), PHP_EOL;
   echo "Using SHA1 algorithm:" . hash('sha1', 'The quick brown fox jumped over the lazy dog.');
?>

它将生成以下 output

Using SHA256 algorithm:68b1282b91de2c054c36629cb8dd447f12f096d3e3c587978dc2248444633483
Using MD5 algorithm:5c6ffbdd40d9556b73a21e63c3e0e904
Using SHA1 algorithm:c0854fb9fb03c41cce3802cb0d220529e6eef94e

PHP – Encryption

PHP 的早期版本包含 mcrypt 扩展,它提供了加密/解密功能。由于缺乏维护,mycrypt 扩展已从 PHP 7.2 版本中弃用并删除。PHP 现在包含 OpenSSL 库,该库具有广泛的功能来支持加密和解密功能。

OpenSSL 支持各种加密算法,例如 AES(高级加密标准)。可通过调用 openssl_get_cipher_methods() 函数获取所有受支持的算法。

OpenSSL 扩展中的两个重要函数为 -

  1. openssl_encrypt() − Encrypts data

  2. openssl_decrypt() − Decrypts data

The openssl_encrypt() Function

此函数使用给定的方法和密钥加密给定数据,并返回原始或 base64 编码的字符串 -

openssl_encrypt(
   string $data,
   string $cipher_algo,
   string $passphrase,
   int $options = 0,
   string $iv = "",
   string &$tag = null,
   string $aad = "",
   int $tag_length = 16
): string|false

该函数具有以下 parameters -

Sr.No

Parameter & Description

1

data 要加密的明文消息数据。

2

cipher_algo The cipher method.

3

passphrase 密码。如果密码短于预期,则用 NULL 字符填充;如果密码长于预期,则将其截断。

4

options options 是标志 OPENSSL_RAW_DATA 和 OPENSSL_ZERO_PADDING 的按位析取。

5

iv A non-NULL Initialization Vector.

6

tag 使用 AEAD 密码模式(GCM 或 CCM)时按引用传递的身份验证标记。

7

aad Additional authenticated data.

8

tag_length 身份验证标记的长度。在 GCM 模式下,其值可以在 4 到 16 之间。

该函数在成功时返回加密字符串,或在失败时返回 false

The openssl_decrypt() Function

此函数获取原始或 base64 编码的字符串并使用给定的方法和密钥对其解密。

openssl_decrypt(
   string $data,
   string $cipher_algo,
   string $passphrase,
   int $options = 0,
   string $iv = "",
   ?string $tag = null,
   string $aad = ""
): string|false

openssl_decrypt() 函数使用与 openssl_encrypt 函数相同的参数。

此函数在成功时返回解密字符串,或在失败时返回 false。

Example

请看以下示例:

<?php
   function sslencrypt($source, $algo, $key, $opt, $iv) {
      $encstring = openssl_encrypt($source, $algo, $key, $opt, $iv);
      return $encstring;
   }

   function ssldecrypt($encstring, $algo, $key, $opt, $iv) {
      $decrstring = openssl_decrypt($encstring, $algo, $key, $opt, $iv);
      return $decrstring;
   }

   // string to be encrypted
   $source = "PHP: Hypertext Preprocessor";

   // Display the original string
   echo "Before encryption: " . $source . "\n";
   $algo = "BF-CBC";
   $opt=0;
   $ivlength = openssl_cipher_iv_length($algo);
   $iv = random_bytes($ivlength);
   $key = "abcABC123!@#";

   // Encryption process
   $encstring = sslencrypt($source, $algo, $key, $opt, $iv);

   // Display the encrypted string
   echo "Encrypted String: " . $encstring . "\n";

   // Decryption process
   $decrstring = ssldecrypt($encstring, $algo, $key, $opt, $iv);

   // Display the decrypted string
   echo "Decrypted String: " . $decrstring;
?>

它将生成以下 output

Before encryption: PHP: Hypertext Preprocessor
Encrypted String:
Decrypted String:

PHP is_null() Function

PHP 将 NULL 定义为其一种特殊数据类型。它表示某个变量尚未分配任何特定数据类型的任何值。它是 PHP 中的一个内置常量,用于指示任何对象或值的故意缺失。可以明确地将变量分配为 NULL,或使用 unset() 函数将值设置为 null。

The is_null() Function

PHP 提供了一个布尔函数 is_null() 来检查变量是否确实为 NULL 类型。

is_null(mixed $value): bool

Example 1

如果任何变量明确地分配为 NULL,则显然 is_null() 函数返回 true

<?php
   $x = NULL;
   echo "Variable \$x is null? ";
   var_dump(is_null($x));
?>

它将生成以下 output

Variable $x is null? bool(true)

Example 2

如果 unset 具有特定值的变量,则 is_null() 函数也返回 true,但带有警告

<?php
   $x = "Hello";
   unset($x);
   echo "Variable \$x is null?\n";
   var_dump(is_null($x));
?>

它将生成以下 output

Variable $x is null?
bool(true)

PHP Warning:  Undefined variable $x in /home/cg/root/89262/main.php on line 5

Example 3

同样,如果您仅声明一个变量而不为其分配任何值,则 is_null() 函数会返回 true 并带有警告 -

<?php
   $y;
   echo "Variable \$y is null?\n";
   var_dump(is_null($y));
?>

它将生成以下 output

Variable $y is null?
bool(true)
Warning: Undefined variable $y in hello.php on line 9

Example 4

您还可以使用相等操作符 (==) 检查变量是否为 NULL。

<?php
   $x = NULL;
   if ($x === NULL) {
      echo '$x is NULL';
   } else {
      echo '$x is not NULL';
   }
?>

它将生成以下 output

$x is NULL

Example 5

空字符串 "" 不认为等同于 NULL。因此,is_null() 函数以及 =="" 操作符返回 false 。请看以下示例 −

<?php
   $y = "";
   if ($y === NULL) {
      echo '$y is NULL';
   } else {
      echo '$y is not NULL';
   }
   echo "$y is null?\n";
   var_dump(is_null($y));
?>

它将生成以下 output

$y is not NULL is null?
bool(false)

PHP 中其他两个与 is_null() 函数相关的函数是 isset() 函数和 empty() 函数。

The isset() Function

isset() 函数确定变量是否已声明且与 NULL 不同。

isset(mixed $var, mixed ...$vars): bool

Example

分配了 NULL 的变量被认为是未设置的。

<?php
   $x = NULL;
   echo '$x is set? ';
   var_dump(isset($x));
?>

它将生成以下 output

$x is set? bool(false)

请注意,空字符 ("\0") 不等同于 PHP null 常量。

The empty() Function

empty() 函数检查一个变量是否被认为是空的。如果变量不存在或其值为 NULL,则该变量被认为是空的。如果变量不存在,empty() 不会生成警告。

Example 1

请看以下示例:

<?php
   $x = NULL;
   echo '$x is empty? ';
   var_dump(empty($x));
   $y;
   echo '$y is empty? ';
   var_dump(empty($y));
?>

它将生成以下 output

$x is empty? bool(true)
$y is empty? bool(true)

Example 2

如果变量设置为 "0"、NULL 或根本未设置,empty() 函数返回 true

<?php
   $var = 0;
   if (empty($var)) {
      echo '$var is either 0, empty, or not set at all';
   }
?>

它将生成以下 output

$var is either 0, empty, or not set at all

PHP – System Calls

PHP 内置函数库包括一类函数,用于在 PHP 代码中调用操作系统实用程序和外部程序。在本章中,我们将讨论用于执行系统调用的 PHP 函数。

The system() Function

system() 函数类似于 C 语言中的 system() 函数,可执行给定的命令并输出结果。

system(string $command, int &$result_code = null): string|false

如果 PHP 作为服务器模块运行,system() 调用会尝试在每行输出之后自动刷新 Web 服务器的输出缓冲区。成功时返回命令输出的最后一行,失败时返回 false。

Example

下面的 PHP 代码调用 Windows 操作系统的 DIR 命令,并显示当前目录中的文件列表。

<?php
   echo '<pre>';

   // Outputs all the result of DOS command "dir", and returns
   // the last output line into $last_line. Stores the return value
   // of the shell command in $retval.
   $last_line = system('dir/w', $retval);

   // Printing additional info
   echo '
   </pre>
   <hr />Last line of the output: ' . $last_line . '
   <hr />Return value: ' . $retval;
?>

它将生成以下 output

Volume in drive C has no label.
Volume Serial Number is 7EE4-E492

Directory of C:\xampp\htdocs
[.]                 [..]                applications.html   bitnami.css
[dashboard]         employee.csv        favicon.ico         hello.csv
hello.html          hello.php           homepage.php        [img]
index.php           [Langi]             menu.php            myform.php
myname.php          new.png             new.txt             test.php
test.zip            [TPcodes]           uploadfile.php      [webalizer]
welcome.png         [xampp]
                 18 File(s)          123,694 bytes
                 8 Dir(s)            168,514,232,320 bytes free

Last line of the output: 8 Dir(s) 168,514,232,320 bytes free
Return value: 0

The shell_exec() Function

shell_exec() 函数等同于 PHP 的反引号操作符。它通过 shell 执行给定命令,并以字符串的形式返回完整的输出。

shell_exec(string $command): string|false|null

函数返回一个包含已执行命令输出的字符串,如果管道不能建立,则返回 false;如果发生错误或命令没有产生输出,则返回 null。

Example

在下面的代码中,我们使用 shell_exec() 函数在当前目录中获取扩展名为 ".php" 的文件列表 −

<?php
   $output = shell_exec('dir *.php');
   echo "<pre>$output</pre>";
?>

它将生成以下 output

Volume in drive C has no label.
Volume Serial Number is 7EE4-E492

Directory of C:\xampp\htdocs

10/26/2023  08:27 PM                73 hello.php
10/12/2023  10:40 AM                61 homepage.php
07/16/2015  09:02 PM               260 index.php
10/12/2023  10:39 AM                49 menu.php
09/25/2023  01:43 PM               338 myform.php
10/12/2023  10:49 AM                51 myname.php
10/26/2023  02:00 PM               369 test.php
09/25/2023  01:42 PM               555 uploadfile.php
               8 File(s)          1,756 bytes
               0 Dir(s)           168,517,771,264 bytes free

The exec() Function

exec() 函数以字符串参数的形式执行给定的命令。

exec(string $command, array &$output = null,
   int &$result_code = null):string|false

如果指定 $output 参数,它将是一个数组,其中填充了命令的每行输出。

Example

在此情况下,我们使用 exec() 函数从程序内部调用 whoami 命令。whoami 命令返回用户名。

<?php

   // outputs the username that owns the running php/httpd process
   // (on a system with the "whoami" executable in the path)
   $output=null;
   $retval=null;
   exec('whoami', $output, $retval);
   echo "Returned with status $retval and output:\n";
   var_dump($output);

?>

它将生成以下 output

Returned with status 0 and output: array(1)
{ [0]=> string(13) "gnvbgl3\mlath" }

The passthru() Function

passthru() 函数执行外部程序并显示原始输出。虽然 passthru() 函数类似于 exec() 或 system() 函数,因为它执行一个命令,但是当操作系统命令的输出是需要直接传回浏览器的二进制数据时,它应该用在它们的地方。

Example

一个使用 passthu() 函数显示系统 PATH 环境变量内容的 PHP 程序

passthru(string $command, int &$result_code = null): ?false
<?php
   passthru ('PATH');
?>

它将生成以下 output

PATH=C:\Python311\Scripts\;C:\Python311\;C:\WINDOWS\system32;C:\WINDOWS;
C:\WINDOWS\System32\Wbem;C:\WINDOWS\System32\WindowsPowerShell\v1.0\;
C:\WINDOWS\System32\OpenSSH\;C:\xampp\php;C:\Users\mlath\AppData\Local
\Microsoft\WindowsApps;C:\VSCode\Microsoft VS Code\bin

Backtick Operator

PHP 支持一个执行运算符:反引号 (``)。(它不是单引号!) PHP 会尝试将反引号的内容作为外壳命令执行;将返回输出。反引号运算符的使用与 shell_exec() 相同。

Example

请看以下示例:

<?php
   $output = `dir *.php`;
   echo "<pre>$output</pre>";
?>

它将生成以下 output

Volume in drive C has no label.
Volume Serial Number is 7EE4-E492

Directory of C:\xampp\htdocs

10/26/2023  08:42 PM                61 hello.php
10/12/2023  10:40 AM                61 homepage.php
07/16/2015  09:02 PM               260 index.php
10/12/2023  10:39 AM                49 menu.php
09/25/2023  01:43 PM               338 myform.php
10/12/2023  10:49 AM                51 myname.php
10/26/2023  02:00 PM               369 test.php
09/25/2023  01:42 PM               555 uploadfile.php
               8 File(s)          1,744 bytes
               0 Dir(s)           168,471,289,856 bytes free

shell_exec() 被禁用时,反引号运算符将被禁用。

PHP – HTTP Authentication

在 PHP 中,header() 函数用于向客户端浏览器发送一个“需要验证”的消息,导致出现一个用户名/密码输入窗口。事实上,header() 允许你发送任何原始 HTTP 标头。

header(string $header, bool $replace = true, int $response_code = 0): void

字符串参数将传递给 header() 函数。例如

header("HTTP/1.1 404 Not Found");

它用于找出要发送的 HTTP 状态代码。

还可以使用 header() 函数将浏览器重定向到另一个 URL。

一旦用户输入了用户名和密码,包含 PHP 脚本的 URL 将再次被调用,其中预定义变量 PHP_AUTH_USER、PHP_AUTH_PW 和 AUTH_TYPE 分别设置为用户名、密码和验证类型。这些预定义变量在 $_SERVER 数组中找到。仅支持“Basic”和“Digest”身份验证方法。

<?php

   /* Redirect browser */
   header("Location: http://www.example.com/");

   /* Make sure that code below does not get executed when we redirect. */
   exit;

?>

可选的替换参数表明标头是否应该替换先前的类似标头或添加第二个相同类型的标头,并且响应代码参数将 HTTP 响应代码强制为指定的值。

为了能够强制客户端身份验证,需要在文档根文件夹中使用 .htaccess 文件。打开一个新文本文档,将以下文本放入其中,并以 .htaccess 为其名称保存。

CGIPassAuth On

Example

强制页面上客户端身份验证的一个示例脚本片段如下所示:

<?php
   if (!isset($_SERVER['PHP_AUTH_USER'])) {
      header('WWW-Authenticate: Basic realm="My Realm"');
      header('HTTP/1.0 401 Unauthorized');
      echo 'User hits Cancel button';7
      exit;
   } else {
      echo "<p>Hello {$_SERVER['PHP_AUTH_USER']}.</p>";
      echo "<p>You entered {$_SERVER['PHP_AUTH_PW']} as your password.</p>";
   }
?>

Output

当你在浏览器中访问脚本时,就会弹出一个对话框,如下所示:

php http authentication 1

一旦你点击了登录按钮,可能会有一个后端脚本来验证登录凭据。一旦身份验证通过,将创建两个服务器变量,其键为 PHP_AUTH_USER 和 PHP_AUTH_PW,可以使用 phpinfo() 函数的输出对其进行验证。

php http authentication 2

PHP – Swapping Variables

PHP 没有提供任何内置函数用于交换或互换两个变量的值。然而,有几种技术可以用来完成交换。

最直接的方法之一是使用第三个变量作为临时的占位符来实现交换。按照特定顺序使用算术运算符也很有效。你也可以用二进制异或操作符用于交换。在本教程中,我们将用 PHP 来实现这些交换技术

Temporary Variable

从逻辑上来说,这是最明显、最简单的方法。要交换 “a” 和 “b” 的值,请使用第三个变量 “c”。将 “a” 的值赋给 “c”,使用 “b” 的现有值覆盖 “a”,然后将 “b” 设置为存储在 “c” 中的 “a” 的早期值。

Example

请看以下示例:

<?php
   $a = 10;
   $b = 20;
   echo "Before swapping - \$a = $a, \$b = $b". PHP_EOL;
   $c = $a;
   $a = $b;
   $b = $c;
   echo "After swapping - \$a = $a, \$b = $b". PHP_EOL;
?>

它将生成以下 output

Before swapping - $a = 10, $b = 20
After swapping - $a = 20, $b = 10

Using addition (+) Operator

此解决方案利用了这样一个事实:从两个数字的和中减去一个数字会得到第二个数字。换句话说,“sum(a+b) – a” 等于 “b”,反之亦然。

Example

让我们利用该属性来交换 “a” 和 “b” −

<?php
   $a = 10;
   $b = 20;
   echo "Before swapping - \$a = $a, \$b = $b". PHP_EOL;
   $a = $a + $b;
   $b = $a - $b;
   $a = $a - $b;
   echo "After swapping - \$a = $a, \$b = $b". PHP_EOL;
?>

它将生成以下 output

Before swapping - $a = 10, $b = 20
After swapping - $a = 20, $b = 10

你也可以像这样使用其他算术运算符来执行交换:减法 (-)、乘法 (*) 和除法 (/)。

Using list() Function

PHP 中的 list() 函数将数组解压为单独的变量。这有助于我们实现两个变量之间的交换目标。为此,生成一个包含 “a” 和 “b” 的数组,然后将其解压到 “b” 和 “a” 变量中,以获取具有交换值的方法获取 “a” 和 “b”。

Example

请看以下示例:

<?php
   $a = 10;
   $b = 20;
   echo "Before swapping - \$a = $a, \$b = $b". PHP_EOL;
   $arr = [$a, $b];
   list($b, $a) = $arr;
   echo "After swapping - \$a = $a, \$b = $b". PHP_EOL;
?>

它将生成以下 output

Before swapping - $a = 10, $b = 20
After swapping - $a = 20, $b = 10

Bitwise XOR

按位异或 (^) 运算符也可以用于交换两个变量 “x” 和 “y” 的值。如果两个操作数在相同位置上的一个位为 1,则返回 1,否则返回 0。

Example

请看以下示例:

<?php
   $a = 10;
   $b = 20;
   echo "Before swapping - \$a = $a, \$b = $b". PHP_EOL;
   $a = $a ^ $b;
   $b = $a ^ $b;
   $a = $a ^ $b;
   echo "After swapping - \$a = $a, \$b = $b". PHP_EOL;
?>

它将生成以下 output

Before swapping - $a = 10, $b = 20
After swapping - $a = 20, $b = 10

PHP – Closure::call()

在 PHP 中, closure 是一个匿名函数,可以访问其创建的范围内的变量,即使该范围已经关闭。你需要在其中指定 use 关键字。

闭包将函数代码与创建它们的范围封装在对象中。在 PHP 7 中,引入了一个新的 closure::call() 方法来将对象范围绑定到闭包并调用它。

Methods in the Closure Class

闭包类具有以下方法,包括 call() 方法 −

final class Closure {

   /* Methods */
   private __construct()
   public static bind(Closure $closure, ?object $newThis, object|string|null $newScope = "static"): ?Closure
   public bindTo(?object $newThis, object|string|null $newScope = "static"): ?Closure
   public call(object $newThis, mixed ...$args): mixed
   public static fromCallable(callable $callback): Closure

}

call() method 是闭包类的静态方法。它被引入为 bind() 或 bindTo() 方法的快捷方式。

bind() method 根据特定的 bound 对象和类范围复制闭包,而 bindTo() 方法则使用新的 bound 对象和类范围复制闭包。

call() 方法具有以下 signature

public Closure::call(object $newThis, mixed ...$args): mixed

call() 方法将闭包临时绑定到 newThis,并使用任何给定的参数调用它。

在 PHP 7 之前的版本中,bindTo() 方法可以使用如下方式:

<?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());
?>

该程序将 $getValue (它是一个闭包对象)绑定到 A 类的对象,并打印其私有变量 $x 的值 - 它为 1。

在 PHP 7 中,绑定通过 call() 方法实现,如下所示 −

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

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

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

PHP – Filtered unserialize()

在 PHP 中,内置函数 unserialize() 可从 PHP 版本 4 开始使用。在 PHP 7 中,添加了一个传递允许类列表的条款。这允许过滤不受信任的源。unserialze() 函数仅反序列化来自可信类的 data。

在 PHP 中,序列化表示生成值的存储表示。这对于存储或传递 PHP 值非常有用,而不会丢失它们的类型和结构。内置 serialize() 函数用于此目的。

serialize(mixed $value): string

unserialize() 函数从序列化的表示中给出一个 PHP 值。从 PHP 7 开始,unserialize() 函数遵循以下格式 -

unserialize(string $data, array $options = [ ]): mixed

$data 参数是你想要反序列化的序列化字符串。

$options 参数已新引入。它是一个关联数组,具有以下键 -

Sr.No

Name & Description

1

allowed_classes 应该接受的类名的数组,或 false 不接受任何类,或 true 接受所有类。省略此选项与将其定义为 true 相同。

2

max_depth 反序列化过程中允许的结构的最大深度。

Example

请看以下示例:

<?php
   class MyClass {
      var int $x;
      function __construct(int $x) {
         $this->x = $x;
      }
   }
   class NewClass {
      var int $y;
      function __construct(int $y) {
         $this->y = $y;
      }
   }

   $obj1 = new MyClass(10);
   $obj2 = new NewClass(20);

   $sob1 = serialize($obj1);
   $sob2 = 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
   $usob1 = unserialize($sob1 , ["allowed_classes" => true]);

   // converts all objects into __PHP_Incomplete_Class object except those of MyClass and NewClass
   $usob2 = unserialize($sob2 , ["allowed_classes" => ["MyClass", "NewClass"]]);

   echo $usob1->x . PHP_EOL;
   echo $usob2->y . PHP_EOL;
?>

它将生成以下 output

10
20

PHP – IntlChar

在 PHP7 中,引入了新的 IntlChar 类。该类提供对可用于访问 Unicode 字符相关信息的大量实用工具方法的访问权限。Intl 类中有很多静态方法和常量。它们紧密遵守底层 ICU(Unicode 的国际组件)库所使用的名称和行为。

Note 您需要在系统中的 PHP 程序中启用 Intl 扩展。要启用它,请打开 php.ini 文件并取消注释(从该行删除前导分号)。

extension=intl

以下内容通过示例展示 Intl 类中的一些静态函数:

IntlChar::charAge

此函数获取码点的“年代”

public static IntlChar::charAge(int|string $codepoint): ?array

“年代”表示将码点首次指定(作为非字符或私用)或分配字符后的 Unicode 版本。

Example

请看以下示例:

<?php
   var_dump(IntlChar::charage("\u{2603}"));
?>

它将生成以下 output

array(4) {
   [0]=>
   int(1)
   [1]=>
   int(1)
   [2]=>
   int(0)
   [3]=>
   int(0)
}

IntlChar::charFromName

charFromName() 函数通过名称查找 Unicode 字符并返回其码点值。

public static IntlChar::charFromName(string $name,
   int $type = IntlChar::UNICODE_CHAR_NAME): ?int

使用查找时要用的名称类型参数组。可以是以下任何一个常量 -

  1. IntlChar::UNICODE_CHAR_NAME (default)

  2. IntlChar::UNICODE_10_CHAR_NAME

  3. IntlChar::EXTENDED_CHAR_NAME

  4. IntlChar::CHAR_NAME_ALIAS

  5. IntlChar::CHAR_NAME_CHOICE_COUNT

Example

请看以下示例:

<?php
   var_dump(IntlChar::charFromName("LATIN CAPITAL LETTER A"));
   var_dump(IntlChar::charFromName("SNOWMAN"));
?>

它将生成以下 output

int(65)
int(9731)

IntlChar::charName

charName() 函数检索 Unicode 字符的名称

public static IntlChar::charName(int|string $codepoint,
   int $type = IntlChar::UNICODE_CHAR_NAME): ?string

Example

请看以下示例:

<?php
   var_dump(IntlChar::charName(".", IntlChar::UNICODE_CHAR_NAME));
   var_dump(IntlChar::charName("\u{2603}"));
?>

它将生成以下 output

string(9) "FULL STOP"
string(7) "SNOWMAN"

IntlChar::isalpha

isalpha() 函数确定指定代码点是否是字母字符。对于通用类别“L”(字母)返回 true。

public static IntlChar::isalpha(int|string $codepoint): ?bool

Example

请看以下示例:

<?php
   var_dump(IntlChar::isalpha("A"));
   var_dump(IntlChar::isalpha("1"));
?>

它将生成以下 output

bool(true)
bool(false)

Intl 类定义了类似的静态方法,例如 isdigit()、isalnum()、isblank() 等等。

IntlChar::islower

islower() 函数确定指定代码点是否具有通用类别“Ll”(小写字母)。

public static IntlChar::islower(int|string $codepoint): ?bool

Example

请看以下示例:

<?php
   var_dump(IntlChar::islower("A"));
   var_dump(IntlChar::islower("a"));
?>

它将生成以下 output

bool(false)
bool(true)

同样,还有如下函数:isupper()、istitle()、iswhitespace() 等等。

IntlChar::toupper

给定字符被映射到其大写等效项。

public static IntlChar::toupper(int|string $codepoint): int|string|null

如果字符没有大写等效项,则返回字符本身。

Example

请看以下示例:

<?php
   var_dump(IntlChar::toupper("A"));
   var_dump(IntlChar::toupper("a"));
?>

它将生成以下 output

string(1) "A"
string(1) "A"

PHP – CSPRNG

CSPRNG 的缩写代表密码安全伪随机数生成器。PHP 函数库包含了许多用于生成随机数的函数。例如:

  1. mt_rand() − 通过 Mersenne Twister 随机数生成器生成一个随机值

  2. mt_srand() − 设置 Mersenne Twister 随机数生成器的种子

  3. rand() − 生成一个随机整数。

Example

以下代码演示了如何使用函数 mt_rand() 来生成随机数:

<?php
   # Generates random integer between the range
   echo "Random integer: " . rand(1,100) . PHP_EOL;
   # Generate a random value via the Mersenne Twister Random Number Generator
   echo "Random number: " . mt_rand(1,100);
?>

它将生成以下 output

Random integer: 45
Random number: 86

请注意,每次执行代码时输出可能不同。但是由这些函数生成的随机数并非密码安全,因为可能会猜出其结果。PHP 7 引入了几个生成安全随机数的函数。

以下函数具有加密安全性,是新添加的 -

  1. random_bytes() − 生成具有加密安全性的伪随机字节。

  2. random_int() − 生成具有加密安全性的伪随机整数。

The random_bytes() Function

random_bytes() 生成任意长度的加密随机比特串,该串适合用于加密用途,例如生成哈希盐、密钥或初始化向量时。

string random_bytes ( int $length )

Parameters

  1. length − 应返回的随机字符串的长度(单位为字节)。

该函数返回一个包含请求数量的加密安全随机比特串的字符串。

如果找不到适当的随机性来源,将抛出一个 Exception。如果给定无效的参数,将抛出一个 TypeError。如果给定了无效的字节长度,将抛出一个 Error。

Example

请看以下示例:

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

它可能生成以下 output (每次可能不同) -

6a85eec950

The random_int() Function

random_int() 生成加密随机整数,适用于在公正结果极其重要的场景下使用。

int random_int ( int $min , int $max )

Parameters

  1. min − 要返回的最小值,该值必须为 PHP_INT_MIN 或更高。

  2. max − 要返回的最大值,该值必须小于或等于 PHP_INT_MAX。

该函数返回一个在 min 到 max 范围内的加密安全随机整数(包含边界值)。

如果找不到适当的随机性来源,将抛出一个 Exception。如果给定无效的参数,将抛出一个 TypeError。如果 max 小于 min,将抛出一个 Error。

Example

请看以下示例:

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

它可能生成以下 output (每次不同) -

495
-563

PHP – Expectations

预期是与旧的 assert() 函数向后兼容的增强功能。预期允许在生产代码中进行零成本的断言,并提供在断言失败时抛出自定义异常的能力。

assert() 现在是一个语言构造,其中第一个参数与要测试的字符串或布尔值相反,是一个表达式。

Configuration Directives for assert()

下表列出了 assert() 函数的配置指令:

Directive

Default value

Possible values

zend.assertions

1

1 - 生成并执行代码(开发模式) 0 - 生成代码但在运行时跳过它 -1 - 不生成代码(生产模式)

assert.exception

0

1 - 在断言失败时抛出,方法是抛出作为异常提供的对象,或者在未提供异常的情况下抛出新的 AssertionError 对象。 0 - 使用或生成一个如上所述的 Throwable,但仅根据该对象生成警告,而不是抛出它(与 PHP 5 行为兼容)

Parameters

  1. Assertion - 断言。在 PHP 5 中,这必须是一个要评估的字符串或要测试的布尔值。在 PHP 7 中,这也可以是返回一个值的任何表达式,它将被执行,其结果将用于指示断言是否成功或失败。

  2. Description - 一个可选的描述,如果断言失败,它将包含在失败消息中。

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

Return Values

如果断言为 false,则返回 FALSE,否则返回 TRUE。

Example

请看以下示例:

<?php
   ini_set('assert.exception', 1);
   class CustomError extends AssertionError {}
   assert(false, new CustomError('Custom Error Message!'));
?>

它将生成以下 output

PHP Fatal error:  Uncaught CustomError: Custom Error Message! In test.php:6

PHP – The "use" Statement

PHP 中的“use”关键字被认为与多种用途相关联,例如别名引用、插入特性以及在闭包中继承变量。

Aliasing

别名引用是通过使用操作符完成的。它允许你用别名或其他名称引用一个外部全限定名称。

Example

请看以下示例:

use My\namespace\myclass as Another;
$obj = new Another;

你还可以按如下所示进行分组使用声明 -

use some\namespace\{ClassA, ClassB, ClassC as C};
use function some\namespace\{fn_a, fn_b, fn_c};
use const some\namespace\{ConstA, ConstB, ConstC};

Traits

借助“use”关键字,你可以向类中插入一个特性。特性类似于类,但只打算以细粒度和一致的方式对功能进行分组。不可能自己实例化特性。

Example

请看以下示例:

<?php
   trait mytrait {
      public function hello() {
         echo "Hello World from " . __TRAIT__ .;
      }
   }

   class myclass {
      use mytrait;
   }

   $obj = new myclass();
   $obj->hello();
?>

它将生成以下 output

Hello World from mytrait

Closures

闭包也是一个匿名函数,它可以在“use”关键字的帮助下访问其作用域之外的变量。

Example

请看以下示例:

<?php
   $maxmarks=300;
   $percent=function ($marks) use ($maxmarks) {
      return $marks*100/$maxmarks;
   };
   $m = 250;
   echo "marks=$m percentage=". $percent($m);
?>

它将生成以下 output

marks=250 percentage=83.333333333333

PHP – Integer Division

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

intdiv() 函数返回两个整数参数的整数商。如果 “a/b” 除法的结果是 “c”,余数是 “r” −

a=b*c+r

在这种情况下, intdiv(a,b) 返回 r

intdiv ( int $x , int $y ) : int

$x 和 $y 是除法表达式的分子和分母部分。intdiv() 函数返回一个整数。如果两个参数都是正数或负数,则返回值为正数。

Example 1

如果分子 < 分母,则 intdiv() 函数返回 “0”,如下所示 −

<?php
   $x=10;
   $y=3;
   $r=intdiv($x, $y);
   echo "intdiv(" . $x . "," . $y . ") = " . $r . "\n";
   $r=intdiv($y, $x);
   echo "intdiv(" . $y . "," . $x . ") = " . $r;
?>

它将生成以下 output

intdiv(10,3) = 3
intdiv(3,10) = 0

Example 2

在以下示例中,intdiv() 函数返回负整数,因为分子或分母是负数。

<?php
   $x=10;
   $y=-3;
   $r=intdiv($x, $y);
   echo "intdiv(" . $x . "," . $y . ") = " . $r . "\n";
   $x=-10;
   $y=3;
   $r=intdiv($x, $y);
   echo "intdiv(" . $x . "," . $y . ") = " . $r . "\n";
?>

它将生成以下 output

intdiv(10,-3) = -3
intdiv(-10,3) = -3

Example 3

分子和分母都是正数或都是负数的情况下,intdiv() 函数返回正整数。

<?php
   $x=10;
   $y=3;
   $r=intdiv($x, $y);
   echo "intdiv(" . $x . "," . $y . ") = " . $r . "\n";

   $x=-10;
   $y=-3;
   $r=intdiv($x, $y);
   echo "intdiv(" . $x . "," . $y . ") = " . $r ;
?>

它将生成以下 output

intdiv(10,3) = 3
intdiv(-10,-3) = 3

Example 4

在以下示例中,分母为 “0”。它导致 DivisionByZeroError 异常。

<?php
   $x=10;
   $y=0;
   $r=intdiv($x, $y);
   echo "intdiv(" . $x . "," . $y . ") = " . $r . "\n";
?>

它将生成以下 output

PHP Fatal error:  Uncaught DivisionByZeroError: Division by zero in hello.php:4

PHP – Deprecated Features

随着每个新版本的添加一些新功能,一些功能也会被移除,因为它们被认为已过时。在本章中,我们将了解 PHP 版本 5 之后的弃用功能。

Deprecated in PHP Ver 7

PHP 4 Style Constructors

PHP 4 样式的构造函数是与它们定义所在的类同名的函数,现在已弃用,并且将在未来移除。如果 PHP 4 构造函数是类中定义的唯一构造函数,则 PHP 7 将发出 E_DEPRECATED。实现 __construct() 函数的类不受影响。

Example

请看以下示例:

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

它在浏览器中生成以下 output

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...

Static Calls to Non-static Methods

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

Example

请看以下示例:

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

它在浏览器中生成以下 output

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

password_hash() salt option

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

capture_session_meta SSL context option

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

ext/mcrypt

mcrypt 扩展已弃用,取而代之的是 OpenSSL。

Unquoted Strings

不存在全局常量的未引用的字符串将被视为它们自身的字符串。此行为过去会发出 E_NOTICE,但现在会发出 E_WARNING。在下一个 PHP 主要版本中,将转而引发 Error 异常。

The __autoload() Method

__autoload() 函数已弃用,因为它不如 spl_autoload_register() (因为它无法链接自动加载器),并且这两种自动加载样式之间没有互操作性。

The create_function() Function

鉴于此函数存在安全问题,现在已弃用。首选的替代方法是使用匿名函数。

The each() Function

此函数会给一些语言更改带来实现问题。因此已将其弃用。

Case-Insensitive Constants

声明不区分大小写的常数已被弃用。现在传递 true 作为 define() 的第三个参数将生成弃用警告。

The (real) and is-real() Function

(真实)转换已被弃用,请改为使用(浮点)。is_real() 函数也被弃用,请改为使用 is_float()。

The "parent" Leyword

在没有父类的类中使用父类已被弃用,并且将来会抛出编译时错误。目前仅在运行时访问父类时才会生成错误。

Deprecated in PHP Ver 8

如果具有默认值的参数后面跟随一个必需参数,则默认值无效。自 PHP 8.0.0 起,则此操作已被弃用,并且通常可以通过删除默认值来解决,而无需更改功能 −

<?php
   function test($a = [], $b) {}  // Before
   function test($a, $b) {}      // After
?>

此规则的一个例外是形式为 Type $param = null 的参数,其中 null 默认值使类型隐式可为 null。这种用法仍然允许,但建议改为使用显式可为 null 的类型 −

<?php
   function test(A $a = null, $b) {} 	// Still allowed
   function test(?A $a, $b) {}         // Recommended
?>

显式将 exclude_disabled 设置为 false 调用 get_defined_functions() 已被弃用,并且不再有效。get_defined_functions() 永远不会包含已禁用的函数。

现在,返回 true 或 false 的排序比较函数将抛出弃用警告,并且应该用返回小于、等于或大于零的整数的实现来替换。

<?php
   // Replace
   usort($array, fn($a, $b) => $a > $b);
   // With
   usort($array, fn($a, $b) => $a <=> $b);
?>

Implicit Incompatible float to int Conversions

导致精度损失的浮点数到整数的隐式转换现在已弃用。这会影响数组键、强制模式下的 int 类型声明以及对整数进行操作的操作符。

Calling a Static Element on a Trait

直接在特性上调用静态方法或访问静态属性已弃用。只有在使用特性的类上才应访问静态方法和属性。

Date Functions

已弃用 date_sunrise() 和 date_sunset()。请改为使用 date_sun_info()。

已弃用 strptime()。请改为使用 date_parse_from_format()(用于与区域设置无关的解析)或 IntlDateFormatter::parse()(用于与区域设置相关的解析)。

已弃用 strftime() 和 gmstrftime()。您可以改为使用 date()(用于与区域设置无关的格式化)或 IntlDateFormatter::format()(用于与区域设置相关的格式化)。

Dynamic Properties

创建动态属性已弃用。相反,请使用允许动态属性的 stdClass。

PHP – Removed Extensions & SAPIs

在每个 PHP 新版本中,都会添加新功能,同时删除某些过时的功能。PHP 版本 7 是一个主要版本,其中一些 PHP 扩展和 SAPI(服务器端应用程序编程接口)被删除。在随后的 PHP 8 版本中,还删除了一些其他扩展。

在 PHP 中,扩展是使用 C/C++ 编写的库或插件,并编译到共享库中,以便可以加载到 PHP 解释器中。一旦 PHP 解释器启动,扩展中的函数就会对 PHP 脚本可用。

定期删除扩展是因为它们不再维护或已被更现代的替代方法所取代。例如,与 PHP 7 同时,ereg 扩展被 preg 扩展替换,mssql 扩展被 PDO_MSSQL 扩展替换。

Removed Extensions

以下扩展已随着 PHP 7 的生效而删除 −

  1. ereg 扩展替换为 preg

  2. mssql 扩展替换为 pdo_mssql

  3. mysql extension mysqli

  4. sybase_ct replaced by pdo_sybase

从 PHP 8 起,已移除以下扩展:

  1. Mcrypt - Mcrypt 扩展用于加密和解密,但它自 PHP 7.1 起已弃用,并在 PHP 8 中因安全漏洞而移除。

  2. MDB2 - MDB2 扩展,此前用于访问 MDB 数据库文件,已在 PHP 8 中移除,因缺乏维护。

  3. Ming - 由于 Flash 现已不受欢迎,Ming 扩展(用于生成 Flash 内容)已自 PHP 5.5 起弃用,并在 PHP 8 中移除。

  4. Phar Data - Phar Data 扩展用于访问 PHAR 档案中的数据,但已在 PHP 8 中移除,因存在其他访问 PHAR 数据的方法。

  5. SNMP - 由于未得到维护,SNMP 扩展已在 PHP 8 中移除。

  6. Tidy - 由于已添加新的 HTML 验证库,Tidy 扩展已在 PHP 中移除。

  7. Tokenizer - Tokenizer 扩展同样因同样的原因在 PHP 8 中移除。

  8. cURL - cURL 扩展已在 PHP 8.1 中移除,因已不再维护。

Removed SAPIs

SAPI 是 PHP 中服务器端应用程序编程接口的缩写。SAPI 负责将 PHP 代码转换为 Web 服务器可以理解的内容。它解析 PHP 代码并调用适当的 Web 服务器函数。然后,Web 服务器会生成一个 HTTP 响应,将其发回客户端。

从 PHP 7 起,已移除以下 SAPI(服务器端应用程序编程接口):

  1. aolserver

  2. apache

  3. apache_hooks

  4. apache2filter

  5. caudium

  6. cgi

  7. cgi-fcgi

  8. fastcgi

  9. isapi

  10. litespeed

  11. nsapi

  12. pwsapi

  13. router

  14. thttpd

  15. uwsgi

  16. webserver

  17. apache2filter

  18. continuity

  19. isapi

  20. milter

  21. nsapi

  22. pi3web

  23. roxen

  24. thttpd

  25. tux

  26. webjames

PHP – PEAR

PEAR 是 PHP Extension and Application Repository 的首字母缩写。它是一个 PHP 包或扩展的存储库。您可以自由地在您的代码中加入任何这些来自 PEAR 的扩展。PEAR 项目是由 Stig S. Bakken 于 1999 年成立的。

大多数 PHP 预编译发行版(如 XAMPP)已经将 PEAR 捆绑在其中。如果没有,您可以通过从 https://pear.php.net/go-pear.phar 下载 go-pear.phar 文件并运行来安装 PEAR:

php go-pear.phar

在 Windows 命令提示符中,以开始安装。

根据您对安装步骤的响应,PEAR 包管理器将安装在您在安装期间指定的路径中。

然后,您可以将该安装路径添加到您的 PATH 环境中。可以手动完成此操作(开始 > 控制面板 > 系统 > 环境),或运行(双击)新生成的 PEAR_ENV.reg,它现在位于 PHP 源代码目录中。

您现在可以通过运行该命令来访问 PEAR 包管理器:

C:\xampp\php>pear

在 Windows 命令提示符中。

您将按照以下方式获取 PEAR 命令的列表:

C:\xampp\php>pear
Commands:
build                  Build an Extension From C Source
bundle                 Unpacks a Pecl Package
channel-add            Add a Channel
channel-alias          Specify an alias to a channel name
channel-delete         Remove a Channel From the List
channel-discover       Initialize a Channel from its server
channel-info           Retrieve Information on a Channel
channel-login          Connects and authenticates to remote channel server
channel-logout         Logs out from the remote channel server
channel-update         Update an Existing Channel
clear-cache            Clear Web Services Cache
config-create          Create a Default configuration file
config-get             Show One Setting
config-help            Show Information About Setting
config-set             Change Setting
config-show            Show All Settings
convert                Convert a package.xml 1.0 to package.xml 2.0 format
cvsdiff                Run a "cvs diff" for all files in a package
cvstag                 Set CVS Release Tag
download               Download Package
download-all           Downloads each available package from the default channel
info                   Display information about a package
install                Install Package
list                   List Installed Packages In The Default Channel
list-all               List All Packages
list-channels          List Available Channels
list-files             List Files In Installed Package
list-upgrades          List Available Upgrades
login                  Connects and authenticates to remote server [Deprecated in favor of channel-login]
logout                 Logs out from the remote server [Deprecated in favor of channel-logout]
makerpm                Builds an RPM spec file from a PEAR package
package                Build Package
package-dependencies   Show package dependencies
package-validate       Validate Package Consistency
pickle                 Build PECL Package
remote-info            Information About Remote Packages
remote-list            List Remote Packages
run-scripts            Run Post-Install Scripts bundled with a package
run-tests              Run Regression Tests
search                 Search remote package database
shell-test             Shell Script Test
sign                   Sign a package distribution file
svntag                 Set SVN Release Tag
uninstall              Un-install Package
update-channels        Update the Channel List
upgrade                Upgrade Package
upgrade-all            Upgrade All Packages [Deprecated in favor of calling upgrade with no parameters]

使用 PEAR 安装软件包非常容易。寻找软件包的一种方法是使用官方 PEAR 站点 https://pear.php.net/packages.php ,然后运行

pear install <package-name>

下一步是在你的代码中使用 PEAR 软件包。为此,你应该在你的程序中使用 include、require、include_once 或 require_once 语句包含软件包的主要 PHP 脚本。

<?php
   include "PEARPACKAGE.php";
   . . . . .
   // rest of the code
   . . . . .
?>

Composer 是一款较新的 PHP 软件包管理器,是管理 PHP 项目软件包的替代可用管理器。Composer 也支持 PEAR 软件包的安装。对于 PHP 软件包分发,许多人更喜欢 Composer 而非 PEAR。

PHP – CSRF

缩写词“CSRF”代表跨站点请求伪造。CSRF 是一种 Internet 漏洞,涉及受信任网站用户的发出未经授权的命令。通过采取本章中说明的措施,可以为 PHP Web 应用程序提供充足的保护来防御此类攻击。

默认情况下,浏览器使用“GET”请求方法来发送数据。这通常用作 CSRF 中的利用点。为了将命令注入到特定网站中,攻击者会使用诸如“IMG”之类的 HTML 标签。例如,Web 应用程序的 URL 端点,如“/delete.php?empcode=1234”,会删除从 GET 请求的 empcode 参数中传递的帐户。现在,如果经过身份验证的用户在任何其他应用程序中遇到以下脚本。

<img src="http://example.com/delete.php?empcode=1234"
   width="0" height="0" border="0">

会不经意地导致与 empcode=1234 相关的数据被删除。

此问题的常见解决方法是使用 CSRF 令牌。CSRF 令牌是一串随机字符,嵌入到请求中,以便 Web 应用程序可以相信已从预期来源接收请求(按照正常工作流程)。

Steps to Implement CSRF

在 PHP 中实现 CSRF 令牌保护的步骤如下 -

  1. 通过启动新会话来开始脚本。

  2. 生成随机字符令牌。你可以使用 PHP 提供的几个内置函数来生成随机字符串。使用 md5() 函数来获取会生成唯一随机字符串的 uniqueid() 函数的哈希值。

  3. 在为用户准备以提交数据而提供的 HTML 表单内,包括一个隐藏文件,其值是上述步骤中生成的随机令牌。

  4. 在表单提交之后,服务器可以根据用户会话验证令牌,以消除恶意请求。

  5. 你还可以添加另一个赋值为当前时间的会话变量,并发送一个用于验证目的的到期时间。

Example

以下 PHP 代码实现了 CSRF 令牌验证机制。以下脚本生成一个令牌并将其嵌入到 HTML 表单中。

<?php
   session_start();
   if(!isset($_SESSION["csrf_token"])) {

      // No token present, generate a new one
      $token = md5(uniqid(rand(), true));
      $_SESSION["csrf_token"] = $token;

   } else {

      // Reuse the token
      $token = $_SESSION["csrf_token"];
   }
?>
<html>
<body>
   <form method="get" action="test.php">
      <input type="text" name="empcode" placeholder="empcode" />
      <input type="hidden" name="csrf_token" value="<?php echo $token;?>" />
      <input type="submit" />
   </form>
</body>
</html>

该表单提交到 "test.php" 脚本,如下所示 -

<?php
   session_start();
   echo "hello";
   if ($_GET["csrf_token"] == $_SESSION["csrf_token"]) {

      // Reset token
      echo $_GET["csrf_token"] . "<br>";
      echo $_SESSION["csrf_token"] . "<br>";
      echo "<h3>CSRF token validation successful. Proceed to further action</h3>";
   } else {
      echo "<h3>CSRF token validation failed</h3>";
   }
?>

它将生成以下 output

php csrf

要模拟 CSRF 验证失败,请打开浏览器的检查工具,手动编辑隐藏字段中的值,然后提交表单以查看令牌不匹配,从而导致验证失败。

PHP – FastCGI Process

PHP FastCGI 进程管理器 (PHP-FPM) 是一个有效的替代传统基于 CGI 的方法,它用于处理 PHP 请求,特别是在高流量环境中。PHP-FPM 有一些重要的特性。这些特性如下所列 −

Reduced Memory Consumption

借助处理请求的工作进程池,与为每个请求产生一个新进程的传统 CGI 方法相比,PHP-FPM 大大降低了内存开销。

Improved Performance

PHP-FPM 的工作进程是持久的。它允许它们处理多个请求。它不需要重复创建和销毁进程。这提高了响应时间,并改善了高并发处理。

Enhanced Scalability

PHP-FPM 的工作进程池可以根据流量需求进行动态调整,从而使它能够有效地扩展以处理不同的工作负载。

Advanced Process Management

PHP-FPM 提供平滑的启动和关闭。它还对进程管理有细颗粒度控制,包括紧急重启和对工作进程的监控。

Environment Isolation

PHP-FPM 能够为不同的应用程序或用户组创建不同的池,以便为每个环境提供更好的隔离和安全性。

Customizable Configuration

PHP-FPM 使用基于 php.ini 的配置选项。通过这些丰富的选项,可以微调其行为,以满足特定的应用程序要求。

Supports multiple PHP Versions

PHP-FPM 可同时管理多个 PHP 版本,从而可以在一台服务器上部署不同的 PHP 应用程序。

PHP-FPM 通常与 Nginx 或 Apache 等 Web 服务器一起使用。它用作处理 PHP 请求的后端处理器。由于其性能、可扩展性和可靠性,它已成为在生产环境中管理 PHP 应用程序的首选方法。

PHP – PDO Extension

PDO 是 PHP 数据对象 (PHP Data Objects) 的缩写。PHP 可以与大多数关系型和 NOSQL 数据库进行交互。默认的 PHP 安装附带已安装和启用的特定供应商的数据库扩展。除了适用于特定类型数据库的此类数据库驱动程序(例如适用于 MySQL 的 mysqli 扩展)之外,PHP 还支持抽象层,例如 PDO 和 ODBC。

PDO 扩展定义了一个轻量级的、一致的接口,用于在 PHP 中访问数据库。每个特定供应商扩展的功能不同于其他扩展。因此,如果你打算更改某个 PHP 应用程序的后端数据库,例如从 PostGreSql 更改为 MySQL,你需要对代码进行许多更改。另一方面,PDO API 除了指定要使用的数据库的新 URL 和凭据之外,不需要任何更改。

你当前的 PHP 安装必须具有相应的 PDO 驱动程序才能正常工作。目前使用相应的 PDO 接口支持以下数据库 −

Driver Name

Supported Databases

PDO_CUBRID

Cubrid

PDO_DBLIB

FreeTDS/Microsoft SQL Server/Sybase

PDO_FIREBIRD

Firebird

PDO_IBM

IBM DB2

PDO_INFORMIX

IBM Informix Dynamic Server

PDO_MYSQL

MySQL 3.x/4.x/5.x/8.x

PDO_OCI

Oracle Call Interface

PDO_ODBC

ODBC v3(IBM DB2、unixODBC 和 win32 ODBC)

PDO_PGSQL

PostgreSQL

PDO_SQLITE

SQLite 3 和 SQLite 2

PDO_SQLSRV

Microsoft SQL Server/SQL Azure

默认情况下,PDO_SQLITE 驱动程序在 php.ini 的设置中启用,因此如果你希望使用 PDO 与 MySQL 数据库进行交互,请确保通过删除前导分号取消注释以下行。

extension=pdo_mysql

你可以通过调用 PDO 类中的 PDO::getAvailableDrivers() 静态函数来获取当前可用的 PDO 驱动程序的列表。

PDO Connection

PDO 基本类的实例表示一个数据库连接。构造函数接受用于指定数据库源(称为 DSN)的参数,还可以接受用于指定用户名和密码(如果有的)的参数。

以下代码段是与 MySQL 数据库建立连接的典型方式 −

<?php
   $dbh = new PDO('mysql:host=localhost;dbname=test', $user, $pass);
?>

如果出现任何连接错误,将抛出 PDOException 对象。

Example

请看以下示例:

<?php
   $dsn="localhost";
   $dbName="myDB";
   $username="root";
   $password="";
   try{
      $dbConn= new PDO("mysql:host=$dsn;dbname=$dbName",$username,$password);
      Echo "Successfully connected with $dbName database";
   } catch(Exception $e){
      echo "Connection failed" . $e->getMessage();
   }
?>

它将生成以下 output

Successfully connected with myDB database

在错误的情况下 −

Connection failedSQLSTATE[HY000] [1049] Unknown database 'mydb'

PDO Class Methods

PDO 类定义以下静态方法——

PDO::beginTransaction

在获取连接对象后,你应调用此方法来启动事务。

public PDO::beginTransaction(): bool

此方法关闭自动提交模式。因此,你需要调用 commit() 方法才能持久更改数据库。调用 rollBack() 将回滚对数据库的所有更改并返回连接到自动提交模式。此方法成功返回 true,失败返回 false。

PDO::commit

commit() 方法提交事务。

public PDO::commit(): bool

由于 BeginTransaction 禁用了自动提交模式,因此你应在事务后调用此方法。它提交事务,将数据库连接返回到自动提交模式,直到下一次调用 PDO::beginTransaction() 开始新事务。此方法成功返回 true,失败返回 false。

PDO::exec

exec() 方法执行 SQL 语句并返回受影响的行数

public PDO::exec(string $statement): int|false

exec() 方法在单个函数调用中执行 SQL 语句,并返回该语句影响的行数。

请注意,它不返回 SELECT 语句的结果。如果你有一个在你的程序中只执行一次的 SELECT 语句,请考虑发出 PDO::query()。

另一方面,对于你需要多次发出的语句,请准备好一个 PDOStatement 对象 (使用 PDO::prepare()),然后使用 PDOStatement::execute() 发出该语句。

exec() 方法需要一个字符串参数,该参数表示要准备并执行的 SQL 语句,并返回由你发出的 SQL 语句修改或删除的行数。如果没有行受到影响,则 PDO::exec() 返回 0。

PDO::query

query() 方法准备并执行没有占位符的 SQL 语句

public PDO::query(string $query, ?int $fetchMode = null): PDOStatement|false

此方法在单个函数调用中准备并执行 SQL 语句,并将该语句作为一个 PDOStatement 对象返回。

PDO::rollBack

rollback() 方法回滚由 PDO::beginTransaction() 启动的事务。

public PDO::rollBack(): bool

如果数据库被设置为自动提交模式,则此函数在回滚事务后将恢复自动提交模式。

请注意,某些数据库(包括 MySQL)在事务中发出 DDL 语句(例如 DROP TABLE 或 CREATE TABLE)时会自动发出隐式 COMMIT,因此它将阻止你回滚事务边界内的任何其他更改。此方法成功返回 true,失败返回 false。

Example

以下代码在 MySQL 服务器上的 myDB 数据库中创建一个 student 表。

<?php
   $dsn="localhost";
   $dbName="myDB";
   $username="root";
   $password="";
   try{
      $conn= new PDO("mysql:host=$dsn;dbname=$dbName",$username,$password);
      Echo "Successfully connected with $dbName database";
      $qry = <<<STRING
      CREATE TABLE IF NOT EXISTS STUDENT (
         student_id INT AUTO_INCREMENT,
         name VARCHAR(255) NOT NULL,
         marks INTEGER(3),
         PRIMARY KEY (student_id)
      );
      STRING;
      echo $qry . PHP_EOL;
      $conn->exec($qry);
      $conn->commit();
      echo "Table created\n";
   }
   catch(Exception $e){
      echo "Connection failed : " . $e->getMessage();
   }
?>

Example

使用以下代码在上述示例中创建的 student 表中插入新记录——

<?php
   $dsn="localhost";
   $dbName="myDB";
   $username="root";
   $password="";
   try {
      $conn= new PDO("mysql:host=$dsn;dbname=$dbName",$username,$password);
      echo "Successfully connected with $dbName database";

      $sql = "INSERT INTO STUDENT values(1, 'Raju', 60)";
      $conn->exec($sql);
      $conn->commit();
      echo "A record inserted\n";
   } catch(Exception $e){
      echo "Connection failed : " . $e->getMessage();
   }
?>

Example

以下 PHP 脚本获取 student 表中的所有记录——

<?php
   $dsn="localhost";
   $dbName="myDB";
   $username="root";
   $password="";
   try {
      $conn= new PDO("mysql:host=$dsn;dbname=$dbName",$username,$password);
      echo "Successfully connected with $dbName database";
      $sql = "SELECT * from student";
      $statement = $conn->query($sql);
      $rows = $statement->fetchAll(PDO::FETCH_ASSOC);

      foreach ($rows as $row) {
         var_dump($row);
      }
   } catch(Exception $e){
      echo "Connection failed : " . $e->getMessage();
   }
?>

PHP - Function References

PHP 非常丰富,有内置函数。以下是各种重要函数类别的列表。还有其他各种此处未涵盖的函数类别。

选择一个类别,以查看与该类别相关的所有函数的列表。