PHP

php
范例多范式命令功能面向对象程序性反思性
设计拉斯穆斯·莱多夫(Rasmus Lerdorf)
开发人员PHP开发团队Zend TechnologiesPHP基金会
首先出现1995年6月8日
稳定版本
8.3.1 / 21 2023年12月21日
打字学科动态虚弱逐渐
实施语言C (主要是某些组件C ++
作业系统类似Unix的WindowsMacOSIBM IOpenVMS
执照双重许可GNU通用公共许可证版本2或任何后期版本和PHP版本3.0或更早的PHP许可证。仅适用于3.01倍和更高版本的PHP许可证Zend Engine许可下的Zend Engine的大部分)。
文件名扩展.php,.phar,.phtml,.pht,.phps
网站www.php.net
主要实施
Zend EngineHHVMPeachpieQuercusParrot
被影响
PerlCC ++JavaTCLJavaScript
受影响
hackjspaspreact js
  • Wikibooks的PHP编程

PHP是一种针对Web开发的通用脚本语言。它最初是由丹麦加拿大程序员Rasmus Lerdorf于1993年创建的,并于1995年发行。PHP参考实施现在由PHP集团生产。 PHP最初是个人主页的缩写,但现在代表递归初始主义PHP:超文本预处理器

PHP代码通常由实现的PHP解释器Web服务器上处理,该模块守护程序公共网关接口(CGI)可执行文件。在Web服务器上,解释和执行的PHP代码的结果可能是任何类型的数据,例如生成的HTML二进制图像数据 - 将构成HTTP响应的全部或部分。存在各种Web模板系统,Web内容管理系统Web框架,可用于协调或促进该响应的产生。此外,PHP可用于Web上下文之外的许多编程任务,例如独立的图形应用程序机器人无人机控制。 PHP代码也可以直接从命令行执行。

Zend Engine提供支持的标准PHP解释器是根据PHP许可发布的免费软件。 PHP已被广泛移植,可以在大多数Web服务器上部署在各种操作系统和平台上

PHP语言在没有书面形式规格或标准的情况下进化,原始实施是其他实施旨在遵循的事实上的标准。

W3Techs报告说,截至2023年12月,PHP均由76.4%的所有网站都可以确定。

历史

PHP的创建者Rasmus LerdorfZend Engine的创建者Andi GutmansZeev Suraski

早期历史

PHP开发始于1993年,当时Rasmus LerdorfC中撰写了几个常见的网关界面(CGI)程序,他用来维持自己的个人主页。他将它们扩展到使用Web表单并与数据库进行通信,并将此实现称为“个人主页/表格口译员”或PHP/FI。

PHP/FI可用于构建简单,动态的Web应用程序。为了加速错误报告和改进代码,Lerdorf最初宣布将PHP/FI发布个人主页工具(PHP工具)版本1.0”。该版本已经具有PHP今天的基本功能。其中包括类似perl的变量,形式处理以及嵌入HTML的能力。语法类似于perl的语法,但更简单,更有限且不一致。

早期PHP语法的一个例子:

<!--include /text/header.html-->
<!--getenv HTTP_USER_AGENT-->
<!--if substr $exec_result Mozilla-->
  Hey, you are using Netscape!<p>
<!--endif-->
<!--sql database select * from table where user='$username'-->
<!--ifless $numentries 1-->
  Sorry, that record does not exist<p>
<!--endif exit-->
  Welcome <!--$user-->!<p>
  You have <!--$index:0--> credits left in your account.<p>
<!--include /text/footer.html-->

早期的PHP从未打算成为一种新的编程语言。相反,它有机地生长,回想起来,Lerdorf指出:“我不知道如何停止它[...]从来没有任何意图编写编程语言[...]我绝对不知道如何写作一种编程语言[.. .],我一直在途中添加下一个逻辑步骤。”一个开发团队开始形成,经过数月的工作和Beta测试,1997年11月正式发布了PHP/FI 2。

PHP最初不是设计而是有机开发的事实,导致功能命名不一致,并且其参数排序不一致。在某些情况下,选择了函数名称以匹配PHP“包装”的较低级别库,而在某些早期版本中,函数名称的长度被内部用作哈希函数,因此选择了名称,因此选择了名称。改善哈希值的分布。

PHP 3和4

这是WordPress内容管理系统的PHP代码的一个示例。

Zeev SuraskiAndi Gutmans在1997年重写了解析器,并形成了PHP 3的基础,将语言的名称更改为递归缩写缩写php:超文本预处理程序。之后,对PHP 3的公开测试开始,正式发布于1998年6月。Suraski和Gutmans随后开始了新的PHP核心重写,并于1999年生产了Zend Engine 。他们还在以色列Ramat Gan创立了Zend Technologies

2000年5月22日,由Zend Engine 1.0提供支持的PHP 4释放。到2008年8月,该分支机构已达到4.4.9版。 PHP 4现在不再正在开发,也没有计划发布任何安全更新。

PHP 5

2004年7月1日,PHP 5发行,由新的Zend Engine II提供支持。 PHP 5包括新功能,例如改进了对对象的编程的支持,PHP数据对象(PDO)扩展名(定义了轻巧且一致的界面以访问数据库),以及大量的性能增强功能。在2008年,PHP 5成为唯一正在开发的稳定版本。以前的PHP版本中缺少晚期静态绑定,并在5.3版中添加。

由于GOPHP5倡议,由PHP开发商由PHP开发人员提供了从PHP 4到PHP 5的过渡,许多备受瞩目的开源项目因2008年2月5日的新代码而停止支持PHP 4。

随着时间的流逝,PHP口译员通过使用PHP源代码构建或使用预构建的二进制文件,可以在大多数现有的32位64位操作系统上使用。对于PHP版本5.3和5.4,唯一可用的Microsoft Windows二进制发行版是32位IA-32构建,在64位Windows平台上使用Internet信息服务(IIS)时,需要Windows 32位兼容模式。 PHP版本5.5使可用于Microsoft Windows的64位X86-64构建。

PHP 5.6的官方安全支持于2018年12月31日结束。

PHP 6和Unicode

由于缺乏核心语言级别的本机Unicode支持,因此PHP收到了不同的评论。 2005年,由Andrei Zmievski领导的一个项目通过嵌入Unicode(ICU)图书馆的国际组件,并在内部代表UTF-16,从而为整个PHP带来本地Unicode支持。由于这将导致语言内部和用户代码的重大更改,因此计划将其发布为语言的6.0版,以及其他主要功能。

