在 Windows 下安装 Magento2

[TOC]

环境依赖

需要注意的事项

安装 Magento2.3

  1. 申请一个 magento 的账号
  2. 生成一个用于 composer 的 access kye
  3. 在安装的目录里运行这句命令,要留意命令最后的 . ,命令最后的参数是安装目录, . 是安装到当前目录
    composer create-project --repository=https://repo.magento.com/ magento/project-community-edition=2.3.7 .
    
  4. 安装的过程中会要求输入 magento 的 access kye
    • 用 composer 下载 magento 时, puliic key 就是 username , private key 就是 password
  5. 安装的过程有点慢,要耐心地等待
  6. magento2 的依赖有点多,最好准备一个 github-oauth
  7. 修改源码
    1. vendor\magento\framework\Image\Adapter\Gd2.php 大概在 90 行左右的位置
      private function validateURLScheme(string $filename) : bool
      {
          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;
      }
      
    2. vendor\magento\framework\View\Element\Template\File\Validator.php 大概在 140 行左右的位置
      protected function isPathInDirectories($path, $directories)
      {
          if (!is_array($directories)) {
              $directories = (array)$directories;
          }
          // $realPath = $this->fileDriver->getRealPath($path);
          $realPath = str_replace('\\', '/', $this->fileDriver->getRealPath($path));
          foreach ($directories as $directory) {
              if (0 === strpos($realPath, $directory)) {
                  return true;
              }
          }
          return false;
      }
      
  8. 修改 hosts 文件,把域名 localhost-magento 指向本地 ip (其实这步没有也没关系,但为了方便下文的描述还是加上了这步)
  9. 在数据库里新建对应的库
    create database magento2ce;
    
  10. 运行安装命令
    php bin/magento setup:install `
        --base-url=http://localhost-magento/ `
        --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
    
  11. 运行一些必要的命令
    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
    
  12. 修改 nginx 的配置
    upstream fastcgi_backend {
        server  127.0.0.1:9001;
    }
    server {
        listen 80;
    
        access_log  logs/localhost-magento.access.log;
        error_log  logs/localhost-magento.error.log;
    
        server_name  localhost-magento;
        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;
    }
    
  13. 重启 nginx 然后在浏览器里输入 localhost-magento ,如无意外能看到 magento 的 home page
  14. 安装示例数据,这一步不是必须的
    1. 查看当前模式
    php bin/magento deploy:mode:show
    
    1. 调整到开发者模式,安装时的默认模式是 default
    php bin/magento deploy:mode:set developer
    
    1. 下载示例数据。这一步也是需要 magento 的账号密码,如果失败,就多试几次
    php bin/magento sampledata:deploy
    
    1. 更新
    php bin/magento setup:upgrade
    

需要注意的事项

除了可以通过 compoer 安装外,还可以通过 github 的仓库安装。

配置 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,
    }
    

安装 2.4

笔者发现 magento2 的每个小版本的系统依赖都有一点不一样 https://devdocs.magento.com/guides/v2.4/install-gde/system-requirements.html

2.3 和 2.4 的主要区别是

因为 Elasticsearch 的存在使得门槛高了不少。笔者感觉奥多比正在抛弃中小用户。

安装流程和注意事项和 2.3 的基本一致。

安装 Elasticsearch

2.4.0 依赖的 elasticsearch 版本为 7.6 。

直接从官网下载就可以了,下载后解压,然后运行 bin/elasticsearch.bat 。压缩包里原本就带着 jdk 。

magento2 的官网推荐使用 nginx 做 es 的反向代理,这样就可以给 es 加上 http 认证。

安装步骤和 2.3 的区别

  1. 下载 magento2 的命令要把版本号改为 2.4.0

    composer create-project --repository=https://repo.magento.com/ magento/project-community-edition=2.4.0 .
    
  2. 修改源码

    1. vendor\magento\framework\App\StaticResource.php 大概在 278 行左右的位置
    private function isThemeAllowed(string $theme): bool
    {
        $theme = str_replace('\\', '/', $theme); // fix windows path
        return in_array($theme, array_keys($this->themePackageList->getThemes()));
    }
    
    1. vendor\magento\framework\Interception\PluginListGenerator.php 大概在 156 行左右的位置
    // $cacheId = implode('|', $this->scopePriorityScheme) . "|" . $this->cacheId;
    $cacheId = implode('-', $this->scopePriorityScheme) . "-" . $this->cacheId;
    
  3. 安装命令要加上 Elasticsearch 的配置

    php bin/magento setup:install  \
        --base-url=http://localhost-magento/  \
        --db-host=localhost  \
        --db-name=magento2ce2  \
        --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
    
  4. 进入后台之前需要禁用两步验证的模块和刷新缓存,不然会因为没有两步验证而无法进入后台

    php bin/magento module:disable Magento_TwoFactorAuth
    php bin/magento cache:flush
    

使用 patch 修改源码

这是上面几个需要修改的文件的合集。 这个 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,

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

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

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

patch -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',
];

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);

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

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

参考

用户指南 https://docs.magento.com/user-guide/

开发文档 https://devdocs.magento.com/

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

magento 相关的博客