摘要:全局命名空間接觸過系統的同學都應該知道根目錄吧,我們可以將全局命名空間想象為的根目錄,在該目錄下存放的都是本身提供的各種接口類函數常量。
以下是我對命名空間的一些體會和理解,最好先看下php的官方文檔再來看此文,會更好一點。由于水平有限,文中如有紕漏,希望指出
前言在php5.3以上的版本中,php引入了命名空間(以下稱呼為namespace)這個性能。個人認為,這是非常重要的一項改變。之所以說重要,并不是說namespace本身有多么牛逼或者多高的技術含量。而是由于命名空間的引入,引起了一些列的連鎖反應,這些連鎖反應給我們現在phper開發者提供了另一種可能。
現在的開發方式
我們在以往開發應用的時候,即使是非常簡單的應用,也經常使用php的那些框架,他們通常很重、很大、很難學,更要命的是,還很多,什么Yii2、Thinkphp、CI、ZendFrame、Laravel......好吧我不想說了。
另一種可能
現在呢,我們似乎有了另外一種選擇。依靠composer包管理工具,加載packagist上面那些優秀的組件,然后通過composer提供的自動加載機制,將組建應用到項目中去。我們的開發似乎變成了擺積木,我們要做的事情只是將組件恰當的組合起來,怎么樣,聽著是不是很心動是么?全世界優秀的輪子隨我用,這個feel倍爽!!!哦,離題有點遠了,那么這和本文的主題namespacey又有什么關系呢?當然有關系了,自動加載的基石namespace
實現另外一種可能很重要的一步就是,將packagist組件自動加載到應用中。由于php的_autoload有各種各樣的實現方式,為此php-fig(php framework interop group一個php組織)提出了psr-0(已經廢棄)和psr-4,這兩個專門自動加載的解決方案,其核心思想就是:將命名空間和實際的磁盤物理路徑建立映射
(ps : 到目前為止spr-0、spr-4只是推薦的自動加載解決方案,并沒有強制,但事實上,基本都采用了這種自動加載方式。除了spr-和spr-4外,composer還支持file 和classmap的方式)
為什么會有命名空間,它解決了什么問題?命名空間出現的根本原因是為了解決命名沖突的問題,個人認為主要是為了解決以下命名沖突
用戶自定義的接口/類/trait/函數/常量 同 php系統提供的 接口/類/trait/函數/常量命名沖突
用戶自定義的接口/類/trait/函數/常量 同 第三方框架提供的 接口/類/trait/函數/常量命名沖突
舉個例子
我們經常使用var_dump進行斷點調試,這個是系統提供給我們的內置函數。但是呢,有的程序員對var_dump輸出的數據格式不是很滿意,希望自己寫一個var_dump函數(var_dump用時間長了,叫其他的名字不習慣),自己格式化其輸出信息,但是報錯!
========================================" echo $message; echo "命名空間的一些基礎概念?
========================================" } /** * 報錯信息:PHP Fatal error: Cannot redeclare var_dump() */
我將采用類比的方法來說明這些高深的概念,盡量能讓大家清楚。
全局命名空間
接觸過linux系統的同學都應該知道根目錄"/"吧,我們可以將全局命名空間想象為linux的根目錄,在該目錄下存放的都是php本身提供的各種接口/類/trait/函數/常量。
完全限定名稱
以全局命名空間為前綴的名稱,例如, $a = new currentnamespacefoo(); 或 currentnamespacefoo::staticmethod();我們可以將其類比為絕對路徑
限定名稱
不以全局命名空間為前綴的名稱,例如,$a = new subnamespacefoo();或subnamespacefoo::staticmethod();我們可以將其類比為相對路徑
非限定名稱
不包含任何前綴的名稱,例如, $a=new foo(); 或 foo::staticmethod();我們可以將其類比一個問文件名稱或者目錄名稱
php中的那些要素會受到命名空間的影響?首先肯定一點,并不是所有的元素都受到命名空間的影響,比如說變量就不會,只有以下php要素會受到影響:
類(class)
接口(interface)
trait
常量(constant)
方法名(function,我認為object里面的方法是method)
什么是別名/導入?命名空間的解析規則是什么?兩者又有什么關系? 什么是別名/導入?我們可以認為別名/導入,類似是windows下的快捷方式或者是linux下的軟鏈,通過該快捷方式我們可以鏈接到,別的空間下的class、interface、trait、constant、function,甚至可以是單純的連接到別的命名空間而不特指該空間下的任何元素。下面舉個例子
當我們的代碼中有以別名打頭的情況時,php就會嘗試鏈接到別名對應的命名空間中的元素,或是別名對應的命名空間,然后拼接剩余的名稱,如果有的話。例子中NSnamesubnsfunc(); 檢查到NSname是別名,所以先鏈接到MyFullNSname, 然后拼接剩余名稱MyFullNSnamesubnsfunc();
(ps:導入的名稱必須是完全限定的,不會根據當前的命名空間作相對解析,前導的反斜杠是不必要的也不推薦的)
命名空間的解析規則是什么?一圖勝千言,還是上圖吧
從圖中,可以看出主要是從完全限定名和非完全限定名這兩塊進行分析的。
兩者的關系是什么?由上圖,我們可以知道,限定名稱和非限定名稱的解析都會受到別名的影響。
而且,別名的優先級比當前命名空間的優先級高(很多地方都沒有說)。
也就是說,在一個命名空間下,限定名稱和非限定名稱會先嘗試尋找別名替換,如果找不到對應的別名,才會將當前的命名空間追加到現在的名字前面組成完全限定名
Test();
a.php和b.php兩個文件在同一個目錄下:在b.php文件中,在namespace Top下面,擁有別名TestTop as Top,所以new TopB() 會被解釋成 new TestTopB(),也就是將別名進行了替換; 而并不是new TopTopB(),將當前空間名添加到現在的名字前面。所以此時的運行結果是:xxxx/b.php
命名空間的一些易錯點,僅個人體會1、class 、interface 、traits和const 、function嘗試執行的加載策略不同
2、一個文件中,只有第一個namespace聲明命名空間前不能有任何字符,特別是bom頭(看不見但是存在),其他的namespace不做限制。
3、namespace本身并不分區大小寫,相同名字的namespace認為是同一個空間
參考資料http://php.net/manual/zh/lang...
《Modern php》
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/21697.html
摘要:什么是是一種中間語言,以接近的語法來編寫代碼,然后轉換編譯成擴展,旨在簡化擴展的創建和可維護性。如果成功,會自動生成文件到目錄你需要編輯填加擴展測試一下就這樣,你也會擴展開發了附附編譯擴展的方法 什么是 Zephir Zephir 是一種中間語言,以接近 PHP 的語法來編寫代碼,然后轉換編譯成 PHP 擴展,旨在簡化 PHP 擴展的創建和可維護性。利用編譯來提高性能和資源消耗,又不需...
摘要:是所用的框架,本文將介紹如何用這個框架寫一個程序。在目錄下建立目錄,并在其中創建文件首先我們定義一個命名空間,我們的程序使用為命名空間。入口程序這樣基本上就完成了。會自動在目錄下找模板文件,約定大于配置。 Typecho Framework是SegmentFault所用的框架,本文將介紹如何用這個框架寫一個Hello World程序。如果你不了解Typecho Framework,請先...
摘要:原文發表于入門教程之目錄結構很多初學的朋友,對于以框架為基礎構建的項目,應該如何組織目錄結構有點摸不著頭腦。只需要通過注冊這些目錄結構,即可正常使用。 原文發表于:Phalcon入門教程之目錄結構 很多初學Phalcon的朋友,對于以Phalcon框架為基礎構建的項目,應該如何組織目錄結構有點摸不著頭腦。比如多模塊的項目中,如何共用libs類庫和models目錄中模型類的情況,就有很...
摘要:然而各自為政的打包方式依賴關系的處理,導致了很難將兩個開源項目集成到一起。雖然有這種官方支持的包管理工具,但是依然沒有很好的統一的依賴關系管理的辦法。項目編譯和打包依賴關系的解決都可以很輕松的實現。 簡介 現在軟件規模越來越大,PHP項目的開發模式和許多年前已經有了很大變化。記得初學PHP那會兒,boblog是一個很好的例子,幾乎可以代表PHP項目的開發模式。當時PHP 5.x以上的版...
閱讀 1991·2023-04-26 01:41
閱讀 2468·2021-11-24 09:39
閱讀 1922·2021-11-24 09:38
閱讀 1947·2021-11-19 09:40
閱讀 3760·2021-11-11 11:02
閱讀 3294·2021-10-20 13:48
閱讀 3156·2021-10-14 09:43
閱讀 4360·2021-09-02 15:11