但是,缺乏理解必要更改的开发人员以及由UTF-16转换引起的性能问题(在Web上下文中很少使用)导致项目延迟。结果,在2009年创建了PHP 5.3版本,其中许多非固定功能从PHP 6(尤其是名称空间)进行了回移。 2010年3月,该项目的当前形式被正式放弃,并且准备释放PHP 5.4释放,以包含PHP 6中最剩余的非固定功能,例如特征和封闭式绑定。最初的希望是将制定一个新计划以进行Unicode集成,但到2014年,没有采用任何计划。

PHP 7

在2014年和2015年期间,开发了新的主要PHP版本PHP 7,它仍然是最常用的PHP版本,比其后继产品更受欢迎。此版本的编号涉及内部开发人员之间的一些辩论。虽然php 6 Unicode实验从未发布,但几篇文章和书名引用了PHP 6名称,如果新版本重复使用该名称,这可能会引起混乱。投票后,选择了PHP 7的名称。

PHP 7的基础是最初被称为PHP下一代PHPNG )的PHP分支。它是由Dmitry Stogov,Xinchen Hui和Nikita Popov撰写的,旨在通过重构Zend Engine来优化PHP性能,同时保持接近完整的语言兼容性。到2014年7月14日,基于WordPress的基准测试是PHPNG项目的主要基准套件,其性能增长了几乎100%。 PHPNG的变化使得在未来版本的性能中更容易提高性能,因为更紧凑的数据结构和其他更改被认为更适合成功地迁移到Just-Undime (JIT)编译器。由于发生了重大变化,重新设计的Zend Engine称为Zend Engine 3 ,在PHP 5中使用了Zend Engine 2。

根据PHP的发布过程,由于PHPNG的重大内部变化,它必须获得新的主要版本数字,而不是较小的PHP 5发布。 PHP的主要版本可以破坏代码的向后兼容性,因此PHP 7为需要向后兼容的其他PHPNG超出PHPNG的其他改进提供了机会。特别是,它涉及以下更改:

  • 许多致命或可追回级别的遗产PHP错误机制被现代面向对象的例外取代。
  • 可变删除的语法被重新设计为内部更加一致和完整,从而允许使用操作员->,[],(),{}, 和::,具有任意有意义的左侧表达式。
  • 对遗产PHP 4风格的构造方法的支持被贬低。
  • 行为foreach陈述更改为更可预测。
  • 在失败后返回无效的几个类别的几个类别的构造函数更改为一致性。
  • 从PHP核心中删除了几个未受未来或不弃用的服务器应用程序编程界面(SAPI)和扩展mysql扩大。
  • 行为list()更改了操作员以删除对字符串的支撑。
  • 删除了遗产ASP风格的定界符的支持<%%><script language="php"> ... </script>.
  • 允许开关语句具有多个的监督default条款是固定的。
  • 从字符串到数字类型的某些隐式转换中,对十六进制的数字支持进行了支持。
  • 更改了左移右移的操作员,以在平台之间更加稳定。
  • 更改了浮点数和整数之间的转换(例如,无穷大更改为零),并在跨平台上更加一致地实现。

PHP 7还包括新的语言功能。最值得注意的是,它在参数和返回类型声明中引入了补充现有参数类型声明的功能的返回类型声明,并支持对标量类型(整数,float,string和boolean)的支持。

PHP 8

PHP 8于2020年11月26日发行,目前是第二大PHP专业版本。 PHP 8是主要版本,与以前的版本有破坏性的变化。新功能和值得注意的更改包括:

及时的汇编

PHP 8中支持及时的汇编

PHP 8的JIT编译器可以为某些用例提供实质性的性能改进,而PHP开发人员Nikita Popov表示,大多数网站的性能改进将不如从PHP 5到PHP的升级。操作比常见的Web开发用例。此外,由于某些用例的性能改进,JIT编译器还提供了将某些代码从C转移到PHP的未来潜力。

匹配表达式的添加

PHP 8介绍了match表达。匹配表达在概念上类似于switch声明,对于某些用例,更紧凑。因为match是表达式,其结果可以分配给变量或从函数返回。

类型更改和添加

PHP 8引入了联盟类型,一种新的static返回类型,新的mixed类型。

PHP 8中添加了“属性”,通常称为其他编程语言中的“注释”,这使元数据可以添加到类中。

throw从作为陈述变成了表达式。这允许在以前无法的地方抛出例外。

语法更改和添加

PHP 8包括更改,以允许在许多情况下进行替代,更简洁或更一致的语法。例如,Nullsafe操作员类似于Null合并操作员??,但在调用方法时使用。如果以下代码段将不会出错getBirthday()返回null:

$human_readable_date = $user->getBirthday()?->diffForHumans();

构建体属性促进已被添加为“句法糖”,允许当参数传递到类构造器中时自动设置类属性。这减少了必须编写的样板代码的数量。

其他较小的更改包括支持使用::class在物体上,它是使用的替代方法get_class();在试用块中的非捕获捕获;可变语法调整以解决不一致;支持指定参数;并支持参数列表中的尾逗号,这在其他情况下(例如在数组中)增加了对尾随逗号的支持一致性。

标准图书馆的更改和添加

  • 在PHP 8中添加了弱图。AWeakMap持有对象的引用,但是这些引用并不能阻止收集此类对象。这可以在缓存数据的方案中提供性能改进;这与对象 - 相关映射(ORM)特别相关。
  • 对界面的各种调整,例如增加支持创建的支持DateTime来自接口的对象,添加Stringable可用于类型提示的接口。
  • 各种新功能,包括str_contains(),str_starts_with()和str_ends_with(); fdiv(); get_debug_type();和get_resource_id()
  • token_get_all()的对象实现

其他更改

  • 类型注释还添加到PHP的C源代码本身中,以允许内部功能和方法具有“反射中的完整类型信息”。
  • 用私人方法继承
  • 特质改进中的抽象方法

PHP 8.1

