php Drupal 是如何工作的?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1068556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 00:51:35  来源:igfitidea点击:

How Drupal works?

phpdrupaldrupal-7

提问by Eaton

Could someone provide a architectural overview of the Drupal 7 control flow? Perhaps in the sense of a flowchart about how a page gets generated. What additional resources would you suggest consulting with regards to how Drupal works?

有人可以提供 Drupal 7 控制流的架构概述吗?也许在关于如何生成页面的流程图的意义上。关于 Drupal 的工作方式,您建议咨询哪些其他资源?

回答by Eaton

Drupal can be confusing on this front, partially because it has a relatively deep function stack. Although it's procedural PHP it's purely event/listener driven in its architecture, and there's no simple "flow" in the main PHP script for you to look though. I recently did a presentation on this very subject, and the slides are posted on slideshare, but a quick high-level summary may be useful.

Drupal 在这方面可能会令人困惑,部分原因是它具有相对较深的函数堆栈。尽管它是过程式 PHP,但它在其体系结构中纯粹是事件/侦听器驱动的,并且在主要的 PHP 脚本中没有简单的“流程”供您查看。我最近做了一个关于这个主题的演讲,幻灯片发布在 slideshare 上,但快速的高层次总结可能会有用。

  • Drupal's index.php file functions as a frontside controller. All page are piped through it, and the "actual" url/path the user requested is passed to index.php as a parameter.
  • Drupal's path router system (MenuAPI) is used to match the requested path to a given plugin module. That plugin module is responsible for building the "primary content" of the page.
  • Once the primary page content is built, index.php calls theme('page', $content), which hands off the content to Drupal's theming/skinning system. There, it's wrapped in sidebars/headers/widgets/etc..
  • The rendered page is then handed back to apache and it gets sent back to the user's browser.
  • Drupal 的 index.php 文件用作前端控制器。所有页面都通过它传输,用户请求的“实际”url/路径作为参数传递给 index.php。
  • Drupal 的路径路由系统 (MenuAPI) 用于将请求的路径与给定的插件模块匹配。该插件模块负责构建页面的“主要内容”。
  • 一旦主页面内容构建完成,index.php 就会调用 theme('page', $content),它将内容交给 Drupal 的主题/外观系统。在那里,它包含在侧边栏/标题/小部件/等中。
  • 然后将呈现的页面交还给 apache,并将其发送回用户的浏览器。

During that entire process, Drupal and third-party plugin modules are firing off events, and listening for them to respond. Drupal calls this the 'hook' system, and it's implemented using function naming conventions. The 'blog' module, for example, can intercept 'user' related by implementing a function named blog_user(). In Drupal parlance, that's called hook_user().

在整个过程中,Drupal 和第三方插件模块会触发事件,并监听它们的响应。Drupal 称其为“钩子”系统,它是使用函数命名约定实现的。例如,“博客”模块可以通过实现名为 blog_user() 的函数来拦截“用户”相关的信息。在 Drupal 中,这称为hook_user()

It's a bit clunky, but due to a PHP quirk (it keeps an internal hashtable of all loaded functions), it allows Drupal to quickly check for listeners just by iterating over a list of installed plugins. For each plugin it can call function_exists() on the appropriately named pattern, and call the function if it exists. ("I'm firing the 'login' event. Does 'mymodule_login' function exist? I'll call it. Does 'yourmodule_login' exist? No? How about 'nextmodule_login'?" etc.) Again, a touch clunky but it works pretty well.

它有点笨重,但由于 PHP 的怪癖(它保留所有加载函数的内部哈希表),它允许 Drupal 只需遍历已安装的插件列表即可快速检查侦听器。对于每个插件,它可以在适当命名的模式上调用 function_exists(),如果存在则调用该函数。(“我正在触发 'login' 事件。'mymodule_login' 函数是否存在?我会调用它。'yourmodule_login' 是否存在?不?'nextmodule_login' 怎么样?”等等)再次,有点笨重,但它效果很好。

Everythingthat happens in Drupal happens because of one of those events being fired. The MenuAPI only knows about what urls/paths are handled by different plugin modules because it fires the 'menu' event (hook_menu) and gathers up all the metadata plugin modules respond with. ("I'll take care of the url 'news/recent', and here's the function to call when that page needs to be built...") Content only gets saved because Drupal's FormAPI is responsible for building a page, and fires the 'a form was submitted' event for a module to respond to. Hourly maintenance happens because hook_cron() is triggered, and any module with mymodulename_cron() as a function name will have its function called.

