Php 简明教程
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 版本。
-
1996 年 4 月,拉斯姆斯推出了 PHP/FI。它加入了对 DBM、mSQL 和 Postgres95 数据库、Cookie 和用户自定义函数的支持。PHP/FI 被赋予了 version 2.0 状态。
-
PHP:超文本预处理器 – PHP 3.0 版本是由泽夫·苏拉斯基和安迪·古特曼在重写 PHP 解析器后推出的,并采用了如今的缩写形式。它为多个数据库、协议和 API 提供了成熟的接口,支持面向对象编程,并实现了语言语法的统一。
-
PHP 4.0 在 2000 年 5 月发布,由 Zend 引擎提供支持。它支持多种 Web 服务器、HTTP 会话、输出缓冲、处理用户输入的安全方式以及多种新语言结构。
-
PHP 5.0 于 2004 年 7 月发布。它主要由其核心技术 Zend Engine 2.0 和十几项新特性驱动。PHP 的开发团队包括几十名开发人员,还有其他人员在从事与 PHP 相关的和支持其的项目,如 PEAR、PECL 和文档编撰。
-
PHP 7.0 于 2015 年 12 月发布。它最初被称为 PHP 下一代 (phpng)。开发者们重新编写了 Zend 引擎,并称其为 Zend 引擎 3。PHP 7 的一些重要特性包括其性能提升、内存用量降低、返回和标量类型声明以及匿名类。
-
PHP 8.0 于 2020 年 11 月 26 日发布。这是一个主版本,包含了相对于前期版本的大量的重大改进。其中一个突出特性是即时 (JIT) 编译,它可以提供大幅的性能提升。PHP 的最新版本是 8.2.8,它于 2023 年 7 月 4 日发布。
PHP Application Areas
PHP 是网络上使用最为广泛的语言之一。以下是 PHP 的一些应用领域:
-
PHP 是一种服务器端脚本语言,它嵌入在 HTML 中。它用于管理动态内容、数据库、会话跟踪,甚至可以构建完整的电子商务网站。尽管它特别适用于 Web 开发,但你还可以构建桌面独立应用程序,因为 PHP 也有命令行界面。你可以使用 PHP-GTK 扩展来在 PHP 中构建 GUI 应用程序。
-
PHP 被广泛用于构建 Web 应用程序,但你不限于仅输出 HTML。PHP 的输出能力包括丰富的文件类型,如图像或 PDF 文件、加密数据和发送电子邮件。你还可以轻松地输出任何文本,如 JSON 或 XML。
-
PHP 是一个跨平台语言,它可以在所有主流的操作系统平台上运行,并与大多数 Web 服务器程序(如 Apache、IIS、lighttpd 和 nginx)兼容。PHP 还通过 LDAP、IMAP、SNMP、NNTP、POP3、HTTP、COM 等协议支持其他服务。
以下是 PHP 的更多一些重要特性:
-
PHP 执行系统功能。它可以创建、打开、读取、写入和关闭文件。
-
PHP 可以处理表单。它可以从文件中收集数据、通过电子邮件发送数据、通过电子邮件保存数据到文件、将数据返回给用户。
-
你可以通过 PHP 在你的数据库中添加、删除和修改元素。
-
访问 Cookie 变量并设置 Cookie。
-
使用 PHP,你可以限制用户访问网站的某些页面。
-
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 的高级特性,特别是与服务器变量、使用后端数据库等网络概念相关的特性,你需要在本地计算机上安装 PHP 环境。
为了开发并运行 PHP 网页,你需要在你的计算机系统上安装三个至关重要的组成部分。
-
Web Server - PHP 几乎可以与所有网络服务器软件配合使用,包括微软的 Internet Information Server (IIS)、NGNIX 或 Lighttpd 等。最常用的网络服务器软件是免费的 Apache Server。此处免费下载 Apache: https://httpd.apache.org/download.cgi
-
Database - PHP 几乎可以与所有数据库软件配合使用,包括 Oracle 和 Sybase,但最常用的数据库是免费的 MySQL 数据库。此处免费下载 MySQL: [role="bare"]https://www.mysql.com/downloads/
-
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 ,并下载以下之一:
-
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/]
-
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,请按照以下步骤操作:
-
要开始安装,请打开 DMG 映像并双击映像以启动安装过程。
-
要启动 XAMPP,只需打开 XAMPP 控制并启动 Apache、MySQL 和 ProFTPD。XAMPP 控制的名称是“manager-osx”。
-
要停止 XAMPP,只需打开 XAMPP 控制并停止服务器。XAMPP 控制的名称是“manager-osx”。
-
XAMPP 控制面板是一个 GUI 工具,可以轻松从中启动和停止 Apache 服务器和 MySQL。
启动 Apache 模块后按下 Admin 按钮。XAMPP 主页会像下面这样显示−
PHP - History
PHP 最初是一个小型开源项目,随着越来越多人发现它的用处,逐渐演变。Rasmus Lerdorf 在 1994 年发布了 PHP 的第一个版本。当时,PHP 的意思是个人主页,因为他用它来维护自己的个人主页。后来,他添加了数据库支持,并称之为“个人主页/Forms 解译器”或 PHP/FI,可以用来构建简单的动态 Web 应用程序。
-
Zeev Suraski 和 Andi Gutmans 在 1997 年重写了解析器,并形成了 PHP 3 的基础。PHP 的语言名称也更改为递归缩写 PHP:超文本预处理器。他们还编写了 Zend Engine,这是 PHP 的编译器和运行时环境。搭载 Zend Engine 的 PHP 4 于 2000 年 5 月发布。
-
PHP 5 于 2004 年发布,其中包含许多新功能,例如面向对象编程支持、PHP 数据对象 (PDO) 和众多性能增强。
-
PHP 7 ,是 2015 年开发的一个新的主要 PHP 版本。它包含了新的语言功能,其中最值得注意的是针对函数的返回类型声明,它补充了现有的参数类型声明,以及在参数和返回类型声明中支持标量类型(整数、浮点数、字符串和布尔值)。
New Features in PHP 8
PHP 8 是最新的主要版本,于 2020 年 11 月发布。一些新功能和值得注意的更改包括:
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 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 采用 Sha1 和 MD5 等安全算法来加密字符串。此外,诸如 filter_var 和 strip_tags 等函数有助于为用户维护一个安全的环境。PHP 还支持 HTTPS 等安全通信协议。
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 定义了使用标记来让 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 能够识别标记 −
-
在构建 PHP 时选择“--enable-short-tags”配置选项。
-
将 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” 等。
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 服务器。
浏览到“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 - Comments
任何计算机程序(如 PHP 程序)中的注释都是一种特定的解释性文本,语言编译器/解释器会忽略它。其目的是帮助用户理解程序算法中使用的逻辑。
尽管在代码中放置注释并不是必须的,但这是强烈推荐的做法。注释也可以作为程序文档。在需要调试和修改代码时,注释也非常有用。
PHP 有两种注释格式 -
-
Single-line Comments
-
Multi-line Comments
Single-line Comments
它们通常用于短说明或与本地代码相关的注释。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 中的变量是一个命名内存位置,它保存属于某种数据类型的数据。
-
PHP 使用美元符号 ($) 前缀变量名称的惯例。
-
PHP 中的变量名称区分大小写。
-
变量名称遵循与 PHP 中其他标签相同的规则。有效的变量名称以字母或下划线开头,后面跟任意数量的字母、数字或下划线。
-
根据命名约定,“$name”、“$rate_of_int”、“$Age”、“$mark1”是 PHP 中的 valid variable names 示例。
-
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
PHP - Echo/Print
在 PHP 中, echo 和 print 语句都用于在浏览器或 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?
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 2
让我们看看它对浮点数变量的行为 −
<?php
$x = 10.25;
var_dump ($x);
?>
var_dump() 函数返回以下 output −
float(10.25)
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 脚本执行期间不能更改。
-
默认情况下,PHP 常量区分大小写。
-
根据惯例,常量标识符始终为大写。
-
常量名称以字母或下划线开头,后面跟任意数量的字母、数字或下划线。
-
不必在常量之前写美元符号($),但必须在变量之前使用美元符号。
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
-
不能通过简单赋值定义常量;只能使用 define() 函数定义常量。
-
可以定义和访问常量,而无需考虑变量作用域规则。
-
一旦常量设置好之后,就不能重新定义或取消定义。
Defining a Named Constant
PHP 函数库中的 define() 函数用于在运行时定义一个命名常量。
define(string $const_name, mixed $value, bool $case = false): bool
Parameters
-
const_name − 常量的名称。
-
value − 常量的值。它可以是一个标量值(int、float、string、bool 或 null),也可以接受数组值。
-
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 不区分大小写常量。
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
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
PHP – Data Types
“数据类型”一词是指将数据分类到不同类别中。PHP 共有八种数据类型,我们使用这些数据类型构造变量−
-
Integers − 无小数点的整数,例如 4195。
-
Doubles − 浮点数,例如 3.14159 或 49.1。
-
Booleans - 只有两种可能的值,即真或假。
-
NULL - 仅有一个值 NULL 的特殊类型。
-
Strings - 字符序列,例如“PHP 支持字符串操作”。
-
Arrays - 其他值的命名和索引集合。
-
Objects - 程序员定义的类的实例,既可以封装其他类型的值,也可以封装特定于该类的函数。
-
Resources - 保存对 PHP 外部资源(例如数据库连接)的引用的特殊变量。
前五个是简单类型,后两个(数组和对象)是复合类型。复合类型可以打包任意类型的其他任意值,而简单类型则不能。
在本章中,让我们详细讨论 PHP 的这些内置数据类型。
Integer Data Type in PHP
没有小数点(例如 4195)的整数在 PHP 中为 int 类型。整型数据类型是最简单的类型。它们对应于简单的整数,包括正数和负数。
-
int 是集合 Z = {…, -2, -1, 0, 1, 2, …} 中的数字。
-
int 可以用十进制(基数 10)、十六进制(基数 16)、八进制(基数 8)或二进制(基数 2)记法表示。
要使用八进制记法,数字应加上前缀“0o”或“0O”。要使用十六进制记法,数字应加上前缀“0x”。要使用二进制记法,数字应加上前缀“0b”。
下面给出一些 examples -
-
Decimal Integer - 201、4195、-15
-
Octal Integer - 0010、0O12、-0O21
-
Hexadecimal Integer - 0x10、-0x100
-
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, while 或 do-while 之类的控制结构。例如,
if (TRUE)
print("This will always print.");
else
print("This will never print.");
Interpreting Other Data Types as Booleans
这里有一组规则,你可以使用它来将其他数据类型解释为布尔值 −
-
如果该值是一个数字,则只有当该值等于零时它才为假,否则该值为真。
-
如果该值是一个字符串,则当该字符串为空(没有字符)或该字符串为“0”时它为假,否则为真。
-
NULL类型的变量总为假。
-
如果该值是一个数组,则当它不包含其他值时它为假;否则为真。对于一个对象,包含一个值意味着有一个已经赋值的成员变量。
-
有效的资源为真(虽然一些在成功时返回资源的函数在不成功时将返回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 中通过以下两种方式进行预处理:
-
以反斜杠 (\) 开头的某些字符序列将替换为特殊字符。
-
变量名(以 $ 开头)将替换为其值的字符串表示形式。
转义序列替换如下:
-
\n 被换行符替换
-
\r 被回车符替换
-
\t 被制表符替换
-
\$ 被美元符号本身 ($) 替换
-
\" 被单个双引号 (") 替换
-
\\ 被单个反斜杠 (\) 替换
PHP 也有字符串数据类型的 Heredoc 和 Nowdoc 表示法。
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 的变量具有以下属性 −
-
在布尔语境中,它被评估为 FALSE。
-
使用 IsSet() 函数测试时,它会返回 FALSE。
Note − PHP 中变量的数据类型在运行时根据赋值给它们的 值来确定。
Array Data Type in PHP
PHP 中的一个数组是一个有序映射,一个键与一个或多个值相关联。PHP 数组使用 array() 函数定义,或使用将数据放入方括号中的简短表示法进行定义。
请看以下 associative arrays 示例 −
Object Data Type in PHP
对象类型是一个由程序员定义的类的实例,它可以将其他类型的值和特定于该类的函数打包在一起。
要创建一个新对象,请使用 new statement 实例化一个类 −
class foo {
function bar() {
echo "Hello World.";
}
}
$obj = new foo;
$obj->bar();
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 中的某些类型转换运算符为 −
-
(int) 或 (integer) 转换为整数
-
(bool) 或 (boolean) 转换为布尔
-
(float) 或 (double) 或 (real) 转换为浮点数
-
(string) 转换为字符串
-
(array) 转换为数组
-
(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 。
-
如果字符串以数字开头,后面跟着非数字字符,则只会考虑初始数字。
-
如果字符串以非数字字符开头,并且数字位于中间,则强转运算符返回“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 包含用于执行类型强制转换的以下内置函数−
-
intval()
-
floatval()
-
strval()
让我们详细讨论这些内置函数。
The intval() Function
这个函数获取一个变量的整数值。
intval(mixed $value, int $base = 10): int
$base 参数默认为 10,这意味着该值转换为十进制数。
-
如果值为一个浮点数,则 intval() 函数返回一个整数,抛弃小数部分。
-
一个数字的字符串表示返回一个对应的整数,抛弃小数部分(如果存在的话)。
-
如果值为一个带有有效八进制数的字符串,并且基数为 8,则 intval() 函数返回一个对应的八进制数。
When the base is "0" ,值的转换基于字符前缀。
-
如果值以 0X 或 0x 开头,则返回一个十六进制数。
-
如果值以 0B 或 0b 开头,则返回一个二进制数
-
如果值以 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 中的“类型转换”与“类型混用”略有不同。
-
在类型混用中,当必要时 PHP 会自动将类型从一个转换到另一个。例如,如果将一个整数值分配给变量,它会变成一个整数。
-
另一方面,类型转换发生在用户显式定义他们想要转换的数据类型时。
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)
}
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
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
与单引号串一样,转义任何其他字符也将导致反斜杠被打印。双引号串最重要的特征是变量名将被展开。
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 )。
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, for 和 foreach 。这些语句的行为取决于布尔运算符返回的 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 ints 。 int 的大小依赖于平台。在 32 位系统上,最大值约为二十亿。64 位平台的最大值通常约为 9E18。
int 大小可以用常量 PHP_INT_SIZE 确定,最大值可以用常量 PHP_INT_MAX 确定,最小值可以用常量 PHP_INT_MIN 确定。
如果整数恰好超出了 int 类型的边界,或任何操作导致数字超出了 int 类型的边界,它将被解释为浮点数。
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 ints 。 int 的大小依赖于平台。在 32 位系统上,最大值约为二十亿。64 位平台的最大值通常约为 9E18。
int 大小可以用常量 PHP_INT_SIZE 确定,最大值可以用常量 PHP_INT_MAX 确定,最小值可以用常量 PHP_INT_MIN 确定。
如果整数恰好超出了 int 类型的边界,或任何操作导致数字超出了 int 类型的边界,它将被解释为浮点数。
PHP - Files & I/O
本章将说明与文件相关的以下函数 −
-
Opening a File
-
Reading a File
-
Writing a File
-
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 读取文件所需的步骤。
-
使用 fopen() 函数打开一个文件。
-
使用 filesize() 函数获取文件的长度。
-
通过 fread() 函数读取文件内容。
-
通过 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>
它将产生以下结果 −
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>
它将产生以下结果 −
我们已介绍了有关 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
PHP exp() Function
exp() 函数计算欧拉数 e 的指数。PHP 有一个预定义常量 M_E,表示欧拉数,等于 2.7182818284590452354。因此,exp(x) 返回 2.7182818284590452354x
此函数始终返回一个浮点数。
exp ( float $arg ) : float
PHP exp() 函数返回提升到给定 arg. 的欧拉数 e。请注意, e 是自然算法的底数。exp() 函数是自然对数的逆函数。
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
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
PHP log10() Function
log10 () 函数计算某个数字的以 10 为底的对数。以 10 为底的对数也称为 common 或 standard algorithm 。log10(x) 函数计算 log10x。它与自然算法之间的关系由以下等式表示 −
log10x=logex/loge10 ; So that
log10100=loge100/loge10 = 2
在 PHP 中, log10 由 log10() 函数表示
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
PHP max() Function
max() 函数返回数组中最大的元素,或者返回两个或两个以上逗号分隔参数中最大的参数。
max ( array $values ) : mixed
或者,
max ( mixed $value1 [, mixed $... ] ) : mixed
-
如果只给出了一个参数,则它应该是可能具有相同或不同类型的值的数组。
-
如果给出了两个或更多参数,则它们应该是具有相同或不同类型的任何可比较值。
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
PHP min() Function
min() 函数返回数组中最小的元素,或者返回两个或两个以上逗号分隔参数中最小的参数。
min ( array $values ) : mixed
或者,
min ( mixed $value1 [, mixed $... ] ) : mixed
-
如果只给出了一个参数,则它应该是可能具有相同或不同类型的值的数组
-
如果给出了两个或更多参数,则它们应该是具有相同或不同类型的任何可比较值
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
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
PHP round() Function
round() 函数可用于将任意浮点数四舍五入到所需精度级别。正精度参数使数字在小数点后四舍五入;而负精度导致数字在小数点前四舍五入。精度默认为“0”。
例如,round(10.6) 返回 11,round(10.2) 返回 10。此函数始终返回浮点数。
该函数还有另一个可选参数,称为 mode ,它采用稍后描述的重新定义的常量之一。
round ( float $value , int $precision , int $mode ) : float
Parameters
-
Value - 要舍入的浮点数。
-
Precision - 要舍入为几位小数。默认为 0。正精度在小数点后舍入给定的数字。负精度在小数点前舍入给定的数字。
-
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
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
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 提供了两种替代方法,可以使用 heredoc 和 newdoc 语法来声明单引号或双引号字符串。
-
单引号字符串不会解释转义字符,也不会展开变量。
-
另一方面,如果您声明一个双引号字符串,而该字符串本身包含双引号字符,则需要使用 "\" 符号对其进行转义。 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 中,对象和数组是两种复合数据类型。
-
数组是有序集合,其中包含其他数据类型的元素,这些元素不一定相同。
-
对象是内置类或用户定义类的实例,由属性和方法组成。
Arrays in PHP
数组是一种数据结构,其中一个变量存储了一个或多个数据值。PHP 中的数组是有序映射,它将值与键关联。
-
PHP 中有两种声明数组的方法。一种是使用内置的 array() 函数,另一种是将数组元素置于方括号内。
-
仅包含值集合的数组称为 indexed array 。每个值由从 0 开始的位置索引标识。
-
如果数组是键值对集合,则称为 associative array 。该对的关键组成部分可以是数字或字符串,而值部分可以是任何类型。
The array() Function in PHP
内置 array() 函数使用提供给它的参数并返回数组类型对象。一个或多个以逗号分隔的参数是数组中的元素。
array(mixed ...$values): array
括号中的每个值可以是单个值(可能是数字、字符串、任何对象,甚至另一个数组),或键值对。键与其值之间的关联由“⇒”符号表示。
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 语句如何工作的一个典型示例:
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 解析器遇到 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
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 引入了以下标量类型声明 −
-
Int
-
Float
-
Bool
-
String
-
Interfaces
-
Array
-
Callable
旧版本的 PHP 只允许使用数组、可调用和类类型作为类型提示。此外,在旧版本的 PHP(PHP 5)中,致命错误为可恢复错误,而新版本(PHP 7)返回可抛出错误。
标量类型声明以两种模式实现 −
-
Coercive Mode − 强制是默认模式,无需指定。
-
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 - Return Type Declarations
PHP 版本 7 将标量类型声明功能扩展到了函数的返回值。根据此新规定,返回类型声明指定函数应返回的值的类型。我们可以为返回类型声明以下类型:
-
int
-
float
-
bool
-
string
-
interfaces
-
array
-
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 会在运行代码之前警告错误,方法是在错误位置显示错误行:
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 中具有以下类型的运算符 −
-
Arithmetic Operators
-
Comparison Operators
-
Logical Operators
-
Assignment Operators
-
String Operators
-
Array Operators
-
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 支持两种类型的赋值运算符 −
-
Simple Assignment Operator − 它是使用最广泛的运算符。它用于为变量或常量赋值。
-
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 中有两个运算符用于处理字符串数据类型 −
-
"."(点)运算符是 PHP 的连接运算符。它连接两个字符串操作数(将右手字符串的字符追加到左手字符串),并返回一个新字符串。
-
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
我们在上面讨论的所有运算符可以归类为以下几类−
-
单目前缀运算符,它位于单个操作数之前。
-
二元运算符,它取两个操作数并执行各种算术和逻辑运算。
-
条件运算符(三元运算符),它取三个操作数并根据第一个表达式的求值结果求值第二个或第三个表达式。
-
赋值运算符,它将值分配给变量。
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 |
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 – 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)
}
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
)
但是,使用(…)运算符的效率要高得多,因为它避免了函数调用的开销。
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
PHP – Decision Making
计算机程序默认按照输入-处理-输出路径顺序执行。这种顺序流可以借助所有计算机编程语言(包括 PHP)提供的决策控制语句进行更改。
Decision Making in a Computer Program
决策是预测程序执行期间出现的条件并根据条件采取指定操作。
你可以在代码中使用条件语句来做出决策。实现条件逻辑的能力是编程语言基本要求之一。
Decision Making Statements in PHP
PHP 支持以下三个决策表述:
-
if…​else statement − 如果你希望在条件为真的时候执行一组代码,而在条件不为真的时候执行另一组代码,那就使用此语句。
-
elseif statement − 将此语句与 if…else 语句搭配使用,以便在许多条件中有一个为真时执行一组代码
-
switch statement − 如果希望从许多代码块中选择一个要执行的代码块,请使用 Switch 语句。 switch 语句用于避免长长的 if..elseif..else 代码块。
几乎所有编程语言(包括 PHP)都定义了 if-else 语句。这允许有条件地执行代码片段。PHP 中使用 if-else 语句的语法类似于 C 中的语法 −
if (expr)
statement1
else
statement2
此处表达式是布尔表达式,对 true 或 false 进行计算
-
任何涉及布尔运算符(如 <、>、⇐、>=、!= 等)的表达式都是布尔表达式。
-
如果表达式产生 true,则会执行后续语句 − 它可以是简单语句或复合语句,即一对大括号中含有的语句组。
-
如果表达式为 false,则后续语句被忽略,而程序流程会继续执行下一条语句。
-
使用 else 语句是可选的。如果程序逻辑需要在表达式( if 关键字之后)计算结果为 false 的情况下执行另一个语句或一组语句。
elseif 语句是 if 与 else 的组合。它允许你检查多个条件的 TRUE 值,并在其中一个条件计算结果为 TRUE 时执行一组代码。就像 else 语句一样, elseif 语句是可选的。
switch 语句类似于针对同一表达式的一系列 if 语句。我们将在本教程的后几章详细了解这些语句。
PHP - If…Else Statement
实现条件逻辑的能力是任何编程语言(包括 PHP)的基本要求。PHP 有三个关键字(也称为 language constructs) – if, elseif 和 else – 根据不同的条件做出决策。
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 语句总后跟一个布尔表达式。
-
如果布尔表达式的估值为 true,PHP 将执行布尔表达式后面的语句。
-
如果布尔表达式的估值为 false,则该语句将被忽略。
-
如果算法需要在表达式为 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 为 if 和 else 语句提供了替代语法。将左大括号改为冒号 (:),将右大括号改为 endif; ,这样可以将 HTML 块添加到 if 和 else 部分。
<?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 语言结构是 if 和 else 的组合。
-
与 else 类似,它指定了一个备用语句,当原始 if 表达式计算为假时执行。
-
然而,与 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 匹配,则执行相应的语句块。
-
switch 语句按行执行大括号内的情语句。
-
当且仅当找到一个 case 语句,其表达式运算得到的值与 switch 表达式的值相匹配时,PHP 才会开始执行语句,直到 switch 块的末尾,或者第一次遇到一个 break 语句。
-
如果您不在 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 支持以下四种类型的循环。
-
for − 对代码块执行指定的次数。
-
foreach − 对数组中每个元素对代码块进行循环
-
while − 在指定条件为真的情况下对代码块进行循环
-
do-while − 对代码块进行一次循环,然后只要特殊的条件为真,就可以重复循环
此外,我们还将说明在 PHP 中如何使用 continue 和 break 语句来控制循环的执行。
PHP for Loop
当你清楚知道要执行一条或多条语句的次数时,就可以使用 for 语句。
PHP while Loop
while 语句会在测试表达式为 true 的情况下执行代码块。
如果测试表达式为 true,则会执行代码块。代码执行后,测试表达式将再次进行评估,并且循环将继续进行,直到发现测试表达式为 false。
PHP break Statement
PHP break 关键字用于过早终止循环的执行。
break 语句位于语句块内。它会为你提供完全的控制权,无论何时你想要退出循环,都可以退出。退出循环后,会执行循环的后续语句。
PHP - For Loop
程序默认情况下会按照语句的顺序进行执行。如果程序流被定向到程序中的任何早期语句,它就构成了循环。PHP 中的 for 语句是构成 PHP 脚本中循环的便捷工具。在本节中,我们将讨论 PHP 的 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 循环如何运行 −
表达式中的值在每次循环开始之前都会被检查。如果 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
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
PHP - Do…While Loop
"do…while" 循环是 PHP 中提供的另一种循环构造。此类型的循环类似于 while 循环,只是测试条件在每次迭代的末尾检查,而不是在新迭代的开始检查。
while 循环在进入循环之前验证真条件,而在 "do…while" 循环中,真条件在重新进入循环之前得到验证。因此,无论真条件如何,"do…while" 循环都保证至少有一次迭代。
下图通过使用两个比较流程图表示形式,展示了 "while" 循环和 "do…while" 循环的区别。
构成“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 括号中的测试条件设置为在计数器大于所需最后值时运行循环。
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 中的任何类型的循环( for 、 while 或 do-while )都被设计为按照所使用的测试条件运行一定次数的迭代。循环块中的 break 语句将程序流带到块外部,放弃可能剩余的其他迭代。
break 语句通常有条件地使用。否则,循环将终止而不完成第一次迭代。
syntax 中 break 语句如下所示:
while(expr){
if (condition){
break;
}
}
以下 flowchart 说明 break 语句的工作原理:
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, while 或 do-while 循环。与 break 类似, continue 关键字通常也以条件方式使用。
while(expr){
if (condition){
continue;
}
}
以下 flowchart 解释了 continue 语句的工作原理 −
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 是一个静态类型语言。
-
PHP 中的数组是一个有序的映射,它将值与键相关联。
-
PHP 数组可用于实现不同的数据结构,例如堆栈、队列、列表(向量)、哈希表、字典等。
-
数组元素的值部分可以是其他数组。这个事实可以用来实现树数据结构和多维数组。
在 PHP 中声明数组有两种方法。一种是使用内置 array() 函数,另一种是使用更短的语法,其中数组元素放在方括号内。
The array() Function
内置 array() 函数使用提供给它的参数并返回数组类型对象。一个或多个以逗号分隔的参数是数组中的元素。
array(mixed ...$values): array
括号中的每个值可以是单个值(可能是数字、字符串、任何对象,甚至另一个数组),或键值对。键与其值之间的关联由“⇒”符号表示。
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(称为数组索引)访问。
-
Indexed Array - 仅含有一系列值的数组称为索引数组。每个值通过从“0”开始的位置索引进行标识。值以线性方式存储和访问。
-
Associative Array - 如果数组是键值对的集合,则称其为关联数组。对的键组件可以是数字或字符串,而值部分可以是任何类型。关联数组按键值(而不是在严格的线性索引顺序中)存储元素值。
-
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)
}
}
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 循环都可以用来遍历数组。如果我们想使用 for 或 while 循环,我们必须使用 count() 函数找到数组中的元素数量,并将其值用作计数 for 或 while 循环的测试条件。
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
您还可以使用 while 或 do-while 循环遍历索引数组。同样,我们需要使用 count() 函数找到数组长度。
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() 输出得到验证。
PHP - Associative Array
如果 PHP 数组中的每个元素都是键值对,则这样的数组称为 associative array 。在这类型数组中,每个值都由其关联的键而不是索引标识。
-
关联数组用于实现字典、映射、树等数据结构。
-
在 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、 while 或 do-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 支持简单的和多维数组并且可以是用户创建的或由其他函数创建的。
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 通过通过定义独立的可重用函数块来安排处理逻辑,支持结构化编程方法。这种方法的主要优点是代码变得易于理解、开发和维护。
下图显示了如何将工资计算过程逐步细化为独立的可重用函数。
Types of Functions
你已经见过了很多诸如 fopen() 和 fread() 等函数。它们是内置函数,但 PHP 也允许你创建你自己的函数。PHP 中有两种类型的函数−
-
Built-in functions − PHP 的标准库包含大量用于字符串处理、文件 I/O、数学计算等的内置函数。
-
User-defined functions − 你还可以创建用户自定义函数,针对编程逻辑的要求进行定制。
可以通过传递必要的数据(称为 parameters 或 arguments ),让一个函数从任何其他函数调用。被调用的函数将它的结果返回给调用环境。
这里有两部分需要明确 −
-
Creating a PHP Function
-
Calling a PHP Function
事实上,你几乎不需要创建你自己的 PHP 函数,因为已经为不同的区域创建了超过 1000 个内置库函数,你只需要根据你的需求调用它们。
请参阅 PHP Function Reference ,了解一组有用的函数。
User-defined Functions in PHP
创建你自己的 PHP 函数非常容易。我们从一个简单的示例开始,然后再详细阐述它的工作原理。假设你想创建一个 PHP 函数,当你在浏览器中调用它时,它会简单的写一条消息。
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 。实际上,这两个术语之间存在一定的差异。
-
参数是指函数定义中使用的变量,而实参是指在调用时传递给函数的值。
-
实参可以是字面量、变量或表达式。
-
函数定义中的参数通常也称为 formal arguments ,而传递的内容称为 actual arguments 。
-
形式实参和实际实参的名称不必相同。实际实参的值会从左到右的顺序分配给相应的形式实参。
-
函数中定义的形式实参数量和传递的实际实参数量应相同。
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 中。
-
Actual Arguments −在函数调用中传递的参数。
-
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(),这些函数可以用类似的结果来使用。
-
func_num_args() − 返回传递给函数的自变量的数量。
-
func_get_arg() - 从参数列表返回一个项目
-
func_get_args() - 返回一个包含函数参数列表的数组
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
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 中,可以定义递归函数。
-
当某个问题通过其自身来定义时,就使用递归。
-
有时,使用迭代方法解决问题可能会很乏味。递归方法为看似复杂的问题提供了非常简洁的解决方案。
-
PHP 中的递归与 C 和 C++ 中的递归非常相似。
-
在遍历嵌套数据结构,以及排序算法或搜索算法中,特别使用递归函数。
-
二叉树遍历、堆排序和寻找最短路径是使用递归的一些情况。
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。
Binary Search using Recursion
让我们看另一个理解递归工作原理的示例。眼前的问题是检查给定数字是否存在于列表中。
虽然我们可以使用 for 循环并比较每个数字,对列表中的特定数字执行顺序查找,但顺序查找效率不高,尤其是在列表过大的情况下。在此,我们可以使用二分查找算法检查索引“high”是否大于索引“low”。根据“mid”变量中存在的值,再次调用该函数以搜索该元素。
我们有一个数字列表,按升序排列。然后,找到列表的中点,并将检查限制在中点的左侧或右侧,具体取决于所需的数字是否小于或大于中点的数字。
下图显示了二分查找的工作原理 -
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 是一种动态类型语言。换句话说,$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 7 开始,类型提示支持已扩展到函数返回值,以防止意外的返回值。您可以通过在冒号 (:) 符号后添加预期类型,在参数列表后添加类型提示返回值。
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 变量可以是以下三种类型中的任何一种 −
主脚本中的变量也可以通过 include 或 require 语句引入任何其他脚本。
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 =
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 是一个在定义时没有任何指定名称的函数。此类函数也称为 closure 或 lambda function 。
有时,您可能只想使用一次函数。匿名函数最常见的一个用法是创建一个 inline callback function 。
匿名函数是使用 Closure 类实现的。闭包是一个匿名函数,它围绕其定义的环境进行闭合。
用于定义匿名函数的 syntax 如下 −
$var=function ($arg1, $arg2) { return $val; };
请注意, function 关键字与左括号之间没有函数名,并且函数定义后有一个分号。这意味着匿名函数定义是表达式。当分配给变量时,可以使用变量名稍后调用匿名函数。
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
PHP - Arrow Functions
箭头函数在 PHP 7.4 版本中引入。箭头函数为编写匿名函数提供了更简单、更简洁的语法。在 PHP 7.4 中,引进了关键词 " fn " 来定义箭头函数,取代原先通用的关键词 " function "。
fn (argument_list) => expr
-
" ⇒ " 符号后面只允许有一个表达式,其值为箭头函数的返回值。
-
箭头函数没有显式的 return 语句。
-
与匿名函数一样,箭头函数赋值给变量才能被调用。
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
还可以使用箭头函数作为回调函数。回调函数作为其他函数的参数之一来使用。箭头函数会即时执行,而 "⇒" 符号后面的表达式的值会变成父函数的参数,父函数可以是内置函数,也可以是用户定义的函数。
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 变量。
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 变量可以是四种作用域类型之一−
-
Local Variables
-
Global Variables
-
Static Variables
-
Function Parameters
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 ”。
-
任何在任何函数、方法或类外部声明的用户自定义变量也是一个全局变量。然而,要访问它,你需要使用 global 关键字。
-
相比之下, superglobals 始终在 PHP 脚本的任何地方都可用,而无需以 global 关键字对其进行声明。
PHP 中的大多数超级全局变量都是关联数组,并且 Web 服务器会填充它们。因此,如果在命令行环境中运行脚本,则某些超级全局变量可能为空。
PHP 中的超级全局变量列表包括以下内容:
-
$GLOBALS
-
$_SERVER
-
$_GET
-
$_POST
-
$_FILES
-
$_COOKIE
-
$_SESSION
-
$_REQUEST
-
$_ENV
在本章中,我们将对 PHP 中的这些超级全局变量进行简要介绍。在后续章节中,我们将详细讨论这些超级全局变量。
$_GET
它是通过附加至 HTTP 请求的 URL 的查询字符串传给当前脚本的变量的关联数组。请注意,除了 GET 请求之外,还通过包含查询字符串的所有请求填充该数组。
查询字符串是所有变量及其值按“var=val”形式形成的列表,并以“&”符号连接起来。
查询字符串本身在问号“?”之后附加至 PHP 脚本名称。例如 http://localhost/hello.php?first_name=Amar&last_name=Sharma 。
$_POST
它是由 HTTP POST 方法通过查询字符串传给 URL 的键-值对的关联数组,在请求中使用 URLEncoded 或 multipart/form-data 内容类型。
$HTTP_POST_VARS 还包含与 $_POST 相同的信息,但不是超级全局变量,现已不赞成使用。向服务器发送具有 POST 请求的数据的最简单方法是将 HTML 表单的方法属性指定为 POST。
$_FILES
变量 $_FILES 是一个关联数组,其中包含通过 HTTP POST 方法上传的项。当一个 HTML 表单包含一个文件类型的输入元素,它的 enctype 属性设置为 multipart/form-data,并且方法属性设置为 HTTP POST 方法时,就会上传一个文件。
$_COOKIE
Cookie 是服务器存储在客户端计算机上的文本文件,并且它们被保留以用于跟踪目的。
超级全局变量 $_COOKIE 将通过 HTTP 请求传递给当前 PHP 脚本的变量以 cookie 的形式存储起来。
$_SESSION
HTTP 会话是用户与服务器建立连接的时间持续期,以及连接被终止的时间之间的时间段。在此间隔期间,某些数据是以会话变量的形式永久存在于页面中。
$_SESSION 超全局变量是会话变量的关联数组,当前脚本可以使用。
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
PHP - $_SERVER
$_SERVER 是 PHP 中的超全局变量。其中包含有关 HTTP 标头、路径以及脚本位置等信息。
-
$_SERVER 是一个关联数组,其中包含所有服务器和执行环境相关信息。
-
此关联数组中的大多数条目均由 Web 服务器填充。由于服务器会省略一些信息或提供其他信息,因此这些条目可能因不同的 Web 服务器而异。
-
对于在命令行上运行的 PHP 脚本,大多数这些条目都不可用或没有任何意义。
-
PHP 还将使用请求标头中的值创建其他元素。这些条目的名称为 "HTTP_",后跟标头名称,该名称以大写字母表示,并用下划线替换连字符。
-
例如,"Accept-Language" 标头可以作为 $_SERVER['HTTP_ACCEPT_LANGUAGE']。
-
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 变量的内容集合组成。
-
“php.ini” 文件中的设置决定了此变量的组成。
-
“php.ini” 中的一个指令是 request_order ,它决定了 PHP 注册 GET、POST 和 COOKIE 变量的顺序。
-
此数组中列出的变量的存在和顺序根据 PHP variables_order 进行定义。
-
如果通过命令行运行 PHP 脚本,则 argc 和 argv 变量不会包含在 $_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 如下 −
$_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 。
您还可以在 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 - $_POST
$_POST 是 PHP 中的一个预定义的超全局变量。它是由 HTTP POST 方法(在请求中使用 URLEncoded 或 multipart/form-data 内容类型)传递给 URL 的键值对关联数组。
-
$HTTP_POST_VARS 也包含与 $_POST 相同的信息,但不是超全局变量,现已弃用。
-
使用 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 。你应该在屏幕上获得以下输出 −
当您按下 Submit 按钮时,数据将使用 POST 方法提交至“hello.php”。
您还可以将 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 - $_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 −
当 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" −
您应该在浏览器窗口中获得类似的 output −
在以下示例中,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 数组包含以下属性−
-
$_FILES['file']['name'] − 用户选择要上传的文件的原始名称。
-
$_FILES['file']['type'] − 文件的 MIME 类型。一个示例是“image/gif”。但是,PHP 方面并未检查此 MIME 类型。
-
$_FILES['file']['size'] − 上传的文件大小(以字节为单位)。
-
$_FILES['file']['tmp_name'] − 已上传的文件在服务器上存储的临时文件名。
-
$_FILES['file']['full_path'] − 浏览器提交的完整路径。PHP 8.1.0 起可用。
-
$_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 按钮。
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 - $_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
PHP 超全局变量 $_COOKIE 存储通过 HTTP 请求以 cookie 形式传递给当前 PHP 脚本的变量。$HTTP_COOKIE_VARS 也包含相同信息,但它不是超全局变量,现在已被弃用。
What is a Cookie?
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);
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
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>
单击“提交”按钮后,它将显示创建的所有会话变量的列表 -
接下来,在“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 - 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 是必需的。以下是参数说明 -
-
$filename - 此参数是一个字符串,表示要打开的资源。它可以是本地文件系统中的文件,也可以是具有 scheme:// 前缀的远程服务器上的文件。
-
$mode - 一个字符串,用于表示对文件/资源的访问类型。
-
$use_include_path - 一个可选布尔参数,如果要搜索 include_path 中的文件,可以将其设置为“1”或 true。
-
$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() 函数从中读取数据。
PHP - Read File
PHP 中有许多选项可用于读取已使用 fopen() 函数打开的文件中的数据。PHP 库中的以下内置函数可以帮助我们执行读取操作 −
-
fgets() − 从文件指针获取一行。
-
fgetc() − 从文件指针返回一个包含单个字符的字符串。
-
fread() − 从文件指针读取指定数量的字节。
-
fscanf() − 从文件中读取数据,并按照指定格式对其进行解析。
The fgets() Function
fgets() 函数可以从一个打开的文件中返回一行。此函数停止在指定长度的新行或 EOF 处返回,以先遇到的为准,并在失败时返回 false 。
fgets(resource $stream, ?int $length = null): string|false
此处, $stream 参数是使用 fopen() 函数以读取或读/写模式打开的文件的文件指针或句柄,而 $length 是指定要读取的字节数的可选参数。
当读取到“length-1”个字节或遇到新行时,读取操作结束,以先遇到的为准。
The fgetc() Function
fgetc() 函数返回从文件句柄当前位置读取的单个字符。遇到 EOF 时,它返回 false 。
fgetc(resource $stream): string|false
此处, $stream 参数是使用 fopen() 函数以读取或读/写模式打开的文件的文件指针或句柄。
The fread() Function
PHP 中的 fread() 函数是用于从文件读取数据的二进制安全函数。虽然 fgets() 函数仅从文本文件中读取,但 fread() 函数可以以二进制模式读取文件。
fread(resource $stream, int $length): string|false
此处, $stream 参数是使用 fopen() 函数以二进制读取或读/写模式( rb 或 rb+ )打开的文件的文件指针或句柄。 $length 参数指定要读取的字节数。
如果未给出 $length 参数,PHP 将尝试读取整个文件,直到到达 EOF,但需符合指定的块大小。
The fscanf() Function
PHP 中的 fscanf() 函数从文件流中读取输入并根据特定格式对其进行解析,从而将其转换为指定类型的变量。每次调用此函数都将从文件中读取一行。
fscanf(resource $stream, string $format, mixed &...$vars): array|int|false|null
此处, $stream 参数是指针,它指向使用 fopen() 函数打开的文件,且为读取模式。同时, $format 为一个字符串,包含下列一个或多个格式说明符 −
-
%% − 返回一个百分比
-
%b − Binary number
-
%c − 根据 ASCII 值设置字符
-
%f − Floating-point number
-
%F − Floating-point number
-
%o − Octal number
-
%s − String
-
%d − 有符号十进制数
-
%e − Scientific notation
-
%u − 无符号十进制数
-
%x − 小写字母十六进制数
-
%X − 大写字母十六进制数
$vars 是一个可选参数,它通过引用指定包含解析值的变量。
假设“employees.txt”文件在与下方 PHP 脚本相同的目录中。文本文件中每一行都有每个员工的 name, email, post 和 salary ,由制表符分隔。
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 的内置函数库在这方面提供了一些实用函数。本章中讨论的某些函数有 −
-
file_exists() − 测试文件是否存在
-
is_file() − fopen() 返回的句柄引用的是文件还是目录
-
is_readable() − 测试你打开的文件是否允许读取数据
-
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
The is_file() Function
file_exists() 函数为现有文件和目录返回 true 。 is_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
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 。你将获得如下所示的“另存为”对话框 -
你可以选择一个名称并下载该文件。
对于大型文件,你可以从文件流中以一定预定义大小的块中读取它。如果 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
你可以通过三种不同的方式将现有文件复制到新文件中 -
-
从一个文件读取一行,并循环写入另一个文件
-
将全部内容读入字符串,将字符串写到另一个文件
-
使用 PHP 的内置函数库,包括 copy() 函数。
Method 1
在第一种方法中,你可以从现有文件中读取每一行,并写入新文件,直到现有文件到达文件结尾。
在以下 PHP 脚本中,一个已存在的文件 (hello.txt) 会在循环中逐行读取,并且每行会被写入到另一个文件 (new.txt)
我们假设“hello.txt”包含以下文本 -
Hello World
TutorialsPoint
PHP Tutorials
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 中。它会返回写入的字节数。
PHP - Append File
在 PHP 中,fopen() 函数返回一个文件指针,用于不同的打开模式,例如“w”表示写入模式,“r”表示读取模式,“r+”或“r+”表示同时读/写操作,以及“a”表示追加模式。
当使用“w”模式参数打开文件时,它总是打开一个新文件。这意味着如果文件已经存在,其内容将丢失。随后的 fwrite() 函数将数据放在文件开始位置。
假设存在一个名为 “new.txt” 的文件,内容如下:
Hello World
TutorialsPoint
PHP Tutorial
以下语句 -
$fp = fopen("new.txt", "w");
删除所有现有数据,然后再写入新内容。
The fseek() Function
PHP 的 fseek() 函数让您能够将文件指针放置到任何您想要的位置 −
fseek(resource $stream, int $offset, int $whence = SEEK_SET): int
$whence 参数是指从哪里计算偏移量。它的值有 −
-
SEEK_SET − 将位置设置为等于偏移字节。
-
SEEK_CUR − 将位置设置为当前位置外加偏移量。
-
SEEK_END − 将位置设置为文件末尾外加偏移量。
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.";
}
?>
Deleting the Symlink to a File
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
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 |
Post |
Salary |
|
Ravishankar |
Manager |
40000 |
|
Kavita |
Assistant |
25000 |
|
Nandkumar |
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
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
-
$directory - 第一个参数 $directory 是必须的。它是一个字符串,其中包含要创建的新目录的绝对路径或相对路径。
-
$permissions - 第二个参数 $permissions 是一个八进制数字,带有四个八进制数字。第一个数字始终为零,第二个数字指定属主的权限,第三个数字指定属主的用户组,第四个数字指定其他人。
每个数字都是针对每种权限类型的值的和 -
-
1 = execute permission
-
2 = write permission
-
4 = read permission
$permissions 参数的默认值为 0777 ,这意味着创建目录时启用了执行、写入和读取权限。
请注意,在 Windows 操作系统上工作时,$permissions 参数会被忽略。
-
$recursive - 如果为 true,则指定目录的任何父目录也会被创建,并具有相同的权限。
-
$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 资源管理器将显示嵌套目录结构,如下所示:
The chdir() Function
PHP 中的 chdir() 函数对应于 Linux/Windows 中的 chdir 或 cd 命令。它会导致根据需要更改当前目录。
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
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() 打开。
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
在我们详细介绍之前,让我们定义与面向对象编程相关的术语。
-
Class − 这是一个由程序员定义的数据类型,它包括本地函数和本地数据。可以将类视作一个模板,用于创建同一类型的(或类)对象的许多实例。
-
Object - 由类定义的数据结构的单个实例。定义一个类一次,然后创建属于它的许多对象。对象也被称为实例。
-
Member Variable − 这些是类内定义的变量。该数据对外不可见,可通过成员函数访问。一旦创建了对象,这些变量就会被调用为对象的属性。
-
Member function − 这些是类内定义的函数,用于访问对象数据。
-
Inheritance − 当一个类继承父类的现有函数时,该类被称为继承。在此,子类将继承父类的一些或全部成员函数和变量。
-
Parent class − 被另一个类继承的类。这也被称为基类或超类。
-
Child Class − 从另一个类继承的类。这也称为子类或派生类。
-
Polymorphism − 这是一个面向对象的概念,同一个函数可用于不同的目的。例如,函数名称保持不变,但是它可以接受不同数量的参数并执行不同的任务。
-
Overloading − 一种类型的多态,其中一些或全部操作符具有不同的实现,具体取决于它们的争论类型。同样,函数也可以通过实现不同而重载。
-
Data Abstraction − 数据的任何表示形式,其中实现细节是隐藏的(抽象的)。
-
Encapsulation − 指一个概念,即我们将所有数据和成员函数封装在一起以形成一个对象。
-
Constructor − 指一个特殊类型的函数,当从类中进行对象形成时,该函数会自动被调用。
-
Destructor − 指一个特殊类型的函数,当一个对象被删除或超出范围时,该函数会自动被调用。
Defining PHP Classes
在 PHP 中定义新类的通用格式如下 −
<?php
class phpClass {
var $var1;
var $var2 = "constant string";
function myfunc ($arg1, $arg2) {
[..]
}
[..]
}
?>
下面是每一行的说明 −
-
特殊格式 class ,后跟要定义的类的名称。
-
一个大括号,包围任意数量的变量声明和函数定义。
-
变量声明以特殊格式 var 开头,后跟一个常规的 $ 变量名;它们还可以将初始赋值设为常量值。
-
函数定义看起来很像独立的 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
Inheritance
PHP 类定义可以使用 extends 子句从父类定义中继承,语法如下:
class Child extends Parent {
<definition body>
}
继承的效果是子类(或子类或派生类)具有以下特征 -
-
自动具有父类的所有成员变量声明。
-
自动具有与父类相同的所有成员函数,这些函数(默认情况下)将按照它们在父类中的工作方式工作。
以下示例继承 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
除非您另行指明,否则类的属性和方法均为公共的。也就是说,它们可以在三种可能的情况下进行访问 -
-
从声明它的类外部
-
从声明它的类中
-
从实现声明它的类的另一个类中
到目前为止,我们已经看到了所有成员作为公共成员。如果您希望限制类成员的可访问性,则可以将类成员定义为 private 或 protected 。
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 是其类的实例。它的特点是类中定义的属性和函数。
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()
方法,因为构造函数在对象声明后立即被调用。但是,此构造函数将针对每个对象调用,因此每个对象都具有 title
和 price
属性的相同值。
要使用不同的值初始化每个对象,请使用带参数定义 @{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, private 和 protected 被称为 access modifiers 。这些关键字控制类属性和方法的可访问性或可见性的范围。其中一个关键字在声明成员变量和定义成员函数时添加为前缀。
PHP 代码是否可以自由地访问类成员,或者被限制获取,或者有条件地访问,是由这些关键字决定的 -
-
Public − 类成员从任何地方都可以访问,即使在类作用域外,但只可以使用对象引用。
-
Private − 类成员可以在类中访问。它防止外部类访问成员,即使参考了类实例。
-
Protected − 成员只能在类及其子类中访问,其他地方都不能访问。
数据封装原则是面向对象编程方法的基础。它指的是将对象的成员数据或属性置于类外部环境的访问范围之外,只允许通过类中可用的方法或函数进行受控访问。
要实现封装,类的成员数据被设为 private ,方法被设为 public 。
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";
?>
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
因此,可以看到受保护的成员只能被同一类和继承类的对象访问。对于所有其他环境,受保护的成员不可访问。
可访问性规则可以由下表总结:
PHP – Inheritance
继承是面向对象编程方法论的基本原则之一。继承是一种软件建模方法,它允许扩展现有类以构建新类,而不是从头开始构建新类。
PHP 提供了所有功能在其对象模型中实现继承。在 PHP 软件开发中纳入继承会产生代码再利用,消除冗余的代码重复及逻辑组织。
想象一下你需要设计一个新类,这个类的大部分功能已经在一个现有类中得到明确定义。继承允许你扩展现有类,添加或移除其功能,并开发一个新类。事实上,PHP 有“extends”关键词来建立现有类和新类之间的继承关系。
class newclass extends oldclass {
...
...
}
当一个新类(以后将被称为继承类、子类、子类,等等)与一个现有类(将被称为基类、超类、父类,等等)拥有“是”关系时,继承就会出现。
在 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 class , myabsmethod() 作为其 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 中的命名空间的优点 −
-
命名空间有助于避免某人使用第三方类/函数/常量定义的类/函数/常量之间的名称冲突。
-
命名空间提供了对 Extra_Long_Names 进行别名(或缩短)的能力,从而提高了源代码的可读性。
-
PHP 命名空间提供了一种对相关的类、接口、函数和常量进行分组的方法。命名空间名称不区分大小写。
Defining a Namespace
PHP 的名称空间关键字用于定义新的命名空间。
namespace myspace;
包含命名空间的 “.php” 文件必须在文件顶部声明命名空间,然后再声明任何其他内容(声明指令除外)。在命名空间中声明类、函数和常量会影响其访问权限。
一个 PHP 脚本可以除了定义命名空间之外,还包含其他代码。为了加载在相同代码中定义的命名空间,PHP 具有“use”关键字。
use myspace;
Include Namespace
可以有一个脚本包含名称空间声明,以及在其中使用 include 语句加载该名称空间的另一个脚本。
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
通过遵循以下规则,可以解决不同名称空间之间出现的函数/类/常量名称冲突:
-
不带名称空间分隔符符号(/)的名称空间标识符表示其正在引用当前名称空间。这是一个不合格的名称。
-
如果它包含分隔符符号,如 myspace\space1,则解析为 myspace 下的子名称空间 space1。这种类型命名是相对名称空间。
-
完全限定名称空间的名称以“\”字符开头。例如,“\myspace”或“\myspace\space1”。
-
完全限定名称解析为绝对名称空间。例如,\myspace\space1 解析为 myspace\space1 名称空间。
-
如果名称出现在全局名称空间中,“namespace\”前缀会被移除。例如,“namespace\space1”解析为 space1。
-
然而,如果它出现在另一个名称空间内,则其处理方式有所不同。例如,如果 namespace\space1 在 myspace 中,则它等同于“myspace\space1”。
-
限定名称中的名称的第一段根据当前类/名称空间导入表进行翻译。
-
如果没有导入规则适用,则在名称前加上当前名称空间。
-
类名类型名称根据类/名称空间导入表进行翻译,函数名称根据函数导入表进行翻译,常量根据常量导入表进行翻译。
-
对于不合格名称,如果未应用导入规则并且名称指向函数或常量,且代码在全局命名空间之外,则该名称在运行时解析。首先,它从当前名称空间查找函数,然后尝试查找并调用全局函数。
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
}
-
rewind() 方法将 Iterator 倒回到第一个元素。这是开始 foreach 循环时调用的第一个方法。它不会在 foreach 循环之后执行。
-
current() 方法返回当前元素。
-
key() 方法在 foreach 循环的每次迭代中返回当前元素的键。
-
next() 方法在每次 foreach 循环之后调用,并向前移动到下一个元素。
-
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, private 和 protected 。
封装是指将对象的数据成员或属性远离类外部环境获取的方式,仅允许通过类中可用的方法或函数进行受控访问。
下图展示了面向对象编程方法中封装的原则。
PHP 的关键字列表包含以下关键字,这些关键字决定了 PHP 中对象实例的属性和方法的可访问性 −
-
Public − 类成员可以在任何地方访问,即使是在类的作用域之外,但只能通过对象引用访问。
-
Private − 类成员可以在类本身内访问。它防止成员在类实例的引用下从类外访问。
-
Protected − 成员只能在类和其子类内访问,在其他任何地方都不能访问。
这三个关键字“ public, private 和 protected ”通常称为访问修饰符。它们也被称为可见性模式,因为它们决定了某类成员可以使用的范围。
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 - 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 方法的类可以扩展,但子类不能覆盖它。
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
在此,
-
__set() 用于向受保护的、私有的或不存在的不可访问属性写入数据。
-
__get() 从不可访问属性读取数据。
-
__isset() 对不可访问属性调用 isset() 或 empty()。
-
在不可访问的属性上调用 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 协议来与服务器建立通信。
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 />";
?>
它将产生以下结果 −
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>
它将产生以下结果 −
-
PHP 默认变量 $_PHP_SELF 用于 PHP 脚本名称,当你点击“提交”按钮时,将调用相同的 PHP 脚本,并将产生以下结果 −
-
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>
它将产生以下结果 −
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
指定在将表单数据发送到服务器之前对其进行编码的方法。可能的值为 −
-
application/x-www-form-urlencoded − 默认值。
-
multipart/form-data − 如果表单包含带有类型=文件的 <input> 元素,请使用此方法。
-
text/plain − 对于调试目的很有用。
Method Attribute
表示提交表单所用 HTTP 方法的字符串。以下方法是 method 属性的可能值 −
-
post − POST 方法;表单数据作为请求正文发送。
-
get (default) − GET;表单数据附加到带有“?”分隔符的操作 URL。在表单没有副作用时使用此方法。
-
dialog − 当表单位于
<dialog>
内部时,关闭该会话框并触发提交事件,而无需提交数据或清除表单。
Target Attribute
一个指示提交表单后显示响应的位置的字符串。应为下列选项之一:
-
_self (default) − 加载到与当前浏览上下文相同的上下文。
-
_blank − 加载到一个新的未命名浏览上下文中。
-
_parent − 加载到当前浏览上下文的父上下文中。
-
_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">
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 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>
数字类型文本字段在右侧显示了向上/向下计数器箭头。只接受数字,可以增量或减量。
如果电子邮件字段中的数据无效,您将收到如下错误信息。
同样,任何不正确的 URL 格式也会显示如下所示的错误 −
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
}
?>
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() 也对表单验证有用。
-
trim() − 从字符串的开头和结尾移除空白
-
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 代码。
以下 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>";
}
}
?>
当脚本从服务器的文档根目录运行时,此为表单中填写的示例数据 −
当提交时, output 呈现如下所示 −
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 −
PHP - File Inclusion
你可以在服务器执行之前将一个 PHP 文件的内容包含到另一个 PHP 文件中。有两个 PHP 函数可用于将一个 PHP 文件包含到另一个 PHP 文件中。
-
The include() Function
-
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>
它将产生以下结果 −
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
-
GET 方法生成一个较长的字符串,它显示在服务器日志中和浏览器的 Location: 方框中。
-
GET 方法只能发送最多 1024 个字符。
-
如果你要向服务器发送密码或其他敏感信息,请切勿使用 GET 方法。
-
GET 不能用于向服务器发送二进制数据,例如图像或 word 文档。
-
通过 QUERY_STRING 环境变量可以访问 GET 方法发送的数据。
-
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>
它将产生以下结果 −
The POST Method
POST 方法通过 HTTP 标头传输信息。该信息已被编码,就像 GET 方法中所描述的那样,并放入名为 QUERY_STRING 的标头中。
-
POST 方法对要发送的数据量没有任何限制。
-
POST 方法可用于发送 ASCII 和二进制数据。
-
POST 方法发送的数据会通过 HTTP 标头,因此安全性取决于 HTTP 协议。通过使用安全 HTTP,你可以确保你的信息安全。
-
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>
它将产生以下结果 −
Difference between GET and POST
GET 方法和 POST 方法之间的主要区别在于,虽然附加到 URL 的请求参数在浏览器的 URL 中公开出来,但 POST 数据包含在消息正文中,并且不会在 URL 中显示出来。因此,GET 方法不应用于将敏感数据发送到服务器。
其次,GET 方法中的请求数据不能超过 2048 个字符,只能由 ASCII 字符组成,而使用 POST 方法时,对请求数据没有限制,也可以是二进制的(POST 数据的默认最大大小由 php.ini 文件中的 post_max_size 设置决定)
PHP 提供了以下三个 superglobals 来检索和处理请求参数 −
-
$_GET − 用于使用 GET 方法访问所有发送信息的一个关联数组。
-
$_POST − 用于使用 POST 方法访问所有发送信息的一个关联数组。
-
$_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” −
您应该会在浏览器窗口中获取类似 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 脚本。
上传文件的过程遵循以下步骤 −
-
用户打开包含 HTML 表单的页面,其中包含文本文件、浏览按钮和提交按钮。
-
用户单击浏览按钮,并从本地 PC 中选择要上传的文件。
-
系统会在文本文件中显示所选文件的完整路径,然后用户单击提交按钮。
-
所选文件将发送到服务器上的临时目录。
-
表单操作属性中指定为表单处理器的 PHP 脚本将检查文件是否已到达,然后将文件复制到目标目录中。
-
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) -
单击 File 按钮,浏览到待上传的目标文件,并单击 Upload 按钮。
服务器返回以下消息 -
PHP - Cookies
万维网由 HTTP 协议驱动,该协议是一种无状态协议。Cookie 机制帮助服务器维护以前请求的信息。PHP 透明支持 HTTP cookie。
-
当客户端首次发送其请求时,服务器随其响应一起包含一个小数据段,作为 cookie。PHP 提供了 setcookie() 方法,用于在响应中注入 cookie。
-
此 cookie 数据以文本文件形式存储在客户端计算机中。在同一客户端的后续访问中,这些 cookie 将作为 request 标头的组成部分包含在内。
-
服务器使用客户端请求中存在的所有 cookie 来填充 PHP 超级全局变量 “$_COOKIE”。
本章将教您如何设置 cookie、如何访问 cookie 以及如何删除 cookie。
The Anatomy of a 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。
How to Set a Cookie in PHP?
PHP 包含 setcookie 函数,用于创建要随 HTTP 响应一起发送给客户端的 cookie 对象。
setcookie(name, value, expire, path, domain, security);
Parameters
以下是所有参数的详细信息-
-
Name -这将设置 cookie 的名称,并存储在名为 HTTP_COOKIE_VARS 的环境变量中。在访问 cookie 时使用此变量。
-
Value -这将设置命名变量的值,并且是您实际上要存储的内容。
-
Expiry − 此处指定了自 1970 年 1 月 1 日格林威治时间 00:00:00 起的秒数中的未来时间。在此时间之后,Cookie 将变得不可访问。如果未设置此参数,则会在关闭 Web 浏览器时自动使 Cookie 过期。
-
Path − 此处指定了 Cookie 生效的目录。单个正斜杠字符允许 Cookie 对所有目录生效。
-
Domain − 在非常大的域中,此可用于指定域名,并且必须包含至少两个句点才有效。所有 Cookie 仅对创建它们的 host 和域有效。
-
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 可在浏览器的开发者工具的“应用程序”选项卡下查看。
如下面的 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.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”保存在文档根目录文件夹中,并在客户端浏览器中打开它。
按 Submit 按钮。浏览器将显示已创建的会话变量 −
浏览器通过遵循所示的链接导航到另一个页面。它读回会话变量。
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,
]);
?>
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
-
to − 必需。指定电子邮件的接收者/收件人
-
subject − 必需。指定电子邮件的主题。此参数不能包含任何换行符
-
message − 必需。定义要发送的邮件。每一行都应该用 LF (\n) 分隔。行数不得超过 70 个字符
-
headers − 可选。指定其他标头,例如发件人、抄送和密件抄送。应该用 CRLF (\r\n) 分隔其他标头
-
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 - 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 处理。 |
The strip_tags() Function
strip_tags() 函数从给定的字符串中删除所有 HTML 和 PHP 标记。
strip_tags(string $string, array|string|null $allowed_tags = null): string
当您希望确保用户输入不包含任何潜在的恶意标记时,这个函数非常有用。
allowed_tags 参数是一个可选的第二个参数,用于指定不应删除的标记。这些标记可以以字符串的形式给出,也可以作为数组给出。
The addslashes() Function
addslashes() 函数向字符串添加反斜杠。
addslashes(string $string): string
此函数返回一个字符串,在需要转义的字符前面添加反斜杠。这些字符为 −
-
Single Quote (')
-
Double Quote (")
-
Backslash (\)
-
NUL (The NUL Byte)
在向数据库中存储用户输入且希望防止 SQL 注入攻击时,请使用此函数。
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 |
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>
假设服务器正在运行,则将上述脚本放置在文档根文件夹中并在浏览器中访问。
填写数据并提交。浏览器会回显结果,然后重新渲染表单。现在,如果您尝试刷新浏览器页面,将会弹出一个警告,如下所示 −
如果您按 Continue ,则会再次发布相同数据。
可以使用以下图形理解问题 −
在 PHP 脚本中执行以下步骤以避免问题 −
-
HTML 表单之前的 PHP 脚本启动一个新会话。
-
检查表单是否已用 POST 方法提交。
-
如果是,请将表单数据存储到会话变量中
-
将浏览器重定向到结果页面。在我们的示例中,即为同一页面。使用 exit 命令停止此脚本,确保不会再执行更多代码。
-
如果 PHP 发现请求方法不是 POST,则会检查会话变量是否已设置。如果是,则会与刚复制的表单一同呈现。
-
现在,即使刷新了表单,您也已成功避免了重新提交的可能性。
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 引擎)。它缩短了页面刷新时间,并且为用户提供了迅速而灵敏的体验。
What is Required to Run AJAX?
AJAX 使用的技术已经在所有现代浏览器中实现。因此,客户端不需要任何额外的模块来运行 AJAX 应用程序。AJAX 使用的技术有 −
-
{s0} − 它是 AJAX 的重要部分。它允许你创建客户端功能。或者我们可以说它用于创建 AJAX 应用程序。
-
{s1} − 它用于在 Web 服务器和客户端之间交换数据。
-
{s2} − 它用于在 Web 浏览器和 Web 服务器之间执行异步数据交换。
-
{s3} − 它用于向网页文本提供标记和样式。
-
{s4} − 它用于动态地与网页布局和内容进行交互并更改它们。
在 PHP 中使用 AJAX,将需要使用 JavaScript 中的 XMLHttpRequest 对象向 PHP 服务器发送请求。然后 PHP 服务器将处理请求并返回响应,通常以 JSON 或 XML 的形式。随后 JavaScript 代码能够分析响应并相应地更新网页。
JavaScript 中的 XMLHttpRequest 对象是基于浏览器的 API,允许开发者向服务器发出 HTTP 请求而无需刷新该页面。这是 AJAX 编程的基础,这允许动态且互动的 Web 应用。
XMLHttpRequest 对象可以用来 −
-
从服务器中检索数据,如 JSON、XML 或 HTML。
-
向服务器发送数据,如表单数据或文件上传。
-
无需重新加载即可更新网页。
-
创建聊天应用程序和其他交互式功能。
要使用 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);
PHP - AJAX Search
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 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 Auto Complete Search
自动完成功能是一种预测机制,当用户在提供的搜索框中输入数据时显示输入建议。它也被称为实时搜索,因为它对用户的输入作出反应。在本例中,我们将使用 PHP 中的 AJAX 和 XML 解析器来演示自动完成文本框的使用。
此应用程序有三个主要部分 −
-
The XML Document
-
JavaScript Code
-
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 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 - 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 标签为数据元素定义用户指定的属性。
Types of XML Parsers
在 PHP 中,有两种类型的 XML 解析器 −
-
Tree based parsers
-
Event based parsers
Tree-based Parsers
使用这种类型的解析器,PHP 将在内存中加载整个 XML 文档,并将 XML 文档转换为树结构。它分析整个文档,并为树元素提供访问权限。
For smaller documents, tree-based parser works well ,但对于大型 XML 文档,它会导致重大的性能问题。 SimpleXML parser 和 DOM XML parser 是基于树的解析器的示例
Simple XML Parser
简单 XML 解析器也称为基于树的 XML 解析器,它将解析简单的 XML 文件。简单 XML 解析器将调用 simplexml_load_file() 方法以从特定路径获取 xml 的访问权限。
Event-based Parsers
基于事件的解析器不会在内存中加载整个 XML 文档。相反,它一次读取一个节点。解析器允许你实时交互。一旦你移到下一个节点,以前的那个节点就会从内存中移除。
由于没有涉及内存过载,因此这种类型的解析器适用于大型 XML 文档,并且解析文档的速度比任何基于树的解析器都要快。XMLReader 和 XML Expat Parser 是基于事件的解析器的示例。
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 。
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 网络应用程序在登录之前将对用户进行认证,通过询问他的凭据,诸如 username 和 password 。然后根据服务器上可用的用户数据对凭据进行检查。在这个例子中,用户数据是用关联数组的形式提供的。以下 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
Incorrect Password
Incorrect Username
当用户单击底部的链接时,会话变量将被删除,且登录屏幕将重新出现。
PHP - Facebook Login
可以使用社交媒体登录(也称为 SSO)要求用户登录 Web 应用程序。这样用户无需创建一个新帐户。相反,用户可以使用其现有的社交媒体帐户信息登录。一些社交媒体登录的示例包括:谷歌、Facebook、LinkedIn、Apple。
在本章中,我们将说明如何使用 Facebook 证书激活登录 PHP 应用程序。
添加 Facebook 登录功能的第一步是创建一个 Facebook 应用程序。访问 https://developers.facebook.com/apps/creation/ 并使用您的 Facebook 帐户登录。
接下来,输入要创建的 Facebook 应用程序的名称 −
进入应用程序设置并获取应用程序 ID 和密钥 −
将平台选为网站 −
接下来,您需要在 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 集成文件系统包含四个文件,如下所示 -
-
constants.php − 这个文件包含 API 用户名、密码和签名。
-
CallerService.php − 这个文件包含用于调用 PayPal 服务的 PayPal 服务。
-
confirmation.php − 这个文件包含执行付款处理所需的最少字段的表单,它将返回付款成功或失败。
-
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>
PHP & MySQL
PHP 几乎可以与所有数据库软件一起使用,包括 Oracle 和 Sybase,但最常用的是免费提供的 MySQL 数据库。
What you should already have ?
-
您已经学习了 MySQL 教程以了解 MySQL 基础知识。
-
下载并安装了最新版本的 MySQL。
-
使用密码 guest123 创建了数据库用户 guest 。
-
如果您尚未创建数据库,则需要 root 用户及其密码才能创建数据库。
我们已将本章分为以下几个部分 −
-
* Connecting to MySQL database* − 学习如何使用 PHP 打开和关闭 MySQL 数据库连接。
-
* Create MySQL Database Using PHP* −本部分说明如何使用 PHP 创建 MySQL 数据库和表。
-
* Delete MySQL Database Using PHP* −本部分说明如何使用 PHP 删除 MySQL 数据库和表。
-
* Insert Data To MySQL Database* −创建数据库和表后,就会希望将数据插入创建的表中。本会话将带你实际演练数据插入过程。
-
* Retrieve Data From MySQL Database* −了解如何使用 PHP 从 MySQL 数据库中检索记录。
-
* Using Paging through PHP* −本部分说明如何将查询结果显示到多个页面以及如何创建导航链接。
-
* Updating Data Into MySQL Database* −本部分说明如何使用 PHP 更新 MySQL 数据库中的现有记录。
-
* Deleting Data From MySQL Database* −本部分说明如何使用 PHP 删除或清除 MySQL 数据库中的现有记录。
-
* 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”文件中一些重要指令的列表:
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_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,所有错误,不包括通知。开发服务器应至少设置为默认值;仅正式服务器才能考虑使用较低的值。
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-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 根目录的一个子目录中),请在此处设置此值。
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
每家公司都基于其最佳实践遵循自己的编码规范。编码规范是必需的,因为可能会有许多开发者在研究不同的模块,因此,如果他们开始发明自己的规范,那么源代码将变得非常难以管理,并且在未来难以维护该源代码。
以下是人们应该使用编码规范的部分原因:
-
你的同伴程序员必须理解你生成的代码。编码规范可作为团队全体人员解读代码的蓝图。
-
通过一致的编码实现的简单性和清晰性让你避免了常见错误。
-
如果你在一段时间后修改你的代码,那么该代码变得容易理解。
-
遵循统一编码规范会让软件的质量更高。
在使用 PHP 编码时可以遵循一些准则。
Indenting and Line Length
使用 4 个空格的缩进,不要使用任何制表符,因为不同的计算机对制表符使用不同的设置。建议将行长度保持在大约 75-85 个字符以内,以便于更好地阅读代码。
Control Structures
这些内容包括 if、for、while、switch 等。控制语句在控制关键字和开括号之间应该有一个空格,以区别于函数调用。强烈建议你始终使用大括号,即使在技术上它们是可选项的情况下也是如此。
Function Calls
函数调用时不应该在函数名称、开括号和第一个参数之间使用空格;在逗号和每个参数之间使用空格;在最后一个参数、闭括号和分号之间不使用空格。以下是一个示例:
$var = foo($bar, $baz, $quux);
PHP - Regular Expressions
正则表达式本身不过是字符的序列或模式。它们为模式匹配功能提供基础。
使用正则表达式,可以在另一个字符串中搜索特定字符串,可以用另一个字符串替换一个字符串,还可以将一个字符串拆分成许多块。
PHP 提供特定于两组正则表达式函数的函数,每个函数都对应一定类型的正则表达式。您可以根据您的喜好使用其中任何一个。
-
POSIX Regular Expressions
-
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 开头的任何字符串。 |
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 中,错误的处理方法有 -
-
The die() function
-
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 。在执行某些数学运算(例如以负数执行按位移位运算)时,可能会发生这种类型的错误。
DivisionByZeroError
DivisionByZeroError 类是 ArithmeticError 类的子类。当除法运算中的分母值为零时,会发生此类型的错误。
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”指令。
Exceptions Handling in PHP
PHP 具有一个类似于其他编程语言的异常模型。异常很重要,并提供了对错误处理的更好控制。
让我们解释一下与异常相关的新的关键字。
-
Try − 使用异常的函数应位于“try”块中。如果异常未触发,则代码将照常继续。但是,如果异常触发,则会“抛出”异常。
-
Throw − 这是触发异常的方法。每个“投掷”都必须至少有一个“捕获”。
-
Catch − “catch”块检索异常并创建一个包含异常信息的对象。
当抛出异常时,语句后面的代码不会执行,并且 PHP 将尝试查找第一个匹配的 catch 块。如果未捕获异常,则会使用“未捕获异常”发出 PHP 致命错误……
-
可以在 PHP 中抛出并捕获(“捕获”)异常。代码可以包围在 try 块中。
-
每个 try 必须至少有一个相应的 catch 块。可以使用多个 catch 块来捕获不同类别的异常。
-
可以在 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 类中使用。
-
getMessage() − 异常消息
-
getCode() − 异常代码
-
getFile() − source filename
-
getLine() − source line
-
getTrace() − backtrace() 的 n 个数组
-
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, throw 和 finally 来处理异常。如果错误是程序自身无法处理的意外程序结果,则必须使用 die() 终止程序或设置自定义错误处理程序。
另一方面,异常是指可以通过某种方式处理的意外情况,在异常从正常流中抛出后,程序可以继续运行。
可以通过 PHP 代码中的 catch 关键字抛出异常,并使用该关键字捕获异常。可能容易出现异常的代码块被 try 块包围。每个 try 至少必须有一个对应的 catch 或 finally 块。
Try, Throw, Catch, and Finally
与异常相关的四个关键字具有以下作用 −
-
Try − 将可能发生异常的代码块放在“try”块中。如果未触发异常,则代码继续执行。但是,如果确实发生了异常,则会“抛出”异常。执行暂停,并且 PHP 查找匹配的“catch”块。如果未捕获异常,则 PHP 会发出致命错误。
-
Throw − 以下是如何触发异常。每个“throw”至少必须有一个“catch”或“finally”块。
-
Catch − 一个检索异常并在对象中创建包含异常信息的块。可以使用多个 catch 块来捕获不同的异常。
-
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 类是用户异常的基础。它实现可抛出的接口。
该类定义以下方法 −
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
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 块内的代码都将在 try 和 catch 块之后始终执行,并且在恢复正常执行之前执行。
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 的值,以只报告特定类型的错误 −
-
E_ALL(针对除了严格注释以外的所有错误)
-
E_PARSE (parse errors)
-
E_ERROR (fatal errors)
-
E_WARNING (warnings)
-
E_NOTICE (notices)
-
E_STRICT (strict notices)
在编写 PHP 程序时,最好使用 PHP 感知编辑器,例如 BBEdit 或 Emacs。这些编辑器的一个特色功能是语法高亮显示。它会根据程序中不同部分的内容更改这些部分的颜色。例如,字符串为粉色,if 和 while 等关键词为蓝色,注释为灰色,变量为黑色。
Microsoft 的 VS Code 也是编辑 PHP 代码的不错选择。如果您安装 VS Code 扩展 Intelephense,在编辑器窗口中输入 PHP 语句时,将获得类型提示和错误消息。
另一个功能是引号和括号匹配,它有助于确保您的引号和括号处于平衡状态。当您键入“}”之类的闭合定界符时,编辑器将高亮显示它匹配的开“{”。
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 都使用大括号将多个语句组织成一个单一代码块。函数调用以函数名开头,后跟用括号括起来并用逗号分隔的实际参数,在两种情况下都一样。
-
PHP 中的所有变量看起来都像 Perl 中的标量变量:一个带有美元符号 ($) 前缀的名称。
-
由于这两种语言都是动态类型的,因此你无需在使用 PHP 和 Perl 变量之前声明其类型。
-
在 PHP 中,和 Perl 一样,变量除了当前持有的值之外没有固有类型。你可以在同一类型变量中存储数字或字符串。
-
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 array 或 associative 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,使闭包成为控制器并使其控制进一步执行。
CakePHP
CakePHP ( https://cakephp.org/ ) 是以简单的方式构建简单而强大的Web应用程序的极好来源。PHP中内置的一些强大功能包括输入验证、SQL注入预防,它们可以使您的应用程序保持安全。
Zend
Zend ( https://framework.zend.com/ ) 是一个现代框架,用于执行高端Web应用程序。它基于加密和安全编码工具工作。Zend Framework是专业PHP包的集合,安装量超过5.7亿次。
它可用于使用PHP 5.6+开发Web应用程序和服务,并使用广泛的语言功能提供100%面向对象代码。
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 应用程序具有自己的优点和缺点−
-
它为开发人员提供了更好的控制和灵活性。
-
同时,对于一个仅使用核心 PHP 开发的大型应用程序可能会变得难以管理和维护。
现在,让我们来看看使用 PHP 框架的优缺点−
-
Symfony、Laravel 或 Yii 等 PHP 框架提供了一种更加标准化的 Web 应用程序开发方式。由于框架处理了大部分例行且重复的部分,因此开发人员可以更加专注于应用程序逻辑。因此,花在调试上的时间减少了。
-
另一方面,与核心 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 架构。
应用中每个层的角色分离如下 −
-
Model − 指数据结构。在本例中指数据库。
-
View − 指用户界面。指 HTML 和 CSS。
-
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 – 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。
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 −
如果你使用 URL http://localhost/hello.php?email= abc@example.com ,
Email is valid
如果 URL 为 http://localhost/hello.php?email=a b c@example.com ,
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 要进行编码的值中存在一个或多个 NAN 或 INF 值 |
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, throw 和 finally 关键字实现。
The Throwable Interface
PHP 中的异常实现了 Throwable interface 。Throwable 接口充当任何可通过 throw 语句引发对象的基类,包括 Error 和 Exception 对象。
用户定义的类不能直接实现 Throwable 接口。相反,要声明一个用户定义的异常类,必须扩展 Exception class 。
带有潜在异常的 PHP 代码被 try 块包围。如果找到异常对象,则抛出该对象,以方便捕获潜在的异常。每个 try 必须至少有一个对应的 catch 或 finally 块。此外,对应于 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。
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 的两种数据类型 resource 和 NULL - 被归类为 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
PHP – Hashing
“哈希” 一词表示一种对数据(特别是文本)进行加密以获得固定长度值的技术。PHP 库包含许多函数,可以通过应用不同的哈希算法(例如 md5、SHA2、HMAC 等)对数据执行哈希。获得的加密值称为原始密钥的哈希。
哈希处理是一个单向过程,从某种意义上说,无法对哈希进行反转,因而无法获取原始键。
Applications of Hashing
哈希技术被有效用于以下目的:
Hashing Algorithms in PHP
PHP 支持多个哈希算法:
-
MD5 - MD5 是一种 128 位的哈希函数,广泛用于软件中,用于验证传输文件的完整性。128 位的哈希值通常表示为 32 位十六进制数。例如,“frog”这个单词总是生成哈希值“8b1a9953c4611296a827abf8c47804d7”
-
SHA - SHA 的全称是安全散列算法,由美国国家标准与技术研究院(NIST)制定的一系列标准。SHA 是 MD5 的改进版本,用于哈希数据和证书。SHA-1 和 SHA-2 是该算法的不同版本。SHA-1 是一个 160 位的哈希算法。SHA-2 实际上是一个哈希“系列”,有各种长度,其中最受欢迎的是 256 位。
-
HMAC - HMAC(基于哈希的消息认证码)是一种加密认证技术,使用哈希函数和密钥。
-
HKDF - HKDF 是一个简单的密钥派生函数 (KDF),基于 HMAC 消息认证码。
-
PBKDF2 - PBKDF2(基于密码的密钥派生函数 2)是一种哈希算法,可根据密码创建加密密钥。
Hash Functions in PHP
PHP 库包含多个哈希函数:
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 扩展中的两个重要函数为 -
-
openssl_encrypt() − Encrypts data
-
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() 函数。
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>";
}
?>
PHP – Swapping Variables
PHP 没有提供任何内置函数用于交换或互换两个变量的值。然而,有几种技术可以用来完成交换。
最直接的方法之一是使用第三个变量作为临时的占位符来实现交换。按照特定顺序使用算术运算符也很有效。你也可以用二进制异或操作符用于交换。在本教程中,我们将用 PHP 来实现这些交换技术
Temporary Variable
从逻辑上来说,这是最明显、最简单的方法。要交换 “a” 和 “b” 的值,请使用第三个变量 “c”。将 “a” 的值赋给 “c”,使用 “b” 的现有值覆盖 “a”,然后将 “b” 设置为存储在 “c” 中的 “a” 的早期值。
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”。
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 版本。
IntlChar::charFromName
charFromName() 函数通过名称查找 Unicode 字符并返回其码点值。
public static IntlChar::charFromName(string $name,
int $type = IntlChar::UNICODE_CHAR_NAME): ?int
使用查找时要用的名称类型参数组。可以是以下任何一个常量 -
-
IntlChar::UNICODE_CHAR_NAME (default)
-
IntlChar::UNICODE_10_CHAR_NAME
-
IntlChar::EXTENDED_CHAR_NAME
-
IntlChar::CHAR_NAME_ALIAS
-
IntlChar::CHAR_NAME_CHOICE_COUNT
IntlChar::charName
charName() 函数检索 Unicode 字符的名称
public static IntlChar::charName(int|string $codepoint,
int $type = IntlChar::UNICODE_CHAR_NAME): ?string
IntlChar::isalpha
isalpha() 函数确定指定代码点是否是字母字符。对于通用类别“L”(字母)返回 true。
public static IntlChar::isalpha(int|string $codepoint): ?bool
PHP – CSPRNG
CSPRNG 的缩写代表密码安全伪随机数生成器。PHP 函数库包含了许多用于生成随机数的函数。例如:
-
mt_rand() − 通过 Mersenne Twister 随机数生成器生成一个随机值
-
mt_srand() − 设置 Mersenne Twister 随机数生成器的种子
-
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 引入了几个生成安全随机数的函数。
以下函数具有加密安全性,是新添加的 -
-
random_bytes() − 生成具有加密安全性的伪随机字节。
-
random_int() − 生成具有加密安全性的伪随机整数。
The random_bytes() Function
random_bytes() 生成任意长度的加密随机比特串,该串适合用于加密用途,例如生成哈希盐、密钥或初始化向量时。
string random_bytes ( int $length )
The random_int() Function
random_int() 生成加密随机整数,适用于在公正结果极其重要的场景下使用。
int random_int ( int $min , int $max )
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 行为兼容) |
PHP – The "use" Statement
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
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...
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() 函数使用。
Unquoted Strings
不存在全局常量的未引用的字符串将被视为它们自身的字符串。此行为过去会发出 E_NOTICE,但现在会发出 E_WARNING。在下一个 PHP 主要版本中,将转而引发 Error 异常。
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 类型声明以及对整数进行操作的操作符。
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 的生效而删除 −
-
ereg 扩展替换为 preg
-
mssql 扩展替换为 pdo_mssql
-
mysql extension mysqli
-
sybase_ct replaced by pdo_sybase
从 PHP 8 起,已移除以下扩展:
-
Mcrypt - Mcrypt 扩展用于加密和解密,但它自 PHP 7.1 起已弃用,并在 PHP 8 中因安全漏洞而移除。
-
MDB2 - MDB2 扩展,此前用于访问 MDB 数据库文件,已在 PHP 8 中移除,因缺乏维护。
-
Ming - 由于 Flash 现已不受欢迎,Ming 扩展(用于生成 Flash 内容)已自 PHP 5.5 起弃用,并在 PHP 8 中移除。
-
Phar Data - Phar Data 扩展用于访问 PHAR 档案中的数据,但已在 PHP 8 中移除,因存在其他访问 PHAR 数据的方法。
-
SNMP - 由于未得到维护,SNMP 扩展已在 PHP 8 中移除。
-
Tidy - 由于已添加新的 HTML 验证库,Tidy 扩展已在 PHP 中移除。
-
Tokenizer - Tokenizer 扩展同样因同样的原因在 PHP 8 中移除。
-
cURL - cURL 扩展已在 PHP 8.1 中移除,因已不再维护。
Removed SAPIs
SAPI 是 PHP 中服务器端应用程序编程接口的缩写。SAPI 负责将 PHP 代码转换为 Web 服务器可以理解的内容。它解析 PHP 代码并调用适当的 Web 服务器函数。然后,Web 服务器会生成一个 HTTP 响应,将其发回客户端。
从 PHP 7 起,已移除以下 SAPI(服务器端应用程序编程接口):
-
aolserver
-
apache
-
apache_hooks
-
apache2filter
-
caudium
-
cgi
-
cgi-fcgi
-
fastcgi
-
isapi
-
litespeed
-
nsapi
-
pwsapi
-
router
-
thttpd
-
uwsgi
-
webserver
-
apache2filter
-
continuity
-
isapi
-
milter
-
nsapi
-
pi3web
-
roxen
-
thttpd
-
tux
-
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 令牌保护的步骤如下 -
-
通过启动新会话来开始脚本。
-
生成随机字符令牌。你可以使用 PHP 提供的几个内置函数来生成随机字符串。使用 md5() 函数来获取会生成唯一随机字符串的 uniqueid() 函数的哈希值。
-
在为用户准备以提交数据而提供的 HTML 表单内,包括一个隐藏文件,其值是上述步骤中生成的随机令牌。
-
在表单提交之后,服务器可以根据用户会话验证令牌,以消除恶意请求。
-
你还可以添加另一个赋值为当前时间的会话变量,并发送一个用于验证目的的到期时间。
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 −
要模拟 CSRF 验证失败,请打开浏览器的检查工具,手动编辑隐藏字段中的值,然后提交表单以查看令牌不匹配,从而导致验证失败。
PHP – FastCGI Process
PHP FastCGI 进程管理器 (PHP-FPM) 是一个有效的替代传统基于 CGI 的方法,它用于处理 PHP 请求,特别是在高流量环境中。PHP-FPM 有一些重要的特性。这些特性如下所列 −
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();
}
?>