在 WordPress 插件中使用 Composer 的敘述

已發表: 2015-07-06

彼得蘇姆 這篇文章由客座作者 Peter Suhm 提供。 Peter 是來自丹麥的網絡開發人員。 他是 WP Pusher 的創造者,也是一個巨大的旅行成癮者,隨身攜帶他的作品。


前幾天,我在 WP Pusher 博客上發布了一條關於在 WordPress 插件中使用 Composer 的警告。 這篇文章引起了很多關注,我覺得有必要澄清一些大家都不清楚的點。 這篇文章在技術方面也有點重,所以在這篇文章中,我將嘗試用一個簡單的敘述來說明我的主要觀點。

敘述

照片來源:2008 年多倫多開門 - 多倫多檔案館 - (許可證)
照片來源:多倫多 2008 年門戶開放 - 多倫多檔案館 - (許可證)

讓我們想像一下,你和我都是插件作者。 對於我們希望通過 WordPress.org 分發的插件,我們倆都有一個好主意。 我們希望在我們的插件中包含一些高級功能,免費版本的用戶可以通過輸入許可證密鑰來解鎖。

我們需要一些代碼來處理這個過程。 我們都意識到這個問題可能已經被其他人解決了。 我們都不是重新發明輪子的粉絲,所以我們前往 Packagist 並輸入“許可證管理器”。 看起來我們的假設是合理的。 Yoast 已經有一個可以處理這個問題的包。 我們都決定做一個快速composer require yoast/license-manager 。 十分簡單。 現在我們可以繼續做一些真正重要的事情——我們各自插件的核心功能。

快進,準備發布您的插件,您意識到:您的用戶在從 WordPress.org 安裝您的插件時不一定有 Composer,那麼他們將如何獲取許可證管理器的代碼? 這種情況有點煩人,因為您真正看到的唯一解決方案是將整個 Composer 生成的vendor目錄提交到您的插件並將其推送到 WordPress.org。 你知道這不是 Composer 應該如何工作的,但無論如何。 你真的沒有其他選擇。

同時,我對我的插件也得出了同樣的結論。 只需包含許可證管理器代碼並完成它。

再一次快進,我們的兩個插件現在都存在於 WordPress.org 存儲庫中,有時,有人決定升級到我們的高級版本。 一切似乎都很好,我們都很感激我們可以使用 Yoast 慷慨開源的代碼,而不必重新發明輪子。

有一天,您收到一封奇怪的電子郵件。 客戶在嘗試解鎖您的高級功能時遇到了一些非常奇怪的行為。 這對你來說毫無意義,因為沒有其他人報告過這一點。 經過數小時的調試,您最終要求您的客戶停用除您的插件之外的所有其他內容,然後:它有效! 唔。 您的插件似乎與另一個插件不兼容。 我的插件。

在瀏覽客戶安裝的所有其他插件的源代碼數小時後,您會意識到這一點。 當您意識到我們都使用許可證管理器時,鈴聲會響起。 真的可以這樣嗎? 如果是這樣,為什麼沒有fatal errors: cannot redeclare class是由 PHP 引起的?

一周前,我將插件中所需的許可證管理器版本升級到了最新版本,其中包括一些(虛構的)重大更改。 經過更多的調試和var_dump() 'ing,您意識到我的許可證管理器版本也是 PHP 在您的插件中加載的版本。 您會覺得這很奇怪,因為您特別需要 Composer 的另一個版本的許可證管理器。 你真的不知道該怎麼做。

因為你真的無能為力。

這裡發生了什麼?

現在我們都看到了問題所在,讓我們花點時間來了解一下敘述中實際發生的事情。 首先,當兩個類明顯同名且我們都包含許可證管理器時,為什麼 PHP 沒有導致致命錯誤?

原因是我們使用了 Composer 生成的自動加載器。 這個自動加載器掃描我們依賴項的目錄結構並將每個類添加到自動加載器。 如果已經添加了一個類,Composer 將忽略它。 默默。 如果您想親自查看,我已經編寫了一個小代碼示例。 它在 GitHub 上。

為什麼我的許可證管理器版本在您之前包含在內?

發生這種情況是因為我的插件的名稱導致它在您之前加載。 也許,在未來,我們都會將我們的插件命名為“Aaaaaa My Plugin”以便首先加載!