PHP 8.1于2021年12月8日发布,其中包括许多新功能和对以前版本的改进。这是对PHP 8.1的一些关键特征和改进的更详细的看法:

  • 联合类型:此功能使您可以指定变量可以具有多种类型,例如整数或字符串。这对于编写更灵活,更强大的代码可能很有用,因为它允许您处理更广泛的输入值。
  • NULLSAFE操作员:该操作员允许您链接方法呼叫,而不必担心NULL引用。例如,如果要调用可能为null的对像上的方法,则可以使用Null Safe操作员来确保仅在对像不为null时才调用该方法。
  • 匹配表达式:这是对值进行匹配的一种更简洁,更灵活的方法。它允许您指定多种情况及其相关值,然后使用match关键字根据表达式的值选择适当的情况。
  • 改进的性能:PHP 8.1包括各种性能改进,例如更快的阵列操作和更好的内存使用情况。这些改进可以帮助您的代码更快,更有效地运行。
  • 新的错误处理功能:PHP 8.1引入了新的错误throws关键字允许您指定函数可以投掷哪些异常,以及一个新的assert()可以在运行时检查某些条件的功能。这些功能可以帮助您编写更可靠和强大的代码。
  • 其他新功能:PHP 8.1还包括其他新功能,例如对命名参数的支持,对属性的支持(类似于其他语言的注释)以及改进了对Unicode的支持。

match表达是PHP 8.1中的一项新功能,可让您以更简洁和灵活的方式执行价值匹配。类似于switch语句,但具有一些其他功能和语法改进。

这是如何使用matchPHP中的表达:

$value = 3;
$result = match ($value) {
  0 => 'The value is zero',
  1, 2, 3 => 'The value is one, two, or three',
  default => 'The value is something else',
};
echo $result; // Outputs: "The value is one, two, or three"

在此示例中,match表达比较$value对于卷曲括号中指定的不同情况。如果$value匹配其中一种情况,返回相应的值。如果案例都不匹配,则default使用案例。

主要好处之一match表达式是您允许您为单个情况指定多个值,如上示例所示。这可以帮助您的代码更加简洁,更易于阅读。

断言()错误处理

assert()功能和throws关键字是PHP 8.1中的新错误处理功能,可以帮助您编写更可靠且可靠的代码。

assert()功能用于检查运行时的某些条件。如果未满足条件,则该功能会生成AssertionError例外。例如:

assert($x > 0, '$x must be greater than zero');

在此示例中,assert()功能检查是否$x大于零。如果不是,一个AssertionError引发了例外信息。$x must be greater than zero".

throws另一方面,关键字用于指定函数或方法可以投掷的例外。这可能有助于记录您的代码,并使其他开发人员更容易理解您的功能和方法的行为。例如:

function divide(int $a, int $b): int
{
    if ($b === 0) {
        throw new DivisionByZeroError('Cannot divide by zero');
    }
    return $a / $b;
}

在此示例中,divide()功能使用throws关键字可以指定它可以抛出DivisionByZeroError例外,如果第二个参数为零。

总体而言,assert()功能和throws关键字是用于处理PHP中错误和异常的有用工具,可以帮助您编写更可靠和强大的代码。

支持枚举

对枚举的支持是PHP 8.1最突出的特征之一。枚举允许开发人员在其代码库中执行状态。以下是枚举的示例:

<?php
namespace App\Enums;
enum InvoiceStatus: string {
    case draft = 'draft';
    case pending = 'pending';
    case paid = 'paid';
    case expired = 'expired';
}

其他PHP 8.1功能

  • 添加了对“仅阅读”属性的支持。
  • 在带有连续编号的键的PHP 7.4中引入阵列在PHP 7.4中解开包装后,PHP 8.1引入了对用字符串键解开包装的支持。
  • PHP 8.1增加了对初始化器中使用“新”的支持。
  • 添加了一个新的语法来创建可可。
  • 在PHP 8.0中引入联合类型之后,PHP 8.1为纯交叉类型提供了支持。

PHP 8.2

PHP 8.2包括许多新功能和改进。这是一些主要的:

  1. 改进的类型差异:PHP 8.2引入了通用类型的改进类型方差,使您可以指定通用类型是协变量,逆转或不变的。这可以帮助提高使用通用类型时的类型安全性和灵活性。
  2. 性能改进:PHP 8.2包括各种性能改进,包括更快的JIT汇编,更快的垃圾收集以及改进的大型阵列处理。这些改进可以帮助使PHP应用程序更快,更高效。
  3. 贬值:某些功能已在PHP 8.2中被贬低,包括与字符串参数一起使用时的essert()函数,以及带有单个数组元素的list()构造。如果您正在从较早版本的PHP中升级,请意识到这些贬值很重要。

以下是在PHP 8.2中已弃用的一些功能的示例:

  1. surst()函数带有字符串参数:assert()函数可用于执行运行时检查,但是与字符串参数一起使用时已对其进行弃用。取而代之的是,您应该使用布尔参数或表达式使用assert()函数。
  2. list()带有单个数组元素的构造:list()构造允许您将数组的元素拆开为单独的变量。与单个数组元素一起使用时已被弃用,因为此用法被认为令人困惑且容易出错。
  3. create_function():create_function()函数已被弃用,因为它已被匿名函数取代,这些函数更灵活,更易于使用。
  4. mb_ereg_replace_callback():已弃用MB_EREG_REPLACE_CALLBACK()函数,因为它已被Preg_replace_callback()函数取代,该功能提供了类似的功能并更广泛地使用。
  5. 不接受的可可$callable()语法(但被call_user_func()接受)。

新的“随机”扩展

“随机”扩展提供了一种新的面向对象的API,用于在PHP中生成随机值。它包括几个类(“引擎” S),它们实现了不同的算法来生成随机数并将其状态存储在对像中。这允许多个独立的播种序列,这些序列在某些情况下可以有用,例如测试或仿真。

\ Random \ Randomizer类提供了一个高级接口,用于使用引擎的随机性生成随机整数,洗牌数组或字符串,选择随机数组键等等。这可能是执行这些常见任务的方便方法,而无需直接使用低级引擎类。

值得注意的是,默认情况下,PHP中未启用“随机”扩展名,您将需要在PHP环境中安装和启用它,以便使用其功能。您可以找到有关官方PHP文档中扩展程序的更多信息。

发布历史

