複製鏈接
請複製以下鏈接發送給好友

PHP

(計算機編程語言)

鎖定
PHP(PHP: Hypertext Preprocessor)即“超文本預處理器”,是在服務器端執行的腳本語言,尤其適用於Web開發並可嵌入HTML中。PHP語法學習了C語言,吸納JavaPerl多個語言的特色發展出自己的特色語法,並根據它們的長項持續改進提升自己,例如java的面向對象編程,該語言當初創建的主要目標是讓開發人員快速編寫出優質的web網站 [1-2]  PHP同時支持面向對象和面向過程的開發,使用上非常靈活。
軟件名稱
PHP
軟件平台
Windows、LinuxUnixmacOS [3] 
上線時間
1995年
最近更新時間
2021年7月1日 [4] 
軟件語言
PHP
開發商
THE PHP Group
軟件授權
Creative Commons Attribution [5] 
軟件版本
PHP 8.1.3 [43] 
軟件大小
16 至 26 MB
最新版本
8.1.3 [43] 

PHP發展歷程

PHP是一個擁有眾多開發者的開源軟件項目,最開始是Personal Home Page的縮寫,已經正式更名為 "PHP: Hypertext Preprocessor"。PHP是在1994年由Rasmus Lerdorf創建的 [30]  ,最初只是一個簡單的用Perl語言編寫的統計他自己網站訪問者數量的程序。後來重新用C語言編寫,同時可以訪問數據庫,1995年,PHP(Personal Home Page Tools)對外發表第一個版本PHP1。此後,越來越多的網站開始使用PHP,並且強烈要求增加一些特性,如循環語句和數組變量等,1995年發佈的PHP2加入了對mySQL的支持。
Andi Gutmans和Zeev Suraski在為一所大學的項目中開發電子商務程序時發現PHP2功能明顯不足,於是他們重寫了代碼發佈了PHP3。PHP3是類似於現代PHP語法結構的第一個版本,PHP3的最強大的功能是它的可擴展性,PHP3的新功能和廣泛的第三方數據庫、API的支持使得這樣程序的編寫成為可能。
PHP3官方發佈不久,Andi Gutmans和Zeev Suraski開始重新編寫PHP代碼。設計目標是增強複雜程序運行時的性能和PHP自身代碼的模塊性。經過不懈努力Zend引擎研發成功並且實現了設計目標,並在1999年中期引入 PHP。基於該引擎並結合了更多新功能的 PHP4於2000年5月正式發佈。除了更高的性能以外,PHP4還包含一些關鍵功能,比如:支持更多的 web 服務器、HTTP Sessions 支持、輸出緩衝、更安全的用户輸入和一些新的語言結構。
PHP5於2004年7月正式發佈,它的核心是Zend引擎2代(PHP7是Zend加強版3代),引入了新的對象模型和大量新功能,開始支持面向對象編程。隨着PHP6經歷長時間的開發流產後,PHP5發佈了6個版本頑強的支撐着開源社區的發展,直到2015-12-03那天迎來了PHP 7.0的發佈,其實PHP5.6已經包含了很多PHP6想實現的特性,它為PHP7的研發爭取了寶貴的時間。不負眾望PHP7.0對比PHP5.6性能整整提升了2倍,PHP7的成功發佈讓很多核心開發成員迴歸到PHP社區,並且在2020-11-26發佈了PHP8。和php7系列相對比,PHP8對各種變量判斷和運算採用更嚴格的驗證判斷模式,這點有利後續版本對jit的性能優化。
PHP語言作為一種高級語言,其特點是開源, 在設計體系上屬於C語言體系,它可以讓很多接受過高等教育的初學者能很快接受並完成入門學習,簡單好上手容易找工作自然粉絲多。如果數據量大及訪問壓力大,可以集成redis、mysql分表分區分庫、elasticsearch搜索引擎、消息隊列寫保護和php系統分佈式集羣部署等技術方案,緩解數據存儲、服務訪問和數據檢索帶來的巨大壓力。
無論是大中小型項目,PHP都是一個十分適合的高級編程語言,是否適合就看項目研發團隊的對它的掌握程度。 但是對於較大的和更為複雜的項目,最常見的php-fpm編程模式就顯出它的薄弱了。針對PHP-fpm暴露出的一系列缺點問題,最簡單靠譜的方案就是及時升級兼容PHP的高版本,PHP7.0.0 [14]  對比PHP5.6性能提升了2倍,另外PHP7.4提供的Preloading預加載機制 [11]  實現了部分程序常駐內存,獲取了不錯的性能提升,在PHP8又提供了高效的JIT (Just-In-Time即時編譯) [12]  運算支持。另外水平更高的開發者可以轉向難度更高的php-cli編程,它能解決大部分的系統性能問題,無論是PHP7和PHP8都支持這種模式的編程。
經過二十多年的發展,隨着php-cli相關組件的快速發展和完善,PHP已經可以應用在 TCP/UDP服務、高性能Web、WebSocket服務、物聯網實時通訊、遊戲、微服務等非 Web 領域的系統研發 [20] 
根據W3Techs2019年12月6號發佈的統計數據,PHP在WEB網站服務器端使用的編程語言所佔份額高達78.9% [22]  。在內容管理系統的網站中,有58.7%的網站使用WordPress(PHP開發的CMS系統),這佔所有網站的25.0%。 [19] 
2023年11月,PHP 8.3發佈。 [45] 