所以總而言之,這裡的主要問題是我們不知道我們的依賴項的哪個版本在什麼時候可供我們使用。 它只是取決於我們作為插件開發人員無法完全控制的因素。

這是 Composer 特有的問題嗎?

不,真的不是。 WordPress 無法處理插件或主題中的第三方代碼。 問題就在於此。 我談論 Composer 的原因是它最近獲得了很大的關注。 如果 WordPress 開發人員想在通過 WordPress.org 發布的插件中使用 Composer,這需要以某種方式解決。 否則,當所有插件開始相互不兼容時,我們將看到真正的混亂,因為它們使用不同的版本。 歡迎來到調試地獄。

我們能做些什麼呢?

真正關心這一點並努力尋找潛在解決方案的人是 Coen Jacobs。 我決定聯繫科恩,問他是否認為我們可以對此做些什麼。

許多開發人員已經在他們的插件中包含了 3rd 方代碼。 這真的是個問題嗎?

是的,這已經是插件生態系統中的一個問題。 當更多的人發現將通用功能放在單獨的包中是個好主意時,情況會變得更糟。 然後可以將這些包與多個插件捆綁在一起,問題會越來越多地出現。 我一直在與幾個已經經歷過調試地獄的開發人員交談,試圖找出導致此問題的原因。

展望未來,您會建議開發人員停止在他們的插件中包含第 3 方代碼嗎?

我在這個問題上有點撕裂。 從開發人員的角度來看,告訴人們停止在他們的插件中捆綁共享包是沒有意義的。 另一方面,每個人都希望為他們的用戶提供最好的用戶體驗。 確定這是一個艱難的決定。

在這一點上,我想推動WordPress相關的發展。 我想共享庫並使用其他人共享的庫。 沒有人應該一遍又一遍地重新發明輪子。 所以我會冒著遇到這樣的問題的風險,在問題出現時解決它們。

這也意味著我將竭盡全力為這個問題找到一個長期的解決方案。 更多的人將開始使用 Composer,更多的人會將庫與他們的插件捆綁在一起。 這個問題會更頻繁地出現,所以是時候解決它了。

插件開發人員可以做些什麼來防止這個問題?

我已經看到一些人已經使用了一種解決方法。 它基本上歸結為將您的依賴項移動到插件的名稱空間。 Danny van Kooten 為他的一個插件做到了這一點。 然而,這並不理想。 每次更新依賴項時,他都必須檢查所有文件並再次更改命名空間。 現在,對於像 Pimple 這樣相對較小的圖書館來說,這並不是一項艱鉅的任務,但對於大型圖書館來說,這是一項艱鉅的任務。

這只能通過命名空間來完成,所以你必須讓你的插件也需要 PHP 5.3+。 我不會撒謊,我認為每個插件遲早都應該開始這樣做,但這絕對是你決定這樣做時需要考慮的事情。

如果有的話,理想的解決方案是什麼?

理想的情況是使用某種依賴管理器。 當然還有 Composer,最常用的依賴管理器。 對於絕大多數 WordPress 用戶來說,Composer 很難使用,如果不是不可能的話。 畢竟它是開發人員的工具。

WordPress 應該讓最終用戶更容易做到這一點,同時仍然使開發人員能夠使用他們想要的幾乎任何包。 基於這個想法,我開始整合 WordPress Composer Installer 插件,當人們像往常一樣安裝插件時,它可以完成所有艱苦的 Composer 工作。 一旦我能夠完成它,我就會將它正確地集成到整個插件安裝程序流程中。

現在也許有一天,它可以集成到核心 WordPress 中。 它還有很長的路要走,但概念驗證已經奏效。

結論

如果你已經讀到這裡,首先:謝謝。 其次,我希望你現在看到這最終會成為一個問題。 我們目前的情況非常令人沮喪,因為我們根本沒有我們需要的工具。 儘管如此,我認為重要的是我們要繼續討論這個問題,並確保我們所有人,作為 WordPress 開發人員,了解我們代碼中第三方依賴衝突所導致的潛在問題。

最後,我想再提一下,這不是 Composer 的問題。 這是一個 WordPress 問題。