- 为什么选择 Magento 2? - 了解其核心优势
- 开发环境准备 - 搭建本地开发环境
- 核心概念入门 - 理解 Magento 的基本架构
- 模块开发 - Magento 开发的基石
- 主题开发 - 自定义前端外观
- 插件与重写 - 核心功能扩展
- 数据库与模型 - 数据操作
- 布局与块 - 前端页面结构
- 实战演练:创建一个简单的“Hello World”模块
- 进阶学习与最佳实践
- 推荐资源
为什么选择 Magento 2?
在开始之前,了解 Magento 2 的强大之处至关重要:

- 面向对象与高度模块化:基于 Zend Framework 和 Symfony 组件,代码结构清晰,易于扩展。
- 性能优化:大量性能提升,如全页面缓存、Varnish 集成、更高效的索引等。
- 现代前端技术:默认使用 RequireJS 进行 JavaScript 模块化管理,Less/Sass 用于 CSS 预处理。
- 强大的后台:提供灵活、可配置的后台管理系统,支持多语言、多货币、多站点。
- REST API:内置强大的 REST API,方便与第三方系统集成或开发移动应用。
- 依赖注入与服务定位器:遵循现代 PHP 设计模式,使代码更易于测试和维护。
开发环境准备
本地开发环境是 Magento 开发的第一步,强烈推荐使用 Docker,因为它能快速搭建一个与生产环境一致的、隔离的开发环境。
推荐方案:Docker (Magerun2 + Docker)
- 安装 Docker:在您的操作系统上安装 Docker Desktop (for Mac/Windows) 或 Docker Engine (for Linux)。
- 安装
magento2-docker:composer global require n98/magerun2
- 初始化项目:
# 进入您想放置项目的目录 cd /path/to/your/projects n98-magerun2 docker-compose create project my-magento2-project
- 启动环境:
cd my-magento2-project docker-compose up -d
- 安装 Magento:
docker-compose exec -u www-data fpm bash -c "bin/magento setup:install \ --db-host=db \ --db-name=magento2 \ --db-user=magento2 \ --db-password=magento2 \ --base-url=http://localhost:8000 \ --admin-firstname=admin \ --admin-lastname=admin \ --admin-email=admin@admin.com \ --admin-user=admin \ --admin-password=admin123 \ --language=en_US \ --currency=USD \ --timezone=America/Chicago \ --use-rewrites=1"注意:端口
8000可以根据需要修改。
传统方案 (XAMPP/MAMP + 手动安装)
- 安装 LAMP/LEMP 环境:安装 Apache/Nginx, PHP (7.4+ 推荐), MySQL。
- 配置 PHP:确保
php.ini中的memory_limit,max_execution_time,upload_max_filesize等参数足够大。 - 下载 Magento:从 Magento 官网 下载 Magento 2 安装包。
- 解压并设置权限:将文件解压到 Web 根目录(如
htdocs/magento2),并设置正确的文件所有者。 - 通过浏览器访问:访问
http://localhost/magento2并按照 Web 安装向导完成安装。
核心概念入门
理解这些概念是 Magento 开发的关键:
- 模块:Magento 功能的基本单元,一个模块可以包含控制器、模型、布局、块、助手等,所有核心功能(如目录、客户、结账)都是以模块形式存在的。
- Area(区域):Magento 将应用分为三个主要区域:
- Frontend:面向用户的商店前端。
- Adminhtml:管理员后台。
- Crontab:用于定时任务。
- 不同区域的配置和布局是独立的。
- 配置:Magento 的核心是它的配置系统,几乎所有东西(路由、布局、依赖注入等)都在
etc/目录下的 XML 文件中声明。 - 依赖注入:Magento 2 大量使用依赖注入,您无需
new一个对象,而是在类的构造函数中声明它需要的依赖,Magento 会自动“注入”正确的实例。 - 插件:这是 Magento 推荐的、最安全的扩展核心类功能的方式,它允许您在方法执行前、后或周围添加逻辑,而无需修改原始代码。
- 重写:一种更强大的方式,可以完全替换一个类的行为。谨慎使用,因为它会覆盖整个类,可能导致与其他模块的冲突。
模块开发
模块是 Magento 2 的心脏,让我们创建一个简单的模块。