PHP語言特點

PHP開源免費

PHP是一個受眾大並且擁有眾多開發者的開源軟件項目,Linux + Nginx + Mysql + PHP是它的經典安裝部署方式,相關的軟件全部都是開源免費的,所以使用PHP可以節約大量的正版授權費用。不過PHP作為一個開源軟件,它缺乏大型科技公司的支持背景,網絡上對它的唱衰也是經久不衰,不過它的持續迭代和性能持續增強的現實卻是鼓舞人心的,PHP社區用實際行動給予各種質疑強有力的回擊。

PHP快捷高效

PHP的內核是C語言編寫的基礎好效率高,可以用C語言開發高性能的擴展組件;PHP的核心包含了數量超過1000的內置函數,功能應有盡有很全面,開箱即用程序代碼簡潔; [26]  PHP數組支持動態擴容,支持以數字、字符串或者混合鍵名的關聯數組,能大幅提高開發效率; [27]  PHP是一門弱類型語言,程序編譯通過率高,相對其他強類型語言開發效率快;PHP天然熱部署,在php-fpm運行模式下代碼文件覆蓋即完成熱部署;PHP經過20多年的發展,在互聯網上可以搜到海量的參考資料供參考學習。

PHP性能提升

PHP版本越高它的整體性能越高,根據官方介紹,PHP7.0.0 [14]  對比PHP5.6性能就提升了2倍,PHP7.4已經比PHP7.0快了約30%,PHP8.0在性能上又相對PHP7.4大約改進了10%。PHP 8.0 引入了 JIT編譯器特性,同時加入多種新的語言功能,例如命名參數、聯合類型、註解、Constructor Property Promotion、match 表達式、nullsafe 運算符以及對類型系統、錯誤處理和一致性的改進。PHP擁有自己的核心開發團隊,保持5年發佈一個大版本、1個月發佈2個小版本的頻率,最新的版本是PHP8.08 [15] PHP 7.0.0 [16]  發佈於2015-12-03,此版本下最新版本是PHP 7.4.21 [18]  (發佈日期:2021-07-01),PHP 8.0.0 [17]  發佈於2020-11-26,此版本下最新版本是PHP 8.0.8(發佈日期:2021-07-01)。

PHP跨平台

每個平台都有對應的php解釋器版本,指針對不同平台均編譯出目標平台的二進制碼(PHP解釋器),php開發的程序可以不經修改運行在windows、linux、unix等多個操作系統上。

PHP常駐內存

php-cli模式下可以實現程序常駐內存,各種變量和數據庫連接都能長久保存在內存 [9]  實現資源複用,比較常用的做法是結合swoole [8]  組件編寫cli框架。