Drupal 中发生的一切都是因为其中一个事件被触发。MenuAPI 只知道不同插件模块处理哪些 url/路径,因为它会触发 'menu' 事件 (hook_menu) 并收集所有元数据插件模块响应。(“我会处理 url 'news/recent',这里是需要构建该页面时调用的函数......”)内容只会被保存,因为 Drupal 的 FormAPI 负责构建一个页面,并触发模块响应的“表单已提交”事件。每小时维护是因为 hook_cron() 被触发,任何以 mymodulename_cron() 作为函数名的模块都会调用它的函数。

Everything else is ultimately just details -- important details, but variations on that theme. index.php is the controller, the menu system determins what the "current page" is, and lots of events get fired in the process of building that page. Plugin modules can hook into those events and change the workflow/supply additional information/etc. That's also part of the reason so many Drupal resources focus on making modules. Without modules, Drupal doesn't actually DO anything other than say, 'Someone asked for a page! Does it exist? No? OK, I'll serve up a 404.'

其他一切最终都只是细节——重要的细节,但该主题的变化。index.php 是控制器,菜单系统确定“当前页面”是什么,并且在构建该页面的过程中会触发许多事件。插件模块可以连接到这些事件并更改工作流程/提供附加信息等。这也是如此多的 Drupal 资源专注于制作模块的部分原因。没有模块,Drupal 除了说,“有人要求一个页面!它存在吗?不?好的,我会提供一个 404。

回答by amitgoyal

Drupal Page Serving Mechanism

Drupal 页面服务机制

To understand how Drupal works, you need to understand Drupal's page serving mechanism.

要了解 Drupal 的工作原理,您需要了解 Drupal 的页面服务机制。

In short, all the calls/urls/requests are served by index.php which loads Drupal by including various include files/modules and then calling the appropriate function, defined in module, to serve the request/url.

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

Here is the extract from the book, Pro Drupal Development, which explains the Drupal's bootstrap process,

这是 Pro Drupal Development 这本书的摘录,它解释了 Drupal 的引导过程,

The Bootstrap Process

引导过程

Drupal bootstraps itself on every request by going through a series of bootstrap phases. These phases are defined in bootstrap.inc and proceed as described in the following sections.

Drupal 通过一系列引导阶段在每个请求上引导自己。这些阶段在 bootstrap.inc 中定义,并按以下部分所述进行。

Initialize Configuration

初始化配置

This phase populates Drupal's internal configuration array and establishes the base URL ($base_url) of the site. The settings.php file is parsed via include_once(), and any variable or string overrides established there are applied. See the “Variable Overrides” and “String Overrides” sections of the file sites/all/default/default.settings.php for details.

此阶段填充 Drupal 的内部配置数组并建立站点的基本 URL ($base_url)。settings.php 文件通过 include_once() 进行解析,并应用在那里建立的任何变量或字符串覆盖。有关详细信息,请参阅文件 site/all/default/default.settings.php 的“变量覆盖”和“字符串覆盖”部分。

Early Page Cache

早期页面缓存

In situations requiring a high level of scalability, a caching system may need to be invoked before a database connection is even attempted. The early page cache phase lets you include (with include()) a PHP file containing a function called page_cache_ fastpath(), which takes over and returns content to the browser. The early page cache is enabled by setting the page_cache_fastpath variable to TRUE, and the file to be included is defined by setting the cache_inc variable to the file's path. See the chapter on caching for an example.

在需要高度可扩展性的情况下,可能需要在甚至尝试连接数据库之前调用缓存系统。早期的页面缓存阶段允许您包含(使用 include())一个 PHP 文件,该文件包含一个名为 page_cache_fastpath() 的函数,该函数接管并将内容返回给浏览器。通过将 page_cache_fastpath 变量设置为 TRUE 来启用早期页面缓存,通过将 cache_inc 变量设置为文件路径来定义要包含的文件。有关示例,请参阅缓存一章。

Initialize Database

初始化数据库

During the database phase, the type of database is determined, and an initial connection is made that will be used for database queries.

