惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
D
Darknet – Hacking Tools, Hacker News & Cyber Security
Schneier on Security
Schneier on Security
C
Cisco Blogs
Help Net Security
Help Net Security
I
Intezer
Simon Willison's Weblog
Simon Willison's Weblog
Know Your Adversary
Know Your Adversary
Hacker News: Ask HN
Hacker News: Ask HN
Cisco Talos Blog
Cisco Talos Blog
A
Arctic Wolf
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
WordPress大学
WordPress大学
小众软件
小众软件
Jina AI
Jina AI
量子位
T
Threatpost
Forbes - Security
Forbes - Security
L
LINUX DO - 最新话题
S
Securelist
K
KPMG report finds enterprise disconnect between AI and its ROI | CIO
C
Cyber Attacks, Cyber Crime and Cyber Security
有赞技术团队
有赞技术团队
博客园_首页
T
Threat Research - Cisco Blogs
Threat Intelligence Blog | Flashpoint
Threat Intelligence Blog | Flashpoint
T
The Exploit Database - CXSecurity.com
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Scott Helme
Scott Helme
博客园 - 【当耐特】
IT之家
IT之家
Hugging Face - Blog
Hugging Face - Blog
月光博客
月光博客
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
大猫的无限游戏
大猫的无限游戏
cs.CL updates on arXiv.org
cs.CL updates on arXiv.org
The Last Watchdog
The Last Watchdog
Attack and Defense Labs
Attack and Defense Labs
Google DeepMind News
Google DeepMind News
阮一峰的网络日志
阮一峰的网络日志
SecWiki News
SecWiki News
博客园 - 叶小钗
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
罗磊的独立博客
The Cloudflare Blog
S
Schneier on Security
爱范儿
爱范儿
N
News and Events Feed by Topic
NISL@THU
NISL@THU
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More

f2h2h1's blog

使用yii3实现一个微框架 claw养殖技术 计算机网络基础知识 定时任务 ACME的使用经验 magento2加上varnish缓存 开发Magento2的模块 在magento2中使用persisted-query socket编程 一些开发笔记 一段CSDN文章主要内容的油猴脚本 电子邮件的不完整总结 git的笔记 在Windows下配置PHP服务器 终端,控制台和外壳 PHP各种运行方式的不完整总结 把网页导出成PDF 和颜色相关的笔记 HTTP认证方式的不完整总结 SEO的经验 密码学入门简明指南 文件的上传和下载 用纯CSS3实现的滑动按钮 在VSCode里调试PHP Linux的GUI 关于字符编码的一些坑 nc的使用和原理 对JS原型链的理解 使用docker-compose部署magento2 浏览器和服务器通讯方式的不完整总结 观察网站性能 一些关于Linux的笔记 telnet的不完整总结 在Windows下安装pear MySQL的时间类型和时间相关的函数 Windows下通过PEB读取进程的环境变量 关于 在VSCode里使用Xdebug远程调试PHP 在Windows下搭建git服务 关于环境变量的不完整总结 使用shell实现的kv数据库 如何完成以xx管理系统为选题的毕业设计 数字号码资源 各种标记语言 使用PowerShell实现的http服务器 kind相关经验 DNSSEC简介 nginx+ffmpeg+websocket实现的直播例子 使用Tesseract识别字符验证码 使用docker部署nuxt FirstData后台的设置 paypal,firtdata,支付宝的不完整接入指南 微信支付的不完整接入指南 用docker-compose部署lnmp环境 mongodb分片 练习
在Windows下安装Magento2
2025-03-07 · via f2h2h1's blog

[TOC]

环境依赖

文档里明确写了不支持 Windows ,但还是可以在 Windows 里安装的,实在不行就用 docker-desktop 或 wsl2 https://experienceleague.adobe.com/en/docs/commerce-operations/installation-guide/system-requirements

  • windows10 20H2
  • git for windows 2.33
  • php 8.1 64 位 ts 版
  • composer 2.2
  • mysql 8.0
  • nginx 1.12
  • apache 2.4
  • redis 7.0
  • elasticsearch 7.9
  • magento 2.4.6