PHP頁面生命週期

在php-fpm模式下,所有的變量都是頁面級的,無論是全局變量還是類的靜態成員,都會在頁面執行完畢後被清空,對程序員水平要求低,佔用內存非常少,特別適合中小型系統的開發。

PHP運行機制

PHP常見的運行模式有2種,分別是php-fpm [6] php-cli [7]  。當PHP 選擇運行在php-fpm模式下,所有的變量都是頁面級的,無論是全局變量還是類的靜態成員,都會在頁面執行完畢後被清空。運行在php-cli模式下可以實現程序常駐內存,各種變量和數據庫連接都能長久保存在內存 [9]  實現資源複用,性能可以得到很大的提升,php-cli雖然開發比較複雜,但是能夠獲取更高的性能,對開發者的要求比較高需要比較高的開發水平,比較常用的模式是結合swoole [8]  組件編寫cli框架,各種變量能保存在跨進程的高性能共享內存 Table [10]  ,可以開發出支持熱啓動的php-cli可靠各類應用系統。
php-fpm在PHP 5.3.3 [25]  版本成為了官方正式組件(2010-07-22),它提供了穩定可靠的進程管理服務,進程不足時候可以智能擴充數量,閒置時候可以自動回收銷燬多餘的進程,同時它對程序的容錯能力很強大運行非常穩定,可以應付企業級的開發需求。php-fpm友好的完成了使用HTTP/HTTPS等TCP/IP互聯網協議下進行的用户的輸入輸出,頁面級生命週期各種資源用完即釋放,不存在內存泄漏的問題。php-fpm也提供有一些常駐內存的技術支持,例如PHP 7.4引入的opcache.preload也能實現局部的PHP類和函數的常駐內存,不過這個方法不夠靈活,和服務器配置捆綁的太死了。
php-cli因為能實現各類資源的常駐內存,所以可以資源複用,更高效完成多進程編程和異步編程,可以開發出負載能力更高的應用系統。但是相對php-fpm的簡單編程開發,開發者要注意很多的事項和需要做很多附加的控制器開發,否則就無法實現期待中的高性能。
首先開發者需要去實現可靠的進程管理服務,保證系統進程遇到各類錯誤退出運行後能夠自動創建新的進程,只有這樣才能保證後續的服務請求有足夠空閒進程可分配。每個業務代碼段都要做異常處理,讓進程遇到非致命錯誤時候不會退出,因為進程重啓意味程序和各類資源需要再次加載,這個過程性能消耗不小,所以只有進程穩定運行了常駐內存才有意義。
其次因為常駐內存,編寫的新的程序必須重啓服務才能生效,這一點習慣了fpm模式的開發者會感到比較陌生。另外開發者需要手工釋放內存,否則系統長時間運行後會出現內存泄露。同時在cli模式下,我們不能像fpm裏直接用 $_SERVER、$_POST、$_GET、$_COOKI和$_FILES 進行編程工作,需要自己去解析各種互聯網通訊協議完成用户的輸入輸出。要實現多進程編程利用多核CPU計算,還有學習使用pcntl和posix編程,這裏涉及到了異步編程邏輯,這塊難度還是比較大的。比較常用的模式是結合swoole [8]  組件編寫cli框架。
PHP是一個活躍的社區開發語言,有專業的核心開發團隊在持續不斷的迭代,最近一個版本就是PHP 8.0.8 [13]  引入了很多的新特性。

PHP參考框架

