How Drupal works?

alice picture alice · Jul 1, 2009 · Viewed 32.1k times · Source

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?

Answer

Eaton picture Eaton · Jul 1, 2009

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'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.

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().

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.

Everything that 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.

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.'