版本发布日期支持直到笔记
1.01995年6月8日正式称为“个人主页工具(PHP工具)”。这是名称“ PHP”的首次使用。
2.01997年11月1日正式称为“ PHP/FI 2.0”。这是第一个实际上可以将其描述为PHP的版本,它是一种独立的语言,其功能已经持续到今天。
3.01998年6月6日2000年10月20日开发从一个人转向多个开发人员。 Zeev Suraski和Andi Gutmans重写了此版本的基础。
4.02000年5月22日2001年6月23日添加了更高级的两阶段解析/执行标签的系统,称为Zend Engine。
4.12001年12月10日2002年3月12日引入了“超级全球”($_GET,$_POST,$_SESSION, ETC。)
4.22002年4月22日2002年9月6日禁用register_globals默认情况下。通过网络接收到的数据不再直接插入全局名称空间中,从而关闭了应用程序中可能的安全孔。
4.32002年12月27日2005年3月31日引入了命令行接口(CLI),以补充CGI。
4.42005年7月11日2008年8月7日修复了一个内存损坏错误,该错误需要针对PHP版本4.3.x进行分解的扩展。
5.02004年7月13日2005年9月5日带有新对像模型的引擎II。
5.12005年11月24日2006年8月24日通过在重新设计的PHP发动机中引入编译器变量的提高性能。添加了PHP数据对象(PDO)作为访问数据库的一致接口。
5.22006年11月2日2011年1月6日默认情况下启用了过滤器扩展名。本地JSON支持。
5.32009年6月30日2014年8月14日名称空间支持;晚期静态绑定,跳跃标签(有限的GOTO ),匿名功能关闭,PHP档案(PHAR),用于循环参考的垃圾收集,改进的Windows支持,SQLITE 3,MySQLND作为Libmysql的替代品,作为与扩展的基础图书馆的替代品MySQL ,FileInfo作为MIME_MAGIC的替代,以获得更好的MIME支持,国际化扩展和EREG扩展的贬值。
5.42012年3月1日2015年9月3日性状支持,简短的数组语法支持。删除项目:register_globals,safe_mode,allow_call_time_pass_reference,session_register(),session_unregister()session_is_registered()。内置的Web服务器。现有功能,性能和记忆要求减少的几种改进。
5.52013年6月20日2016年7月10日支持发电机finally异常处理的块,OPCACHE(基于Zend Optimizer+)捆绑在官方分发中。
5.62014年8月28日2018年12月31日恒定标量表达式,变异功能,参数解开包装,新的指示操作员,扩展的扩展use功能和常数的声明,新的phpdbg调试器作为SAPI模块以及其他较小的改进。
6.x未发布放弃的PHP版本,计划包括本机Unicode支持。
7.02015年12月3日2019年1月10日Zend Engine 3(窗户上的性能改进和64位整数支持),统一的可变语法,基于AST的编译过程,添加了Closure::call(),跨平台的位移动一致性,??null Cocce )操作员, Unicode代码点逃脱语法,返回类型声明,标量类型(整数,浮点,字符串,字符串和布尔值)声明,<=>“太空飞船”的三路比较操作员,生成器代表团,匿名类,更简单,更稳定的CSPRNG API,更换了许多剩余的内部PHP“错误”和更现代的异常,以及用于从名称空间导入多个项目的速记构成。
7.12016年12月1日2019年12月1日具有峰值的类型,无效的类型, void返回类型,类恒定可见性修饰符,简短列表语法,多键入
7.22017年11月30日2020年11月30日对象参数和返回类型声明,libsodium扩展,抽象方法覆盖,参数类型加宽
7.32018年12月6日2021年12月6日灵活的Heredoc和Nowdoc语法,支持参考分配和带有list()的数组解构(),PCRE2支持,HRTime()函数
7.42019年11月28日2022年11月28日Typed properties 2.0, preloading, null-coalescing assignment operator, improve openssl_random_pseudo_bytes, Weak References, FFI – foreign function interface , always available hash extension, password hash registry, multibyte string splitting, reflection for references, unbundle ext/wddx, new custom object serialization机制
8.02020年11月26日2023年11月26日即时(JIT)汇编,以负索引开头的数组,更严格/更清晰的语言语言(抽象性状方法的验证),saner string到数字比较,saner数字字符串,无效算法/位置操作员的类型,重新分类各种发动机错误,内部功能的一致类型错误,不兼容方法签名的致命错误),与区域无关的浮点与字符串转换,可变语法调整,属性,属性,命名参数,匹配表达式,构造函数表达式,构造者属性促进,工会类型,混合类型,静态类型,静态类型,静态返回类型,nullsafe操作员,非捕获捕获量,投掷表达式,JSON扩展总是可用的。
8.12021年11月25日2024年11月25日显式八进制整数符号,枚举,可读性属性,一流的可呼叫语法,新的初始化器,纯相交类型,永不返回类型,最终类约束,光纤
8.22022年12月8日2025年12月8日可读类,null,false和true作为独立类型,独立的案例转换,分离的正常形式类型,特质中的常数
8.32023年11月23日2026年11月23日打字类常数,动态类常数提取,新#[\覆盖]
传奇:
旧版
较旧的版本,仍然保持
最新版本
最新的预览版
未来发布

从2011年6月28日开始,PHP开发团队实施了发布新版本PHP的时间表。在此系统下,至少每月应进行至少一个版本。每年一次,应进行次要发布,其中可能包括新功能。每个次要版本至少应通过安全性和错误修复来支持两年,然后至少仅一年的安全修复程序,每次次要发行程序总共进行了为期三年的发布过程。除非小且独立,否则在三年发布过程中不会引入次要版本。

吉祥物

大象PHP吉祥物

PHP项目的吉祥物是大象,它是蓝色大象,其侧面是PHP徽标,由Vincent Pontier在1998年设计。毛绒玩具形式时,像有时会颜色不同。

多年来,这种吉祥物的许多变化是。社区只有基于文森特·庞蒂尔(Vincent Pontier)的原始设计的大像被官方视为官方。这些是可收集的,其中一些非常罕见。

句法

在其内置开发服务器上运行的PHP 7.4中的“ Hello World”应用程序

以下“你好,世界!”程序HTML文档中嵌入的PHP代码编写:

<!DOCTYPE html>
<html>
    <head>
        <title>PHP "Hello, World!" program</title>
    </head>
    <body>
        <?php
            echo '<p>Hello, World!</p>';
        ?>
    </body>