在数据库阶段,确定数据库的类型,并建立将用于数据库查询的初始连接。

Hostname/IP-Based Access Control

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

Drupal allows the banning of hosts on a per-hostname/IP address basis. In the access control phase, a quick check is made to see if the request is coming from a banned host; if so, access is denied.

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

Initialize Session Handling

初始化会话处理

Drupal takes advantage of PHP's built-in session handling but overrides some of the handlers with its own to implement database-backed session handling. Sessions are initialized or reestablished in the session phase. The global $user object representing the current user is also initialized here, though for efficiency not all properties are available (they are added by an explicit call to the user_load() function when needed).

Drupal 利用 PHP 的内置会话处理,但用自己的处理程序覆盖一些处理程序以实现数据库支持的会话处理。会话在会话阶段被初始化或重新建立。表示当前用户的全局 $user 对象也在此处初始化,但为了提高效率,并非所有属性都可用(在需要时通过显式调用 user_load() 函数添加它们)。

Late Page Cache

后期页面缓存

In the late page cache phase, Drupal loads enough supporting code to determine whether or not to serve a page from the page cache. This includes merging settings from the database into the array that was created during the initialize configuration phase and loading or parsing module code. If the session indicates that the request was issued by an anonymous user and page caching is enabled, the page is returned from the cache and execution stops.

在后期页面缓存阶段,Drupal 加载足够的支持代码来确定是否从页面缓存中提供页面。这包括将数据库中的设置合并到在初始化配置阶段和加载或解析模块代码期间创建的数组中。如果会话表明请求是由匿名用户发出的并且页面缓存已启用,则页面将从缓存中返回并停止执行。

Language Determination

语言决定

At the language determination phase, Drupal's multilingual support is initialized and a decision is made as to which language will be used to serve the current page based on site and user settings. Drupal supports several alternatives for determining language support, such as path prefix and domain-level language negotiation.

在语言确定阶段,Drupal 的多语言支持被初始化,并根据站点和用户设置决定使用哪种语言来提供当前页面。Drupal 支持多种确定语言支持的替代方法,例如路径前缀和域级语言协商。

Path

小路

At the path phase, code that handles paths and path aliasing is loaded. This phase enables human-readable URLs to be resolved and handles internal Drupal path caching and lookups.

在路径阶段,加载处理路径和路径别名的代码。此阶段使人类可读的 URL 能够被解析并处理内部 Drupal 路径缓存和查找。

Full

满的

This phase completes the bootstrap process by loading a library of common functions, theme support, and support for callback mapping, file handling, Unicode, PHP image toolkits, form creation and processing, mail handling, automatically sortable tables, and result set paging. Drupal's custom error handler is set, and all enabled modules are loaded. Finally, Drupal fires the init hook, so that modules have an opportunity to be notified before official processing of the request begins.

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

Once Drupal has completed bootstrapping, all components of the framework are available. It is time to take the browser's request and hand it off to the PHP function that will handle it. The mapping between URLs and functions that handle them is accomplished using a callback registry that takes care of both URL mapping and access control. Modules register their callbacks using the menu hook (for more details, see Chapter 4).

一旦 Drupal 完成引导,框架的所有组件都可用。是时候接收浏览器的请求并将其交给处理它的 PHP 函数了。URL 和处理它们的函数之间的映射是使用负责 URL 映射和访问控制的回调注册表完成的。模块使用菜单钩子注册它们的回调(更多详细信息,请参阅第 4 章)。

When Drupal has determined that there exists a callback to which the URL of the browser request successfully maps and that the user has permission to access that callback, control is handed to the callback function.

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

Processing a Request

处理请求

The callback function does whatever work is required to process and accumulate data needed to fulfill the request. For example, if a request for content such as http://example.com/q=node/3 is received, the URL is mapped to the function node_page_view() in node.module. Further processing will retrieve the data for that node from the database and put it into a data structure. Then, it's time for theming.

回调函数执行处理和累积满足请求所需的数据所需的任何工作。例如,如果 接收到诸如http://example.com/q=node/3 的内容请求,则将 URL 映射到 node.module 中的函数 node_page_view()。进一步的处理将从数据库中检索该节点的数据并将其放入数据结构中。然后,是时候进行主题化了。