(一)WordPress內容管理系統(CMS) [21] 
功能強大、擴展性強,易於擴充功能;搭建的博客對seo搜索引擎友好,收錄快排名靠前;網站上主題多,各色各樣應有盡有;有強大的社區支持,有上千萬的開發者貢獻和審查。
(二)Hyperf [23] 
Hyperf 是一個基於Swoole 高性能、高靈活性的漸進式 PHP 協程框架,內置協程服務器及大量常用的組件,性能較傳統基於PHP-FPM 的框架有質的提升,提供超高性能的同時,也保持着極其靈活的可擴展性,標準組件均基於 PSR 標準實現,基於強大的依賴注入設計,保證了絕大部分組件或類都是 可替換 與 可複用 的。
(三)ThinkPHP
ThinkPHP是一個快速、兼容而且簡單的輕量級國產PHP開發框架,最早誕生於2006年初,遵循Apache2開源協議發佈。秉承簡潔實用、出色的性能和至簡的代碼、注重易用性。並且擁有眾多原創功能和特性,在社區團隊的積極參與下,在易用性、擴展性和性能方面不斷優化和改進。
(四)Drupal [24] 
Drupal誕生於2000年 ,是一個基於PHP語言編寫的開發型CMF(內容管理框架),即:CMS+ framework。Drupal的架構由三大部分組成:內核、模塊、主題。三者通過Hook機制緊密的聯繫起來。可自由配置,能支持從個人博客到大型社區驅動的網站等各種不同應用的網站項目。
(五)easyswoole [28] 
EasySwoole是一款常駐內存型的國產分佈式swoole框架,支持同時混合監聽HTTP、WebSocket、自定義TCP、UDP協議,且擁有豐富的組件,例如協程 連接池、協程Kafka客户端、協程ElasticSearch客户端、、協程Redis客户端、協程自定義隊列、 協程Memcached客户端、協程HTTP客户端、Crontab定時器等。
(六)Laravel [29] 
Laravel是一套簡潔、優雅的PHP Web開發框架(PHP Web Framework)。它可以讓你從麪條一樣雜亂的代碼中解脱出來;它可以幫你構建一個不錯的網絡APP,而且每行代碼都可以簡潔、富於表達力。
(七)CakePHP [41] 
CakePHP 設計層面很優雅,沒有自帶多餘的 library,所有的功能都是純粹的框架,執行效率還不錯。
(八)imi [42] 
它可以運行在 PHP-FPM、Swoole、Workerman 多種容器環境下

PHP語言參考

PHP內置函數

PHP 有很多標準的函數和結構。還有一些函數需要和特定的擴展模塊一起編譯,否則在使用它們的時候就會得到一個致命的“未定義函數”錯誤。例如,要使用 image 函數中的 imagecreatetruecolor(),需要在編譯 PHP 的時候加上 GD 的支持。或者要使用 mysqli_connect() 函數,就需要在編譯 PHP 的時候加上 MySQLi 支持。有很多核心函數已包含在每個版本的 PHP 中如字符串和變量函數。調用 phpinfo() 或者 get_loaded_extensions() 可以得知 PHP 加載了那些擴展庫。同時還應該注意,很多擴展庫默認就是有效的。 [37] 
在PHP編程裏需要注意用户的輸入安全,對用户各個方面的輸入都要做好相關的過濾處理,內置函數里提供了不少的安全相關的函數,編程學習者需要重點掌握以下的7個重點函數如下表格:
用户輸入安全的7個內置函數
函數名稱
用途簡介
htmlentities
將字符轉換為 HTML 轉義字符
htmlspecialchars_decode
將特殊的 HTML 實體轉換回普通字符
htmlspecialchars
將特殊字符轉換為 HTML 實體
nl2br
在字符串所有新行之前插入 HTML 換行標記
str_replace
子字符串替換
strip_tags
從字符串中去除 HTML 和 PHP 標記
stripslashes
反引用一個引用字符串

PHP預定義變量

對於全部腳本而言,PHP 提供了大量的預定義變量。這些變量將所有的外部變量表示成內建環境變量,並且將錯誤信息表示成返回頭。 [31]  在PHP的編程裏我們經常需要用到以下幾個系統變量,編程學習者需要重點掌握的7個預定義變量如下表格:
重點需要掌握的7大預定義變量
變量名稱
變量用途説明
$GLOBALS
引用全局作用域中可用的全部變量
$_SERVER
服務器和執行環境信息
$_GET
HTTP GET 變量(用户輸入之一)
$_POST
HTTP POST 變量(用户輸入之一)
$_FILES
HTTP 文件上傳變量
$_SESSION
Session 變量(用户會話)
$_COOKIE
HTTP Cookies(用户會話標識)