</html>

但是,由于没有要求将PHP代码嵌入HTML中,这是Hello,World的最简单版本!可以像这样写,带有关闭标签?>在包含纯PHP代码的文件中省略了首选。

<?php echo 'Hello, World!';

PHP解释器仅在其定界符内执行PHP代码。尽管非PHP文本仍受PHP代码中描述的控制结构的约束,但PHP均未处理其分界符之外的任何内容。最常见的定系数是<?php打开和?>关闭PHP部分。缩短形式<?也存在。这个简短的定界符使脚本文件的便携性较低,因为可以在本地PHP配置中禁用对它们的支持,因此不建议使用它。相反,没有针对回声短标签的建议<?=。在PHP 5.4.0之前,此简短的语法echo仅与short_open_tag启用了配置设置,而对于PHP 5.4.0,始终可用。所有这些定系数的目的是将PHP代码与非PHP内容分开,例如JavaScript代码或HTML标记。所以最短的“你好,世界!”用PHP编写的程序是:

<?='Hello, World!';

第一种定系数的形式,<?php?>,在XHTML和其他XML文档中,正确形成了XML处理指令。这意味着服务器端文件中PHP代码和其他标记的结果本身是XML良好的。

变量以美元符号前缀,并且不需要提前指定一种类型。 PHP 5引入了类型声明,允许函数强制其参数为特定类,数组,接口或回调函数的对象。但是,在PHP 7之前,类型声明不能与标量类型(例如整数或字符串)一起使用。

以下是如何声明和初始化PHP变量的示例。

<?php
    $name = 'John';  // variable of string type being declared and initialized
    $age = 18;       // variable of integer type being declared and initialized
    $height = 5.3;   // variable of double type being declared and initialized
    echo $name . ' is ' . $height . "m tall\n"; // concatenating variables and strings
    echo "$name is $age years old."; // interpolating variables to string
?>

与函数和班级名称不同,可变名称对病例敏感。双引号(“”)和Heredoc字符串都提供了将变量值插入字符串中的能力。 PHP以自由形式的语言方式将新线视为白条,并被半隆终止。 PHP具有三种类型的评论语法/* */标记块和内联评论;//或者#用於单行评论。这echo声明是PHP提供的几种设施之一。

在关键字和语言语法方面,PHP类似于C风格语法。if状况,forwhile循环和功能返回在语法上与C,C ++,C#,Java和Perl等语言相似。

数据类型

PHP松散地键入。它将整数存储在平台依赖性范围内,以32、64或128位签名的整数等效于C-Language Long类型。在某些情况下,未签名的整数转换为签名值,这与许多其他编程语言不同。整数变量可以使用十进制(正和负),八分之一十六进制二进制符号来分配。

浮点数也存储在特定于平台的范围内。可以使用浮点数符号或两种形式的科学符号来指定它们。 PHP具有与JavaC ++中本机布尔类型相似的本机布尔类型。使用布尔类型转换规则,非零值被解释为真实,零为false,如perl和c ++。

NULL数据类型表示没有值的变量;NULL是此数据类型的唯一允许值。

“资源”类型的变量表示来自外部资源的资源引用。这些通常是由特定扩展名的函数创建的,只能通过相同扩展的函数来处理;示例包括文件,图像和数据库资源。

数组可以包含PHP可以处理的任何类型的元素,包括资源,对象甚至其他数组。订单保留在值列表和具有密钥和值的哈希中,两者可以混合在一起。 PHP还支持字符串,可以与单引号,双引号,Nowdoc或Heredoc语法一起使用。

标准PHP库(SPL)试图解决标准问题并实现有效的数据访问界面和类。

功能

PHP在核心语言中定义了大量的功能,许多功能也可以在各种扩展中提供。这些功能已被充分记录在线PHP文档。但是,内置库具有各种命名惯例和相关的矛盾,如上所述

自定义功能可以由开发人员定义:

function myAge(int $birthYear): string
{
    // calculate the age by subtracting the birth year from the current year.
    $yearsOld = date('Y') - $birthYear;
    // return the age in a descriptive string.
    return $yearsOld . ($yearsOld == 1 ? ' year' : ' years');
}
echo 'I am currently ' . myAge(1995) . ' old.';

截至2024年,上述样本程序的输出为“我目前已有29岁”。

代替功能指针,可以用包含其名称的字符串引用PHP中的功能。以这种方式,可以使用正常的PHP功能,例如作为回调功能表中。可以随时创建用户定义的功能,而无需原型。可以在代码块内定义函数,从而允许对是否应定义函数的运行时间决策。有一个function_exists确定是否已经定义了具有给定名称的函数的函数。函数调用必须使用括号,除了零量的类构造函数与php运算符调用new,在这种情况下,括号是可选的。

自PHP 4.0.1以来create_function(),周围的薄包装纸eval(),允许在程序执行期间创建正常的PHP功能;它在PHP 7.2中被弃用,并在PHP 8.0中删除,以匿名函数或可以从周围范围捕获变量的语法,该语法已添加到PHP 5.3中。在PHP 7.4中添加了速记箭头语法:

function getAdder($x) {
    return fn($y) => $x + $y;
}
$adder = getAdder(8);
echo $adder(2);  // prints "10"

在上面的示例中,getAdder()函数使用传递的参数创建闭合$x,还有一个额外的论点$y并将创建的闭合返回到呼叫者。这样的函数是头等对象,这意味着它可以存储在变量中,作为参数传递给其他函数等。

对于动态键入的语言而言,PHP异常地支持在运行时执行的功能参数的类型声明。自PHP 5.0以来,该类和接口的支持,自PHP 5.1以来的数组,自PHP 5.4以来的“可可”和“可可”和标量(Integer,float,string和boolean)类型以来自PHP 7.0以来。 PHP 7.0还具有函数返回类型的类型声明,该声明是通过在参数列表下方放置的类型名称表示的,此前是结肠。例如,getAdder可以用php 7中的类型来注释早期示例的功能:

function getAdder(int $x): Closure
{
    return fn(int $y): int => $x + $y;
}
$adder = getAdder(8);
echo $adder(2); // prints "10"
echo $adder(null); // throws an exception because an incorrect type was passed
$adder = getAdder([]); // would also throw an exception

