天天看點

雲客Drupal源碼分析之實體Entity概述

第一次在軟體開發領域聽說“實體Entity”是不是有點蒙圈不知道在說什麼呢?我們經常有聽過實體經濟,但軟體裡面實體是個什麼鬼?這個名詞怎麼來的?和那有什麼關系麼?drupal裡面實體好像還很重要,甚至有人說drupal裡面一切皆是實體;這個詞在感覺上很不直覺,有些讀者覺得drupal難學,可能就是展現在這些地方吧,entity的英文翻譯為:實體、本質、存在、物體,其實在不同的領域對實體有不同的定義,比如我們可以說由鋼鐵等組成的機器人身體是那個機器人的實體,當然實體不一定非得要是摸的着看得到的物質,如果你看過電影《黑客帝國》,裡面的虛拟人物也可以看做是數字世界中的一個個實體,從這個角度看實體就是一種存在,在漢語中實體有一些解釋,援引如下:

實體(Entity):客觀存在并可互相差別的事物稱之為實體。

指不僅可觸知的而且是有形的東西

實際存在的物體,物質

可以搜尋一下關于實體這個詞的更多解釋,在軟體中實體以“實體(Entity):客觀存在并可互相差別的事物稱之為實體”做解釋是比較合适的,有了這些印象我們來看一看drupal中的實體是什麼意思。

讓我們從一個例子開始:

假設現在讓我們不使用任何架構,直接用php去開發一個小小的新聞系統,我們要做些什麼呢?

首先寫一個腳本,用來産生一個錄入新聞的表單頁面,接着寫一個腳本來處理表單送出後的資料庫儲存工作,再寫一個腳本來根據url中送出的id來顯示新聞,如果需要修改更新新聞,那麼還需要一個腳本讀取被儲存的新聞,然後将資料填到送出表單裡面,再将表單發送給浏覽器,使用者修改後送出到錄入腳本,要浏覽新聞得寫一個清單腳本,免不了要删除不适合的新聞還需要删除腳本,現在就開發出了一個最簡單的新聞系統,可能許多小夥伴初學php時有過這樣的經曆吧。

初版的新聞系統形成後,很快我們發現了不足,我們看到産生了錄入、儲存、更新、顯示、清單、删除6個腳本,太分散了!現在我們改用面向對象程式設計,定義一個新聞類:news,裡面具備6個方法分别處理那6個操作,現在6個腳本變為一個類腳本了,用以通路的url中加上方法名作為參數,頁面模闆也可以分離出來儲存到模闆檔案夾中,現在這個新聞系統變的更加緊湊了,也更加合理了!

現在看起來我們的新聞系統已經很好了,但本質上它隻是以面向對象程式設計方式包裝着一個面向過程的思路而已,讓我們真正以面向對象的方式,發揮oop的精髓,将一切都看做對象,接着來看這個例子,進步無止境,來把它做成一個簡單的cms系統,有了這個想法後發現新聞系統隻不過是cms中的一個子對象而已,想到了一種新的方法來實作新聞系統,采用完全不一樣的方法,依然用一個類來實作新聞系統,發揮OOP的精髓,整個新聞系統用一個對象表示,隻不過它是在cms中而已,預想它的使用方法是這樣的:

$new=new news(); //初始化新聞系統,新聞系統的所有邏輯都在這個類裡面
$new->create($arr); //建立一篇新聞,參數是一個數組,作為可選值,鍵名為新聞的字段名、鍵值為字段值,如:['title' => '這是新聞标題内容', 'body' => "這個是新聞内容"]
$new->title="新的标題"; //建立後還能修改或指派所有的新聞屬性
$new->save();//建立好了,這個對象自己負責儲存新聞到資料庫,cms程式簡單的調用一個方法即可
$new->load($id); //簡單的調用一個方法就可以将以前儲存的某篇新聞初始化到一新聞對象中
$new->delete($id); //簡單的調用一個方法就可以删除某篇新聞
echo $html=$new->list(); //顯示新聞清單
echo $html=$new->toString (); //顯示新聞
           

除了這些,還可以很靈活的加許多功能到這個新聞類上面去,比如儲存新聞的時候可以執行資料驗證,防止标題為空等等,隻需要這樣:

$isOk=$new->validate();

還可以做權限檢查,這樣來:

$isOk=$new->access($operation, $account = NULL );

參數$operation為操作辨別,如“create”、“delete”等等,參數$account為賬戶對象

甚至要得到某篇新聞的url可以這樣:

$url=$new->toUrl();

這個實作新聞系統的想法實在是太棒了,在cms中和其他元件的接口非常簡單,而且操作靈活!

此時忍不住想思考這裡的$new對象現在成了什麼呢?它包含着新聞的資料,還有對新聞的各類操作,一切都變得簡單了。