PHP數據類型

PHP 支持 10 種原始數據類型。四種標量類型:bool(布爾型)、int(整型)、float(浮點型,也稱作 double)和string(字符串);四種複合類型:array(數組)、object(對象)、callable(可調用)和iterable(可迭代);最後是兩種特殊類型:resource(資源)和NULL(無類型)。 [32] 

PHP運算符

運算符是可以通過給出的一或多個值(用編程行話來説,表達式)來產生另一個值(因而整個結構成為一個表達式)的東西。PHP的運算符包含:運算符優先級、算術運算符、賦值運算符、位運算符、比較運算符、錯誤控制運算符、執行運算符、遞增/遞減運算符、邏輯運算符、字符串運算符、數組運算符和類型運算符。 [33] 

PHP流程控制

任何PHP腳本都是由一系列語句構成的,一條語句可以是一個賦值語句、一個函數調用、一個循環、一個條件語句或者甚至是一個什麼也不做的語句(空語句)。語句通常以分號結束,此外還可以用花括號將一組語句封裝成一個語句組,語句組本身可以當作是一行語句。 [34] 

PHP類與對象

每個類的定義都以關鍵字class開頭,後面跟着類名,後面跟着一對花括號,裏面包含有類的屬性與方法的定義。類名可以是任何非PHP保留字 的合法標籤。一個合法類名以字母或下劃線開頭,後面跟着若干字母,數字或下劃線。以正則表達式表示為:^[a-zA-Z_\x80-\xff][a-zA-Z0-9_\x80-\xff]*$。一個類可以包含有屬於自己的常量,變量(稱為“屬性”)以及函數(稱為“方法”)。要創建一個類的實例,必須使用 new 關鍵字。當創建新對象時該對象總是被賦值,除非該對象定義了 構造函數 並且在出錯時拋出了一個 異常。類應在被實例化之前定義(某些情況下則必須這樣)。如果在new之後跟着的是一個包含有類名的字符串 string,則該類的一個實例被創建。如果該類屬於一個命名空間,則必須使用其完整名稱。 [35] 

PHP命名空間

在 PHP中,命名空間用來解決在編寫類庫或應用程序時創建可重用的代碼如類或函數時碰到的兩類問題:用户編寫的代碼與PHP內部的類/函數/常量或第三方類/函數/常量之間的名字衝突。為很長的標識符名稱(通常是為了緩解第一類問題而定義的)創建一個別名(或簡短)的名稱,提高源代碼的可讀性。PHP命名空間提供了一種將相關的類、函數和常量組合到一起的途徑。 [36] 

PHP參考手冊

php的文檔內容比較多,這裏這是摘錄了部分內容,有需要的用户可以訪問官網獲取更完整的使用手冊。 [38] 

PHP版本記錄

