Answers:
Drupal在这方面可能会造成混乱,部分原因是因为它具有相对较深的功能栈。尽管它是过程性PHP,但在其体系结构中纯粹是事件/侦听器驱动的,但是在主PHP脚本中没有简单的“流程”供您查看。我最近在这个主题上做了一个演示,并且幻灯片已发布在slideshare上,但是快速的高级摘要可能会有用。
在整个过程中,Drupal和第三方插件模块会触发事件,并监听它们的响应。Drupal将其称为“挂钩”系统,并使用函数命名约定来实现。例如,“博客”模块可以通过实现名为blog_user()的函数来拦截与之相关的“用户”。用Drupal的话来说,这叫做hook_user()。
这有点笨拙,但是由于PHP的怪癖(它保留了所有已加载函数的内部哈希表),因此它允许Drupal只需遍历已安装的插件列表即可快速检查侦听器。对于每个插件,它可以在适当命名的模式上调用function_exists(),并调用该函数(如果存在)。(“我正在触发'login'事件。'mymodule_login'函数是否存在?我将其称为。'yourmodule_login'存在吗?否?'nextmodule_login'如何?”等。)同样,触摸起来笨拙但它效果很好。
Drupal中发生的所有事情都是由于其中一种事件被触发而发生的。MenuAPI仅知道由不同插件模块处理的URL /路径,因为它会触发“菜单”事件(hook_menu)并收集所有响应的元数据插件。(“我将处理url'news / recent',这是需要构建该页面时要调用的函数...”)内容仅被保存,因为Drupal的FormAPI负责构建页面并触发“表单已提交”事件,模块需要响应。每小时进行维护是因为触发了hook_cron(),并且任何将mymodulename_cron()作为函数名称的模块都将调用其函数。
其他所有内容最终都只是细节-重要细节,只是该主题的变化。index.php是控制器,菜单系统确定“当前页面”是什么,并且在构建该页面的过程中会触发许多事件。插件模块可以插入这些事件并更改工作流/提供其他信息/等。这也是许多Drupal资源专注于制作模块的部分原因。没有模块,Drupal实际上不会做任何事情,只是说:“有人要一页!是否存在?没有?好吧,我将提供404服务。”
要了解Drupal的工作原理,您需要了解Drupal的页面投放机制。
简而言之,所有调用/ URL /请求均由index.php提供服务,该索引通过包含各种包含文件/模块并随后调用模块中定义的适当函数来服务于请求/ URL,从而加载Drupal。
这是Pro Drupal Development一书的摘录,它解释了Drupal的引导过程,
引导过程
Drupal通过执行一系列引导阶段来对每个请求进行引导。这些阶段在bootstrap.inc中定义,并按照以下各节的说明进行。
初始化配置
此阶段填充Drupal的内部配置数组,并建立站点的基本URL($ base_url)。通过include_once()解析settings.php文件,并应用在此建立的任何变量或字符串替代。有关详细信息,请参见文件sites / all / default / default.settings.php的“变量替代”和“字符串替代”部分。
早期页面缓存
在需要高度可伸缩性的情况下,可能甚至在尝试数据库连接之前就需要调用缓存系统。早期的页面缓存阶段使您可以包含一个PHP文件(包括include()),该文件包含一个名为page_cache_ fastpath()的函数,该文件将接管并将内容返回给浏览器。通过将page_cache_fastpath变量设置为TRUE来启用早期页面缓存,并且通过将cache_inc变量设置为文件路径来定义要包含的文件。有关示例,请参见有关缓存的章节。
初始化数据库
在数据库阶段,将确定数据库的类型,并进行初始连接,该连接将用于数据库查询。
基于主机名/ IP的访问控制
Drupal允许基于每个主机名/ IP地址禁止主机。在访问控制阶段,将进行快速检查以查看请求是否来自被禁止的主机。如果是这样,则拒绝访问。
初始化会话处理
Drupal利用了PHP的内置会话处理功能,但是用其自身覆盖了一些处理程序来实现数据库支持的会话处理。在会话阶段初始化或重新建立会话。代表当前用户的全局$ user对象也在这里初始化,尽管为了提高效率,并非所有属性都可用(它们在需要时通过显式调用user_load()函数添加)。
后页缓存
在页面缓存后期,Drupal加载了足够的支持代码来确定是否从页面缓存中提供页面。这包括将设置从数据库合并到在初始化配置阶段创建的阵列中,以及加载或解析模块代码。如果会话指示该请求是由匿名用户发出的,并且启用了页面缓存,则从缓存返回页面,并停止执行。
语言确定
在语言确定阶段,将初始化Drupal的多语言支持,并根据站点和用户设置来决定使用哪种语言为当前页面提供服务。Drupal支持多种确定语言支持的方法,例如路径前缀和域级语言协商。
路径
在路径阶段,将加载处理路径和路径别名的代码。这个阶段可以解析人类可读的URL,并处理内部Drupal路径缓存和查找。
充分
此阶段通过加载公用功能库,主题支持以及对回调映射,文件处理,Unicode,PHP图像工具包,表单创建和处理,邮件处理,可自动排序的表以及结果集分页的支持来完成引导过程。设置Drupal的自定义错误处理程序,并加载所有启用的模块。最后,Drupal触发init钩子,以便在正式处理请求之前有机会通知模块。
一旦Drupal完成引导,框架的所有组件都将可用。现在是时候接受浏览器的请求并将其交给处理该请求的PHP函数了。URL和处理它们的函数之间的映射是使用回调注册表完成的,该回调注册表负责URL映射和访问控制。模块使用菜单钩子注册其回调(有关更多详细信息,请参见第4章)。
当Drupal确定存在一个回调时,浏览器请求的URL已成功映射到该回调,并且用户有权访问该回调,则将控制权交给该回调函数。
处理请求
回调函数完成处理和累积满足请求所需的数据所需的任何工作。例如,如果 收到了对诸如http://example.com/ q = node / 3之类的内容的请求,则该URL将映射到node.module中的函数node_page_view()。进一步的处理将从数据库中检索该节点的数据,并将其放入数据结构中。然后,该进行主题了。
数据主题化
主题化涉及将已检索,处理或创建的数据转换为HTML(或XML或其他输出格式)。Drupal将使用管理员选择的主题为网页提供正确的外观。然后将结果输出发送到Web浏览器(或其他HTTP客户端)。
伊顿的答案提供了很好的概述。(我是新来的,所以我无法修改他,因此无法发表评论。)
对我来说,最残酷的“ aha”时刻是通过index.php,然后通过模块的瀑布(首先是核心,然后是站点)来实现所有事情。要扩展核心功能,请不要重写它。而是将模块复制到/ sites / all / modules /或/ sites / [您的站点] / modules中,并扩展该功能,或在这些位置创建一个新模块。主题相同。模块目录也可以包含显示代码,例如tpl,css等形式。
如果您习惯使用更严格的MVC类型框架(如Rails,Django等),那么所有这些都会使您感到困惑。模块可能会混入很多显示代码,如果您正在查看其他人的模块或模板,则最终会倒退遍历整个堆栈。那就是使用PHP的美丽/痛苦。
具有讽刺意味的是,“仅仅构建一个应用程序”可能是最糟糕的学习方法。Drupal开箱即用地做很多事情,直到您弄清楚控制流程为止,它还是很晦涩的。例如,tpl文件中没有任何内容可以告诉您带有有趣名称(例如l())的函数的来源。
这取决于您正在寻找的理解深度。如果您对php有一定的了解,我建议您通读代码本身,从index.php开始,然后进入include / bootstrap.inc,然后进入该目录中的其他一些脚本。
关键包括文件:
modules /目录中还有一些关键功能。特别是,modules / node / node.module构成了节点系统的基础,该节点系统通常是用来封装站点内容的。
通常,该代码的注释非常清楚。在注释中使用Doxygen标记意味着代码实际上是规范的文档。
它还可以使用可以快速跳转到函数定义的编辑器来完成此操作。将vim与ctags结合使用对我来说很有效。您必须告诉ctags将.inc,.module等文件索引为php文件。
关于该主题的最佳书籍是“ Pro Drupal开发”和“使用Drupal”。
“ Pro Drupal开发”包括几个不错的流程图以及每个Drupal API(表单,主题等)的详尽摘要。它的目的是对制作自己的模块和主题的人特别有启发性,但对于想要了解Drupal的PHP普通开发人员来说,它具有很大的价值。除此之外,我还为我建立的每个站点创建了一个自定义模块,目的是获得对诸如在各种表单上有选择地隐藏字段的控制(通常为了简化节点表单,用户),因此最好将这些知识放在您的帽子下。
“使用Drupal”面向希望了解如何构建画廊,博客和社交网站等好东西的站点开发人员。它介绍了几个用例,并展示了如何配置现有模块来完成每个工作。在此过程中,它使您熟悉了基本的附加模块“内容构建工具包”(CCK)和“视图”,如何制作自定义块和模板,以及维护Drupal站点的来龙去脉。我特别推荐这本书给那些想起步并立即使用Drupal的人。在此过程中,您将了解Drupal的内部组织。
新的贡献者在这里,谈话晚了2年;-)
回复https://stackoverflow.com/a/1070325/1154755
要扩展核心功能,请不要重写它。而是将模块复制到/ sites / all / modules /或/ sites / [您的站点] / modules中,并扩展该功能,或在这些位置创建一个新模块。主题相同。
实际上,我从不需要复制核心模块来更新它。Drupal挂钩应该是您所需要的。
是的,对于主题而言,有时候这是唯一的方法,但是通常,您可以构建一个子主题来获得所需的结果。