初始化和 bootstrap 概述

文档: https://experienceleague.adobe.com/en/docs/commerce-operations/configuration-guide/setup/initialization

index.php 入口文件

路径:pub/index.php

<?php
/**
* Public alias for the application entry point
*
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
 
use Magento\Framework\App\Bootstrap;
 
try {
require __DIR__ . '/../app/bootstrap.php';
} catch (\Exception $e) {
echo <<<HTML
<div style="font:12px/1.35em arial, helvetica, sans-serif;">
<div style="margin:0 0 25px 0; border-bottom:1px solid #ccc;">
<h3 style="margin:0;font-size:1.7em;font-weight:normal;text-transform:none;text-align:left;color:#2f2f2f;">
Autoload error</h3>
</div>
<p>{$e->getMessage()}</p>
</div>
HTML;
http_response_code(500);
exit(1);
}
 
// Bootstrap::create(BP, $_SERVER);:这行代码使用应用的基础路径(Agento 应用的根目录,被定义为 'BP' 常量)
// 和服务器的全局变量 $_SERVER 来创建一个新的 Bootstrap 实例。Magento 中的 Bootstrap 类负责初始化和运行应用
$bootstrap = Bootstrap::create(BP, $_SERVER);
/** @var \Magento\Framework\App\Http $app */
// 创建一个 HTTP 应用程序实例
$app = $bootstrap->createApplication(\Magento\Framework\App\Http::class);
 
// 这行代码将处理 HTTP 请求并将结果发送回客户端
$bootstrap->run($app);

bootstrap.php

app/bootstrap.php 文件执行基本的初始化例程,如错误处理、初始化自动加载器、设置性能分析选项和设置默认时区。

<?php
 
// 将 PHP 错误报告级别设为显示所有错误和警告。E_ALL 是 PHP 预定义错误常量,用于显示所有类型的错误信息。
error_reporting(E_ALL);
 
// 如果 phar(PHP 的归档协议,常用于打包应用)已经注册为流包装器,就注销它。
// 这行代码的目标是提高安全性:防止通过网络加载并执行的 PHAR 文件被恶意利用。
if (in_array('phar', \stream_get_wrappers())) {
stream_wrapper_unregister('phar');
}
#ini_set('display_errors', 1);
 
/* PHP version validation */
// PHP版本验证:这个条件语句监测当前运行的PHP版本,Magento要求PHP版本必须在8.1.0或之后
if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID < 80100) {
if (PHP_SAPI == 'cli') {
echo 'Magento supports PHP 8.1.0 or later. ' .
'Please read https://devdocs.magento.com/guides/v2.4/install-gde/system-requirements-tech.html';
} else {
echo <<<HTML
<div style="font:12px/1.35em arial, helvetica, sans-serif;">
<p>Magento supports PHP 8.1.0 or later. Please read
<a target="_blank" href="https://devdocs.magento.com/guides/v2.4/install-gde/system-requirements-tech.html">
Magento System Requirements</a>.
</div>
HTML;
}
http_response_code(503);
exit(1);
}
 
// PHP 8 compatibility. Define constants that are not present in PHP < 8.0
// PHP 8兼容性定义:如果PHP版本小于8.0,定义不存在的常数以确保代码的正常运行,例如T_NAME_QUALIFIED 和 T_NAME_FULLY_QUALIFIED
if (!defined('PHP_VERSION_ID') || PHP_VERSION_ID < 80000) {
if (!defined('T_NAME_QUALIFIED')) {
define('T_NAME_QUALIFIED', 24001);
}
if (!defined('T_NAME_FULLY_QUALIFIED')) {
define('T_NAME_FULLY_QUALIFIED', 24002);
}
}
 
// 加载 autoload.php 文件,初始化并启动自动加载器
require_once __DIR__ . '/autoload.php';
 
 
// Sets default autoload mappings, may be overridden in Bootstrap::create
// 这行代码使用 Magento 框架的 Bootstrap 类来设置额外的自动加载映射
\Magento\Framework\App\Bootstrap::populateAutoloader(BP, []);
 
/* Custom umask value may be provided in optional mage_umask file in root */
// 文件 magento_umask 提供了自定义的 umask 设置,umask 是用来设置默认文件权限的掩码,
// 这段代码会检查是否存在magento_umask文件,若存在则使用文件中的设定,若不存在则使用默认的 002
$umaskFile = BP . '/magento_umask';
$mask = file_exists($umaskFile) ? octdec(file_get_contents($umaskFile)) : 002;
umask($mask);
 
// 此段代码主要是用于解决在 IIS 环境下 URL 重写的问题。如果 $_SERVER['ENABLE_IIS_REWRITES'] 不是 1,那么就清除一些 IIS URL 重写所需要的头信息
if (empty($_SERVER['ENABLE_IIS_REWRITES']) || ($_SERVER['ENABLE_IIS_REWRITES'] != 1)) {
/*
* Unset headers used by IIS URL rewrites.
*/
unset($_SERVER['HTTP_X_REWRITE_URL']);
unset($_SERVER['HTTP_X_ORIGINAL_URL']);
unset($_SERVER['IIS_WasUrlRewritten']);
unset($_SERVER['UNENCODED_URL']);
unset($_SERVER['ORIG_PATH_INFO']);
}
 