說到這裡你可能已經開悟了,它!就是實體!“客觀存在并可互相差別的事物”!這個想法就是drupal中實體概念的最初來源,實際中drupal系統裡的實體概念現在已經發展的更加成熟和全面。

    帶着這種開悟的喜悅,接着看看這個$new實體,我們發現在cms中不止是新聞可以這麼辦,其他的内容比如:文章、産品也可以這麼辦,隻不過類型不同而已,這裡就産生了一個概念:“實體類型”,前面提到的$new隻是諸多類型中的一個而已,不同的類型可能名稱不同(新聞、産品)、資料模型不同(标題、型号、價格等)、針對資料的驗證不同等等,由此有必要設定一個實體類型對象來儲存實體的這些相關資訊,它和實體對象配合起來使用。

   現在有了實體、實體類型的概念,他們為cms的架構帶來了極大的靈活性,我們發現這些實體有個共同特點:都是來儲存cms中的内容的,至少會有個标題,或者說是id,用來索引這些内容,我們可以将這些共同點歸納起來,形成一個基礎對象,或者叫基礎實體,它隻包含id這樣的基礎字段,和基礎CRUD方法,其他實體就不用重複實作這些内容,隻需要繼承這個基礎實體,添加自己額外的特有字段和方法就可以了,這樣一來就産生了一個新概念:基礎實體是一種實體類型,繼承它的實體是子類型,在drupal中節點Node就是基礎實體,隻包含内容的id等,不同的内容類型,如文章、新聞等等就是子類型,在drupal的世界裡面子類型又叫父類型的bundles,硬性翻譯為捆、束,在了解上它是同類事物的細分,當然有些實體是沒必要有子類型的,他們就沒有bundles。

     如果沒有上述過程、來曆的介紹,了解實體是很困難的,它們較為抽象,雲客有些感歎:國内的許多cms系統對内容的抽象隻是到了欄目一級,不同欄目有不同資料模型,沒有想過它們本質上是相同的,沒有更進一步的抽象出實體這個概念來,還有待發展吧,也許也跟php從面向過程到面向對象轉變的過程有關,這種轉變在國内的展現還很慢,國外程式員重于追求最合理最好,而國内程式員太遷就于适應環境。

   在drupal中出現實體概念後很快就發現本質上實體是一種存放資訊的容器,同時帶了對資訊的各種操作,既然如此,實體就不止是系統中管理的内容了,還可以用來代表配置,在drupal8中目前已經形成了如下的實體,以層級關系列出:

實體變體:
    内容:
        内容實體類型:
            節點:
                文章(節點的Bundles)
                基本頁(節點的Bundles)
            分類:
                詞彙表A(分類的Bundles)
                詞彙表B(分類的Bundles)
                詞彙表...
            内容塊:
                塊内容A(塊的Bundles)
                塊内容B(塊的Bundles)
                塊内容... (塊的Bundles)
    配置:
        配置實體類型:
            視圖(沒有bundles)
            菜單(沒有bundles)
            角色(沒有bundles)
           

   在drupal中使用者也可以自定義實體,實體這個概念的發展還在繼續,它是伴随着抽象層級的提升而提升的,我們需要注意它的解釋“客觀存在并可互相差別的事物”,說不定很久以後drupal已不再是一個cms系統,而是一個數字世界,實體就是那個世界中的一位虛拟的有意識的人,未來未成定數一切尚未可知。

回歸正題,我們來看一下官方文檔對實體的解釋:

實體Entities:

從程式角度來講,在drupal8中實體是一個持久化儲存内容或配置的對象,比如将資料儲存到資料庫就是一種持久化儲存,這個對象處理資料的加載、儲存、修改、删除、驗證等,從使用者角度來講,實體是被管理資料的進階抽象,相當于一個大的資料結構,但它不隻是包括資料,還包括處理資料的方法,如一個對象代表一篇新聞,它包含新聞标題、副标題、内容、日期等等内容,并且這個對象還提供方法處理這些資料的儲存、加載、編輯、删除等等,那麼這個對象就是這篇新聞的實體對象,它就是一個實體。

    在drupal中實體要處理的事情很多,比如實作可修訂版本功能(同一内容存在多個版本),可翻譯功能(有些字段是語言相關的)、各類操作表單的處理、各種清單和内容的顯示方式、通路權限控制、儲存問題等等,内部邏輯會比較複雜,是以它是系統中一個很大的子系統,建立在許多基礎元件之上,本系列會分多個主題來介紹實體各個部分,要準備學習實體需要具備哪些前提知識呢:

鈎子和插件:它們将子產品個核心連為一個整體,實體系統中大量使用

字段api:解決内容實體的資料庫儲存、顯示、表單等相關問題

類型化資料api:實體也可以看做是複合資料類型,建構在類型化資料元件之上,實作友善操作

權限控制:用于實體的通路檢查

語言和翻譯:實體的多語言功能必不可少

以上這些主要内容雲客源碼分析系列大多已經釋出了,如果一直跟随而來将不會陌生,請看相關文章,還未釋出的或隻釋出了上篇的内容,接下來會釋出,順序上盡可能做到順應學習過程,一步一步的了解學習。

點燃好奇心,列出一個列子,先一窺實體的魅力吧:

在自定義子產品的控制器中執行以下代碼:

$nodeStorage = \Drupal::entityTypeManager()->getStorage("node"); //擷取節點實體儲存處理器
$nodeEntity = $nodeStorage->create(['type' => 'article', 'title' => '實體測試20180914', 'body' => "我的實體内容"]); //建立一篇文章(建立一個實體)
$nodeEntity->save(); //儲存實體
           

然後到管理頁面背景的内容裡面,看一看是不是就添加了一篇文章呢

$entity = \Drupal::entityTypeManager()->getStorage("node")->load(1);
echo $entity->label();
           

加載一個節點,顯示它的标題

我是雲客,【雲遊天下,做客四方】,聯系方式見首頁,歡迎轉載,但須注明出處

繼續閱讀