需要注意的事项

  • magento2 的每个小版本的系统依赖都有一点不一样
  • 环境的搭建可以参考这篇文章 《在Windows下配置PHP服务器》
    • 环境的搭建是指 php composer mysql nginx apache redis elasticsearch 这些软件的安装和配置
  • composer 和 magento 的命令最好在有管理员权限的 git bash 下运行
  • php 需要开启这些拓展
    bcmath
    ctype
    curl
    dom
    fileinfo
    filter
    gd
    hash
    iconv
    intl
    json
    libxml
    mbstring
    openssl
    pcre
    pdo_mysql
    simplexml
    soap
    sockets
    sodium
    tokenizer
    xmlwriter
    xsl
    zip
    zlib
    
  • php 需要修改配置文件
    post_max_size = 128M
    memory_limit = 2048M
    upload_max_filesize = 64M
    short_open_tag = On
    max_execution_time = 900
    max_input_time = 300
    max_input_vars = 500
    realpath_cache_size=10M
    realpath_cache_ttl=7200
    
  • php 最好启用 opcache ,因为 magento2 真的很慢
  • 调整这两个值能有效地提升性能
    PHP_FCGI_CHILDREN
    PHP_FCGI_MAX_REQUESTS
    
    大概就是在环境变量里设置
    set PHP_FCGI_MAX_REQUESTS=1000
    set PHP_FCGI_CHILDREN=32
    
  • mysql 需要提前新建对应的数据库,并且默认编码是 utf-8
  • magento2 里有大量的静态文件需要加载,启用 http2 能稍微提升一下速度
  • nginx 的配置 worker_processes 要设为 cpu 逻辑核心数的两倍,例如 cpu 是 2 核 4 线程,那么 worker_processes 就是 8
  • nginx php-cgi mysql 最好以管理员运行,这样可以有效避免权限的问题
  • nginx php mysql 等软件和 magento2 的源码,最好不要放在系统盘,这样可以有效避免权限的问题
  • 软件和源码最好都放在固态硬盘里,这样能有效地提升速度
  • 其实大部分经验在 linux 环境下也适用