// 满足条件则开启性能分析器
if (
(!empty($_SERVER['MAGE_PROFILER']) || file_exists(BP . '/var/profiler.flag'))
&& isset($_SERVER['HTTP_ACCEPT'])
&& strpos($_SERVER['HTTP_ACCEPT'], 'text/html') !== false
) {
$profilerConfig = isset($_SERVER['MAGE_PROFILER']) && strlen($_SERVER['MAGE_PROFILER'])
? $_SERVER['MAGE_PROFILER']
: trim(file_get_contents(BP . '/var/profiler.flag'));
 
if ($profilerConfig) {
$profilerConfig = json_decode($profilerConfig, true) ?: $profilerConfig;
}
 
Magento\Framework\Profiler::applyConfig(
$profilerConfig,
BP,
!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && $_SERVER['HTTP_X_REQUESTED_WITH'] == 'XMLHttpRequest'
);
}
 
// 将默认的时间区设为 UTC
date_default_timezone_set('UTC');
 
/* For data consistency between displaying (printing) and serialization a float number */
// 为了保证浮点数的显示和序列化数据一致,将浮点数的精度设为14位
ini_set('precision', 14);
ini_set('serialize_precision', 14);

autoload.php

路径:app/autoload.php

<?php
/**
* Register basic autoloader that uses include path
*
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);
 
use Magento\Framework\Autoload\AutoloaderRegistry;
use Magento\Framework\Autoload\ClassLoaderWrapper;
 
/**
* Shortcut constant for the root directory
*/
// 'BP' 是 Magento 应用的根目录(base directory
\define('BP', \dirname(__DIR__));
 
// 'VENDOR_PATH' 是包含 Composer 供应商目录路径的文件的位置
\define('VENDOR_PATH', BP . '/app/etc/vendor_path.php');
 
// 检查 VENDOR_PATH 所指定的文件是否可读,如果不可读则抛出异常
if (!\is_readable(VENDOR_PATH)) {
throw new \Exception(
'We can\'t read some files that are required to run the Magento application. '
. 'This usually means file permissions are set incorrectly.'
);
}
 
$vendorAutoload = (
static function (): ?string {
$vendorDir = require VENDOR_PATH;
 
$vendorAutoload = BP . "/{$vendorDir}/autoload.php";
if (\is_readable($vendorAutoload)) {
return $vendorAutoload;
}
 
$vendorAutoload = "{$vendorDir}/autoload.php";
if (\is_readable($vendorAutoload)) {
return $vendorAutoload;
}
 
return null;
}
)();
 
if ($vendorAutoload === null) {
throw new \Exception(
'Vendor autoload is not found. Please run \'composer install\' under application root directory.'
);
}
 
$composerAutoloader = include $vendorAutoload;
AutoloaderRegistry::registerAutoloader(new ClassLoaderWrapper($composerAutoloader));

vendorAutoload 函数:

$vendorAutoload = (
static function (): ?string {
$vendorDir = require VENDOR_PATH;
 
$vendorAutoload = BP . "/{$vendorDir}/autoload.php";
if (\is_readable($vendorAutoload)) {
return $vendorAutoload;
}
 
$vendorAutoload = "{$vendorDir}/autoload.php";
if (\is_readable($vendorAutoload)) {
return $vendorAutoload;
}
 
return null;
}
)();

这段代码中的 static 关键字用来定义一个匿名函数,并使其在运行时绑定到调用它的上下文中。static 关键字通常用于类的方法,使得这个方法不会被继承类重写,但在这里,它用在了匿名函数中,因此,这个匿名函数不会在运行时改变它的作用域。这意味着函数中的 $thisself 和 parent 将引用定义函数时的上下文,而不是调用函数时的上下文。

在 $vendorAutoload = (static function (): ?string {...})(); 这行代码中的尾部的 () 是立即调用函数表达式 (Immediately Invoked Function Expression, IIFE) 的一部分。IIFE 是一种常见的 JavaScript 工程中的模式,但也可以用于 PHP 中。这种模式创建一个函数,并立即执行它。通过这种方式,可以为代码块创建一个私有作用域,避免命名冲突,并且可以防止在全局作用域中创建不必要的变量。

所以,末尾的 () 是在声明函数之后立即调用这个匿名函数的。这个匿名函数的目的是检查并返回的 Composer 的自动加载器的路径,如果路径不存在或对应的文件不可读,函数会返回 null

Http.php 类

路径:vendor/magento/framework/App/Http.php

\Magento\Framework\App\http 的运行方式如下:

  1. 确定应用程序领域,application area 文档: application area.
  2. 启动前端控制器和路由系统,查找并执行控制器操作。
  3. 使用 HTTP 响应对象返回从控制器操作获得的结果。
  4. 错误处理 (按以下优先顺序):
    • 如果您正在使用开发人员模式  developer mode
      • 如果未安装 Commerce 应用程序,请重定向至安装向导。
      • 如果安装了 Commerce 应用程序,则显示错误和 HTTP 状态代码 500(内部服务器错误)。
    • 如果商务应用程序处于维护模式,则显示一个用户友好的“服务不可用”登录页面,并显示 HTTP 状态代码 503(服务不可用)。
    • 如果未安装 Commerce 应用程序,请重定向至安装向导。
    • 如果会话无效,请重定向至主页。
    • 如果存在任何其他应用程序初始化错误,则显示一个用户友好的“Page Not Found”页面,并显示 HTTP 状态代码 404(Not Found)。
    • 对于任何其他错误,使用 HTTP 响应 503 显示用户友好的“服务不可用”页面,并生成错误报告并在页面上显示其 ID。

静态资源入口点

todo 看了文档,不理解

媒体资源入口点

todo 看了文档,不理解