Drupal如何工作?

有人能提供Drupal 7控制stream程的架构概述吗? 也许是关于如何生成页面的stream程图。 你会build议什么额外的资源咨询Drupal如何工作?

Drupal在这方面可能会令人困惑,部分原因是它有一个相对较深的function堆栈。 虽然它是程序化的PHP,但是它的架构中纯粹是事件/侦听器的驱动,并且主要的PHP脚本中没有简单的“stream程”供您查看。 我最近做了一个关于这个主题的演讲 ,幻灯片放在幻灯片上,但是快速的高层次总结可能是有用的。

  • Drupal的index.php文件作为前端控制器。 所有的页面都通过它传递,用户请求的“实际”URL /path被传递给index.php作为参数。
  • Drupal的path路由器系统(MenuAPI)用于匹配请求的path给定的插件模块。 该插件模块负责构build页面的“主要内容”。
  • 一旦build立了主页面内容,index.php就会调用主题('page',$ content),将主题内容交给Drupal的主题/皮肤系统。 在那里,它被包裹在侧边栏/标题/小部件/等等。
  • 呈现的页面然后被交还给Apache,并被发送回用户的浏览器。

在整个过程中,Drupal和第三方插件模块正在触发事件,并聆听他们的回应。 Drupal将此称为“挂钩”系统,并使用函数命名约定来实现。 例如,“博客”模块可以通过实现一个名为blog_user()的函数拦截“用户”。 在Drupal的说法,这就是所谓的hook_user()