安装 Magento2.4

  1. 下载源码
    1. 通过 composer
      1. 申请一个 magento 的账号
      2. 生成一个用于 composer 的 access kye
      3. 在安装的目录里运行这句命令,要留意命令最后的 . ,命令最后的参数是安装目录, . 是安装到当前目录
        composer create-project --repository=https://repo.magento.com/ magento/project-community-edition=2.4.6 .
        
      4. 安装的过程中会要求输入 magento 的 access kye
        • 用 composer 下载 magento 时, puliic key 就是 username , private key 就是 password
    2. 通过 github
      • clone 的命令
        clone 整个仓库后再切换分支
        git clone https://github.com/magento/magento2.git .
        git pull
        git switch 2.4.6-p1
        只 clone 一个分支
        git clone -b 2.4.6-p1 https://github.com/magento/magento2.git --depth=1 .
        
        切换到对应的 tag
        git pull
        git checkout 2.4.5
        
      • 只 clone 一个分支,以更快的方式
        git clone -b 2.4.6-p7 --single-branch --no-tags https://github.com/magento/magento2.git --depth=1 .
        
      • 如果 clone 速度太慢,可以在 releases 那里下载源码的压缩包(如果还是太慢就用一些下载工具来下载 releases 的压缩包)
        curl -L -o magento2.tar.gz --connect-timeout 120 --max-time 3600 --retry 100 --retry-delay 5 https://github.com/magento/magento2/archive/refs/tags/2.4.6-p8.tar.gz
        
  2. 安装 composer 依赖
    1. 准备一个 github-oauth
      • 也可以参考这篇文章 《在Windows下配置PHP服务器》
    2. 运行安装命令 composer install
    3. 安装的过程有点慢,要耐心地等待
  3. 修改源码
    • 参考下文的这一章节 使用 patch 修改源码
  4. 修改 hosts 文件,把域名 localhost-magento.com 指向本地 ip (其实这步没有也没关系,但为了方便下文的描述还是加上了这步)
  5. 正确地启动 mysql redis elasticsearch
  6. 在数据库里新建对应的库
    create database magento2ce;
    
  7. 运行安装命令
    php bin/magento setup:install  \
        --base-url=http://localhost-magento.com/  \
        --db-host=localhost  \
        --db-name=magento2ce \
        --db-user=root  \
        --db-password=1234  \
        --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  \
        --search-engine=elasticsearch7  \
        --elasticsearch-host=localhost  \
        --elasticsearch-port=9200  \
        --elasticsearch-index-prefix=magento2
    
  8. 运行一些必要的命令
    php bin/magento setup:upgrade
    php bin/magento setup:di:compile
    php bin/magento setup:static-content:deploy -f
    php bin/magento indexer:reindex
    php bin/magento cache:flush
    
  9. 修改 nginx 的配置
    upstream fastcgi_backend {
        server  127.0.0.1:9001;
    }
    server {
        listen 80;
    
        # listen 443 ssl http2;
        # ssl_certificate  ./cert/localhost-magento.com/domain.crt;
        # ssl_certificate_key ./cert/localhost-magento.com/rsa_private_key.pem;
    
        access_log  logs/localhost-magento.access.log;
        error_log  logs/localhost-magento.error.log;
    
        server_name  localhost-magento.com;
        set $MAGE_ROOT C:/code/magento-community; # 这里是 magento 的根目录
        set $MAGE_DEBUG_SHOW_ARGS 1;
        include C:/code/magento-community/nginx.conf.sample; # 这里是 magento 的根目录里的 nginx.conf.sample
        fastcgi_buffers 16 16k;
        fastcgi_buffer_size 32k;
        proxy_buffer_size 128k;
        proxy_buffers 4 256k;
        proxy_busy_buffers_size 256k;
    }
    
  10. 重启 nginx 然后在浏览器里输入 localhost-magento.com ,如无意外能看到 magento 的 home page
  11. 安装示例数据,这一步不是必须的
    1. 查看当前模式
      php bin/magento deploy:mode:show
      
    2. 调整到开发者模式,安装时的默认模式是 default
      php bin/magento deploy:mode:set developer
      
    3. 下载示例数据。
      1. 通过命令行下载,这一步也是需要 magento 的账号密码,如果失败,就多试几次
        php bin/magento sampledata:deploy
        
      2. 通过 github 下载
        1. clone magento2-sample-data 仓库
          git clone https://github.com/magento/magento2-sample-data
          
        2. 运行安装命令,这命令里的路径必须使用绝对路径,且必须在管理员权限下运行
          php -f /d/magento2-sample-data/dev/tools/build-sample-data.php -- --sample-data-source="/d/magento2-sample-data" --ce-source="/d/magento-ce" --command=link
          
    4. 更新
      php bin/magento setup:static-content:deploy -f
      php bin/magento setup:upgrade
      
  12. 验证
    • 访问前台地址 http://localhost-magento.com
    • 访问后台地址 http://localhost-magento.com/admin
    • 进入后台之前需要禁用两步验证的模块和刷新缓存,不然会因为没有两步验证而无法进入后台, Magento_TwoFactorAuth 这个模块好像社区版没有
      php bin/magento module:disable Magento_TwoFactorAuth
      php bin/magento cache:flush
      

