php基本知識

來源:互聯網
上載者:User
PHP基本知識 轉至中繼資料結尾 轉至中繼資料起始 傳送門

[基礎知識]

類型

變數

常量

運算式

運算子

流程式控制制 編程範式

PHP是一個靈活的動態語言,支援多種編程範式。這些年來一直在不斷的進化,重要的裡程碑包括PHP 5.0 (2004)增加完善的 物件導向模型、PHP 5.3 (2009)增加匿名函數和命名空間和PHP 5.4 (2012)增加traits. 物件導向編程

PHP具有完整的物件導向編程特性,如類、抽象類別、介面、繼承、建構函式、複製和異常等。 學習PHP物件導向編程 函數式編程

PHP支援第一類函數(first-class function),即函數可以賦值給變數,包括使用者自訂的函數和內建函數,然後動態調用它。 函數可以作為參數傳遞給其他函數(即高階函數),也可以作為函數傳回值返回。

PHP支援函數遞迴調用,即函數自己調用自己,不過在實際的PHP代碼中,我們更喜歡用迭代來代替遞迴。 學習動態調用函數call_user_func_array 元編程

PHP通過反射API和魔術方法機制,支援多種方式的元編程。開發人員通過魔術方法,如__get(), __set(), __clone(),__toString(), __invoke()等,可以改變類的行為。Ruby開發人員經常說PHP沒有method_missing方法,實際上通過__call()和__callStatic()就可以 完成同樣的功能。 學習魔術方法 學習反射 命名空間

如前所述,PHP社區的眾多開發人員已經開發了大量的代碼。這意味著一個函數庫中的PHP代碼可能使用了另外一個庫中相同的類名,如果它們共用一個命名空間,則會產生衝突導致異常。

命名空間解決了這個問題。如PHP手冊裡描述的那樣,命名空間類似於作業系統中的目錄,兩個同名檔案可以共存於不同的目錄。同理,同名的PHP類可以在不同的PHP命名空間下共存,就這麼簡單。

因而把代碼放在自己的命名空間下就顯得非常必要,這樣其他人就可以放心的使用這些代碼,而無需擔心與其他函數庫的命名衝突。

PSR-0 裡提供了命名空間的推薦使用方式, 它試圖提供一個標準的檔案、類和命名空間的使用慣例,從而讓代碼做到隨插即用。

2013年12月,PHP-FIG發布了新的自動載入標準:PSR-4,將來可能會替換舊的PSR-0標準。PSR-4要求PHP5.3版本以上,而目前很多項目用的都是PHP5.2, 因此當前兩個標準都可用,但是對於新應用或者包的話,應優先考慮PSR-4. 瞭解更多命名空間 異常

異常是大部分流行語言的標準特性,但是PHP開發人員卻不太重視。其他語言如Ruby極度倚賴異常,在任何錯誤發生的時候,如HTTP請求失敗、DB查詢錯誤,甚至圖片資源未找到,都會拋出一個異常,以及時提示那裡發生了一個錯誤。

PHP則對此很寬鬆,如調用file_get_contents()失敗,只是返回FALSE並提示一個warning資訊而已。很多老的PHP架構,如CodeIgniter會返回false,然後在自己的日誌裡記錄一個訊息,開發人員需要使用如$this->upload->get_error()的方式來查看發生了什麼錯誤。這麼做需要你自己檢查是否有錯誤,並需要根據不同類調用不同的方法來擷取錯誤訊息,而不能讓錯誤明顯的顯示出來。

這種做法的另外一個弊端是當類自動在螢幕列印一個錯誤,然後退出進程,阻止了其他開發人員動態處理該錯誤的機會。而異常則是讓開發人員知道發生了錯誤,並讓他們選擇如何處理:

<?php $email = new Fuel\Email;$email->subject('My Subject');$email->body('How the heck are you?');$email->to('guy@example.com', 'Some Guy'); try{ $email->send();}catch(Fuel\Email\ValidationFailedException $e){ // The validation failed}catch(Fuel\Email\SendingFailedException $e){ // The driver could not send the email}finally{ // Executed regardless of whether an exception has been thrown, and before normal execution resumes}
SPL異常

預設的異常類Exception包含的上下文資訊很少,對於debug不方便,常見的做法是建立更具體的子類:

<?php class ValidationException extends Exception {}

這使得你可以包含多個catch子句來處理不同的異常,但是這又會導致建立很多的自訂異常類,可以用SPL中的異常類來緩解這個問題 SPL擴充.

如使用__call()魔術方法,對不存在的方法調用拋出一個throw new BadFunctionCallException;,既避免了拋出含義模糊的Exception異常,也省去了自訂異常類的麻煩。 學習更多Exceptions 瞭解跟多SPL Exceptions PHP中的異常嵌套 PHP 5.3異常最佳實務 資料庫

通常PHP代碼使用資料庫來持久化儲存資料,並有多種方式去串連和操作資料庫。在PHP5.1.0之前,推薦的方式有mysql、mysqli和pgsql等。

如果應用只是使用一個資料庫的話,原生驅動就工作的非常好,否則使用MySQL的同時,還需要使用MSSQL或Oracle資料庫的話,那麼就沒有辦法只使用一個原生驅動了,只能分別學習各個資料庫驅動的API,這非常令人生厭。

另外需要注意,mysql這個原生驅動已經不在活躍開發狀態了,從PHP5.4.0開始被標記為不推薦使用,意味著將來版本如PHP 5.6可能會移除這個擴充。如果你正在使用mysql_connect()和mysql_query(),那麼將來可能要重寫部分代碼,所以最好用mysqli或PDO來代替。如果你正在開發新項目,請不要用mysql擴充,嘗試用MySQLi擴充或PDO來替代 PHP: 選擇MySQL API PDO

PDO是資料庫連接抽象庫,從PHP5.1.0開始提供,提供多種資料庫的統一的操作介面。PDO不會轉化你的SQL查詢或者類比缺失特性;它只是提供統一的API去串連不同的資料庫而已。

更重要的是,PDO允許你綁定SQL查詢語句中的變數,而無需擔心SQL注入問題,這主要通過PDO statements和變數綁定來實現。

假設PHP指令碼接收一個數字ID作為查詢參數,從資料庫取回一條記錄。下面是一種錯誤的做法:

$pdo = new PDO('sqlite:users.db');$pdo->query("SELECT name FROM users WHERE id = " . $_GET['id']); // <-- NO!

這是非常糟糕的代碼,直接在SQL中插入一個原始輸入變數,導致潛在的SQL注入風險。假如駭客構造URL:http://domain.com/?id=1%3BDELETE+FROM+users來傳入惡意參數id,則$_GET['id']的變數值為1;DELETE FROM users,這將刪除資料表中的所有使用者。因此,你應該使用PDO的綁定參數功能來處理ID輸入參數。

$pdo = new PDO('sqlite:users.db');$stmt = $pdo->prepare('SELECT name FROM users WHERE id = :id');$stmt->bindParam(':id', $_GET['id'], PDO::PARAM_INT); // <-- Automatically sanitized by PDO$stmt->execute();

這才是正確的代碼,在PDO statement中綁定一個參數,使得查詢被發給資料庫之前,對輸入參數進行轉義,防止SQL注入攻擊。 學習PDO

另外一個要注意的問題是,如果資料庫連接沒有隱式地關閉,那麼資料庫連接數可能會超過資料庫伺服器的限制而串連失敗,這種錯誤在其他程式設計語言中比較常見。PDO對象在銷毀的時候會隱式的關閉資料庫連接,只要你把指向它的引用全部刪除即可,如設定為NULL。如果沒有,PHP也會在指令碼結束時關閉所有非持久化的資料庫連接。 瞭解更多PDO串連 緩衝 位元組程式碼快取

在一個PHP檔案被執行時,它先被編譯為位元組碼(也稱opcode),然後這些位元組碼被執行。如果檔案沒有修改,那麼位元組碼也會保持不變,這意味著編譯這一步白白浪費了CPU資源。

這就是引入位元組程式碼快取的原因,通過把位元組碼儲存在記憶體中來消除冗餘的編譯,重用它們完成後續的調用。配置位元組程式碼快取非常簡單,而且可以極大地提高應用的執行效率,沒有理由不使用位元組程式碼快取。

PHP 5.5開始內建位元組程式碼快取組件OPcache,老版本的PHP可以使用第三方的位元組程式碼快取組件,流行的位元組程式碼快取方案有: APC (PHP 5.4 and earlier) 對象緩衝

很多時候,在代碼中緩衝對象可以帶來很大的收益,例如擷取代價很大的資料和查詢結果很少變化的資料庫調用。我們可以使用對象緩衝系統緩衝這些資料,大大加快後續的同類訪問請求。如果你在取得這些資料之後,把它們緩衝在系統中,在後續對這些資料的請求中,就可以直接使用緩衝中的對象,這麼做可以很大的提示系統效能,減少伺服器的負載。

很多流行的位元組程式碼快取方案也允許你緩衝自訂資料,因此我們更應該充分利用對象緩衝功能。APCu、XCache和WinCache都提供API,讓你把資料緩衝在他們的記憶體cache中。

使用最多的記憶體對象緩衝系統是APCu和redis,APCu是很好的一個對象緩衝方案,它提供了簡單的API來讓你把Object Storage Service在記憶體中,而且配置和使用都非常容易,它的一個缺點是只能在本機使用。REDIS則是另外一種方式,它是一個單獨的服務,可以通過網路訪問,這意味著可以在一個地方寫入資料,然後在不同的系統中訪問這份資料。

Note that when running PHP as a (Fast-)CGI application inside your webserver, every PHP process will have its own cache, i.e. APCu data is not shared between your worker processes. In these cases, you might want to consider using redis instead, as it's not tied to the PHP processes.

在單機效能上,APCu通常比redis更高,但是redis提供了更多進階資料結構和更多得功能

Note that prior to PHP 5.5, APC provides both an object cache and a bytecode cache. APCu is a project to bring APC's object cache to PHP 5.5+, since PHP now has a built-in bytecode cache (OPcache).

學習更多個物件緩衝系統: APCu APC Functions Memcached Redis XCache APIs WinCache Functions 架構

我們使用YAF作為基礎架構參考YAF手冊 http://www.laruence.com/manual/ 安全 Web應用安全

總有一些人會千方百計的想著破壞你的Web應用,提前想辦法加強自己的Web應用的安全性非常重要。幸運的是,The Open Web Application Security Project (OWASP) 已經提供詳盡的已知安全問題列表和防範對策。每個關注Web安全的開發人員都應該仔細閱讀該列表。 閱讀OWASP安全指南 資料過濾

永遠不要在PHP代碼中信任外部輸入,在使用之前一定要先過濾和驗證,filter_var和filter_input函數可以協助過濾文本和驗證文字格式設定(如郵箱地址)。

外部輸入可以是:$_GET和$_POST表單輸入資料、$_SERVER超級變數中的某些值和通過fopen('php://input', 'r')擷取的HTTP請求體。要記住外部輸入不僅僅是使用者提交的表單資料,還包括上傳和下載的檔案、session變數、cookie資料和第三方Web服務提供的資料等。

當外部資料被儲存合并之後,下次讀取時,它們仍然算是外部輸入,每次在代碼中處理的時候,需要問自己是否已經正確過濾,是否可以信任它們。

資料需要根據不同用處,進行不同的過濾,如果把未經過濾的資料輸出到HTML頁面,它可以在你的網站裡執行HTML和JavaScript。即通常說的跨站指令碼攻擊(XSS)。避免XSS的一個策略就是使用strip_tags函數過濾外部輸入的所有HTML標籤,或者使用htmlentities/htmlspecialchars轉義其中的HTML實體。

另外一個例子是傳給命令列命令的選項,這可能非常危險(通常不是一個好主意),不過你可以用內建的escapeshellarg函數過濾命令列的參數。

最後一個例子是根據外部輸入來從檔案系統中負載檔案的操作,可以通過修改路徑中的檔案名稱實施攻擊。你需要過濾輸入中的"/", "../",null bytes, 或其他特殊字元,以防止載入不能公開的包含敏感性資料的檔案。 學習更多資料過濾 瞭解更多filter_var 瞭解更多filter_input 學習更多null位元組處理 資料清洗

資料清洗就是刪除或轉義外部輸入中的非法或Unsafe 字元。比如把外部資料輸出到HTML或插入到SQL語句之前,需要先清洗外部輸入。當你通過PDO綁定資料時,它會替你轉義輸入資料。

有時候需要允許外部資料包含安全的HTML標籤,並輸出到HTML頁面中。這個比較難處理,可以考慮使用其他更嚴格的格式,如或BBCode,實在不能的話,可以使用HTML Purifier庫來進行資料清洗。

瞭解更多資料清洗過濾器 資料驗證

資料驗證外部輸入就是你預期的,如你在處理註冊表單時,需要驗證email地址、電話號碼和年齡等資料

瞭解更多資料驗證過濾器

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.