You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Phoenix框架中__using__/1宏的用途、示例及apply调用解析

Understanding the __using__/1 Macro in Phoenix's *_web.ex File

Great question! Let's break down what this macro does, show it in action, and clarify where that apply call targets.

What's the Purpose of __using__/1?

This macro acts as a centralized dispatch hub for Phoenix's code injection system. When you write use YourAppWeb, :controller (or :view, :channel, etc.) in a module, it triggers this macro. Instead of writing repetitive import/use statements in every controller/view/channel, Phoenix lets you define all that shared setup in your *_web.ex file, and this macro routes your use call to the right setup function.

It keeps your code DRY (Don't Repeat Yourself) by consolidating all the common boilerplate for different Phoenix component types in one place.

Practical Example in Action

Let's walk through how this works with a real-world scenario.

First, look at the helper functions defined in your YourAppWeb module (right above the __using__/1 macro in lib/your_app_web.ex):

# Example controller setup function in YourAppWeb
def controller do
  quote do
    # Bring in core Phoenix Controller functionality
    use Phoenix.Controller, formats: [:html, :json], layouts: [html: YourAppWeb.Layouts]

    # Import common utilities
    import Plug.Conn
    import YourAppWeb.Gettext
    alias YourAppWeb.Router.Helpers, as: Routes
  end
end

# Example view setup function
def view do
  quote do
    use Phoenix.View,
      root: "lib/your_app_web/templates",
      namespace: YourAppWeb

    # Import shared view helpers
    import YourAppWeb.ErrorHelpers
    import YourAppWeb.Gettext
    alias YourAppWeb.Router.Helpers, as: Routes
  end
end

Now, when you create a controller, you just need one line to pull in all that setup:

defmodule YourAppWeb.UserController do
  # This triggers __using__/1 with :controller as the argument
  use YourAppWeb, :controller

  def index(conn, _params) do
    users = YourApp.Accounts.list_users()
    # We can use render/3 directly because it's imported via the controller setup
    render(conn, :index, users: users)
    # Routes is also available without manual aliasing
  end
end

Same goes for a view module:

defmodule YourAppWeb.UserView do
  use YourAppWeb, :view
  # Now we have access to Phoenix.View functions, ErrorHelpers, and Routes automatically
end

Where Does the apply Call Target?

The line apply(__MODULE__, which, []) is straightforward once you parse it:

  • __MODULE__ refers to the current module (e.g., YourAppWeb or ChatWeb—the module where the __using__/1 macro is defined)
  • which is the atom you passed to use (like :controller or :view)
  • So apply calls the function with the same name as the which atom in the YourAppWeb module. For example, if you pass :controller, it calls YourAppWeb.controller(), which returns the quoted code that gets injected into your module.

These target functions (controller/0, view/0, channel/0, etc.) are always defined in the same *_web.ex file as the __using__/1 macro—Phoenix generates them automatically when you create a new project, and you can customize them to add your own shared imports/aliases.

内容的提问来源于stack exchange,提问作者nelsonic

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.26 10:11:53