需要注意的事项

  • 如果没有对应的语言包就不要修改语言设置,因为没有对应的语言包但又修改了语言设置,可能会导致一些 css 加载失败

  • 日志在这个位置 var/log ,安装过程中遇到什么问题可以在这里找日志看

  • 可以在这个文件 app/etc/env.php 里查看 admin 的 url ,运行完安装命令后也会输出 admin 的 url

    'backend' => [
        'frontName' => 'admin_1a3uev'
    ],
    
  • 支付的设置在这里

    admin >> STORE >> Configuration >> SALES >> Payment Methods
    
  • magento2 的运行效率真的很低

  • 可以在 magento 的根目录里运行这样的命令启动 php 的内置 web server ,但速度真的很慢,要注意修改 base-url ,可以通过修改 DEBUG_ROUTER 这个常量启用 router.php 的 debug 模式

    php -S 127.0.0.1:8082 -t ./pub/ ./phpserver/router.php
    在 linux 环境下,可以设置这个环境变量 PHP_CLI_SERVER_WORKERS 来达到多线程的效果
    PHP_CLI_SERVER_WORKERS="10" php -S 127.0.0.1:8082 -t ./pub/ ./phpserver/router.php
    
  • 2.4.7 之后的版本也有一个内置的 server

    php bin/magento server:run
    php bin/magento server:run --port=8080
    php bin/magento server:run --port=8080 --workerNum=10
    
  • magento2 的缓存十分严重,如果发现一些修改没有生效,可以尝试运行这几条命令刷新缓存

    php bin/magento cache:clean
    php bin/magento indexer:reindex
    php bin/magento cache:flush
    
  • 如果运行了上面几句命令都没有效果,可以试试直接删掉对应的临时文件,像这样

    rm -rf var/di/* var/generation/* var/cache/* var/page_cache/* var/view_preprocessed/* var/composer_home/cache/*
    rm -rf generated/code/* generated/metadata/*
    rm -rf pub/static/*
    
  • 可以修改 app/etc/env.php 使用 redis 作为缓存,这是 redis 大致的配置,使用 redis 后能有效地提升速度

    'session' => [
        'save' => 'redis',
        'redis' => [
            'host' => '127.0.0.1',
            'port' => '6379',
            'password' => '',
            'timeout' => '2.5',
            'persistent_identifier' => '',
            'database' => '2',
            'compression_threshold' => '2048',
            'compression_library' => 'gzip',
            'log_level' => '4',
            'max_concurrency' => '6',
            'break_after_frontend' => '5',
            'break_after_adminhtml' => '30',
            'first_lifetime' => '600',
            'bot_first_lifetime' => '60',
            'bot_lifetime' => '7200',
            'disable_locking' => '0',
            'min_lifetime' => '60',
            'max_lifetime' => '2592000'
        ]
    ],
    'cache' => [
        'frontend' => [
            'default' => [
                'backend' => 'Cm_Cache_Backend_Redis',
                'backend_options' => [
                    'server' => '127.0.0.1',
                    'database' => '0',
                    'port' => '6379'
                ],
            ]
        ]
    ],
    
  • 为了开发方便,可以关掉 merge_files 和 minify_files , css 和 js 的都关掉,但加载一大堆小文件也会拖慢速度,在 app/etc/config.php 里配置

    'system' => [
        'default' => [
            'dev' => [
                'js' => [
                    'merge_files' => '0',
                    'minify_files' => '0',
                    'enable_js_bundling' => '0'
                ],
                'css' => [
                    'minify_files' => '0',
                    'merge_css_files' => '0'
                ],
            ]
        ]
    ],
    
  • 在 php 的配置文件启用命令行的 opcache opcache.enable_cli=1

  • 启用 jit 也能提升速度,但启用 jit 需要禁用 xdebug ,启用 jit 需要启用 opcache

    opcache.jit=1255
    opcache.jit_buffer_size=128M
    
  • 使用开发者模式可以不用编译,但运行速度会变得更慢

  • 关掉 xdebug 后速度也有提升

  • 运行这句 composer 命令 composer dumpautoload -o 后速度也有提升

    • 这句需要运行在 php bin/magento setup:di:compile 后面
    • 这句需要运行在 php bin/magento setup:static-content:deploy -f 前面
    • 如果是开发者模式就不要运行这句
  • 运行部署静态文件这条命令时最好翻墙,不然一些字体文件没法下载

    php bin/magento setup:static-content:deploy
    
  • 打开浏览器的开发者工具时,关掉禁用缓存的选项也能提升速度, magento2 的静态文件真的非常多,但有时又会因为浏览器的缓存这样观察不到更新

  • 使用 imdisk 这类内存硬盘能有效地提升速度。但内存硬盘存在断电后数据丢失的风险,而且真的非常消耗内存,内存至少也要有 16G

    • 只把生成的目录和文件放在内存硬盘里,这里需要用软连接把 var 和 generated 文件夹映射到内存硬盘
    • 把整套项目源码放在内存硬盘里
    • 把整套项目源码和数据库都放在内存硬盘里
  • 可以使用 Papercut-SMTP mailpit 这类软件来接收测试的邮件

  • 浏览器禁用图片的加载也能有效地提升速度

  • magento2 有三种模式,按性能由低到高,依次为:developer < default < production ;除此之外还有一个维护模式 maintenance ,用户访问会返回 503

  • 通过 composer 安装的 magento 的框架文件在这个目录里 vendor/magento/framework

  • 通过 github 源码安装的 magento 的框架文件在这个目录里 lib/internal/Magento/Framework

  • github 代码里的 app/magento/ 下那一堆 模块 对应 通过 composer 安装的 vendor/magento/module-* 的模块

  • 如果没有开启url重写,大部分链接前面都会带着 index.php,如果开了url重写则没有 index.php

    • 例如 后台的链接
      没有url重写 /index.php/admin
      有url重写 /admin
      
  • magento2 的官网推荐使用 nginx 做 es 的反向代理,这样就可以给 es 加上 http 认证

  • 配置 vscode 的 xml 文件语法高亮

    1. vscode 里装上这个插件
      XML Language Support by Red Hat
      
    2. 在项目根目录运行这句命令
      php bin/magento dev:urn-catalog:generate --ide vscode -- .vscode/misc.xml
      
    3. 在 vscode 的配置文件 .vscode/settings.json 里加上这几句
      {
          "xml.catalogs": [
              ".vscode\\misc.xml"
          ],
          "xml.validation.resolveExternalEntities": true,
          "xml.codeLens.enabled": true,
      }
      
  • 在 vscode 中关掉 git 的自动刷新

        "git.autorefresh": false
    
  • 在 vscode 中可以用这样的配置来忽略一些文件的解析

        "intelephense.references.exclude": [
            "**/vendor/**",
            "generated",
            "dev",
            "var",
            "pub/media",
            "pub/static"
        ]
    

不使用 es

禁用 es 相关的模块,用这个库来替换

https://github.com/swissup/module-search-mysql-legacy

因为 Elasticsearch 的存在使得门槛高了不少。笔者感觉奥多比正在抛弃中小用户。 笔者感到很奇怪,没有 redis 也可以安装,但没有 Elasticsearch 却不行。

安装时就排除 es

  1. 修改安装命令
    1. 排除 es 相关的配置
      就是安装命令里删掉这几个参数
      --search-engine
      --elasticsearch-host
      --elasticsearch-port
      --elasticsearch-index-prefix
      
    2. 禁用 es 相关的模块
      就是安装命令里加上这一个参数
      --disable-modules=Magento_Elasticsearch,Magento_Elasticsearch7,Magento_OpenSearch
      2.4 的小版本里,有好几个和 es 相关的模块
      Magento_Elasticsearch
      Magento_Elasticsearch6
      Magento_Elasticsearch7
      Magento_Elasticsearch8
      Magento_InventoryElasticsearch
      Magento_OpenSearch
      2.4.5 是 Magento_Elasticsearch,Magento_Elasticsearch7,Magento_Elasticsearch6
      2.4.6 是 Magento_Elasticsearch,Magento_Elasticsearch7,Magento_OpenSearch
      2.4.8 是 Magento_Elasticsearch,Magento_Elasticsearch8,Magento_OpenSearch
      
    3. 比较完整的安装命令,但仅供参考
      php bin/magento setup:install  \
          --base-url=http://localhost-magento.com/  \
          --db-host=localhost  \
          --db-name=magento2ce  \
          --db-user=root  \
          --db-password=1234  \
          --admin-firstname=admin  \
          --admin-lastname=admin  \
          --admin-email=admin@admin.com  \
          --admin-user=admin  \
          --admin-password=admin123  \
          --language=en_US  \
          --currency=USD  \
          --timezone=Asia/Shanghai  \
          --use-rewrites=0 \
          --disable-modules=Magento_Elasticsearch,Magento_Elasticsearch7,Magento_OpenSearch
      
  2. 安装 mysql 搜索模块
    composer require swissup/module-search-mysql-legacy --prefer-source --ignore-platform-reqs
    
  3. 启用 mysql 搜索模块
    php bin/magento module:enable Swissup_SearchMysqlLegacy Swissup_Core
    php bin/magento setup:upgrade --safe-mode=1
    php bin/magento setup:di:compile
    
  4. 把搜索的引擎设为 mysql
    • 用命令行设置
      php bin/magento config:set catalog/search/engine 'lmysql'
      
    • 在后台设置
      AdminPortal > Store > Settings > Configuration > CATALOG > Catalog > Catalog Search > Search Engine
      
  5. 刷新索引
    php bin/magento indexer:reindex
    

安装完后再排除 es

  1. 进入维护模式
    php bin/magento maintenance:enable
    
  2. 禁用 es 相关的模块
    php bin/magento module:disable Magento_Elasticsearch Magento_Elasticsearch7 Magento_OpenSearch
    2.4 的小版本里,有好几个和 es 相关的模块
    最好先用 php bin/magento module:status 看看有哪些和 es 相关的模块再禁用
    
  3. 安装 mysql 搜索模块
    • 和上一节一样
  4. 启用 mysql 搜索模块
    • 和上一节一样
  5. 把搜索的引擎设为 mysql
    • 和上一节一样
  6. 刷新索引
    • 和上一节一样
  7. 退出维护模式
    php bin/magento maintenance:disable
    

使用 patch 修改源码

  • 要注意区分通过 composer 安装和通过 github 安装的路径
  • 这个 patch 要在项目的根目录下运行,
  • 这个 patch 要在 composer install 之后运行, php bin/magento setup:upgrade 前运行

patch 文件的内容

--- lib/internal/Magento/Framework/Image/Adapter/Gd2.php	2023-12-19 17:16:58.149464800 +0800
+++ lib/internal/Magento/Framework/Image/Adapter/Gd2.php	2023-12-19 17:22:09.469880100 +0800
@@ -91,10 +91,12 @@ class Gd2 extends AbstractAdapter
      */
     private function validateURLScheme(string $filename) : bool
     {
-        $allowed_schemes = ['ftp', 'ftps', 'http', 'https'];
-        $url = parse_url($filename);
-        if ($url && isset($url['scheme']) && !in_array($url['scheme'], $allowed_schemes)) {
-            return false;
+        if (!file_exists($filename)) { // if file not exist
+            $allowed_schemes = ['ftp', 'ftps', 'http', 'https'];
+            $url = parse_url($filename);
+            if ($url && isset($url['scheme']) && !in_array($url['scheme'], $allowed_schemes)) {
+                return false;
+            }
         }
 
         return true;
--- lib/internal/Magento/Framework/View/Element/Template/File/Validator.php	2023-12-19 17:17:02.495932300 +0800
+++ lib/internal/Magento/Framework/View/Element/Template/File/Validator.php	2023-12-19 17:23:23.889091300 +0800
@@ -135,7 +135,8 @@ class Validator
         if (!is_array($directories)) {
             $directories = (array)$directories;
         }
-        $realPath = $this->fileDriver->getRealPath($path);
+        // $realPath = $this->fileDriver->getRealPath($path);
+        $realPath = str_replace('\\', '/', $this->fileDriver->getRealPath($path));
         foreach ($directories as $directory) {
             if ($directory !== null && 0 === strpos($realPath, $directory)) {
                 return true;
--- lib/internal/Magento/Framework/App/StaticResource.php	2023-12-19 17:16:54.560803000 +0800
+++ lib/internal/Magento/Framework/App/StaticResource.php	2023-12-19 17:21:47.440984600 +0800
@@ -285,6 +285,7 @@ class StaticResource implements \Magento
      */
     private function isThemeAllowed(string $theme): bool
     {
+        $theme = str_replace('\\', '/', $theme); // fix windows path
         return in_array($theme, array_keys($this->themePackageList->getThemes()));
     }
 }
--- lib/internal/Magento/Framework/Interception/PluginListGenerator.php	2023-12-19 17:16:58.383831000 +0800
+++ lib/internal/Magento/Framework/Interception/PluginListGenerator.php	2023-12-19 17:22:39.196325500 +0800
@@ -153,7 +153,8 @@ class PluginListGenerator implements Con
                 if (false === in_array($scope, $this->scopePriorityScheme, true)) {
                     $this->scopePriorityScheme[] = $scope;
                 }
-                $cacheId = implode('|', $this->scopePriorityScheme) . "|" . $this->cacheId;
+                // $cacheId = implode('|', $this->scopePriorityScheme) . "|" . $this->cacheId;
+                $cacheId = implode('-', $this->scopePriorityScheme) . "-" . $this->cacheId;
                 [
                     $virtualTypes,
                     $this->scopePriorityScheme,
--- lib/internal/Magento/Framework/Interception/PluginList/PluginList.php	2026-05-21 11:54:31.838225000 +0800
+++ lib/internal/Magento/Framework/Interception/PluginList/PluginList.php	2026-05-21 17:14:00.172654000 +0800
@@ -217,7 +217,7 @@ class PluginList extends Scoped implemen
             }
             $this->_scopePriorityScheme[] = $scope;
 
-            $cacheId = implode('|', $this->_scopePriorityScheme) . "|" . $this->_cacheId;
+            $cacheId = implode('-', $this->_scopePriorityScheme) . "-" . $this->_cacheId;
             $configData = $this->configLoader->load($cacheId);
 
             if ($configData) {

这是针对使用 github 新建的项目,如果是通过 composer 新建的项目,要替换一些路径

sed -i 's/lib\/internal\/Magento\/Framework\//vendor\/magento\/framework\//g' windows.patch;

执行 patch 的命令,要在项目的根目录运行

patch --verbose -p0 --no-backup-if-mismatch < windows.patch;

生成 patch 文件的方式

\define('PATCH_FILE', 'windows.patch');
$targetArr = [
    'lib/internal/Magento/Framework/Image/Adapter/Gd2.php',
    'lib/internal/Magento/Framework/View/Element/Template/File/Validator.php',
    'lib/internal/Magento/Framework/App/StaticResource.php',
    'lib/internal/Magento/Framework/Interception/PluginListGenerator.php',
    'lib/internal/Magento/Framework/Interception/PluginList/PluginList.php',
];

echo "
先确定好哪些文件需要修改
复制一份
修改文件
生成 patch 文件,patch 的文件结尾要有一个空行
替换 patch 文件里的路径
在项目根目录执行 patch
";

echo PHP_EOL . PHP_EOL;

$cpArr = array_map(function($item) {
    return 'cp ' . $item . ' ' . str_replace('.php', '2.php', $item);
}, $targetArr);

$diffArr = array_map(function($item) {
    return str_replace('cp ', 'diff -up ', $item) . ' >> ' . PATCH_FILE;
}, $cpArr);

$sedArr = array_map(function($item) {
    $item = str_replace('/', '\/', $item);
    $a = str_replace('.php', '2.php', $item);
    $b = $item;
    return sprintf("sed -i 's/%s/%s/g' " . PATCH_FILE, $a, $b);
}, $targetArr);

$rmArr = array_map(function($item) {
    return sprintf("rm %s ", str_replace('.php', '2.php', $item));
}, $targetArr);

array_map(function($item) {
    echo join(';' . PHP_EOL, $item) . PHP_EOL . PHP_EOL;
    return $item;
}, [$cpArr, $diffArr, $sedArr, $rmArr]);

echo 'patch --verbose -p0 --no-backup-if-mismatch < ' . PATCH_FILE . PHP_EOL;

参考

安装指南 https://experienceleague.adobe.com/zh-hans/docs/commerce-operations/installation-guide/overview

开发文档 https://developer.adobe.com/commerce/php/development/

github https://github.com/magento/magento2

magento 相关的博客