版本
發佈日期
最終支持
相關更新及備註
1.0
1995-06-08
--
首次使用
2.0
1996-04-16
--
針對PHP 1.0的改進版,速度更快、體積更小,更容易產生動態網頁。
3.0
1998-06-06
2000-10-20
Zeev Suraski和Andi Gutmans重寫了底層,支持可擴展組件。
4.0
2000-05-22
2001-06-23
增加了Zend引擎,支持更多的 web 服務器、HTTP Sessions 支持、輸出緩衝、更安全的用户輸入和一些新的語言結構
4.1
2001-12-10
2002-03-12
加入了superglobal(超全局的概念,即$_GET、$_POST等)
4.2
2002-04-22
2002-09-06
默認禁用register_globals
4.3
2002-12-27
2005-03-31
引入了命令行界面CLI用來不用CGI
4.4
2005-07-11
2008-08-08
修復了一些致命錯誤
5.0
2004-07-13
2005-09-05
Zend升級為二代引擎,開始支持面向對象編程
5.1
2005-11-24
2006-08-24
引入了編譯器來提高性能、增加了PDO作為訪問數據庫的接口
5.2
2006-11-02
2011-01-06
默認啓用過濾器擴展
5.3
2009-06-30
2014-08-14
支持命名空間;使用XMLReader和XMLWriter增強XML支持;支持SOAP ,延遲靜態綁定,跳轉標籤(有限的goto), 閉包,Native PHP archives。php-fpm在php5.3.3 [25]  版本成為了官方正式組件
5.4
2012-03-01
2015-09-03
支持Trait、簡短數組表達式。移除了register_globals, safe_mode, allow_call_time_pass_reference, session_register(), session_unregister(), magic_quotes以及session_is_registered()。加入了內建的Web服務器。增強了性能,減小內存使用量。
5.5
2013-06-20
2016-07-10
支持generators,用於異常處理的finally ,將OpCache(基於 Zend Optimizer+)加入官方發佈中。
5.6
2014-08-28
2018-12-31
常數標量表達式、可變參數函數、參數拆包、新的求冪運算符、函數和常量的use語句的擴展、新的phpdbg調試器作為SAPI模塊,以及其他更小的改進。使用php://input替代 $HTTP_RAW_POST_DATA,iconv和mbstring配置選項中和編碼相關的選項廢棄。
6.x
未發佈
--
取消掉的、從未正式發佈的PHP版本。
7.0
2015-12-03
2018-12-03
Zend引擎升級到三代 ,整體性能是5.6的2倍。移除ereg、mssql、mysql、sybase_ct等4個擴展。引入了類型聲明,有兩種模式: 強制 (默認) 和 嚴格模式。支持匿名類。
7.1
2016-12-01
2019-12-01
void返回值類型,類常量,可見性修飾符,新增可為空(Nullable)類型,新增短數組語法([])的,支持多異常捕獲處理,廢棄了mcrypt 擴展用OpenSSL取代
7.2
2017-11-30
2020-11-30
GD 擴展內的 png2wbmp() 和 jpeg2wbmp() 被廢棄,對象參數和返回類型提示、抽象方法重寫等
7.3
2018-12-06
2021-12-06
更靈活的 Heredoc 和 Nowdoc 語法,大小寫不敏感的常量聲明現被廢棄,在字符串中搜索非字符串內容都將被視為字符串,而不是 ASCII 編碼值。
7.4
2019-11-28
2022-11-28
Preloading預加載機制,改進OpenSSL、弱引用等。屬性添加限定類型、有限返回類型協變與參數類型逆變、數值文字分隔符,為過渡到PHP8做了一定的準備。
8.0.0
2020-11-26
--
JIT (Just-In-Time即時編譯)、新增static返回類型、新增mixed 類型、命名參數(Named arguments)和註釋(Attributes) [40]  ,不再允許通過靜態調用的方式去調用非靜態方法,字符串與數字的比較將首先將數字轉為字符串再比較 [39] 
8.2
2022-12
--
PHP 8.2 新增支持在 traits 中定義常量、引入了“Random”擴展和“read-only”類、Disjunctive Normal Form (DNF) 類型,更新了內置 web 服務器的 MIME 類型表,減少了各種函數返回的字符串的內存佔用,初步支持 macOS Instrument 的 JIT 性能分析生成,為 Linux 啓用 arc4random_buf,為隨機字節引入 Glibc 2.36 以上版本。
PHP 8.2 初步支持 Windows for ARM64 平台上的跨平台創建,分配 JIT 緩衝區 Opcache 靠近 PHP .text 字段,以允許使用直接的 IP 相關調用和跳轉。新版本還為 PHP Sockets 引入新選項,支持新的 Curl 選項,新的 ZipArchive 方法,廢棄動態屬性,並優化了一些性能。 [44] 
8.3
2023-11

添加類常量顯式類型、只讀屬性深拷貝,新增#[\Override] 屬性,新增 json_validate () 函數,添加 Randomizer::getBytesFromString () 方法,添加 Randomizer::getFloat () 和 Randomizer::nextFloat () 方法 [45] 
參考資料
展開全部 收起