默认情况下,标量类型声明遵循弱打字原则。因此,例如,如果参数的类型为int,PHP不仅允许整数,还允许可转换数字字符串,浮子或布尔值传递给该功能,并将其转换。但是,PHP 7具有“严格的键入”模式,使用时,将这些转换用于文件中的函数调用和返回。

PHP对象

PHP 3中添加了基本面向对象的编程功能,并在PHP 4中进行了改进。这允许PHP获得进一步的抽象,从而使使用该语言的程序员更容易创造性任务。对象处理已完全重写为PHP 5,扩展了功能集并增强性能。在以前的PHP版本中,对像类似于价值类型。该方法的缺点是,如果要修改对象,则必须大量使用PHP的“参考”变量,而不是创建其副本。在新方法中,对像是由句柄引用的,而不是通过值引用的。

PHP 5引入了私人和受保护的成员变量和方法,以及抽像类最终类摘要方法最终方法。它还引入了一种标准方式来宣布构造函数破坏者,类似于其他面向对象的语言,例如C ++ ,以及标准的异常处理模型。此外,PHP 5添加了接口并允许实现多个接口。有一些特殊的接口允许对象与运行时系统进行交互。实现ArrayAccess的对象可以与数组语法一起使用,并且可以将实现迭代仪iteratorAggregate的对像用于foreach语言构造。引擎中没有虚拟表功能,因此静态变量在编译时绑定了名称而不是引用。

如果开发人员使用保留单词创建对象的副本clone,Zend Engine将检查是否__clone()方法已定义。如果没有,它将调用默认值__clone()它将复制对象的属性。如果一个__clone()定义方法,然后将负责在创建对像中设置必要的属性。为了方便起见,引擎将提供一个函数,以导入源对象的属性,因此程序员可以从源对象的副价值开头,而仅覆盖需要更改的属性。

PHP属性和方法的可见性是使用关键字定义的public,private, 和protected。如果仅使用var ,则默认值是公开的;varpublic。声明的项目public可以到处访问。protected限制访问继承的类(以及定义项目的类)。private仅限于定义项目的类限制可见性。同一类型的对象可以访问彼此的私人和受保护成员,即使它们不是同一实例。

例子

以下是PHP 8中面向对象编程的基本示例:

<?php

abstract class User
{
    protected string $name;

    public function __construct(string $name)
    {
        // make first letter uppercase and the rest lowercase
        $this->name = ucfirst(strtolower($name));
    }

    public function greet(): string
    {
        return "Hello, my name is " . $this->name;
    }

    abstract public function job(): string;
}

class Student extends User
{
    public function __construct(string $name, private string $course)
    {
        parent::__construct($name);
    }

    public function job(): string
    {
        return "I learn " . $this->course;
    }
}

class Teacher extends User
{
    public function __construct(string $name, private array $teachingCourses)
    {
        parent::__construct($name);
    }

    public function job(): string
    {
        return "I teach " . implode(", ", $this->teachingCourses);
    }
}

$students = [
    new Student("Alice", "Computer Science"),
    new Student("Bob", "Computer Science"),
    new Student("Charlie", "Business Studies"),
];

$teachers = [
    new Teacher("Dan", ["Computer Science", "Information Security"]),
    new Teacher("Erin", ["Computer Science", "3D Graphics Programming"]),
    new Teacher("Frankie", ["Online Marketing", "Business Studies", "E-commerce"]),
];

foreach ([$students, $teachers] as $users) {
    echo $users[0]::class . "s:\n";

    array_walk($users, function (User $user) {
        echo "{$user->greet()}, {$user->job()}\n";
    });
}

该程序输出以下内容:

Students:
Hello, my name is Alice, I learn Computer Science
Hello, my name is Bob, I learn Computer Science
Hello, my name is Charlie, I learn Business Studies
Teachers:
Hello, my name is Dan, I teach Computer Science, Information Security
Hello, my name is Erin, I teach Computer Science, 3D Graphics Programming
Hello, my name is Frankie, I teach Online Marketing, Business Studies, E-commerce

实施

唯一完整的PHP实现是原始的,仅称为PHP。它是最广泛使用的,由Zend发动机提供动力。为了使其与其他实现相关,有时会非正式地称为“ Zend PHP”。 Zend Engine可以将PHP源代码直接编译为可以执行的内部格式,因此它可以作为解释器。它也是PHP的“参考实现”,因为PHP没有正式规范,因此Zend PHP的语义定义了PHP的语义。由于由Zend的工作方式定义的PHP的复杂和细微差别的语义,因此竞争实现很难提供完整的兼容性。

PHP的单次订阅执行模型以及Zend Engine是解释器的事实导致效率低下。结果,已经开发了各种产品来帮助提高PHP性能。为了加快执行时间的速度,不必每次访问网页时都要编译PHP源代码,也可以使用OpCode Cache在PHP引擎的内部格式中部署PHP脚本共享内存中的PHP脚本(OpCodes),以避免每次运行脚本时解析编译代码的开销。自版本5.5以来,PHP内置了OpCode Cache, Zend Opcache 。广泛使用的OpCode缓存的另一个示例是替代PHP缓存(APC),该缓存可作为PECL扩展。

尽管Zend PHP仍然是最受欢迎的实施,但已经开发了其他一些实现。其中一些是编译器或支持JIT汇编,因此以缺乏完全的PHP兼容性为代价,为Zend PHP提供了性能优势。替代实现包括以下内容:

  • HHVM (HIPHOP虚拟机) - 在Facebook上开发并作为开源,它将PHP代码转换为高级字节码(通常称为中间语言),然后将其转换为运行时,在运行时动态地将其转换为X86-64机器代码及时的(JIT)编译器,最多可改善6倍的性能。但是,由于版本7.2 Zend的表现优于HHVM,而HHVM 3.24是正式支持PHP的最后一个版本。
    • HIPHOP - 在Facebook上开发并作为开源,它将PHP脚本转换为C ++代码,然后编译结果代码,将服务器加载最多减少到50%。在2013年初,由于多种原因,Facebook弃用了HHVM,包括部署困难和对整个PHP语言的支持,包括create_function()eval()结构体。
  • 鹦鹉- 一种虚拟机,旨在有效地运行动态语言;交叉译者PIPP将PHP源代码转换为鹦鹉中间表示,然后将其转换为鹦鹉的字节码并由虚拟机执行。
  • Peachpie - 第二代编译器。在罗斯林平台上构建的净通用中间语言(CIL)字节码; Phalanger的继任者,分享了几个建筑组件
  • Phalanger - 将PHP编译到.NET通用中间语言字节码中; Peachpie的前身
  • Quercus - 将PHP编译到Java字节码