它有点笨拙,但是由于PHP怪癖(它保留了所有加载函数的内部哈希表),它允许Drupal通过遍历已安装的插件列表来快速检查侦听器。 对于每个插件,它可以调用适当命名模式下的function_exists(),并在存在的情况下调用该函数。 (“我发射'login'事件'mymodule_login'函数是否存在?我会调用它''yourmodule_login'是否存在?否?'nextmodule_login'?”等等)再次,触摸笨重,但它工作得很好。

在Drupal中发生的一切都是因为这些事件中的一个被解雇了。 MenuAPI只知道不同插件模块处理的URL /path,因为它激发了“菜单”事件(hook_menu)并收集了所有的元数据插件模块响应。 (“我会照顾url'新闻/最近',这是当页面需要build立时调用的函数…”)内容只被保存,因为Drupal的FormAPI负责build立一个页面, “提交表单”事件以供模块响应。 发生小时维护是因为hook_cron()被触发,任何具有mymodulename_cron()作为函数名的模块都会调用它的函数。

其他一切最终都只是细节 – 重要的细节,但在这个主题上的变化。 index.php是控制器,菜单系统确定“当前页面”是什么,并且在构build页面的过程中有很多事件被触发。 插件模块可以挂钩到这些事件和改变工作stream程/提供额外的信息/等。 这也是很多Drupal资源专注于制作模块的原因之一。 没有模块,Drupal实际上不会做任何事情,除非说“有人要求一个页面! 它存在吗? 没有? 好吧,我会提供一个404.

Drupal页面服务机制

要理解Drupal如何工作,您需要了解Drupal的页面服务机制 – http://drupal.org/node/10858

简而言之,所有的调用/ URL /请求由index.php提供,它通过包含各种包含文件/模块加载Drupal,然后调用模块中定义的相应函数来提供请求/ URL。

这里是本书的摘录,Pro Drupal Development,它解释了Drupal的启动过程,

Bootstrap过程

Drupal通过一系列引导阶段来引导每一个请求。 这些阶段在bootstrap.inc中定义,并按照以下部分中的说明进行操作。

初始化configuration

这个阶段填充Drupal的内部configuration数组,并build立站点的基本URL($ base_url)。 settings.php文件通过include_once()进行parsing,并且应用了在此处build立的任何variables或string覆盖。 有关详细信息,请参阅文件sites / all / default / default.settings.php的“variables覆盖”和“string覆盖”部分。

早期页面caching

在需要高度可伸缩性的情况下,甚至在尝试连接数据库之前可能需要调用高速caching系统。 早期的页面caching阶段允许包含include()一个包含名为page_cache_fastpath()的函数的PHP文件,该文件接pipe并返回内容到浏览器。 通过将page_cache_fastpathvariables设置为TRUE来启用早期页面caching,并且通过将cache_incvariables设置为文件path来定义要包含的文件。 有关示例,请参阅caching一章。

初始化数据库

在数据库阶段,确定数据库的types,并build立一个将用于数据库查询的初始连接。

主机名/基于IP的访问控制

Drupal允许在每个主机名/ IP地址的基础上禁止主机。 在访问控制阶段,快速检查请求是否来自禁止的主机; 如果是这样,访问被拒绝。

初始化会话处理

Drupal利用了PHP内置的会话处理function,但是重写了一些自己的处理程序来实现数据库支持的会话处理。 会话在会话阶段初始化或重新build立。 代表当前用户的全局$ user对象也在这里被初始化,尽pipe为了效率,并不是所有的属性都可用(当需要时,通过显式调用user_load()函数来添加它们)。

晚期页面caching

在后期页面caching阶段,Drupal会加载足够的支持代码来确定是否从页面caching中提供页面。 这包括将数据库中的设置合并到在初始化configuration阶段创build的数组中,并加载或parsing模块代码。 如果会话指示请求是由匿名用户发出的,并且启用了页面caching,则页面将从caching中返回,并停止执行。

语言确定

在语言确定阶段,Drupal的多语言支持将被初始化,并根据网站和用户设置决定使用哪种语言来为当前页面提供服务。 Drupal支持多种select来确定语言支持,例如path前缀和域级语言协商。

path

在path阶段,加载处理path和path别名的代码。 这个阶段使人们可读的URL被parsing并处理内部的Drupalpathcaching和查找。

充分

这一阶段通过加载常用函数库,主题支持,以及对callback映射,文件处理,Unicode,PHP图像工具箱,表单创build和处理,邮件处理,自动sorting表和结果集分页的支持来完成引导过程。 Drupal的自定义error handling程序已设置,并且所有已启用的模块都已加载。 最后,Drupal会触发init钩子,以便模块有机会在正式处理请求之前得到通知。

一旦Drupal完成引导,框架的所有组件都可用。 现在是时候把浏览器的请求交给PHP函数来处理了。 URL和处理它们的函数之间的映射是使用callbackregistry来完成的,该registry负责URL映射和访问控制。 模块使用菜单钩子来注册它们的callback(更多细节见第4章)。

当Drupal确定存在一个callback,浏览器请求的URL成功映射到该callback,并且用户有权访问该callback时,控制交给callback函数。

处理请求

callback函数可以完成任何工作来处理和累积满足请求所需的数据。 例如,如果收到对http://example.com/q = node / 3等内容的请求,则URL将映射到node.module中的函数node_page_view()。 进一步处理将从数据库中检索该节点的数据,并将其放入数据结构中。 那么,现在是主题的时候了。

整理数据

主题化涉及到将检索,处理或创build的数据转换为HTML(或XML或其他输出格式)。 Drupal将使用pipe理员select的主题为网页提供正确的外观和感觉。 然后将生成的输出发送到Web浏览器(或其他HTTP客户端)。

伊顿的答案提供了一个很好的概述。 (我在这里是新来的,所以我不能模仿他,所以这个评论。)

对我来说,残酷的“aha”时刻是通过index.php实现一切,然后通过模块的瀑布(核心第一,然后通过网站)。 为了扩展核心function,不要重写它。 相反,将模块复制到/ sites / all / modules /或/ sites / [yoursite] /模块并扩展,或者在这些地方创build一个新模块。 主题也一样。 模块目录也可以包含显示代码,例如tpl,css等。

如果你习惯于严格的MVCtypes的框架,如Rails,Django等,所有这一切有点混淆。 模块可以混合使用大量的显示代码,如果您正在查看别人的模块或模板,您最终会在堆栈中向后走。 这是使用PHP的美丽/痛苦。

讽刺的是,“只是build立一个应用程序”可能是学习这个最糟糕的方式。 Drupal做了很多开箱即可,直到找出控制stream程。 例如,tpl文件中没有任何内容告诉你具有诸如l()之类的有趣名称的函数来自哪里。

http://drupal.org/handbooks

阅读手册,特别是主题开发人员指南。 Drupal支持几个主题引擎。 Zen使用phptemplate,所以请注意指南的这一部分。

对于模块开发,API在api.drupal.org上有logging。

特别是当您需要快速而快速地获取信息时,请特别注意以下信息:http://www-128.ibm.com/developerworks/ibm/osource/implement.html

我通过将drupal .php代码导入到NetBeans项目中学习了加载。 然后,您可以运行netbeansdebugging器,并观察页面的不同阶段。

关于这个主题的最好的书是“Pro Drupal开发”和“使用Drupal”。

“亲Drupal开发”包括几个好的stream程图和每个Drupal的API(forms,主题等)的全面总结。 对于有自己的模块和主题的人来说,这是特别有启发意义的,但是对于想了解Drupal的普通PHP开发人员来说,这些开发人员有很大的价值。 除此之外,我为每个build立的站点都创build了一个自定义模块,只是为了获得额外的控制权,比如select性地隐藏各种forms的字段(为了简化节点表单,用户),所以有这个知识是很好的。

“使用Drupal”是针对想要知道如何构build像画廊,博客和社交网站等好东西的网站开发人员。 它经历了几个用例,并展示了如何configuration现有模块来完成每项工作。 在这个过程中,它使您熟悉基本的附加模块“内容构build工具包”(CCK)和“视图”,如何制作自定义块和模板,以及维护Drupal站点的入门知识。 我推荐这本书,尤其是那些想要加快速度,并且马上使用Drupal的人。 在这个过程中,您将了解到Drupal的内部组织。

这个 (对于Drupal 6)和这个 (对于Drupal 7)是一个很好的Drupal架构概述。 如果你想要更多的细节,那么我会开始写大部分的文档是好的。 试图以高水平的细节来学习,而没有具体的东西来实现,要尝试一些东西会困难得多。

这取决于你正在寻找的理解有多深; 如果你对php有很好的了解,我会build议你阅读一下代码本身,从index.php开始,然后进入includes / bootstrap.inc,然后是目录中的其他脚本。

关键包括文件:

  • menu.inc对理解整个系统如何工作非常重要,因为它处理了很多URL到内容的隐式映射。
  • common.inc拥有绝大部分构成API基础的神秘函数。
  • module.inc处理伊顿提到的钩子调用
  • form.inc处理表单显示,提交和处理
  • theme.inc处理演示文稿。

modules /目录中还有一些关键function; 特别是modules / node / node.module构成了节点系统的基础,这通常是用来封装网站内容的。

一般而言,代码非常好评,清晰。 在注释中使用Doxygen标记意味着代码有效的是规范文档。

使用可以快速跳转到函数定义的编辑器也可以做到这一点。 结合使用vim和ctags对我来说是合适的; 你必须告诉ctags将.inc,.module等文件索引为php文件。

新的贡献者在这里,两年后的谈话;-)

回复到https://stackoverflow.com/a/1070325/1154755

为了扩展核心function,不要重写它。 相反,将模块复制到/ sites / all / modules /或/ sites / [yoursite] /模块并扩展,或者在这些地方创build一个新模块。 主题也一样。

其实,我从来不需要复制一个核心模块来更新它。 Drupal钩应该是你所需要的。

对于主题来说,是的,有时候这是唯一的出路,但是通常情况下,你可以build立一个分主题来获得你需要的结果。