Theming the Data

数据主题化

Theming involves transforming the data that has been retrieved, manipulated, or created into HTML (or XML or other output format). Drupal will use the theme the administrator has selected to give the web page the correct look and feel. The resulting output is then sent to the web browser (or other HTTP client).

主题化涉及将已检索、操作或创建的数据转换为 HTML(或 XML 或其他输出格式)。Drupal 将使用管理员选择的主题为网页提供正确的外观和感觉。然后将结果输出发送到 Web 浏览器(或其他 HTTP 客户端)。

回答by axoplasm

Eaton's answer provides a good overview. (I'm new here so I can't mod him up, thus the comment.)

伊顿的回答提供了一个很好的概述。(我是新来的,所以我不能修改他,因此评论。)

The brutal "aha" moment for me was realizing everything happens through index.php, and then through the waterfall of modules (core first, then by site). To extend core functionality don't rewrite it. Instead copy the module into /sites/all/modules/ or /sites/[yoursite]/modules and extend THAT, or create a new module in those places. Same for themes. Module directories can contain display code as well, in the form of tpl, css etc.

对我来说,残酷的“啊哈”时刻是意识到一切都通过 index.php 发生,然后通过模块的瀑布(首先是核心,然后是站点)。扩展核心功能不要重写它。而是将模块复制到 /sites/all/modules/ 或 /sites/ [yoursite]/modules 并扩展它,或在这些地方创建一个新模块。主题也一样。模块目录也可以包含显示代码,形式为 tpl、css 等。

If you're used to stricter MVC type frameworks like Rails, Django etc. all this gets a little confusing. Modules can mix in a lot of display code, and if you're looking at someone else's modules or templates you'll eventually wind up walking backwards through the stack. That's the beauty/pain of working in PHP.

如果您习惯于更严格的 MVC 类型框架,如 Rails、Django 等,所有这些都会有点令人困惑。模块可以混入大量显示代码,如果您正在查看其他人的模块或模板,您最终会在堆栈中倒退。这就是使用 PHP 的美妙/痛苦。

Ironically, "just build an app" might be the worst way to learn this. Drupal does so much out of the box that's simply obscure until you figure out the control flow. There's nothing in a tpl file that tells you where a function with a fun name like l() comes from, for example.

具有讽刺意味的是,“只构建一个应用程序”可能是最糟糕的学习方式。Drupal 做了很多开箱即用的工作,在您弄清楚控制流之前,这些工作都是很模糊的。例如,tpl 文件中没有任何内容可以告诉您具有像 l() 这样有趣名称的函数的来源。

回答by intuited

It depends on how deep an understanding you're looking for; if you have a good knowledge of php, I would suggest reading through the code itself, starting with index.php, and then going on to the includes/bootstrap.inc, and then some of the other scripts in that directory.

这取决于你寻求的理解有多深;如果您对 php 有很好的了解,我建议您通读代码本身,从 index.php 开始,然后继续阅读 include/bootstrap.inc,然后是该目录中的其他一些脚本。

The key include files:

关键包含文件:

  • menu.inc is very important to understanding how the overall system works, as it handles a lot of the implicit mapping of URLs to content.
  • common.inc has most of the otherwise-mysterious functions that form the basis of the API.
  • module.inc handles the hook invocations that Eaton mentioned
  • form.inc deals with form display, submission and processing
  • theme.inc handles presentation.
  • menu.inc 对于理解整个系统的工作方式非常重要,因为它处理了很多 URL 到内容的隐式映射。
  • common.inc 拥有构成 API 基础的大多数其他神秘功能。
  • module.inc 处理伊顿提到的钩子调用
  • form.inc 处理表单的显示、提交和处理
  • theme.inc 处理演示文稿。

There's also some key functionality in the modules/ directory; in particular, modules/node/node.module forms the basis of the node system, which is in general what's used to encapsulate site content.

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

The code is, in general, very well-commented and clear. The use of Doxygen markup within the commenting means that the code effectively is the canonical documentation.

总的来说,代码注释得非常好且清晰。在注释中使用 Doxygen 标记意味着代码实际上是规范文档。

It also helps to do this using an editor that can quickly jump to the definition of a function. Using vim in combination with ctags works for me; you do have to tell ctags to index .inc, .module, etc. files as php files.

