PHP:创建可扩展的CMS系统

8
我获得了客户的新任务,基本上是为演员/歌手等创建一个CMS,并将其销售给他们。它基本上是一个包,与WordPress非常相似,可以直接交给购买者使用,但当然这不是一个博客平台。它将允许开发人员:
- 添加插件/小部件 - 添加模板/主题
我认为观察者模式可能会有用,但我并不确定。您们能否建议一下在以下方面创建这样灵活/可扩展的CMS:
- 能够添加插件(例如像WordPress一样) - 能够添加主题/模板(例如像WordPress一样) - 设计模式 - 其他任何事项

好奇...是否有任何原因现有的内容管理系统(如Drupal)不能被扩展以实现您想要的功能? - xenoterracide
@xenoterracide:客户要求创建一个新的CMS系统,针对媒体中的演员、歌手和类似实体。 - Sarfraz
2
http://journal.relativesanity.com/2008/11/17/how-not-to-build-an-in-house-cms/ - Ignacio Vazquez-Abrams
@mario:是的,那是一个方便的资源,谢谢 :) - Sarfraz
我认为Charles已经明白了。观察者模式没问题,但这只是冰山一角。你需要为插件提供钩子(即决定插件可以介入的位置,并使用观察者模式通知那些是钩子的人),并且你需要为插件提供API以执行有用的操作。我认为最后一步是最具挑战性的。 - Artefacto
显示剩余5条评论
1个回答

19

观察者模式很好,但您需要考虑超越基本的设计模式。经典的观察者/主题模式只向观察者发送主题对象,没有其他内容,甚至没有通知的原因。

最初的解决方案可能看起来像是将通知的原因也包含在观察者中,但这样可能会通知不关心某些通知的观察者。更好的解决方案可能是要求观察者还请求他们想收到的通知列表。

但这也带来了一个问题。为了让观察者实际上连接到主题,它们必须被实例化。每一次都要实例化,即使它们永远不会被使用。这是愚蠢的。

因此,我们很快就达到了插件的经典PHP实现之一:“钩子”。钩子使用与观察者/主题相同的概念,但实现方式有一个非常重要的区别:实际的观察者并不是为了观察主题而被实例化的。相反,主题将通知发送到某种中央存储库。该存储库配置有所有已安装和激活的插件(观察者)的列表,并包含每个插件想要接收的所有事件的列表。每个插件仅在事件发生时被通知,通常是通过静态方法而不是通过创建插件实例并通知它来完成的。call_user_func_array和一个很好的自动加载程序使这变得非常简单。

因此,您可以为所有插件创建一个简单的接口。您将需要的方法包括但不限于:

  • 获取有关插件的数据的方法,例如其名称、作者、官方网站、版本等。人类可消费信息。
  • 返回插件要订阅的事件的方法。
  • 安装方法,用于插件需要执行的任务以安装自己,例如操作数据库。
  • 卸载方法也可能很方便。
  • (可能是静态的)方法将接收事件通知并返回所需的任何数据。

根据插件概念的深度,您可能需要考虑到具有用户可配置选项的插件。为了使插件有效,您需要在各处放置钩子,并经常与最终用户合作添加所需的新钩子。小部件可以轻松地以类似插件的方式工作,作为页面呈现之前调用的插件。

主题/模板是两个大选项,您需要根据最终用户来决定使用哪种模板引擎。Smarty非常有限,但如果您希望确保模板中只运行批准的代码,则它可能是一个可行的选择。另一方面,Wordpress模板之所以如此好用是因为它们是纯PHP。如果您的最终用户具备技术素养或至少熟练于技术,则可以使用PHP模板。不过,在应用程序中允许对PHP模板进行编辑可能会打开巨大的安全隐患。您可能希望将其限制为文件系统。

此外,您还应该考虑CSS。最终用户能否直接操作CSS?他们是否想这样做?如果默认模板包含足够的语义化类,则即使最终用户知道自己在做什么,他们也可以轻松地进行大量的样式设置。另一方面,最终用户可能不知道CSS是什么,因此他们可能希望有颜色选择器、预构建的配色方案和配色方案选择器等繁琐的构建工具。最好现在就考虑这些问题。

其他杂项事项。

没有任何一个CMS完整无缺地没有草稿和发布状态的概念。我在这里没有别的建议,只是“首先编写代码”。如果您的客户或最终用户想要任何类型的历史存档、管理批准机制或其他使得草稿/已发布不再仅仅只是一个简单状态字段的东西,那么您需要尽早了解。(我曾经被这个问题咬过一口。我们设计了一个围绕着一个简单的已发布/未发布模型的整个系统,并在规范构建和相关原型代码完成的9/10时意识到它行不通,我们必须做一些远远更复杂的事情来真正满足客户的需求。重新构建粗略计划是我们遇到的最大的时间浪费。)
你会使用ORM吗?如果不使用,务必使用适当的数据库接口库。PDO,或者可能是PEAR中的某些内容,或者可能是Zend_Db。您肯定会有一个客户坚持要求代码在Oracle或MSSQL上运行。或SQLite。告诉他们可以通过一些努力实现将是很好的。插件作者也会感谢您保持清醒。不要自己造轮子。
(不过考虑到你的声望等级,我认为你已经熟悉我说的几乎所有内容了。啊,我为了分散注意力而做的事情,同时思考着我自己的一套编码问题...)

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接