模块结构
一个模块的基本结构如下:
app/code/
└── Vendor/
└── ModuleName/
├── etc/ # 模块配置目录
│ ├── module.xml # 模块声明文件
│ ├── di.xml # 依赖注入配置
│ ├── routes.xml # 路由配置
│ └── ...
├── Controller/ # 控制器目录
│ └── Index/
│ └── Test.php
├── view/ # 视图文件目录
│ ├── frontend/
│ │ ├── layout/
│ │ │ └── test_index_index.xml
│ │ └── templates/
│ │ └── test.phtml
│ └── adminhtml/
├── registration.php # 模块注册文件
└── ...
步骤:
-
创建目录和
registration.php:// app/code/Vendor/ModuleName/registration.php <?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'Vendor_ModuleName', __DIR__ ); -
声明模块 (
module.xml):<!-- app/code/Vendor/ModuleName/etc/module.xml --> <?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="Vendor_ModuleName" setup_version="1.0.0" /> </config> -
启用模块: 在 Magento 根目录下执行命令:
(图片来源网络,侵删)bin/magento module:enable Vendor_ModuleName bin/magento setup:upgrade
主题开发
主题控制着商店的前端外观。
主题结构
app/design/frontend/
└── Vendor/
└── theme-name/
├── composer.json # 主题元数据
├── registration.php # 主题注册
├── etc/
│ └── view.xml # 主题配置
├── web/ # 静态资源
│ ├── css/
│ ├── js/
│ ├── images/
│ └── fonts/
└── templates/ # 覆盖的模板文件
└── ...
创建主题:
-
创建目录结构。
-
创建
registration.php:// app/design/frontend/Vendor/theme-name/registration.php <?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::THEME, 'frontend/Vendor/theme-name', __DIR__ ); -
创建
composer.json:{ "name": "vendor/theme-name", "description": "My custom theme", "type": "magento2-theme", "version": "1.0.0", "license": [ "OSL-3.0", "AFL-3.0" ], "require": { "php": "~7.0.13|~7.1.0|~7.2.0", "magento/framework": "*" }, "autoload": { "files": [ "registration.php" ] } } -
应用主题: 在后台
Content -> Design -> Configuration中为您的网站或商店视图指定此主题。
插件与重写
这是扩展 Magento 功能的两种主要方式。
插件
优点:安全、非侵入式、可以多次作用于同一个方法。
缺点:不能修改方法参数或返回值类型,不能用于 final、__construct 和 static 方法。
场景:在保存产品前添加日志,在价格计算后添加折扣。
配置 (di.xml):
<!-- app/code/Vendor/ModuleName/etc/di.xml -->
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd">
<type name="Magento\Catalog\Model\Product">
<plugin name="vendor_module_name_product_plugin"
type="Vendor\ModuleName\Plugin\Model\ProductPlugin" />
</type>
</config>
插件类:
// app/code/Vendor/ModuleName/Plugin/Model/ProductPlugin.php
<?php
namespace Vendor\ModuleName\Plugin\Model;
class ProductPlugin
{
public function beforeSave(\Magento\Catalog\Model\Product $subject, $product)
{
// 在原始 save 方法执行前运行
// 可以修改 $product 对象
return [$product];
}
public function afterSave(\Magento\Catalog\Model\Product $subject, $result)
{
// 在原始 save 方法执行后运行
// $result 是原始方法的返回值
return $result;
}
}
重写
优点:完全控制类的行为。
缺点:危险,容易与其他模块的重写冲突,升级时可能被覆盖。
使用场景:当插件无法满足需求时(如必须重写 final 方法),或者您想完全替换一个类的逻辑。
步骤:
-
在
di.xml中配置:<!-- app/code/Vendor/ModuleName/etc/di.xml --> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:ObjectManager/etc/config.xsd"> <preference for="Magento\Catalog\Model\Product" type="Vendor\ModuleName\Model\Catalog\Product" /> </config> -
创建新类并继承原始类:
// app/code/Vendor/ModuleName/Model/Catalog/Product.php <?php namespace Vendor\ModuleName\Model\Catalog; class Product extends \Magento\Catalog\Model\Product { // 在这里重写您需要的方法 public function getName() { return 'Custom Prefix: ' . parent::getName(); } }
数据库与模型
Magento 2 使用 EAV (Entity-Attribute-Value) 模型来存储大部分数据(如产品、类别、客户),但也有简单的表模型。
模型、资源模型 和 集合
- 模型:代表一个数据对象(如一个
Product对象),包含数据和业务逻辑。 - 资源模型:负责与数据库交互(
SELECT,INSERT,UPDATE,DELETE),它不直接使用 SQL,而是使用 Magento 的抽象层。 - 集合:代表一个模型对象的数组(如一组
Product对象)。
创建一个简单的自定义表模型:
-
etc/db_schema.xml(推荐方式,声明表结构):<schema xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Setup/Declaration/Schema/etc/schema.xsd"> <table name="vendor_module_name_example" resource="default" engine="innodb"> <column xsi:type="int" name="id" padding="10" unsigned="true" nullable="false" identity="true" comment="Example ID"/> <column xsi:type="varchar" name="name" length="255" nullable="false" comment="Example Name"/> <column xsi:type="timestamp" name="created_at" on_update="false" nullable="false" default="CURRENT_TIMESTAMP" comment="Creation Time"/> <constraint xsi:type="primary" referenceId="PRIMARY"> <column name="id"/> </constraint> </table> </schema>执行
bin/magento setup:db-declaration:generate-whitelist和bin/magento setup:upgrade来创建表。 -
模型类:
// app/code/Vendor/ModuleName/Model/Example.php <?php namespace Vendor\ModuleName\Model; class Example extends \Magento\Framework\Model\AbstractModel { protected function _construct() { $this->_init(\Vendor\ModuleName\Model\ResourceModel\Example::class); } } -
资源模型类:
// app/code/Vendor/ModuleName/Model/ResourceModel/Example.php <?php namespace Vendor\ModuleName\Model\ResourceModel; class Example extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb { protected function _construct() { $this->_init('vendor_module_name_example', 'id'); } }
布局与块
布局和块共同构成了 Magento 的前端页面结构。
布局
布局文件是 XML 文件,它们定义了页面的结构,比如包含哪些块,以及它们的顺序和位置。
- 位置:
app/design/frontend/Vendor/theme-name/frontend/layout/ - 命名:
<router_name>_<controller_name>_<action_name>.xml(catalog_product_view.xml) - 核心概念:
<page>:页面容器。<head>,<body>:页面的<head>和<body>部分。<block>:定义一个块。name:块的唯一名称。class:块的 PHP 类。template:要渲染的 PHTML 文件路径。as:在父块中引用此块的别名。
<move>:移动一个块到另一个位置。<referenceBlock>:引用并修改一个已存在的块(如remove)。
块
块是 PHP 类,负责准备和传递数据给模板文件。
- 作用:
- 加载数据。
- 执行业务逻辑。
- 将数据分配给模板变量。
- 类型:
- 纯块:只包含逻辑,不渲染模板。
\Magento\Framework\View\Element\Template\Context。 - 模板块:最常见,继承自
\Magento\Framework\View\Element\Template,关联一个.phtml文件。
- 纯块:只包含逻辑,不渲染模板。
示例:
在 catalog_product_view.xml 中添加一个自定义块:
<!-- app/design/frontend/Vendor/theme-name/frontend/layout/catalog_product_view.xml -->
<page layout="1column" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:View/Layout/etc/page_configuration.xsd">
<body>
<referenceContainer name="content">
<block class="Vendor\ModuleName\Block\Product\View" name="product.custom.info" template="Vendor_ModuleName::product/view/custom-info.phtml" before="product.info.main" />
</referenceContainer>
</body>
</page>
对应的块类:
// app/code/Vendor/ModuleName/Block/Product/View.php
<?php
namespace Vendor\ModuleName\Block\Product;
class View extends \Magento\Framework\View\Element\Template
{
protected $_product;
public function __construct(
\Magento\Framework\View\Element\Template\Context $context,
\Magento\Catalog\Model\Product $product,
array $data = []
) {
$this->_product = $product;
parent::__construct($context, $data);
}
public function getProduct()
{
// 在控制器或布局中设置产品
if (!$this->_product->getId()) {
// 可以尝试从当前请求中获取
}
return $this->_product;
}
}
对应的模板文件:
<!-- app/design/frontend/Vendor/theme-name/frontend/templates/product/view/custom-info.phtml -->
<div class="product-custom-info">
<h2>Custom Information</h2>
<p>Custom SKU: <?php echo $block->getProduct()->getSku(); ?></p>
</div>
实战演练:创建一个简单的“Hello World”模块
让我们整合以上知识,创建一个模块,在首页显示 "Hello, Magento 2 World!"。
-
创建模块结构:
app/code/ └── HelloWorld/ └── Helloworld/ ├── etc/ │ ├── module.xml │ └── frontend/ │ └── routes.xml ├── registration.php └── Controller/ └── Index/ └── Index.php -
registration.php:<?php \Magento\Framework\Component\ComponentRegistrar::register( \Magento\Framework\Component\ComponentRegistrar::MODULE, 'HelloWorld_Helloworld', __DIR__ ); -
etc/module.xml:<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:Module/etc/module.xsd"> <module name="HelloWorld_Helloworld" setup_version="1.0.0" /> </config> -
定义路由 (
etc/frontend/routes.xml):<?xml version="1.0"?> <config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="urn:magento:framework:App/etc/routes.xsd"> <router id="standard"> <route id="helloworld" frontName="helloworld"> <module name="HelloWorld_Helloworld"/> </route> </router> </config> -
创建控制器 (
Controller/Index/Index.php):<?php namespace HelloWorld\Helloworld\Controller\Index; class Index extends \Magento\Framework\App\Action\Action { public function execute() { // 输出 "Hello World!" 到页面 echo "Hello, Magento 2 World!"; // 不需要渲染任何布局 exit; } } -
启用模块:
bin/magento module:enable HelloWorld_Helloworld bin/magento setup:upgrade
-
访问: 清除缓存后,访问
http://your-magento-domain.com/helloworld/index/index,您应该能看到 "Hello, Magento 2 World!"。
进阶学习与最佳实践
- 命令行工具:熟练使用
bin/magento命令来管理模块、缓存、静态内容等。 - 调试:
- Xdebug:设置 Xdebug 是调试 PHP 代码的最佳方式。
- 日志:使用
\Magento\Framework\Logger\Monolog记录日志。 - 变位词/翻译:利用
__(...)函数和翻译文件进行调试。
- 部署:
每次修改主题文件(CSS, JS, PHTML)后,都需要部署静态内容:
bin/magento setup:static-content:deploy <locale> # en_US
- 缓存管理:Magento 2 缓存非常强大,但也需要手动管理,开发时经常需要清空缓存:
bin/magento cache:clean bin/magento cache:flush
- 代码质量:遵循 Magento 的编码标准,使用工具如 PHP CodeSniffer 和 PHPMD。
- 依赖管理:使用 Composer 管理第三方库,不要将第三方库直接放入
lib或vendor目录,除非是 Magento 官方推荐的。
推荐资源
- 官方文档:Magento DevDocs (这是最重要的资源,务必经常查阅)
- 官方教程:Magento 2 Developer Tutorial
- Magento 2 深入分析:一本经典的付费电子书,深入讲解了 Magento 2 的内部机制。
- 博客与社区:
- Alan Storm's Blog (Magento 2 的传奇人物,文章非常深刻)
- Meet Magento (全球性的 Magento 大会,有大量演讲视频)
- Magento StackExchange (遇到问题,先来这里搜索)
Magento 2 是一个强大但复杂的平台,学习曲线较陡峭,保持耐心,多动手实践,多阅读官方文档,您会逐渐掌握它的精髓,祝您开发愉快!