使用可以快速跳转到函数定义的编辑器也有助于做到这一点。将 vim 与 ctags 结合使用对我有用;您必须告诉 ctags 将 .inc、.module 等文件索引为 php 文件。

回答by Scott Lahteine

The best books on the subject are "Pro Drupal Development" and "Using Drupal."

关于该主题的最佳书籍是“Pro Drupal Development”和“Using Drupal”。

"Pro Drupal Development" includes several nice flowcharts and thorough summaries of each of Drupal's APIs (forms, theming, etc.). It's intended to be especially instructive to people making their own modules and themes, but has lots of value to the average PHP-savvy developer who wants to understand Drupal. Besides which, I've created a custom module for every site I've built, just to gain the extra control over things like selectively hiding fields on various forms (which you generally want to do for the sake of simplifying node forms for end-users), so it's good to have this knowledge under your hat.

“Pro Drupal Development”包括几个不错的流程图和每个 Drupal API(表单、主题等)的全面总结。它旨在对制作自己的模块和主题的人特别有指导意义,但对于想要了解 Drupal 的普通 PHP 精通开发人员来说,它具有很多价值。除此之外,我为我构建的每个站点创建了一个自定义模块,只是为了获得对诸如选择性隐藏各种表单上的字段之类的额外控制(您通常希望这样做是为了简化最终节点的表单-用户),所以在你的帽子下掌握这些知识是很好的。

"Using Drupal" is aimed at the site developer who wants to know how to build the good stuff like galleries, blogs, and social networking sites. It goes through several use-cases and shows how to configure existing modules to do each job. In the process it familiarizes you with the essential add-on modules "Content Construction Kit" (CCK) and "Views," how to make custom blocks and templates, and the ins-and-outs of maintaining a Drupal site. I recommend this book especially for those who want to get up to speed and actually USE Drupal right away. In the process you gain an understanding of the internal organization of Drupal.

“使用 Drupal”针对的是想知道如何构建像画廊、博客和社交网站这样的好东西的站点开发人员。它经历了几个用例,并展示了如何配置现有模块来完成每项工作。在此过程中,它使您熟悉基本的附加模块“内容构建工具包”(CCK) 和“视图”,如何制作自定义块和模板,以及维护 Drupal 站点的来龙去脉。我特别向那些想要加快速度并立即实际使用 Drupal 的人推荐这本书。在此过程中,您将了解 Drupal 的内部组织。

回答by Ben Hammond

I learned loads by importing the drupal .php code into a NetBeans project. You can then run the netbeans debugger and watch the different phases of the page come together.

我通过将 drupal .php 代码导入 NetBeans 项目来学习负载。然后,您可以运行 netbeans 调试器并观察页面的不同阶段。

回答by Jeremy French

This(for Drupal 6) & this(for Drupal 7) is a pretty good architectural overview of drupal. If you want more detail then I would start writing something mostof the documentation is good. Trying to learn it at a high level of detail without something concrete to achieve will be much more difficult that trying something out.

This(for Drupal 6) & this(for Drupal 7) 是一个很好的drupal架构概述。如果你想要更多细节,那么我会开始写一些大部分文档都很好的东西。在没有具体实现的情况下,尝试在高层次的细节上学习它比尝试一些东西要困难得多。

回答by Robin Millette

New contributor here, 2 years late on the conversation ;-)

这里的新贡献者,谈话晚了 2 年;-)

Replying to https://stackoverflow.com/a/1070325/1154755

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

To extend core functionality don't rewrite it. Instead copy the module into /sites/all/modules/ or /sites/[yoursite]/modules and extend THAT, or create a new module in those places. Same for themes.

扩展核心功能不要重写它。而是将模块复制到 /sites/all/modules/ 或 /sites/ [yoursite]/modules 并扩展它,或在这些地方创建一个新模块。主题也一样。

Actually, I never had to copy a core module to update it. Drupal Hooks should be all you need.

实际上,我从来不需要复制核心模块来更新它。Drupal Hooks 应该就是你所需要的。

For themes, yeah, sometimes it's the only way to go, but often, you can build a subtheme to get the result you need.

对于主题,是的,有时这是唯一的方法,但通常,您可以构建一个子主题来获得所需的结果。