许可

PHP是根据PHP许可发布的免费软件,该软件规定:

未经[email protected]的事先书面许可,从该软件中得出的产品也不能称为“ PHP”,也不可以以其名称出现。您可以通过说“ foo for php”而不是称其为“ PHP FOO”或“ PHPFOO”来指示您的软件与PHP结合使用。

对使用“ PHP”的这种限制使PHP许可证与通用公共许可证(GPL)不相容,而Zend许可证由于广告条款与原始BSD许可证的广告条款类似。

发展和社区

PHP在其源分布中包括各种免费和开源库,或将它们用于由此产生的PHP二进制构建中。 PHP从根本上是一个Internet -Wawawawawawawawawawe系统,具有用于访问文件传输协议(FTP)服务器和许多数据库服务器的内置模块,包括PostgreSQLMySQLMicrosoft SQL ServerSQLite (这是嵌入式数据库), LDAP服务器等。 C程序员熟悉了许多功能,例如STDIO家族中的功能,可以在标准PHP版本中获得。

PHP允许开发人员在C中编写扩展,以在PHP语言中添加功能。 PHP扩展可以静态地汇总到PHP中,也可以在运行时动态加载。已经编写了许多扩展程序,以增加对Windows API的支持,类似Unix的操作系统的流程管理,多型字符串( UNICODE ), CURL和几种流行的压缩格式。通过扩展提供的其他PHP功能包括与Internet继电器聊天(IRC)集成,动态生成图像和Adobe Flash内容, PHP数据对象(PDO)作为用于访问数据库的抽象层,甚至语音合成。该语言的一些核心功能,例如处理字符串和数组的功能,也被用作扩展。 PHP扩展社区库(PECL)项目是用于扩展PHP语言的存储库。

其他一些项目(例如Zephir )为使用高级语言创建PHP扩展名并将其编译成本地PHP扩展名提供了能力。这种方法不是直接在C中编写PHP扩展,而是简化了扩展的开发,并减少了编程和测试所需的时间。

到2018年12月,PHP组由十个人组成:Thies C. Arntzen,Stig Bakken,Shane Caraveo, Andi GutmansRasmus LerdorfSam Ruby ,Sascha Schumann, Zeev Suraski ,Jim Winstead和Andrei Zmievski

Zend Technologies提供了基于PHP 7考试(和以前基于PHP 5.5)的PHP认证,以供程序员成为认证的PHP开发人员。

PHP基金会

php
形成2021年11月22日
创始人AutomatticLaravelAcquiaZend ,私人4HEAKFONY, SYMFONY ,CRAFT CMS,TIDEWAYS, PRESTASHOP ,JETBRAINS, JETBRAINS
网站https://thephp.foundation

2021年11月26日, Jetbrains博客宣布了PHP基金会的创建,该基金会将赞助PHP的设计和开发。

安装和配置

php 7.1中phpinfo()函数的示例输出

有两种主要方法可以将PHP支持到Web服务器 - 作为本机Web服务器模块,或作为CGI可执行文件。 PHP具有一个名为Server Application编程接口(SAPI)的直接模块接口,该接口得到了许多Web服务器的支持,包括Apache HTTP ServerMicrosoft IISIplanet Web服务器。其他一些Web服务器(例如OmniHttpd)支持Internet Server应用程序编程接口(ISAPI),即Microsoft的Web Server模块接口。如果PHP对Web服务器没有模块支持,则可以始终用作通用网关接口(CGI)或FastCGI处理器;在这种情况下,Web服务器被配置为使用PHP的CGI可执行文件将所有请求处理到PHP文件。

PHP-FPM(FASTCGI Process Manager)是PHP的替代FASTCGI实现,自第5.3.3版以来与官方PHP发行捆绑在一起。与较旧的FastCGI实现相比,它包含一些其他功能,最可用于重载的Web服务器。

当使用PHP进行命令行脚本时,需要使用PHP命令行接口(CLI)可执行文件。自PHP 4.3.0以来,PHP支持CLI服务器应用程序编程接口(SAPI)。该SAPI的主要重点是使用PHP开发外壳应用程序。 CLI SAPI和其他SAPI之间存在很多差异,尽管它们确实具有许多相同的行为。

PHP具有用于不同Web服务器的直接模块接口,称为SAPI;如果Windows上的Php 5和Apache 2.0,则以DLL文件的形式提供php5apache2.dll是一个模块,除其他功能外,还提供了PHP和Web服务器之间的接口,该模块以服务器理解的形式实现。这种形式就是所谓的SAPI。

对于各种Web服务器扩展,有不同种类的SAPI。例如,除了上面列出的那些外,PHP语言的其他SAPI还包括通用网关接口和命令行接口。

PHP还可以使用PHP-GTK扩展名来编写桌面图形用户界面(GUI)应用程序。 PHP-GTK不包括在官方的PHP分布中,作为扩展名,它只能与PHP版本5.1.0及更新一起使用。安装PHP-GTK的最常见方法是从源代码中对其进行编译。

当安装PHP并在环境中使用时,提供了软件开发套件(SDK),用于使用特定于云的功能。例如:

支持许多配置选项,影响核心PHP功能和扩展。配置文件php.ini根据不同位置进行搜索,具体取决于使用PHP的方式。配置文件分为各个部分,而某些配置选项也可以在Web服务器配置中设置。

使用

灯软件捆绑包的广泛概述,与鱿鱼一起显示

PHP是一种通用脚本语言,特别适合服务器端Web开发,在这种情况下,PHP通常在Web服务器上运行。请求文件中的任何PHP代码均由PHP运行时执行,通常是为了创建动态网页内容或网站或其他地方使用的动态图像。它也可用于命令行脚本和客户端图形用户界面(GUI)应用程序。 PHP可以部署在大多数Web服务器,许多操作系统和平台上,并且可以与许多关系数据库管理系统(RDBMS)一起使用。大多数网络托管提供商都支持PHP供客户使用。它可以免费提供,PHP组为用户提供完整的源代码,以构建,自定义和扩展以供自己使用。

