序言
閑來無事,下載了一些電子書,然后看書名不錯《PHP高級程序設計_模式、框架與測試》,翻了一下雖然書有點老了但是講的內容經常會碰到!給大家推薦一下,然后這里放上我的讀書筆記,每日更新。
【作 者】(加)Kevin McArthur [同作者作品] [作譯者介紹]
【譯 者】 汪泳[同譯者作品]
【叢 書 名】 圖靈程序設計叢書
【出 版 社】 人民郵電出版社 【書 號】 9787115193179
【上架時間】 2009-5-31
【出版日期】 2009 年7月 【開 本】 16開 【頁 碼】 1 【版 次】1-1
翻譯很到位,給翻譯官加雞腿!PHP進階篇。
另外《PHP核心技術與最佳實踐》也可以去翻翻,哇學無止境啊!
索要此書電子版可在下方留言你的郵箱!
章節
- 第一章 抽象類、接口和契約式編程
- 第二章 靜態變量、成員和方法
- 第三章 單例模式和工程模式
- 第四章 異常
- 第五章 PHP 6中的新特性
- 第六章 文檔編寫和編碼規范
- 第七章 反射API
- 第八章 測試、部署和持續集成
- 第九章 SPL簡介
- 第十章 SPL迭代器
- 第十一章 SPL文件和目錄處理
- 第十二章 SPL數組重載
- 第十三章 SPL異常
- 第十四章 MVC架構
- 第十五章 Zend框架簡介
- 第十六章 Zend框架高級功能
- 第十七章 應用Zend框架
- 第十八章 Ajax和JSON
- 第十九章 Web服務和SOAP協議介紹
- 第二十章 高級Web服務
- 第二十一章 證書驗證
讀書筆記
第一章 抽象類、接口和契約式編程
抽象類
抽象類是使用abstract關鍵字聲明的類。通過將某個類標記成抽象類,我們可以推遲實現所聲明的方法。要將某個方法聲明成抽象方法,只需要省略掉包含所有大括號的方法實現體,將方法聲明的代碼行用分號結束即可。
抽象類不能直接實例化,他們必須被繼承。如果某個類從抽象類繼承,當它沒有實現基類中所聲明的所有抽象方法時,它就必須也被聲明成抽象的。
接口
在接口中,我們也可以聲明沒有方法體的方法原型,這點與抽象類很類似。它們之間的區別在於,接口不能聲明任何具有方法體的方法;並且它們使用的語法也不一樣。為了將接口規則強制加到某個類上,我們必須使用implements關鍵字,而不是使用extends關鍵字。
instanceof
在某些情況下,我們希望確定某個類是否是特定的類型,或者是否實現了特定的接口。instanceof操作符非常適合這個任務。instanceof操作符檢查三件事情:實例是否是某個特定的類型,實例是否從某個特定的類型繼承,實例或者他的任何祖先類是否實現了特定的接口。
某些語言具有從多個基類繼承的功能,這成為多重繼承。PHP不支持多重繼承。相反,它提供了為一個類聲明多個接口的功能。
接口在生命類必須遵循的規則時非常有用。契約式編程技術使用這一功能來增強封裝性,優化工作流。
第二章 靜態變量、成員和方法
靜態變量
靜態變量是經過修飾的函數變量,在某個函數執行完成之后,它的值r仍然不會丟失。使用static關鍵字可以創建靜態變量,同時還可以提供一個默認的初始值。不過,這個初始化值不能是一個表達式。當使用全局變量來模擬靜態變量時,有可能發生變量名稱沖突的現象,靜態變量在消除這一沖突方面是非常有用的。
靜態成員和方法
static關鍵字還可以用在類中修飾屬性和方法。用在屬性上時,它使屬性不再為每個實例保存一個值,,而是只為整個類自身保存一個值。這個值也可以被用做事類的所有實例之間共享的值。
要訪問靜態方法,可以使用雙冒號操作符(::),它也被稱為作用域限定操作符。這個操作符的左邊是一個類名稱或者某個預定義作用域,預定義作用域包括self、parent或者PHP6中的static。操作符的右邊是一個靜態方法、變量和常量。在類中使用self預定義作用域時,它代表的是類自身。而parent預定難以作用域代表的是父類,當我們需要訪問可能已經被重寫的基類中的方法時,parent作用域非常有用。
靜態類會對特定類型的測試產生影響。當在PHP中使用靜態類時,IoC(控制反轉)設計原型會受到限制。這是因為靜態特性的使用會導致類之間通過名稱綁定在一起,這使得單獨地測試某個組件變得更加困難。不過,大多數PHP應用程序最終都沒有采用IoC設計原型,並且靜態特性的使用通常會被優先考慮。
第三章 單例模式和工程模式
單例模式為我們提供了定義系統職責中心點的功能。單例類在一個靜態變量中保存了自身的一個實例,並且提供了一個getInstance()靜態方法對這個實例進行訪問。這個方法會返回對這個變量的引用,並且如果這個變量之前還沒有執行初始的實例化工作,這個方法便會執行。這種延時實例化的行被稱為
延時加載。單例類還應該將他的構造函數標記為private,從而防止其他類直接實例化這個類。為了清除其他可以創建這個單實例的副本的漏洞,還可以定義__clone()魔術方法,並且將它標記成private。(看到這是不是想起了TP框架)
工廠模式的作用在於,可以根據輸入參數或者應用程序配置的不同來創建一種專門用於實例化並返回其他類的實例的類。工程模式包含一個名為factory()的方法,這個方法必須返回一個對象.
第四章 異常
try關鍵字定義了要執行的代碼塊,並且需要檢測拋出的異常。你可以為不同類型的異常定義多個catch語句塊。
你能夠使用變量和內部調用來拋出內置的Exception類。當一個異常發生時,可以檢測異常具有的一些屬性,其中包括錯誤信息、錯誤代碼和跟蹤信息。
Exception 類方法:
getMessage() 返回異常信息,此信息是描述錯誤狀態的字符串
getCode() 返回錯誤代碼
getFile() 返回發送的錯誤所在的源文件。
getLine() 返回異常拋出偽造在源文件的行號
getTrace() 趕回包含場景回溯的一個數組。
getTraceAsString() 與getTrace()相同,不過這個函數返回的是字符串而不是數組。
__toString() 返回用字符串表達的整個異常信息
可以通過擴展內置的Exception類為應用程序創建自定義異常。
還可以通過定義set_exception_handler()回調函數來重寫內置的異常處理程序,並且將所有未捕捉的異常信息記錄到日志文件中。
然而,使用異常也會帶來一定的開銷。應該避免過度使用異常來控制程序流。
通過使用錯誤代碼類,可以將錯誤信息集中起來。隨着系統規模的不斷擴大,這種做法可以創建更加可控的應用程序。
將類型提示機制應用在異常上,可以用不同的異常類型實現多個catch語句塊。
最后,我們可以捕捉、檢測某個異常,然后再將這個異常重新拋給未捕捉異常的異常處理程序。
第五章 PHP 6中的新特性
這一章跳過......
第六章 文檔編寫和編碼規范
PHP注釋:
//單行注釋
/*
多行注釋
*/
/**
文檔注釋(文檔塊)
*/
文法解析:PHP代碼在被實際執行之前會轉換成二進制格式。這種從編程語言到可執行代碼的轉換過程被稱為文法解析。
元數據:描述數據的數據。在編程中,這意味着元數據是關於程序的信息。
可以再代碼中使用單行注釋、多行注釋和文檔注釋。在文法解析之后,只有文檔注釋會被保存,這對 通過編程訪問這些信息非常有用。
PHPDoc是在應用程序中嵌入元數據的一種方法。PHPDoc格式是PHP文檔的一種標准。而大量可用的PHPDoc標簽,你還可以創建自己所需標簽。
/**
這里是PHPDoc注釋
@param bool $foo foo 給函數傳遞了一些信息
*/
function bar ($foo){}
PHPDoc標簽列表請參加:http://manual.phpdoc.org/
DocBook標准是一種綜合性的基於XML的文檔類型,它定義了程序手冊的數據標記。它的設計目的更加關注於創建實際的書籍,而不是關注程序中的注釋代碼。
第七章 反射API
一個關於反射API的實例
<?php interface Iplugin{ public static function getName(); public static function getMenuItems(); public static function getArticles(); public static function getSideBars(); } class MyCoolIplugin implements Iplugin{ public static function getName(){ return "MyCoolIplugin"; } public static function getMenuItems(){ return array(array( 'description'=>"MyCoolIplugin", 'link'=>"/MyCoolIplugin" )); } public static function getArticles(){ return array(array( 'path'=>"11111111", 'desc'=>'aaaaaaaaa' )); } public static function getSideBars(){ return array(array( 'description'=>'SideBars', 'test'=>'qqqqqqqqq' )); } } function findIplugin(){ $plugins=array(); foreach(get_declared_classes() as $class){ $reflectionClass= new ReflectionClass($class); if($reflectionClass->implementsInterface('Iplugin')){ $plugins[]=$reflectionClass; } } return $plugins; } function computerMenu(){ $menu=array(); foreach (findIplugin() as $plugin){ if($plugin->hasMethod('getMenuItems')){ $reflectionMethod=$plugin->getMethod('getMenuItems'); if($reflectionMethod->isStatic()){ $items=$reflectionMethod->invoke(null); }else{ $items=$reflectionMethod->invoke($plugin->newInstance()); } } } $menu=array_merge($menu,$items); return $menu; } function computerArticles(){ $articles=array(); foreach(findIplugin() as $plugin){ if($plugin->hasMethod('getArticles')){ $reflectionMethod=$plugin->getMethod('getArticles'); if($reflectionMethod->isStatic()){ $items=$reflectionMethod->invoke(null); }else{ $items=$reflectionMethod->invoke($plugin->newInstance()); } } } $articles=array_merge($articles,$items); return $articles; } function computerSideBars(){ $sideBars=array(); foreach (findIplugin() as $plugin){ if($plugin->hasMethod('getSideBars')){ $reflectionMethod=$plugin->getMethod('getSideBars'); if($reflectionMethod->isStatic()){ $items=$reflectionMethod->invoke(null); }else{ $items=$reflectionMethod->invoke($plugin->newiInstance()); } } } $sideBars=array_merge($sideBars,$items); return $sideBars; } print_r(computerMenu()); print_r(computerArticles()); print_r(computerSideBars());