动态网页:服务器端脚本示例(PHP和MySQL)

PHP最初是为创建动态网页而设计的,现在主要关注服务器端脚本,它类似于其他服务器端脚本语言,这些语言可提供从Web服务器到客户端的动态内容,例如Microsoft的ASP Python 。网络太阳微型系统Javaserver页面mod_perl。 PHP还吸引了许多软件框架的开发,这些软件框架提供了构建基础和设计结构以促进快速应用开发(RAD)。其中一些包括PradoCakePHPSymfonyCodeigniterLaravelYII框架PhalconLaminas ,提供类似于其他Web框架的功能。

LAMP架构在网络行业中已成为一种部署Web应用程序的方式。 PHP通常与LinuxApacheMySQL一起在此捆绑中用作P ,尽管P也可能指pythonPerl或三个混合物。 WindowsMacos也可以使用类似的包装,即WAMPMAMP ,其首字母代表相应的操作系统。尽管PHP和Apache均作为MacOS基础安装的一部分提供,但这些软件包的用户寻求更简单的安装机制,可以更轻松地保持最新状态。

对于特定,更高级的用法方案,PHP提供了一种定义明确且有记录的方式,用于在CC ++中编写自定义扩展。除了以其他的形式扩展语言本身外,扩展还提供了一种提高执行速度至关重要的执行速度的方法,并且使用真实的编译语言也可以改进其空间。 PHP还提供了定义明确的方法,可以将自己嵌入其他软件项目中。这样,PHP可以轻松地用作另一个项目的内部脚本语言,还可以与项目的特定内部数据结构进行紧密的接口。

由于缺乏对核心语言级别的多线程的支持,PHP获得了混合的评论,尽管“ Pthreads” PECL扩展可以使用线程。

已经生产了用于PHP的命令行接口,PHP-CLI和两个ActiveX Windows脚本脚本引擎。

受欢迎程度和用法统计

PHP版本的使用份额,2023年12月23日,PHP 8.3发布后1个月

 PHP 8.3,EOL 2026(0.04%)
 PHP 8.2,EOL 2025(3.27%)
 PHP 8.1,EOL 2024(8.53%)
 PHP 8.0,EOL 2023(10.25%)
 PHP 7.4,EOL 2022(40.45%)
 PHP 7.3,EOL 2021(8.47%)
 PHP 7.2,EOL 2020(6.07%)
 PHP 7.1,EOL 2019(2.4%)
 PHP 7.0,EOL 2019(2.7%)
 PHP 5,EOL 2018(17.7%)
 PHP 4,EOL 2008(0.2%)

PHP用于Web内容管理系统,包括MediaWikiWordPressJoomlaDrupalMoodleEZ PublishEZ PlatformSilverStripe

截至2013年1月,PHP已在超过2.4亿个网站(占样品的39%)中使用,并安装在210万个网络服务器上。

截至2023年12月23日(PHP 8.3发布后1个月),PHP用作76.7%的网站上可以确定该语言的服务器端编程语言; PHP 7是该语言最常用的版本,使用该版本的PHP 60.1%,而22.1%使用PHP 8和17.7%使用PHP 5。

安全

2019年,国家漏洞数据库列出的所有漏洞中有11%与PHP有关;从历史上看,自1996年以来该数据库中列出的所有漏洞中约有30%链接到PHP。语言本身或其核心库的技术安全缺陷并不常见(2009年的22个,大约是PHP的1%,尽管PHP适用于列出的计划的20%)。认识到程序员会犯错误,某些语言包括调查检查以自动检测缺乏引起许多问题的输入验证。这种功能正在为PHP开发,但是过去已将其包含在发行版中多次。

有高级保护补丁,例如SuhosinHardening -patch,专为Web托管环境设计。

从历史上看,PHP的旧版本具有一些配置参数和此类运行时设置的默认值,这些设置使某些PHP应用程序容易出现安全问题。在这些当中,magic_quotes_gpcregister_globals配置指令是最著名的;后者使任何URL参数成为PHP变量,通过允许攻击者设置任何非直接全局变量的值并干扰执行PHP脚本,从而为严重的安全漏洞打开了道路。自PHP 5.3.0以来,对“魔术报价”和“注册全球群体”设置的支持已被弃用,并从PHP 5.4.0中删除。

潜在的运行时安装漏洞的另一个示例来自未禁用PHP执行(例如,使用engine配置指令)用于存储上传文件的目录;启用它可以导致执行上传文件中嵌入的恶意代码。最好的做法是,要幺在Web服务器可用的文档根外部找到图像目录,并通过中介脚本使用它,或禁用存储上载文件的目录的PHP执行。

另外,启用PHP扩展的动态加载(通过enable_dl共享Web托管环境中的配置指令)可能导致安全问题。

导致不同值被视为平等的,有时反对程序员意图的隐含类型转换可能会导致安全问题。例如,比较结果'0e1234' == '0'true,因为随着数字转换为数字的字符串;在这种情况下,第一个比较的价值被视为具有值的科学符号0 × 10 1234 ),为零。当比较MD5密码哈希时,像这样的错误导致了简单机器论坛Typo3PHPBB的身份验证漏洞。建议的方法是使用hash_equals() (用于时机攻击安全),strcmp或身份操作员(===), 作为'0e1234' === '0'结果是false.

在2013年对超过170,000个网站污损分析中,最常用的技术(53%)是对文件包含脆弱性的开发,主要与PHP语言构造的不安全使用有关include,require, 和allow_url_fopen.

截至2023年12月23日(PHP 8.3发布后1个月)W3Techs报告说,使用PHP的网站中有85.9%,使用版本8.0或以上(不再得到PHP开发团队的支持)。

截至2023年12月23日,所有网站中仍有13.6%使用版本5。强烈建议迁移到PHP 8.1或更高版本并使用random_int()代替rand()或者mt_rand(),因为后者的功能在密码上没有安全。可以通过PHP熵来源进行两次攻击:“种子攻击”和“状态恢复攻击”。借助当前的GPU技术,攻击者可以使用250美元的GPU每秒进行2 30 MD5的计算,而额外的500美元可以达到2 32美元的计算。结合“生日攻击”,这可能导致严重的安全漏洞。

也可以看看