diff --git a/_translations/po/zh-CN/guide_caching_data.md.po b/_translations/po/zh-CN/guide_caching_data.md.po index 2f47812c..c079ff93 100644 --- a/_translations/po/zh-CN/guide_caching_data.md.po +++ b/_translations/po/zh-CN/guide_caching_data.md.po @@ -19,17 +19,17 @@ msgstr "" #: ../../guide/en/caching/data.md #, no-wrap msgid "Data caching" -msgstr "" +msgstr "数据缓存" #. type: Plain text #: ../../guide/en/caching/data.md msgid "Data caching is about storing some PHP variables in a cache and retrieving them later from the cache. It's also the foundation for more advanced caching features, such as [page caching](page.md)." -msgstr "" +msgstr "数据缓存是将一些 PHP 变量存储在缓存中,然后稍后从缓存中检索它们。它也是更高级缓存功能(如 [页面缓存](page.md))的基础。" #. type: Plain text #: ../../guide/en/caching/data.md msgid "To use cache, install [yiisoft/cache](https://github.com/yiisoft/cache) package:" -msgstr "" +msgstr "要使用缓存,请安装 [yiisoft/cache](https://github.com/yiisoft/cache) 包:" #. type: Fenced code block (shell) #: ../../guide/en/caching/data.md @@ -40,7 +40,7 @@ msgstr "" #. type: Plain text #: ../../guide/en/caching/data.md msgid "The following code is a typical usage pattern of data caching, where `$cache` refers to a `Cache` instance from the package:" -msgstr "" +msgstr "以下代码是数据缓存的典型使用模式,其中 `$cache` 引用包中的 `Cache` 实例:" #. type: Fenced code block (php) #: ../../guide/en/caching/data.md @@ -63,58 +63,58 @@ msgstr "" #. type: Plain text #: ../../guide/en/caching/data.md msgid "When cache has data associated with the `$key`, it returns the cached value. Otherwise, it executes the passed anonymous function to calculate the value to cache and return." -msgstr "" +msgstr "当缓存中有与 `$key` 关联的数据时,它返回缓存的值。否则,它执行传递的匿名函数来计算要缓存的值并返回。" #. type: Plain text #: ../../guide/en/caching/data.md msgid "If the anonymous function requires some data from the outer scope, you can pass it with the `use` statement." -msgstr "" +msgstr "如果匿名函数需要来自外部作用域的一些数据,您可以使用 `use` 语句传递它。" #. type: Title ## #: ../../guide/en/caching/data.md #, no-wrap msgid "Cache handlers" -msgstr "" +msgstr "缓存处理器" #. type: Plain text #: ../../guide/en/caching/data.md msgid "The cache service uses [PSR-16](https://www.php-fig.org/psr/psr-16/) compatible cache handlers which represent various cache storages, such as memory, files, and databases." -msgstr "" +msgstr "缓存服务使用兼容 [PSR-16](https://www.php-fig.org/psr/psr-16/) 的缓存处理器,它们代表各种缓存存储,如内存、文件和数据库。" #. type: Plain text #: ../../guide/en/caching/data.md msgid "Yii provides the following handlers:" -msgstr "" +msgstr "Yii 提供以下处理器:" #. type: Bullet: '- ' #: ../../guide/en/caching/data.md msgid "`NullCache` — a cache placeholder which does no real caching. The purpose of this handler is to simplify the code that needs to check the availability of cache. For example, during development or if the server doesn't have actual cache support, you may configure a cache service to use this handler. When you enable actual cache support, you can switch to using the corresponding cache handler. In both cases, you may use the same code without extra checks." -msgstr "" +msgstr "`NullCache` — 一个不进行实际缓存的缓存占位符。此处理器的目的是简化需要检查缓存可用性的代码。例如,在开发期间或服务器没有实际缓存支持时,您可以配置缓存服务使用此处理器。当您启用实际缓存支持时,可以切换到使用相应的缓存处理器。在这两种情况下,您都可以使用相同的代码而无需额外检查。" #. type: Bullet: '- ' #: ../../guide/en/caching/data.md msgid "`ArrayCache` — provides caching for the current request only by storing the values in an array." -msgstr "" +msgstr "`ArrayCache` — 通过将值存储在数组中,仅为当前请求提供缓存。" #. type: Bullet: '- ' #: ../../guide/en/caching/data.md msgid "[APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP [APC](https://secure.php.net/manual/en/book.apc.php) extension. You can consider this option as the fastest one when dealing with cache for a centralized thick application (e.g., one server, no dedicated load balancers, etc.)." -msgstr "" +msgstr "[APCu](https://github.com/yiisoft/cache-apcu) - 使用 PHP [APC](https://secure.php.net/manual/en/book.apc.php) 扩展。在处理集中式厚应用程序(例如,单服务器,无专用负载均衡器等)的缓存时,您可以将此选项视为最快的选项。" #. type: Bullet: '- ' #: ../../guide/en/caching/data.md msgid "[Database](https://github.com/yiisoft/cache-db) — uses a database table to store cached data." -msgstr "" +msgstr "[数据库](https://github.com/yiisoft/cache-db) — 使用数据库表存储缓存数据。" #. type: Bullet: '- ' #: ../../guide/en/caching/data.md msgid "[File](https://github.com/yiisoft/cache-file) — uses standard files to store cached data. This is particularly suitable to cache large chunks of data, such as page content." -msgstr "" +msgstr "[文件](https://github.com/yiisoft/cache-file) — 使用标准文件存储缓存数据。这特别适合缓存大块数据,如页面内容。" #. type: Bullet: '- ' #: ../../guide/en/caching/data.md msgid "[Memcached](https://github.com/yiisoft/cache-memcached) — uses a PHP [memcached](https://secure.php.net/manual/en/book.memcached.php) extension. You can consider this option as the fastest one when dealing with cache in a distributed application" -msgstr "" +msgstr "[Memcached](https://github.com/yiisoft/cache-memcached) — 使用 PHP [memcached](https://secure.php.net/manual/en/book.memcached.php) 扩展。在分布式应用程序中处理缓存时,您可以将此选项视为最快的选项" #. type: Plain text #: ../../guide/en/caching/data.md @@ -124,11 +124,14 @@ msgid "" "- [Wincache](https://github.com/yiisoft/cache-wincache) — uses PHP [WinCache](https://iis.net/downloads/microsoft/wincache-extension)\n" " ([see also](https://secure.php.net/manual/en/book.wincache.php)) extension.\n" msgstr "" +" (例如,多个服务器、负载均衡器等)\n" +"- [Wincache](https://github.com/yiisoft/cache-wincache) — 使用 PHP [WinCache](https://iis.net/downloads/microsoft/wincache-extension)\n" +" ([另见](https://secure.php.net/manual/en/book.wincache.php))扩展。\n" #. type: Plain text #: ../../guide/en/caching/data.md msgid "[You could find more handlers at packagist.org](https://packagist.org/providers/psr/simple-cache-implementation)." -msgstr "" +msgstr "[您可以在 packagist.org 找到更多处理器](https://packagist.org/providers/psr/simple-cache-implementation)。" #. type: Plain text #: ../../guide/en/caching/data.md @@ -139,42 +142,46 @@ msgid "" "> - To use memory-based cache storage to store small but constantly used data (e.g., statistics)\n" "> - To use file-based or database-based cache storage to store big and less often used data (e.g., page content)\n" msgstr "" +"> [!TIP]\n" +"> 您可以在同一应用程序中使用不同的缓存存储。常见策略是:\n" +"> - 使用基于内存的缓存存储来存储小但经常使用的数据(例如,统计信息)\n" +"> - 使用基于文件或数据库的缓存存储来存储大且不常使用的数据(例如,页面内容)\n" #. type: Plain text #: ../../guide/en/caching/data.md msgid "Cache handlers are usually set up in a [dependency injection container](../concept/di-container.md) so that they can be globally configurable and accessible." -msgstr "" +msgstr "缓存处理器通常在[依赖注入容器](../concept/di-container.md)中设置,以便它们可以全局配置和访问。" #. type: Plain text #: ../../guide/en/caching/data.md msgid "Because all cache handlers support the same set of APIs, you can swap the underlying cache handler with a different one. You can do it by reconfiguring the application without modifying the code that uses the cache." -msgstr "" +msgstr "由于所有缓存处理器都支持相同的 API 集,您可以将底层缓存处理器替换为不同的处理器。您可以通过重新配置应用程序来实现,而无需修改使用缓存的代码。" #. type: Title ### #: ../../guide/en/caching/data.md #, no-wrap msgid "Cache keys" -msgstr "" +msgstr "缓存键" #. type: Plain text #: ../../guide/en/caching/data.md msgid "A key uniquely identifies each data item stored in the cache. When you store a data item, you have to specify a key for it. Later, when you retrieve the data item, you should give the corresponding key." -msgstr "" +msgstr "键唯一标识存储在缓存中的每个数据项。当您存储数据项时,必须为其指定一个键。稍后,当您检索数据项时,应提供相应的键。" #. type: Plain text #: ../../guide/en/caching/data.md msgid "You may use a string or an arbitrary value as a cache key. When a key isn't a string, it will be automatically serialized into a string." -msgstr "" +msgstr "您可以使用字符串或任意值作为缓存键。当键不是字符串时,它将自动序列化为字符串。" #. type: Plain text #: ../../guide/en/caching/data.md msgid "A common strategy of defining a cache key is to include all determining factors in terms of an array." -msgstr "" +msgstr "定义缓存键的常见策略是将所有决定因素包含在数组中。" #. type: Plain text #: ../../guide/en/caching/data.md msgid "When different applications use the same cache storage, you should specify a unique cache key prefix for each application to avoid conflicts of cache keys. You can do this by using `\\Yiisoft\\Cache\\PrefixedCache` decorator:" -msgstr "" +msgstr "当不同的应用程序使用相同的缓存存储时,您应该为每个应用程序指定唯一的缓存键前缀以避免缓存键冲突。您可以使用 `\\Yiisoft\\Cache\\PrefixedCache` 装饰器来实现:" #. type: Fenced code block (php) #: ../../guide/en/caching/data.md @@ -188,12 +195,12 @@ msgstr "" #: ../../guide/en/caching/data.md #, no-wrap msgid "Cache expiration" -msgstr "" +msgstr "缓存过期" #. type: Plain text #: ../../guide/en/caching/data.md msgid "A data item stored in a cache will remain there forever unless it's removed because of some caching policy enforcement. For example, caching space is full and cache storage removes the oldest data. To change this behavior, you can set a TTL parameter when calling a method to store a data item:" -msgstr "" +msgstr "存储在缓存中的数据项将永久保留在那里,除非由于某些缓存策略强制执行而被删除。例如,缓存空间已满,缓存存储会删除最旧的数据。要更改此行为,您可以在调用方法存储数据项时设置 TTL 参数:" #. type: Fenced code block (php) #: ../../guide/en/caching/data.md @@ -208,12 +215,12 @@ msgstr "" #. type: Plain text #: ../../guide/en/caching/data.md msgid "The `$ttl` parameter indicates for how many seconds the data item can remain valid in the cache. When you retrieve the data item, if it has passed the expiration time, the method will execute the function and set the resulting value into cache." -msgstr "" +msgstr "`$ttl` 参数指示数据项在缓存中可以保持有效的秒数。当您检索数据项时,如果已超过过期时间,该方法将执行函数并将结果值设置到缓存中。" #. type: Plain text #: ../../guide/en/caching/data.md msgid "You may set the default TTL for the cache:" -msgstr "" +msgstr "您可以为缓存设置默认 TTL:" #. type: Fenced code block (php) #: ../../guide/en/caching/data.md @@ -224,7 +231,7 @@ msgstr "" #. type: Plain text #: ../../guide/en/caching/data.md msgid "Additionally, you can invalidate a cache key explicitly:" -msgstr "" +msgstr "此外,您可以显式使缓存键失效:" #. type: Fenced code block (php) #: ../../guide/en/caching/data.md @@ -236,17 +243,17 @@ msgstr "" #: ../../guide/en/caching/data.md #, no-wrap msgid "Invalidation dependencies" -msgstr "" +msgstr "失效依赖" #. type: Plain text #: ../../guide/en/caching/data.md msgid "Besides the expiration setting, changes of the so-called **invalidation dependencies** may also invalidate cached data item. For example, `\\Yiisoft\\Cache\\Dependency\\FileDependency` represents the dependency of a file's modification time. When this dependency changes, it means something modifying the corresponding file. As a result, any outdated file content found in the cache should invalidate." -msgstr "" +msgstr "除了过期设置外,所谓的**失效依赖**的更改也可能使缓存的数据项失效。例如,`\\Yiisoft\\Cache\\Dependency\\FileDependency` 表示文件修改时间的依赖关系。当此依赖关系发生变化时,意味着有东西修改了相应的文件。因此,在缓存中找到的任何过时的文件内容都应该失效。" #. type: Plain text #: ../../guide/en/caching/data.md msgid "Cache dependencies are objects of `\\Yiisoft\\Cache\\Dependency\\Dependency` descendant classes. When you store a data item in the cache, you can pass along an associated cache dependency object. For example," -msgstr "" +msgstr "缓存依赖是 `\\Yiisoft\\Cache\\Dependency\\Dependency` 后代类的对象。当您在缓存中存储数据项时,可以传递关联的缓存依赖对象。例如," #. type: Fenced code block (php) #: ../../guide/en/caching/data.md @@ -270,53 +277,53 @@ msgstr "" #. type: Plain text #: ../../guide/en/caching/data.md msgid "Below is a summary of the available cache dependencies:" -msgstr "" +msgstr "以下是可用缓存依赖的摘要:" #. type: Bullet: '- ' #: ../../guide/en/caching/data.md msgid "`\\Yiisoft\\Cache\\Dependency\\ValueDependency`: invalidates the cache when specified value changes." -msgstr "" +msgstr "`\\Yiisoft\\Cache\\Dependency\\ValueDependency`:当指定值更改时使缓存失效。" #. type: Bullet: '- ' #: ../../guide/en/caching/data.md msgid "`\\Yiisoft\\Cache\\Dependency\\CallbackDependency`: invalidates the cache when the result of the specified PHP callback is different." -msgstr "" +msgstr "`\\Yiisoft\\Cache\\Dependency\\CallbackDependency`:当指定 PHP 回调的结果不同时使缓存失效。" #. type: Bullet: '- ' #: ../../guide/en/caching/data.md msgid "`\\Yiisoft\\Cache\\Dependency\\FileDependency`: invalidates the cache when the file's last modification time is different." -msgstr "" +msgstr "`\\Yiisoft\\Cache\\Dependency\\FileDependency`:当文件的最后修改时间不同时使缓存失效。" #. type: Bullet: '- ' #: ../../guide/en/caching/data.md msgid "`\\Yiisoft\\Cache\\Dependency\\TagDependency`: associates a cached data item with one or many tags. You may invalidate the cached data items with the specified tag(s) by calling `TagDependency::invalidate()`." -msgstr "" +msgstr "`\\Yiisoft\\Cache\\Dependency\\TagDependency`:将缓存的数据项与一个或多个标签关联。您可以通过调用 `TagDependency::invalidate()` 使具有指定标签的缓存数据项失效。" #. type: Plain text #: ../../guide/en/caching/data.md msgid "You may combine many dependencies using `\\Yiisoft\\Cache\\Dependency\\AnyDependency` or `\\Yiisoft\\Cache\\Dependency\\AllDependencies`." -msgstr "" +msgstr "您可以使用 `\\Yiisoft\\Cache\\Dependency\\AnyDependency` 或 `\\Yiisoft\\Cache\\Dependency\\AllDependencies` 组合多个依赖项。" #. type: Plain text #: ../../guide/en/caching/data.md msgid "To implement your own dependency, extend from `\\Yiisoft\\Cache\\Dependency\\Dependency`." -msgstr "" +msgstr "要实现您自己的依赖项,请从 `\\Yiisoft\\Cache\\Dependency\\Dependency` 扩展。" #. type: Title ### #: ../../guide/en/caching/data.md #, no-wrap msgid "Cache stampede prevention" -msgstr "" +msgstr "缓存雪崩预防" #. type: Plain text #: ../../guide/en/caching/data.md msgid "[A cache stampede](https://en.wikipedia.org/wiki/Cache_stampede) is a type of cascading failure that can occur when massively parallel computing systems with caching mechanisms come under a high load. This behavior is sometimes also called dog-piling." -msgstr "" +msgstr "[缓存雪崩](https://en.wikipedia.org/wiki/Cache_stampede)是一种级联故障,当具有缓存机制的大规模并行计算系统处于高负载时可能发生。这种行为有时也称为 dog-piling。" #. type: Plain text #: ../../guide/en/caching/data.md msgid "The `\\Yiisoft\\Cache\\Cache` uses a built-in \"Probably early expiration\" algorithm that prevents cache stampede. This algorithm randomly fakes a cache miss for one user while others are still served the cached value. You can control its behavior with the fifth optional parameter of `getOrSet()`, which is a float value called `$beta`. By default, beta is `1.0`, which is usually enough. The higher the value, the earlier cache will be re-created." -msgstr "" +msgstr "`\\Yiisoft\\Cache\\Cache` 使用内置的“可能提前过期”算法来防止缓存雪崩。该算法随机为一个用户伪造缓存未命中,而其他用户仍然获得缓存值。您可以使用 `getOrSet()` 的第五个可选参数来控制其行为,该参数是一个名为 `$beta` 的浮点值。默认情况下,beta 为 `1.0`,这通常就足够了。值越高,缓存重新创建得越早。" #. type: Fenced code block (php) #: ../../guide/en/caching/data.md diff --git a/_translations/po/zh-CN/guide_caching_overview.md.po b/_translations/po/zh-CN/guide_caching_overview.md.po index cdbbcd99..57ebf1f7 100644 --- a/_translations/po/zh-CN/guide_caching_overview.md.po +++ b/_translations/po/zh-CN/guide_caching_overview.md.po @@ -19,39 +19,39 @@ msgstr "" #: ../src/guide/caching/overview.md ../src/guide/index.md #, no-wrap msgid "Caching" -msgstr "" +msgstr "缓存" #. type: Plain text #: ../src/guide/caching/overview.md msgid "Caching is an inexpensive and effective way to improve the performance of an application. By storing relatively static data in cache and serving it from cache when requested, the application saves the time that it otherwise would require to generate the data from scratch every time." -msgstr "" +msgstr "缓存是提高应用程序性能的一种廉价而有效的方法。通过将相对静态的数据存储在缓存中,并在请求时从缓存中提供数据,应用程序节省了每次从头生成数据所需的时间。" #. type: Plain text #: ../src/guide/caching/overview.md msgid "Caching can occur at different levels and places in an application. On the server-side, at the lower level, cache may be used to store basic data, such as a list of most recent article information fetched from the database; and at the higher level, cache may be used to store fragments or whole of Web pages, such as the rendering result of the most recent articles. On the client-side, you may use HTTP caching to keep most recently visited page content in the browser cache." -msgstr "" +msgstr "缓存可以在应用程序的不同级别和位置发生。在服务器端,在较低级别,缓存可用于存储基本数据,例如从数据库获取的最新文章信息列表;在较高级别,缓存可用于存储 Web 页面的片段或整体,例如最新文章的渲染结果。在客户端,您可以使用 HTTP 缓存将最近访问的页面内容保存在浏览器缓存中。" #. type: Plain text #: ../src/guide/caching/overview.md msgid "Yii supports all these caching mechanisms:" -msgstr "" +msgstr "Yii 支持所有这些缓存机制:" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md msgid "[Data caching](data.md)" -msgstr "" +msgstr "[数据缓存](data.md)" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md msgid "[Fragment caching](fragment.md)" -msgstr "" +msgstr "[片段缓存](fragment.md)" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md msgid "[Page caching](page.md)" -msgstr "" +msgstr "[页面缓存](page.md)" #. type: Bullet: '* ' #: ../src/guide/caching/overview.md msgid "[HTTP caching](http.md)" -msgstr "" +msgstr "[HTTP 缓存](http.md)" diff --git a/_translations/po/zh-CN/guide_concept_aliases.md.po b/_translations/po/zh-CN/guide_concept_aliases.md.po index 0cc873e9..1ddad6d0 100644 --- a/_translations/po/zh-CN/guide_concept_aliases.md.po +++ b/_translations/po/zh-CN/guide_concept_aliases.md.po @@ -19,28 +19,28 @@ msgstr "" #: ../src/guide/concept/aliases.md #, no-wrap msgid "Aliases" -msgstr "" +msgstr "别名" #. type: Plain text #: ../src/guide/concept/aliases.md msgid "You can use aliases to represent file paths or URLs so that you don't have to hard-code absolute paths or URLs in your project. An alias must start with the `@` character to be differentiated from normal file paths and URLs. Alias defined without leading `@` will be prefixed with `@` character." -msgstr "" +msgstr "您可以使用别名来表示文件路径或 URL,这样您就不必在项目中硬编码绝对路径或 URL。别名必须以 `@` 字符开头,以便与普通文件路径和 URL 区分开来。定义时没有前导 `@` 的别名将自动添加 `@` 字符前缀。" #. type: Plain text #: ../src/guide/concept/aliases.md msgid "Default Yii application has some aliases pre-defined in `config/params.php`. For example, the alias `@public` represents the web root path; `@baseUrl` represents the base URL for the currently running Web application." -msgstr "" +msgstr "默认的 Yii 应用程序在 `config/params.php` 中预定义了一些别名。例如,别名 `@public` 表示 Web 根路径;`@baseUrl` 表示当前运行的 Web 应用程序的基础 URL。" #. type: Title ## #: ../src/guide/concept/aliases.md #, no-wrap msgid "Defining aliases " -msgstr "" +msgstr "定义别名 " #. type: Plain text #: ../src/guide/concept/aliases.md msgid "You can define an alias via application's `config/params.php`:" -msgstr "" +msgstr "您可以通过应用程序的 `config/params.php` 定义别名:" #. type: Fenced code block (php) #: ../src/guide/concept/aliases.md @@ -73,16 +73,18 @@ msgid "" "> [!NOTE]\n" "> The file path or URL being aliased may *not* necessarily refer to an existing file or resource.\n" msgstr "" +"> [!NOTE]\n" +"> 被别名化的文件路径或 URL *不一定*指向现有的文件或资源。\n" #. type: Plain text #: ../src/guide/concept/aliases.md msgid "Given a defined alias, you may derive a new alias by appending a slash `/` followed with one or more path segments. For example, `@foo` is a root alias, while `@foo/bar/file.php` is a derived alias." -msgstr "" +msgstr "给定一个已定义的别名,您可以通过附加斜杠 `/` 后跟一个或多个路径段来派生新别名。例如,`@foo` 是根别名,而 `@foo/bar/file.php` 是派生别名。" #. type: Plain text #: ../src/guide/concept/aliases.md msgid "You can define an alias using another alias (either root or derived):" -msgstr "" +msgstr "您可以使用另一个别名(根别名或派生别名)来定义别名:" #. type: Fenced code block (php) #: ../src/guide/concept/aliases.md @@ -93,7 +95,7 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/aliases.md msgid "The `yiisoft/aliases` parameter initializes `Aliases` service from [`yiisoft/aliases`](https://github.com/yiisoft/aliases) package. You can set extra aliases in runtime by using the service:" -msgstr "" +msgstr "`yiisoft/aliases` 参数从 [`yiisoft/aliases`](https://github.com/yiisoft/aliases) 包初始化 `Aliases` 服务。您可以在运行时使用该服务设置额外的别名:" #. type: Fenced code block (php) #: ../src/guide/concept/aliases.md @@ -111,12 +113,12 @@ msgstr "" #: ../src/guide/concept/aliases.md #, no-wrap msgid "Using aliases in configuration " -msgstr "" +msgstr "在配置中使用别名 " #. type: Plain text #: ../src/guide/concept/aliases.md msgid "It's preferred to resolve aliases at the configuration level, so services get URLs and paths as ready to use strings:" -msgstr "" +msgstr "最好在配置级别解析别名,这样服务就可以获得可直接使用的 URL 和路径字符串:" #. type: Fenced code block (php) #: ../src/guide/concept/aliases.md @@ -142,12 +144,12 @@ msgstr "" #: ../src/guide/concept/aliases.md #, no-wrap msgid "Resolving aliases " -msgstr "" +msgstr "解析别名 " #. type: Plain text #: ../src/guide/concept/aliases.md msgid "You can use `Aliases` service to resolve an alias or derived alias into the file path or URL it represents:" -msgstr "" +msgstr "您可以使用 `Aliases` 服务将别名或派生别名解析为它所代表的文件路径或 URL:" #. type: Fenced code block (php) #: ../src/guide/concept/aliases.md @@ -166,7 +168,7 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/aliases.md msgid "The path/URL represented by a derived alias is determined by replacing the root alias part with its corresponding path/URL in the derived alias." -msgstr "" +msgstr "派生别名所代表的 path/URL 是通过将派生别名中的根别名部分替换为其对应的 path/URL 来确定的。" #. type: Plain text #: ../src/guide/concept/aliases.md @@ -175,11 +177,13 @@ msgid "" "> [!NOTE]\n" "> The `get()` method doesn't check whether the resulting path/URL refers to an existing file or resource.\n" msgstr "" +"> [!NOTE]\n" +"> `get()` 方法不检查结果 path/URL 是否指向现有的文件或资源。\n" #. type: Plain text #: ../src/guide/concept/aliases.md msgid "A root alias may also contain slash `/` characters. The `get()` method is intelligent enough to tell, which part of an alias is a root alias and thus correctly determines the corresponding file path or URL:" -msgstr "" +msgstr "根别名也可以包含斜杠 `/` 字符。`get()` 方法足够智能,可以判断别名的哪一部分是根别名,从而正确确定相应的文件路径或 URL:" #. type: Fenced code block (php) #: ../src/guide/concept/aliases.md @@ -200,75 +204,75 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/aliases.md msgid "If `@foo/bar` isn't defined as a root alias, the last statement would display `/path/to/foo/bar/file.php`." -msgstr "" +msgstr "如果 `@foo/bar` 未定义为根别名,最后一条语句将显示 `/path/to/foo/bar/file.php`。" #. type: Title ## #: ../src/guide/concept/aliases.md #, no-wrap msgid "Predefined aliases " -msgstr "" +msgstr "预定义别名 " #. type: Plain text #: ../src/guide/concept/aliases.md msgid "[Yii application](https://github.com/yiisoft/app) predefines a set of aliases to reference commonly used file paths and URLs:" -msgstr "" +msgstr "[Yii 应用程序](https://github.com/yiisoft/app) 预定义了一组别名来引用常用的文件路径和 URL:" #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@root` - the base directory of the currently running application." -msgstr "" +msgstr "`@root` - 当前运行应用程序的基础目录。" #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@assets` - application's public directory where it publishes assets." -msgstr "" +msgstr "`@assets` - 应用程序发布资源的公共目录。" #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@assetsUrl` - URL of base directory with published assets." -msgstr "" +msgstr "`@assetsUrl` - 已发布资源的基础目录的 URL。" #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@baseUrl` - the base URL of the currently running Web application. Defaults to `/`." -msgstr "" +msgstr "`@baseUrl` - 当前运行的 Web 应用程序的基础 URL。默认为 `/`。" #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@npm` - node packages directory." -msgstr "" +msgstr "`@npm` - node 包目录。" #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@bower` - bower packages directory." -msgstr "" +msgstr "`@bower` - bower 包目录。" #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@vendor` - Composer's `vendor` directory." -msgstr "" +msgstr "`@vendor` - Composer 的 `vendor` 目录。" #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@public` - application's publicly accessible directory that with `index.php`." -msgstr "" +msgstr "`@public` - 应用程序的公共可访问目录,包含 `index.php`。" #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@runtime` - the runtime path of the currently running application. Defaults to `@root/runtime`." -msgstr "" +msgstr "`@runtime` - 当前运行应用程序的运行时路径。默认为 `@root/runtime`。" #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@layout` - the directory with layouts." -msgstr "" +msgstr "`@layout` - 布局目录。" #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@resources` - directory with views, asset sources and other resources." -msgstr "" +msgstr "`@resources` - 包含视图、资源源文件和其他资源的目录。" #. type: Bullet: '- ' #: ../src/guide/concept/aliases.md msgid "`@views` - application view templates base directory." -msgstr "" +msgstr "`@views` - 应用程序视图模板基础目录。" diff --git a/_translations/po/zh-CN/guide_concept_autoloading.md.po b/_translations/po/zh-CN/guide_concept_autoloading.md.po index 8ed0421a..8e93f45f 100644 --- a/_translations/po/zh-CN/guide_concept_autoloading.md.po +++ b/_translations/po/zh-CN/guide_concept_autoloading.md.po @@ -30,17 +30,17 @@ msgstr "参考资料" #: ../src/guide/concept/autoloading.md #, no-wrap msgid "Class autoloading" -msgstr "" +msgstr "类自动加载" #. type: Plain text #: ../src/guide/concept/autoloading.md msgid "Since Yii uses [Composer](https://getcomposer.org) to manage packages, it automatically loads classes from these packages without the need to `require` their file explicitly. When it installs packages, it generates a [PSR-4 compatible autoloader](https://www.php-fig.org/psr/psr-4/). To use it, `require_once` autoloader `/vendor/autoload.php` in your `index.php` entry point file." -msgstr "" +msgstr "由于 Yii 使用 [Composer](https://getcomposer.org) 来管理包,它会自动从这些包中加载类,而无需显式 `require` 它们的文件。当它安装包时,会生成一个 [兼容 PSR-4 的自动加载器](https://www.php-fig.org/psr/psr-4/)。要使用它,请在您的 `index.php` 入口文件中 `require_once` 自动加载器 `/vendor/autoload.php`。" #. type: Plain text #: ../src/guide/concept/autoloading.md msgid "You can use autoloader not only for the packages installed, but for your application as well since it's also a package. To load classes of a certain namespace, add the following to `composer.json`:" -msgstr "" +msgstr "您不仅可以为已安装的包使用自动加载器,还可以为您的应用程序使用,因为它也是一个包。要加载特定命名空间的类,请将以下内容添加到 `composer.json`:" #. type: Fenced code block (json) #: ../src/guide/concept/autoloading.md @@ -58,19 +58,19 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/autoloading.md msgid "Where `App\\\\` is a root namespace and `src/` is a directory where you have your classes. You can add more source roots if needed. When done, execute `composer dump-autoload` or simply `composer du` and classes from the corresponding namespaces will start loading automatically." -msgstr "" +msgstr "其中 `App\\\\` 是根命名空间,`src/` 是您放置类的目录。如果需要,您可以添加更多源根目录。完成后,执行 `composer dump-autoload` 或简单地执行 `composer du`,相应命名空间的类将开始自动加载。" #. type: Plain text #: ../src/guide/concept/autoloading.md msgid "If you need development-environment-specific autoloading that isn't used when executing Composer with `--no-dev` flag, add it to `autoload-dev` section instead of `autoload`." -msgstr "" +msgstr "如果您需要开发环境特定的自动加载,在使用 `--no-dev` 标志执行 Composer 时不使用,请将其添加到 `autoload-dev` 部分而不是 `autoload`。" #. type: Bullet: '- ' #: ../src/guide/concept/autoloading.md msgid "[PSR-4: Autoloader](https://www.php-fig.org/psr/psr-4/)." -msgstr "" +msgstr "[PSR-4: 自动加载器](https://www.php-fig.org/psr/psr-4/)。" #. type: Bullet: '- ' #: ../src/guide/concept/autoloading.md msgid "[Composer guide on autoloading](https://getcomposer.org/doc/01-basic-usage.md#autoloading)." -msgstr "" +msgstr "[Composer 自动加载指南](https://getcomposer.org/doc/01-basic-usage.md#autoloading)。" diff --git a/_translations/po/zh-CN/guide_concept_configuration.md.po b/_translations/po/zh-CN/guide_concept_configuration.md.po index fa7e3cc0..d1f5ac87 100644 --- a/_translations/po/zh-CN/guide_concept_configuration.md.po +++ b/_translations/po/zh-CN/guide_concept_configuration.md.po @@ -34,33 +34,33 @@ msgstr "配置" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "There are many ways to configure your application. We will focus on concepts used in the [default project template](https://github.com/yiisoft/app)." -msgstr "" +msgstr "有很多方法可以配置您的应用程序。我们将重点关注 [默认项目模板](https://github.com/yiisoft/app) 中使用的概念。" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "Yii3 configs are part of the application. You can change many aspects of how the application works by editing configuration under `config/`." -msgstr "" +msgstr "Yii3 配置是应用程序的一部分。您可以通过编辑 `config/` 下的配置来更改应用程序工作方式的许多方面。" #. type: Title ## #: ../src/en/guide/concept/configuration.md #, no-wrap msgid "Config plugin" -msgstr "" +msgstr "配置插件" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "In the application template [yiisoft/config](https://github.com/yiisoft/config) is used. Since writing all application configurations from scratch is a tedious process, many packages offer default configs, and the plugin helps with copying these into the application." -msgstr "" +msgstr "在应用程序模板中使用了 [yiisoft/config](https://github.com/yiisoft/config)。由于从头开始编写所有应用程序配置是一个繁琐的过程,许多包提供默认配置,插件帮助将这些配置复制到应用程序中。" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "To offer default configs, `composer.json` of the package has to have `config-plugin` section. When installing or updating packages with Composer, the plugin reads `config-plugin` sections for each dependency, copies files themselves to application `config/packages/` if they don't yet exist and writes a merge plan to `config/packages/merge_plan.php`. The merge plan defines how to merge the configs into a single big array ready to be passed to [DI container](di-container.md)." -msgstr "" +msgstr "要提供默认配置,包的 `composer.json` 必须有 `config-plugin` 部分。在使用 Composer 安装或更新包时,插件会读取每个依赖项的 `config-plugin` 部分,如果文件尚不存在,则将文件本身复制到应用程序 `config/packages/`,并将合并计划写入 `config/packages/merge_plan.php`。合并计划定义了如何将配置合并到一个准备传递给 [DI 容器](di-container.md) 的大数组中。" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "Take a look at what's in the \"yiisoft/app\" `composer.json` by default:" -msgstr "" +msgstr "看看默认情况下 \"yiisoft/app\" `composer.json` 中有什么:" #. type: Fenced code block (json) #: ../src/en/guide/concept/configuration.md @@ -108,48 +108,48 @@ msgstr "" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "There are many named configs defined. For each name, there is a configuration." -msgstr "" +msgstr "定义了许多命名配置。对于每个名称,都有一个配置。" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "A string means that the plugin takes config as is and merges it with same-named configs from packages you require. That happens if these packages have `config-plugin` in their `composer.json`." -msgstr "" +msgstr "字符串意味着插件按原样获取配置并将其与您需要的包中的同名配置合并。如果这些包的 `composer.json` 中有 `config-plugin`,就会发生这种情况。" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "The array means that the plugin will merge many files in the order they're specified." -msgstr "" +msgstr "数组意味着插件将按指定的顺序合并多个文件。" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "`?` at the beginning of the file path indicated that the file may be absent. In this case, it's skipped." -msgstr "" +msgstr "文件路径开头的 `?` 表示文件可能不存在。在这种情况下,它会被跳过。" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "`$` at the beginning of the name means a reference to another named config." -msgstr "" +msgstr "名称开头的 `$` 表示对另一个命名配置的引用。" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "`params` is a bit special because it's reserved for application parameters. These are automatically available as `$params` in all other configuration files." -msgstr "" +msgstr "`params` 有点特殊,因为它是为应用程序参数保留的。这些参数在所有其他配置文件中自动作为 `$params` 可用。" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "You can learn more about config plugin features [from its documentation](https://github.com/yiisoft/config/blob/master/README.md)." -msgstr "" +msgstr "您可以 [从其文档](https://github.com/yiisoft/config/blob/master/README.md) 中了解有关配置插件功能的更多信息。" #. type: Title ## #: ../src/en/guide/concept/configuration.md #, no-wrap msgid "Config files" -msgstr "" +msgstr "配置文件" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "Now, as you know how the plugin assembles configs, look at `config` directory:" -msgstr "" +msgstr "现在,当您知道插件如何组装配置时,请查看 `config` 目录:" #. type: Fenced code block #: ../src/en/guide/concept/configuration.md @@ -180,7 +180,7 @@ msgstr "" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "The application consists of a set of services registered in a [dependency container](di-container.md). The config files that responsible for direct dependency container configuration are under `common/`, `console/` and `web/` directories. We use `web/` for config specific to web application and `console/` for config specific to console commands. Both web and console are sharing configuration under `common/`." -msgstr "" +msgstr "应用程序由在 [依赖容器](di-container.md) 中注册的一组服务组成。负责直接依赖容器配置的配置文件位于 `common/`、`console/` 和 `web/` 目录下。我们使用 `web/` 用于特定于 Web 应用程序的配置,使用 `console/` 用于特定于控制台命令的配置。Web 和控制台都共享 `common/` 下的配置。" #. type: Fenced code block (php) #: ../src/en/guide/concept/configuration.md @@ -206,38 +206,38 @@ msgstr "" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "Config plugin passes special `$params` variable to all config files. The code passes its values to the service." -msgstr "" +msgstr "配置插件将特殊的 `$params` 变量传递给所有配置文件。代码将其值传递给服务。" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "The guide on [\"Dependency injection and container\"](di-container.md) describes the configuration format and the idea of dependency injection in detail." -msgstr "" +msgstr "[\"依赖注入和容器\"](di-container.md) 指南详细描述了配置格式和依赖注入的思想。" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "For convenience, there is a naming convention for custom string keys:" -msgstr "" +msgstr "为方便起见,自定义字符串键有一个命名约定:" #. type: Bullet: '1. ' #: ../src/en/guide/concept/configuration.md msgid "Prefix package name such as `yiisoft/cache-file/custom-definition`." -msgstr "" +msgstr "前缀包名称,例如 `yiisoft/cache-file/custom-definition`。" #. type: Bullet: '2. ' #: ../src/en/guide/concept/configuration.md msgid "In case configuration are for the application itself, skip package prefix, such as `custom-definition`." -msgstr "" +msgstr "如果配置是针对应用程序本身的,请跳过包前缀,例如 `custom-definition`。" #. type: Title ### #: ../src/en/guide/concept/configuration.md #, no-wrap msgid "Service providers" -msgstr "" +msgstr "服务提供者" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "As an alternative to registering dependencies directly, you can use service providers. Basically, these are classes that given parameters are configuring and registering services within the container. Similar to three dependency configuration files described, there are three configs for specifying service providers: `providers-console.php` for console commands, `providers-web.php` for web application and `providers.php` for both:" -msgstr "" +msgstr "作为直接注册依赖项的替代方法,您可以使用服务提供者。基本上,这些是给定参数配置并在容器中注册服务的类。与所描述的三个依赖配置文件类似,有三个用于指定服务提供者的配置:`providers-console.php` 用于控制台命令,`providers-web.php` 用于 Web 应用程序,`providers.php` 用于两者:" #. type: Fenced code block (php) #: ../src/en/guide/concept/configuration.md @@ -265,17 +265,17 @@ msgstr "" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "In this config keys are provider names. By convention these are `vendor/package-name/provider-name`. Values are provider class names. These classes could be either created in the project itself or provided by a package." -msgstr "" +msgstr "在此配置中,键是提供者名称。按照惯例,这些是 `vendor/package-name/provider-name`。值是提供者类名。这些类可以在项目本身中创建,也可以由包提供。" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "If you need to configure some options for a service, similar to direct container configuration, take values from `$params` and pass them to providers." -msgstr "" +msgstr "如果您需要为服务配置一些选项,类似于直接容器配置,从 `$params` 中获取值并将它们传递给提供者。" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "Provider should implement a single method, `public function register(Container $container): void`. In this method you need to add a service to container using `set()` method. Below is a provider for a cache service:" -msgstr "" +msgstr "提供者应该实现一个方法,`public function register(Container $container): void`。在此方法中,您需要使用 `set()` 方法将服务添加到容器。下面是缓存服务的提供者:" #. type: Fenced code block (php) #: ../src/en/guide/concept/configuration.md @@ -316,12 +316,12 @@ msgstr "" #: ../src/en/guide/concept/configuration.md #, no-wrap msgid "Routes" -msgstr "" +msgstr "路由" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "You can configure how web application responds to certain URLs in `config/routes.php`:" -msgstr "" +msgstr "您可以在 `config/routes.php` 中配置 Web 应用程序如何响应某些 URL:" #. type: Fenced code block (php) #: ../src/en/guide/concept/configuration.md @@ -338,7 +338,7 @@ msgstr "" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "Read more about it in [\"Routes\"](../runtime/routing.md)." -msgstr "" +msgstr "在 [\"路由\"](../runtime/routing.md) 中阅读更多相关内容。" #. type: Title ## #: ../src/en/guide/concept/configuration.md ../src/en/guide/concept/events.md @@ -350,7 +350,7 @@ msgstr "事件" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "Many services emit certain events that you can attach to. You could do that via three config files: `events-web.php` for web application events, `events-console.php` for console events and `events.php` for both. The configuration is an array where keys are event names and values are an array of handlers:" -msgstr "" +msgstr "许多服务会发出您可以附加的某些事件。您可以通过三个配置文件来执行此操作:`events-web.php` 用于 Web 应用程序事件,`events-console.php` 用于控制台事件,`events.php` 用于两者。配置是一个数组,其中键是事件名称,值是处理程序数组:" #. type: Fenced code block (php) #: ../src/en/guide/concept/configuration.md @@ -387,7 +387,7 @@ msgstr "" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "Read more about it in [\"Events\"](events.md)." -msgstr "" +msgstr "在 [\"事件\"](events.md) 中阅读更多相关内容。" #. type: Title ## #: ../src/en/guide/concept/configuration.md @@ -399,7 +399,7 @@ msgstr "参数" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "Parameters, `config/params.php` store configuration values that are used in other config files to configuring services and service providers." -msgstr "" +msgstr "参数 `config/params.php` 存储用于配置服务和服务提供者的其他配置文件中使用的配置值。" #. type: Plain text #: ../src/en/guide/concept/configuration.md @@ -409,11 +409,14 @@ msgid "" "> Don't use parameters, constants or environment variables directly in your application, configure\n" "> services instead.\n" msgstr "" +"> [!TIP]\n" +"> 不要在应用程序中直接使用参数、常量或环境变量,而是配置\n" +"> 服务。\n" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "Default application `params.php` looks like the following:" -msgstr "" +msgstr "默认应用程序 `params.php` 如下所示:" #. type: Fenced code block (php) #: ../src/en/guide/concept/configuration.md @@ -472,40 +475,40 @@ msgstr "" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "For convenience, there is a naming convention about parameters:" -msgstr "" +msgstr "为方便起见,关于参数有一个命名约定:" #. type: Bullet: '1. ' #: ../src/en/guide/concept/configuration.md msgid "Group parameters package name such as `yiisoft/cache-file`." -msgstr "" +msgstr "按包名称分组参数,例如 `yiisoft/cache-file`。" #. type: Bullet: '2. ' #: ../src/en/guide/concept/configuration.md msgid "In case parameters are for the application itself, as in `app`, skip package prefix." -msgstr "" +msgstr "如果参数是针对应用程序本身的,如 `app`,请跳过包前缀。" #. type: Bullet: '3. ' #: ../src/en/guide/concept/configuration.md msgid "In case there are many services in the package, such as `file-target` and `file-rotator` in `yiisoft/log-target-file` package, group parameters by service name." -msgstr "" +msgstr "如果包中有许多服务,例如 `yiisoft/log-target-file` 包中的 `file-target` 和 `file-rotator`,请按服务名称分组参数。" #. type: Bullet: '4. ' #: ../src/en/guide/concept/configuration.md msgid "Use `enabled` as parameter name to be able to disable or enable a service, such as `yiisoft/yii-debug`." -msgstr "" +msgstr "使用 `enabled` 作为参数名称以能够禁用或启用服务,例如 `yiisoft/yii-debug`。" #. type: Title ### #: ../src/en/guide/concept/configuration.md #, no-wrap msgid "Package configs" -msgstr "" +msgstr "包配置" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "Config plugin described copy default package configurations to `packages/` directory. Once copied you own the configs, so you can adjust these as you like. `yiisoft/` in the default template stands for package vendor. Since only `yiisoft` packages are in template, there's a single directory. `merge_plan.php` is used in runtime to get the order on how configs are merged. Note that for config keys there should be a single source of truth. One config can't override values of another config." -msgstr "" +msgstr "所描述的配置插件将默认包配置复制到 `packages/` 目录。一旦复制,您就拥有了配置,因此您可以根据需要调整这些配置。默认模板中的 `yiisoft/` 代表包供应商。由于模板中只有 `yiisoft` 包,因此只有一个目录。`merge_plan.php` 在运行时用于获取配置合并的顺序。请注意,对于配置键,应该有一个单一的真实来源。一个配置不能覆盖另一个配置的值。" #. type: Plain text #: ../src/en/guide/concept/configuration.md msgid "`dist.lock` is used by the plugin to keep track of changes and display diff between current config and example one." -msgstr "" +msgstr "`dist.lock` 由插件用于跟踪更改并显示当前配置与示例配置之间的差异。" diff --git a/_translations/po/zh-CN/guide_concept_di-container.md.po b/_translations/po/zh-CN/guide_concept_di-container.md.po index 3ebf854e..527b662f 100644 --- a/_translations/po/zh-CN/guide_concept_di-container.md.po +++ b/_translations/po/zh-CN/guide_concept_di-container.md.po @@ -19,23 +19,23 @@ msgstr "" #: ../src/guide/concept/di-container.md #, no-wrap msgid "Dependency injection and container" -msgstr "" +msgstr "依赖注入和容器" #. type: Title ## #: ../src/guide/concept/di-container.md #, no-wrap msgid "Dependency injection " -msgstr "" +msgstr "依赖注入 " #. type: Plain text #: ../src/guide/concept/di-container.md msgid "There are two ways of re-using things in OOP: inheritance and composition." -msgstr "" +msgstr "在面向对象编程中,有两种重用代码的方式:继承和组合。" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Inheritance is simple:" -msgstr "" +msgstr "继承很简单:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -65,12 +65,12 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "The issue here is that these two are becoming unnecessarily coupled or inter-dependent, making them more fragile." -msgstr "" +msgstr "这里的问题是这两者变得不必要地耦合或相互依赖,使它们更加脆弱。" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Another way to handle this is composition:" -msgstr "" +msgstr "另一种处理方式是组合:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -111,119 +111,119 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "We've avoided unnecessary inheritance and used `CacheInterface` in the `CacheWidget` to reduce coupling. You can replace cache implementation without changing `CachedWidget` so it's becoming more stable. The less edits are made to the code, the less chance of breaking it." -msgstr "" +msgstr "我们避免了不必要的继承,并在 `CacheWidget` 中使用 `CacheInterface` 来减少耦合。您可以在不更改 `CachedWidget` 的情况下替换缓存实现,因此它变得更加稳定。对代码的编辑越少,破坏它的机会就越小。" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "The `CacheInterface` here is a dependency: a contract our object needs to function. In other words, our object depends on the contract." -msgstr "" +msgstr "这里的 `CacheInterface` 是一个依赖:我们的对象需要运行的契约。换句话说,我们的对象依赖于这个契约。" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "The process of putting an instance of a contract into an object (`CachedWidget`) is called dependency injection. There are many ways to perform it:" -msgstr "" +msgstr "将契约的实例放入对象(`CachedWidget`)的过程称为依赖注入。有多种方式可以执行它:" #. type: Bullet: '- ' #: ../src/guide/concept/di-container.md msgid "Constructor injection. Best for mandatory dependencies." -msgstr "" +msgstr "构造函数注入。最适合强制性依赖。" #. type: Bullet: '- ' #: ../src/guide/concept/di-container.md msgid "Method injection. Best for optional dependencies." -msgstr "" +msgstr "方法注入。最适合可选依赖。" #. type: Bullet: '- ' #: ../src/guide/concept/di-container.md msgid "Property injection. Better to be avoided in PHP except maybe data transfer objects." -msgstr "" +msgstr "属性注入。在 PHP 中最好避免使用,除非可能是数据传输对象。" #. type: Title ### #: ../src/guide/concept/di-container.md #, no-wrap msgid "Why use private properties " -msgstr "" +msgstr "为什么使用私有属性 " #. type: Plain text #: ../src/guide/concept/di-container.md msgid "In the composition example above, note that the `$cache` property is declared as `private`." -msgstr "" +msgstr "在上面的组合示例中,请注意 `$cache` 属性被声明为 `private`。" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "This approach embraces composition by ensuring objects have well-defined interfaces for interaction rather than direct property access, making the code more maintainable and less prone to certain types of mistakes." -msgstr "" +msgstr "这种方法通过确保对象具有明确定义的交互接口而不是直接属性访问来拥抱组合,使代码更易于维护,并且不太容易出现某些类型的错误。" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "This design choice provides several benefits:" -msgstr "" +msgstr "这种设计选择提供了几个好处:" #. type: Bullet: '- ' #: ../src/guide/concept/di-container.md msgid "**Encapsulation**: Private properties with getters/setters allow you to control access and make future changes without breaking existing code." -msgstr "" +msgstr "**封装**:带有 getter/setter 的私有属性允许您控制访问并在不破坏现有代码的情况下进行未来更改。" #. type: Bullet: '- ' #: ../src/guide/concept/di-container.md msgid "**Data integrity**: Setters can validate, normalize, or format values before storing them, ensuring properties contain valid data." -msgstr "" +msgstr "**数据完整性**:Setter 可以在存储值之前验证、规范化或格式化值,确保属性包含有效数据。" #. type: Bullet: '- ' #: ../src/guide/concept/di-container.md msgid "**Immutability**: Private properties enable immutable object patterns where setter `with*()` methods return new instances rather than modifying the current one." -msgstr "" +msgstr "**不可变性**:私有属性启用不可变对象模式,其中 setter `with*()` 方法返回新实例而不是修改当前实例。" #. type: Bullet: '- ' #: ../src/guide/concept/di-container.md msgid "**Flexibility**: You can create read-only or write-only properties or add additional logic to property access later." -msgstr "" +msgstr "**灵活性**:您可以创建只读或只写属性,或稍后向属性访问添加额外的逻辑。" #. type: Title ## #: ../src/guide/concept/di-container.md #, no-wrap msgid "DI container " -msgstr "" +msgstr "DI 容器 " #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Injecting basic dependencies is straightforward. You're choosing a place where you don't care about dependencies, which is usually an action handler, which you aren't going to unit-test ever, create instances of dependencies needed and pass these to dependent classes." -msgstr "" +msgstr "注入基本依赖很简单。您选择一个不关心依赖的地方,通常是一个操作处理器,您永远不会对其进行单元测试,创建所需依赖的实例并将这些传递给依赖类。" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "It works well when there are few dependencies overall and when there are no nested dependencies. When there are many and each dependency has dependencies itself, instantiating the whole hierarchy becomes a tedious process, which requires lots of code and may lead to hardly debuggable mistakes." -msgstr "" +msgstr "当总体依赖很少且没有嵌套依赖时,它运行良好。当有很多依赖并且每个依赖本身都有依赖时,实例化整个层次结构变成一个繁琐的过程,需要大量代码,并可能导致难以调试的错误。" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Additionally, lots of dependencies, such as certain third-party API wrappers, are the same for any class using it. So it makes sense to:" -msgstr "" +msgstr "此外,许多依赖(例如某些第三方 API 包装器)对于使用它的任何类都是相同的。因此,有必要:" #. type: Bullet: '- ' #: ../src/guide/concept/di-container.md msgid "Define how to instantiate such common dependencies." -msgstr "" +msgstr "定义如何实例化这些常见依赖。" #. type: Bullet: '- ' #: ../src/guide/concept/di-container.md msgid "Instantiate them when required and only once per request." -msgstr "" +msgstr "在需要时实例化它们,并且每个请求只实例化一次。" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "That's what dependency containers are for." -msgstr "" +msgstr "这就是依赖容器的用途。" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "A dependency injection (DI) container is an object that knows how to instantiate and configure objects and all objects they depend on." -msgstr "" +msgstr "依赖注入(DI)容器是一个知道如何实例化和配置对象以及它们所依赖的所有对象的对象。" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Yii provides the DI container feature through the [yiisoft/di](https://github.com/yiisoft/di) package and [yiisoft/injector](https://github.com/yiisoft/injector) package." -msgstr "" +msgstr "Yii 通过 [yiisoft/di](https://github.com/yiisoft/di) 包和 [yiisoft/injector](https://github.com/yiisoft/injector) 包提供 DI 容器功能。" #. type: Plain text #: ../src/guide/concept/di-container.md @@ -233,6 +233,9 @@ msgid "" "> The container contains only shared instances. If you need a factory, use the dedicated\n" "> [yiisoft/factory](https://github.com/yiisoft/factory) package.\n" msgstr "" +"> [!NOTE]\n" +"> 容器仅包含共享实例。如果您需要工厂,请使用专用的\n" +"> [yiisoft/factory](https://github.com/yiisoft/factory) 包。\n" #. type: Plain text #: ../src/guide/concept/di-container.md @@ -242,17 +245,20 @@ msgid "" "> [Martin Fowler's article](https://martinfowler.com/articles/injection.html) has well\n" "> explained why DI container is useful. Here we will mainly explain the usage of the DI container provided by Yii.\n" msgstr "" +"> [!TIP]\n" +"> [Martin Fowler 的文章](https://martinfowler.com/articles/injection.html) 很好地\n" +"> 解释了为什么 DI 容器有用。这里我们将主要解释 Yii 提供的 DI 容器的使用。\n" #. type: Title ### #: ../src/guide/concept/di-container.md #, no-wrap msgid "Configuring container " -msgstr "" +msgstr "配置容器 " #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Because to create a new object you need its dependencies, you should register them as early as possible. You can do it in the application configuration, `config/web.php`. For the following service:" -msgstr "" +msgstr "因为要创建新对象需要其依赖,所以您应该尽早注册它们。您可以在应用程序配置 `config/web.php` 中执行此操作。对于以下服务:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -274,7 +280,7 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "configuration could be:" -msgstr "" +msgstr "配置可以是:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -292,7 +298,7 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "That's equal to the following:" -msgstr "" +msgstr "这等同于以下内容:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -305,7 +311,7 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "You can provide arguments with names as well:" -msgstr "" +msgstr "您也可以提供带名称的参数:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -323,7 +329,7 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "That's basically it. You define a map of interfaces to classes and define how to configure them. When an interface is requested in constructor or elsewhere, container creates an instance of a class and configures it as per the configuration:" -msgstr "" +msgstr "基本上就是这样。您定义接口到类的映射并定义如何配置它们。当在构造函数或其他地方请求接口时,容器会创建类的实例并根据配置对其进行配置:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -346,12 +352,12 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "There are extra methods of declaring dependency configuration." -msgstr "" +msgstr "还有其他声明依赖配置的方法。" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "For simplest cases where there are no custom values needed and all the constructor dependencies could be obtained from a container, you can use a class name as a value." -msgstr "" +msgstr "对于不需要自定义值且所有构造函数依赖都可以从容器获取的最简单情况,您可以使用类名作为值。" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -372,7 +378,7 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "In the above example, if we already have cache defined in the container, nothing besides the class name is needed:" -msgstr "" +msgstr "在上面的示例中,如果我们已经在容器中定义了缓存,则除了类名之外不需要任何东西:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -387,7 +393,7 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "If you have a dependency that has public properties, you can configure it as well." -msgstr "" +msgstr "如果您有一个具有公共属性的依赖,您也可以配置它。" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -402,7 +408,7 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Here's how to do it for the example above:" -msgstr "" +msgstr "以下是上面示例的操作方法:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -417,12 +423,12 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "In this example, you may notice `NameProvider` specified twice. The key is what you may request as dependency and the value is how to create it." -msgstr "" +msgstr "在此示例中,您可能会注意到 `NameProvider` 被指定了两次。键是您可以请求作为依赖的内容,值是如何创建它。" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "If the configuration is tricky and requires some logic, a closure can be used:" -msgstr "" +msgstr "如果配置很复杂并需要一些逻辑,可以使用闭包:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -436,7 +442,7 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Additionally, to `ContainerInterface`, you can request any registered service directly as a closure parameter. The injector will automatically resolve and inject these:" -msgstr "" +msgstr "此外,除了 `ContainerInterface`,您还可以直接将任何已注册的服务作为闭包参数请求。注入器将自动解析并注入这些:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -450,7 +456,7 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "It's possible to use a static method call:" -msgstr "" +msgstr "可以使用静态方法调用:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -461,7 +467,7 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Or an instance of an object:" -msgstr "" +msgstr "或对象的实例:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -473,17 +479,17 @@ msgstr "" #: ../src/guide/concept/di-container.md #, no-wrap msgid "Injecting dependencies properly " -msgstr "" +msgstr "正确注入依赖 " #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Directly referencing a container in a class is a bad idea since the code becomes non-generic, coupled to the container interface and, what's worse, dependencies are becoming hidden. Because of that, Yii inverts the control by automatically injecting objects from a container in some constructors and methods based on method argument types." -msgstr "" +msgstr "在类中直接引用容器是一个坏主意,因为代码变得不通用,耦合到容器接口,更糟糕的是,依赖变得隐藏。因此,Yii 通过根据方法参数类型在某些构造函数和方法中自动从容器注入对象来反转控制。" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "This is primarily done in constructor and handing method of action handlers:" -msgstr "" +msgstr "这主要在操作处理器的构造函数和处理方法中完成:" #. type: Fenced code block (php) #: ../src/guide/concept/di-container.md @@ -516,15 +522,15 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/di-container.md msgid "Since it's [yiisoft/injector](https://github.com/yiisoft/injector) that instantiates and calls action handler, it checks the constructor and method argument types, gets dependencies of these types from a container and passes them as arguments. That's usually called auto-wiring. It happens for sub-dependencies as well, that's if you don't give dependency explicitly, the container would check if it has such a dependency first. It's enough to declare a dependency you need, and it would be got from a container automatically." -msgstr "" +msgstr "由于是 [yiisoft/injector](https://github.com/yiisoft/injector) 实例化并调用操作处理器,它会检查构造函数和方法参数类型,从容器中获取这些类型的依赖并将它们作为参数传递。这通常称为自动装配。它也适用于子依赖,也就是说,如果您没有显式提供依赖,容器会首先检查它是否有这样的依赖。只需声明您需要的依赖,它就会自动从容器中获取。" #. type: Title ## #: ../src/guide/concept/di-container.md #, no-wrap msgid "References " -msgstr "" +msgstr "参考资料 " #. type: Bullet: '- ' #: ../src/guide/concept/di-container.md msgid "[Inversion of Control Containers and the Dependency Injection pattern by Martin Fowler](https://martinfowler.com/articles/injection.html)" -msgstr "" +msgstr "[Martin Fowler 的控制反转容器和依赖注入模式](https://martinfowler.com/articles/injection.html)" diff --git a/_translations/po/zh-CN/guide_concept_events.md.po b/_translations/po/zh-CN/guide_concept_events.md.po index c6523633..5618d0e3 100644 --- a/_translations/po/zh-CN/guide_concept_events.md.po +++ b/_translations/po/zh-CN/guide_concept_events.md.po @@ -25,12 +25,12 @@ msgstr "事件" #. type: Plain text #: ../src/guide/concept/events.md msgid "Events allow you to make custom code executed at certain execution points without modifying existing code. You can attach a custom code called \"handler\" to an event so that when the event is triggered, the handler gets executed automatically." -msgstr "" +msgstr "事件允许您在特定执行点执行自定义代码,而无需修改现有代码。您可以将称为“处理器”的自定义代码附加到事件,以便在触发事件时,处理器会自动执行。" #. type: Plain text #: ../src/guide/concept/events.md msgid "For example, when a user is signed up, you need to send a welcome email. You can do it right in the `SignupService` but then, when you additionally need to resize user's avatar image, you'll have to change `SignupService` code again. In other words, `SignupService` will be coupled to both code sending welcome email and code resizing avatar image." -msgstr "" +msgstr "例如,当用户注册时,您需要发送欢迎邮件。您可以直接在 `SignupService` 中执行此操作,但如果您还需要调整用户头像图片的大小,则必须再次更改 `SignupService` 代码。换句话说,`SignupService` 将与发送欢迎邮件的代码和调整头像图片大小的代码耦合。" #. type: Plain text #: ../src/guide/concept/events.md @@ -41,27 +41,31 @@ msgid "" " and, therefore, will be executed. If you'll ever need to do more on signup, you'll be able to attach extra event\n" "handlers without modifying `SignupService`. \n" msgstr "" +"为避免这种情况,您可以触发 `UserSignedUp` 事件,\n" +"然后完成注册流程,而不是明确告知注册后要做什么。发送邮件的代码和调整头像图片大小的代码将附加到该事件,\n" +"因此,它们将被执行。如果您以后需要在注册时执行更多操作,您可以附加额外的事件\n" +"处理器,而无需修改 `SignupService`。\n" #. type: Plain text #: ../src/guide/concept/events.md msgid "For raising events and attaching handlers to these events, Yii has a special service called event dispatcher. It's available from [yiisoft/event-dispatcher package](https://github.com/yiisoft/event-dispatcher)." -msgstr "" +msgstr "要触发事件并将处理器附加到这些事件,Yii 有一个称为事件调度器的特殊服务。它可以从 [yiisoft/event-dispatcher 包](https://github.com/yiisoft/event-dispatcher) 获取。" #. type: Title ## #: ../src/guide/concept/events.md #, no-wrap msgid "Event Handlers " -msgstr "" +msgstr "事件处理器 " #. type: Plain text #: ../src/guide/concept/events.md msgid "An event handler is [PHP callable](https://www.php.net/manual/en/language.types.callable.php) that gets executed when the event it's attached to is triggered." -msgstr "" +msgstr "事件处理器是 [PHP callable](https://www.php.net/manual/en/language.types.callable.php),当它附加的事件被触发时执行。" #. type: Plain text #: ../src/guide/concept/events.md msgid "The signature of an event handler is:" -msgstr "" +msgstr "事件处理器的签名是:" #. type: Fenced code block (php) #: ../src/guide/concept/events.md @@ -76,12 +80,12 @@ msgstr "" #: ../src/guide/concept/events.md #, no-wrap msgid "Attaching event handlers " -msgstr "" +msgstr "附加事件处理器 " #. type: Plain text #: ../src/guide/concept/events.md msgid "You can attach a handler to an event like the following:" -msgstr "" +msgstr "您可以按如下方式将处理器附加到事件:" #. type: Fenced code block (php) #: ../src/guide/concept/events.md @@ -106,34 +110,34 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/events.md msgid "The `attach()` method is accepting a callback. Based on the type of this callback argument, the event type is determined." -msgstr "" +msgstr "`attach()` 方法接受一个回调。根据此回调参数的类型,确定事件类型。" #. type: Title ## #: ../src/guide/concept/events.md #, no-wrap msgid "Event handlers order" -msgstr "" +msgstr "事件处理器顺序" #. type: Plain text #: ../src/guide/concept/events.md msgid "You may attach one or more handlers to a single event. When an event is triggered, the attached handlers will be called in the order that they were attached to the event. In case an event implements `Psr\\EventDispatcher\\StoppableEventInterface`, event handler can stop executing the rest of the handlers that follow it if `isPropagationStopped()` returns `true`." -msgstr "" +msgstr "您可以将一个或多个处理器附加到单个事件。当事件被触发时,附加的处理器将按照它们附加到事件的顺序被调用。如果事件实现了 `Psr\\EventDispatcher\\StoppableEventInterface`,当 `isPropagationStopped()` 返回 `true` 时,事件处理器可以停止执行其后的其余处理器。" #. type: Plain text #: ../src/guide/concept/events.md msgid "In general, it's better not to rely on the order of event handlers." -msgstr "" +msgstr "一般来说,最好不要依赖事件处理器的顺序。" #. type: Title ## #: ../src/guide/concept/events.md #, no-wrap msgid "Raising events " -msgstr "" +msgstr "触发事件 " #. type: Plain text #: ../src/guide/concept/events.md msgid "Events are raised like the following:" -msgstr "" +msgstr "事件按如下方式触发:" #. type: Fenced code block (php) #: ../src/guide/concept/events.md @@ -162,12 +166,12 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/events.md msgid "First, you create an event supplying it with data that may be useful for handlers. Then you dispatch the event." -msgstr "" +msgstr "首先,您创建一个事件,并为其提供可能对处理器有用的数据。然后您调度该事件。" #. type: Plain text #: ../src/guide/concept/events.md msgid "The event class itself may look like the following:" -msgstr "" +msgstr "事件类本身可能如下所示:" #. type: Fenced code block (php) #: ../src/guide/concept/events.md @@ -187,12 +191,12 @@ msgstr "" #: ../src/guide/concept/events.md #, no-wrap msgid "Events hierarchy" -msgstr "" +msgstr "事件层次结构" #. type: Plain text #: ../src/guide/concept/events.md msgid "Events don't have any name or wildcard matching on purpose. Event class names and class/interface hierarchy and composition could be used to achieve great flexibility:" -msgstr "" +msgstr "事件故意没有任何名称或通配符匹配。事件类名称以及类/接口层次结构和组合可用于实现极大的灵活性:" #. type: Fenced code block (php) #: ../src/guide/concept/events.md @@ -214,7 +218,7 @@ msgstr "" #. type: Plain text #: ../src/guide/concept/events.md msgid "With the interface, you can listen to all document-related events:" -msgstr "" +msgstr "使用接口,您可以监听所有与文档相关的事件:" #. type: Fenced code block (php) #: ../src/guide/concept/events.md @@ -229,12 +233,12 @@ msgstr "" #: ../src/guide/concept/events.md #, no-wrap msgid "Detaching event handlers " -msgstr "" +msgstr "分离事件处理器 " #. type: Plain text #: ../src/guide/concept/events.md msgid "To detach a handler from an event you can call `detach()` method:" -msgstr "" +msgstr "要从事件中分离处理器,您可以调用 `detach()` 方法:" #. type: Fenced code block (php) #: ../src/guide/concept/events.md @@ -246,9 +250,9 @@ msgstr "" #: ../src/guide/concept/events.md #, no-wrap msgid "Configuring application events" -msgstr "" +msgstr "配置应用程序事件" #. type: Plain text #: ../src/guide/concept/events.md msgid "You usually assign event handlers via application config. See [\"Configuration\"](configuration.md) for details." -msgstr "" +msgstr "您通常通过应用程序配置来分配事件处理器。有关详细信息,请参阅 [\"配置\"](configuration.md)。" diff --git a/_translations/po/zh-CN/guide_concept_immutability.md.po b/_translations/po/zh-CN/guide_concept_immutability.md.po index 32ced730..5255c89c 100644 --- a/_translations/po/zh-CN/guide_concept_immutability.md.po +++ b/_translations/po/zh-CN/guide_concept_immutability.md.po @@ -25,13 +25,13 @@ msgstr "不可变性" #. type: Plain text #: ../src/en/guide/concept/immutability.md msgid "Immutability means an object's state cannot change after it has been created. Instead of modifying an instance, you create a new instance with the desired changes. This approach is common for value objects such as Money, IDs, and DTOs. It helps to avoid accidental side effects: methods cannot silently change shared state, which makes code easier to reason about." -msgstr "" +msgstr "不可变性是指对象在创建后其状态不能被改变。您不能修改一个已有实例,而是创建一个包含所需更改的新实例。这种方式常用于值对象,如 Money、ID 和 DTO。它有助于避免意外的副作用:方法不能静默修改共享状态,从而使代码更易于理解。" #. type: Title ## #: ../src/en/guide/concept/immutability.md #, no-wrap msgid "Mutable pitfalls (what we avoid)" -msgstr "" +msgstr "可变对象的陷阱(我们要避免的)" #. type: Fenced code block (php) #: ../src/en/guide/concept/immutability.md @@ -52,12 +52,12 @@ msgstr "" #: ../src/en/guide/concept/immutability.md #, no-wrap msgid "Creating an immutable object in PHP" -msgstr "" +msgstr "在 PHP 中创建不可变对象" #. type: Plain text #: ../src/en/guide/concept/immutability.md msgid "There is no direct way to modify an instance, but you can use clone to create a new instance with the desired changes. That is what `with*` methods do." -msgstr "" +msgstr "PHP 中没有直接修改实例的方式,但可以使用 clone 创建一个包含所需更改的新实例。这正是 `with*` 方法的作用。" #. type: Fenced code block (php) #: ../src/en/guide/concept/immutability.md @@ -140,12 +140,12 @@ msgstr "" #. type: Bullet: '- ' #: ../src/en/guide/concept/immutability.md msgid "We mark the class `final` to prevent subclass mutations; alternatively, design for extension carefully." -msgstr "" +msgstr "将类标记为 `final` 以防止子类修改状态;也可以谨慎地设计以支持扩展。" #. type: Bullet: '- ' #: ../src/en/guide/concept/immutability.md msgid "Validate in the constructor and `with*` methods so every instance is always valid." -msgstr "" +msgstr "在构造函数和 `with*` 方法中进行验证,确保每个实例始终处于有效状态。" #. type: Plain text #: ../src/en/guide/concept/immutability.md @@ -155,22 +155,25 @@ msgid "" "> If you define a simple DTO, you can use modern PHP `readonly` and leave properties `public`. The `readonly` keyword\n" "> would ensure that the properties cannot be modified after the object is created.\n" msgstr "" +"> [!TIP]\n" +"> 如果您定义的是简单的 DTO,可以使用现代 PHP 的 `readonly` 关键字并将属性设为 `public`。`readonly` 关键字\n" +"> 可确保属性在对象创建后无法被修改。\n" #. type: Title ## #: ../src/en/guide/concept/immutability.md #, no-wrap msgid "Using clone (and why it is inexpensive)" -msgstr "" +msgstr "使用 clone(以及为何开销低)" #. type: Plain text #: ../src/en/guide/concept/immutability.md msgid "PHP's clone performs a shallow copy of the object. For immutable value objects that contain only scalars or other immutable objects, shallow cloning is enough and fast. In modern PHP, cloning small value objects is inexpensive in both time and memory." -msgstr "" +msgstr "PHP 的 clone 对对象执行浅拷贝。对于只包含标量或其他不可变对象的不可变值对象,浅拷贝已经足够且速度很快。在现代 PHP 中,克隆小型值对象在时间和内存方面的开销都很低。" #. type: Plain text #: ../src/en/guide/concept/immutability.md msgid "If your object holds mutable sub-objects that must also be copied, implement `__clone` to deep-clone them:" -msgstr "" +msgstr "如果对象持有也需要复制的可变子对象,请实现 `__clone` 来对其进行深拷贝:" #. type: Fenced code block (php) #: ../src/en/guide/concept/immutability.md @@ -206,19 +209,19 @@ msgstr "" #: ../src/en/guide/concept/immutability.md #, no-wrap msgid "Usage style" -msgstr "" +msgstr "使用风格" #. type: Bullet: '- ' #: ../src/en/guide/concept/immutability.md msgid "Build a value object once and pass it around. If you need a change, use a `with*` method that returns a new instance." -msgstr "" +msgstr "一次性构建值对象并传递使用。如需更改,使用返回新实例的 `with*` 方法。" #. type: Bullet: '- ' #: ../src/en/guide/concept/immutability.md msgid "Prefer scalar/immutable fields inside immutable objects; if a field can mutate, isolate it and deep-clone in `__clone` when needed." -msgstr "" +msgstr "不可变对象内部优先使用标量或不可变字段;如果某个字段可能发生变化,请将其隔离,并在需要时在 `__clone` 中对其进行深拷贝。" #. type: Plain text #: ../src/en/guide/concept/immutability.md msgid "Immutability aligns well with Yii's preference for predictable, side-effect-free code and makes services, caching, and configuration more robust." -msgstr "" +msgstr "不可变性与 Yii 对可预测、无副作用代码的偏好高度契合,能使服务、缓存和配置更加健壮。" diff --git a/_translations/po/zh-CN/guide_databases_db-migrations.md.po b/_translations/po/zh-CN/guide_databases_db-migrations.md.po index b5423795..0e156bd3 100644 --- a/_translations/po/zh-CN/guide_databases_db-migrations.md.po +++ b/_translations/po/zh-CN/guide_databases_db-migrations.md.po @@ -19,92 +19,92 @@ msgstr "" #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Migrations" -msgstr "" +msgstr "数据库迁移" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "During the course of developing and maintaining a database-driven application, the structure of the database being used evolves just like the source code does. For example, during the development of an application, a new table may be found necessary; after the application is deployed to production, it may be discovered that an index should be created to improve the query performance; and so on. Because a database structure change often requires some source code changes, Yii supports the so-called *database migration* feature that allows you to keep track of database changes in terms of *database migrations* which are version-controlled together with the source code." -msgstr "" +msgstr "在开发和维护数据库驱动的应用程序过程中,所使用的数据库结构会像源代码一样不断演变。例如,在应用程序开发过程中,可能发现需要一张新表;在应用程序部署到生产环境后,可能发现应该创建一个索引来提高查询性能;等等。由于数据库结构变更通常需要相应的源代码变更,Yii 支持所谓的*数据库迁移*功能,允许您以*数据库迁移*的形式追踪数据库变更,这些迁移与源代码一起进行版本控制。" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "The following steps show how database migration can be used by a team during development:" -msgstr "" +msgstr "以下步骤展示了团队在开发过程中如何使用数据库迁移:" #. type: Bullet: '1. ' #: ../src/guide/databases/db-migrations.md msgid "Tim creates a new migration (e.g. creates a new table, changes a column definition, etc.)." -msgstr "" +msgstr "Tim 创建一个新的迁移(例如创建一张新表、修改列定义等)。" #. type: Bullet: '2. ' #: ../src/guide/databases/db-migrations.md msgid "Tim commits the new migration into the source control system (e.g. Git, Mercurial)." -msgstr "" +msgstr "Tim 将新的迁移提交到源代码控制系统(例如 Git、Mercurial)。" #. type: Bullet: '3. ' #: ../src/guide/databases/db-migrations.md msgid "Doug updates his repository from the source control system and receives the new migration." -msgstr "" +msgstr "Doug 从源代码控制系统更新他的仓库,获取新的迁移。" #. type: Bullet: '4. ' #: ../src/guide/databases/db-migrations.md msgid "Doug applies the migration to his local development database, thereby synchronizing his database to reflect the changes that Tim has made." -msgstr "" +msgstr "Doug 将迁移应用到他的本地开发数据库,从而将数据库同步以反映 Tim 所做的更改。" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "And the following steps show how to deploy a new release with database migrations to production:" -msgstr "" +msgstr "以下步骤展示了如何将带有数据库迁移的新版本部署到生产环境:" #. type: Bullet: '1. ' #: ../src/guide/databases/db-migrations.md msgid "Scott creates a release tag for the project repository that contains some new database migrations." -msgstr "" +msgstr "Scott 为包含一些新数据库迁移的项目仓库创建一个发布标签。" #. type: Bullet: '2. ' #: ../src/guide/databases/db-migrations.md msgid "Scott updates the source code on the production server to the release tag." -msgstr "" +msgstr "Scott 将生产服务器上的源代码更新到该发布标签。" #. type: Bullet: '3. ' #: ../src/guide/databases/db-migrations.md msgid "Scott applies any accumulated database migrations to the production database." -msgstr "" +msgstr "Scott 将所有累积的数据库迁移应用到生产数据库。" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Yii provides a set of migration command line tools that allow you to:" -msgstr "" +msgstr "Yii 提供了一套迁移命令行工具,允许您:" #. type: Bullet: '* ' #: ../src/guide/databases/db-migrations.md msgid "create new migrations;" -msgstr "" +msgstr "创建新迁移;" #. type: Bullet: '* ' #: ../src/guide/databases/db-migrations.md msgid "apply migrations;" -msgstr "" +msgstr "应用迁移;" #. type: Bullet: '* ' #: ../src/guide/databases/db-migrations.md msgid "revert migrations;" -msgstr "" +msgstr "回滚迁移;" #. type: Bullet: '* ' #: ../src/guide/databases/db-migrations.md msgid "re-apply migrations;" -msgstr "" +msgstr "重新应用迁移;" #. type: Bullet: '* ' #: ../src/guide/databases/db-migrations.md msgid "show migration history and status." -msgstr "" +msgstr "显示迁移历史和状态。" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "All these tools are accessible through the command `yii migrate`. In this section we will describe in detail how to accomplish various tasks using these tools." -msgstr "" +msgstr "所有这些工具都可以通过命令 `yii migrate` 访问。在本节中,我们将详细描述如何使用这些工具完成各种任务。" #. type: Plain text #: ../src/guide/databases/db-migrations.md @@ -114,6 +114,9 @@ msgid "" "> Migrations could affect not only database schema but adjust existing data to fit new schema, create RBAC\n" "hierarchy or clean up cache.\n" msgstr "" +"> [!TIP]\n" +"> 迁移不仅可以影响数据库模式,还可以调整现有数据以适应新模式、创建 RBAC\n" +"层次结构或清理缓存。\n" #. type: Plain text #: ../src/guide/databases/db-migrations.md @@ -127,17 +130,23 @@ msgid "" "> may accidentally break the existing migrations. For this reason migration code should be kept independent of other\n" "> application logic such.\n" msgstr "" +"> [!NOTE]\n" +"> 在使用迁移操作数据时,您可能会发现使用 Active Record 或实体类会很有用,\n" +"> 因为其中已经实现了一些逻辑。但请记住,与迁移中编写的代码(其本质是永久不变的)不同,\n" +"> 应用程序逻辑是会发生变化的。因此,在迁移代码中使用 Active Record 或实体类时,\n" +"> 源代码中逻辑的变更可能会意外破坏现有的迁移。出于这个原因,迁移代码应保持与\n" +"> 其他应用程序逻辑相互独立。\n" #. type: Title ## #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Initial configuration" -msgstr "" +msgstr "初始配置" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "To use migrations, install [yiisoft/db-migration](https://github.com/yiisoft/db-migration/) package:" -msgstr "" +msgstr "要使用迁移,请安装 [yiisoft/db-migration](https://github.com/yiisoft/db-migration/) 包:" #. type: Fenced code block (sh) #: ../src/guide/databases/db-migrations.md ../src/guide/start/databases.md @@ -148,12 +157,12 @@ msgstr "" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Create a directory to store migrations `src/Migration` right in the project root." -msgstr "" +msgstr "在项目根目录中创建一个用于存储迁移的目录 `src/Migration`。" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Add the following configuration to `config/common/params.php`:" -msgstr "" +msgstr "将以下配置添加到 `config/common/params.php`:" #. type: Fenced code block (php) #: ../src/guide/databases/db-migrations.md ../src/guide/start/databases.md @@ -168,23 +177,23 @@ msgstr "" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "If you want to place migrations elsewhere, you can define the path in `newMigrationPath`. If your migrations to be applied are from multiple sources, such as external modules, `sourcePaths` could be used to define these." -msgstr "" +msgstr "如果您想将迁移放置在其他位置,可以在 `newMigrationPath` 中定义路径。如果您要应用的迁移来自多个来源(例如外部模块),可以使用 `sourcePaths` 来定义这些来源。" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "You need a database connection configured as well. See [Working with databases](../start/databases.md) for an example of configuring it for PostgreSQL." -msgstr "" +msgstr "您还需要配置数据库连接。有关为 PostgreSQL 配置的示例,请参阅 [使用数据库](../start/databases.md)。" #. type: Title ## #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Creating a migration" -msgstr "" +msgstr "创建迁移" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "To create a new empty migration, run the following command:" -msgstr "" +msgstr "要创建一个新的空迁移,请运行以下命令:" #. type: Fenced code block (sh) #: ../src/guide/databases/db-migrations.md @@ -197,7 +206,7 @@ msgstr "" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "The required `name` argument gives a brief description about the new migration. For example, if the migration is about creating a new table named *news*, you may use the name `create_news_table` and run the following command:" -msgstr "" +msgstr "必填的 `name` 参数对新迁移进行简短描述。例如,如果迁移是关于创建一张名为 *news* 的新表,您可以使用名称 `create_news_table` 并运行以下命令:" #. type: Fenced code block #: ../src/guide/databases/db-migrations.md @@ -215,11 +224,14 @@ msgid "" "> Because the `name` argument will be used as part of the generated migration class name,\n" "> it should only contain letters, digits, and/or underscore characters.\n" msgstr "" +"> [!NOTE]\n" +"> 由于 `name` 参数将用作生成的迁移类名的一部分,\n" +"> 因此它应该只包含字母、数字和/或下划线字符。\n" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "The above command will create a new PHP class file named `src/Migration/M251225221906CreateNewsTable.php`. The file contains the following code which mainly declares a migration class with the skeleton code:" -msgstr "" +msgstr "上述命令将创建一个名为 `src/Migration/M251225221906CreateNewsTable.php` 的新 PHP 类文件。该文件包含以下代码,主要声明了一个带有骨架代码的迁移类:" #. type: Fenced code block (php) #: ../src/guide/databases/db-migrations.md @@ -251,7 +263,7 @@ msgstr "" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "In the migration class, you are expected to write code in the `up()` method that makes changes to the database structure. You may also want to write code in the `down()` method to revert the changes made by `up()`. The `up()` method is invoked when you upgrade the database with this migration, while the `down()` method is invoked when you downgrade the database. The following code shows how you may implement the migration class to create a `news` table:" -msgstr "" +msgstr "在迁移类中,您需要在 `up()` 方法中编写对数据库结构进行更改的代码。您也可以在 `down()` 方法中编写代码来回滚 `up()` 所做的更改。当您使用此迁移升级数据库时,将调用 `up()` 方法;当您降级数据库时,将调用 `down()` 方法。以下代码展示了如何实现迁移类来创建一张 `news` 表:" #. type: Fenced code block (php) #: ../src/guide/databases/db-migrations.md @@ -289,32 +301,32 @@ msgstr "" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Migration builder `$b` in the above manages database schema while the column builder `$cb` manages column types. Both allow using *abstract types*. When a migration is applied to a particular database, the abstract types will be translated into the corresponding database physical types and corresponding SQL to define them." -msgstr "" +msgstr "上面的迁移构建器 `$b` 管理数据库模式,而列构建器 `$cb` 管理列类型。两者都支持使用*抽象类型*。当迁移应用到特定数据库时,抽象类型将被转换为相应的数据库物理类型和相应的 SQL 定义语句。" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Methods available in migration builder belong to the following types:" -msgstr "" +msgstr "迁移构建器中可用的方法属于以下类型:" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "Raw queries" -msgstr "" +msgstr "原始查询" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "getDb — to get database connection instance." -msgstr "" +msgstr "getDb — 获取数据库连接实例。" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md msgid "execute — to execute raw SQL query." -msgstr "" +msgstr "execute — 执行原始 SQL 查询。" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "Data" -msgstr "" +msgstr "数据" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md @@ -334,7 +346,7 @@ msgstr "" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "Tables and views" -msgstr "" +msgstr "表和视图" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md @@ -359,7 +371,7 @@ msgstr "" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "Columns" -msgstr "" +msgstr "列" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md @@ -374,7 +386,7 @@ msgstr "" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "Keys and indexes" -msgstr "" +msgstr "键和索引" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md @@ -394,12 +406,12 @@ msgstr "" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Additionally, there's a `columnBuilder()` which is used to obtain a column builder as in example above. The builder has static methods that define various column types:" -msgstr "" +msgstr "此外,还有一个 `columnBuilder()`,用于获取如上例所示的列构建器。该构建器具有定义各种列类型的静态方法:" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "Keys" -msgstr "" +msgstr "主键" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md @@ -424,7 +436,7 @@ msgstr "" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "Boolean" -msgstr "" +msgstr "布尔值" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md @@ -434,7 +446,7 @@ msgstr "" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "Numbers" -msgstr "" +msgstr "数字" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md @@ -500,7 +512,7 @@ msgstr "" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "Date and time" -msgstr "" +msgstr "日期和时间" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md @@ -535,7 +547,7 @@ msgstr "" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "Special types" -msgstr "" +msgstr "特殊类型" #. type: Bullet: ' - ' #: ../src/guide/databases/db-migrations.md @@ -575,7 +587,7 @@ msgstr "" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "All the above methods create a base type which could be adjusted with additional methods:" -msgstr "" +msgstr "以上所有方法都会创建一个基础类型,可通过以下附加方法进行调整:" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md @@ -631,28 +643,28 @@ msgstr "" #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Irreversible migrations" -msgstr "" +msgstr "不可逆迁移" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Not all migrations are reversible. For example, if the `up()` method deletes a row of a table, you may not be able to recover this row in the `down()` method. Sometimes, you may be just too lazy to implement the `down()`, because it is not very common to revert database migrations. In this case, you should implement `Yiisoft\\Db\\Migration\\MigrationInterface` that has `up()` only." -msgstr "" +msgstr "并非所有迁移都是可逆的。例如,如果 `up()` 方法删除了一行数据,您可能无法在 `down()` 方法中恢复该行。有时,您可能懒得实现 `down()`,因为回滚数据库迁移并不常见。在这种情况下,您应该实现只有 `up()` 的 `Yiisoft\\Db\\Migration\\MigrationInterface`。" #. type: Title ### #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Transactional migrations" -msgstr "" +msgstr "事务性迁移" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "While performing complex DB migrations, it is important to ensure each migration to either succeed or fail as a whole so that the database can maintain integrity and consistency. To achieve this goal, it is recommended that you may enclose the DB operations of each migration in a transaction automatically by adding `TransactionalMigrationInterface` to `implements` of your migration." -msgstr "" +msgstr "在执行复杂的数据库迁移时,确保每个迁移作为一个整体要么全部成功要么全部失败非常重要,这样数据库才能保持完整性和一致性。为了实现这个目标,建议在迁移的 `implements` 中添加 `TransactionalMigrationInterface`,从而自动将每个迁移的数据库操作封装在事务中。" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "As a result, if any operation in the `up()` or `down()` method fails, all prior operations will be rolled back automatically." -msgstr "" +msgstr "因此,如果 `up()` 或 `down()` 方法中的任何操作失败,所有之前的操作将自动回滚。" #. type: Plain text #: ../src/guide/databases/db-migrations.md @@ -661,17 +673,19 @@ msgid "" "> Note: Not all DBMS support transactions. And some DB queries cannot be put into a transaction. For some examples,\n" "please refer to [implicit commit](https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html).\n" msgstr "" +"> 注意:并非所有数据库管理系统都支持事务。而且某些数据库查询无法放入事务中。有关一些示例,\n" +"请参阅 [隐式提交](https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html)。\n" #. type: Title ## #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Generating a migration" -msgstr "" +msgstr "生成迁移" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Instead of writing migrations by hand, the command provides a convenient way generate some of the code." -msgstr "" +msgstr "该命令提供了一种方便的方式来生成部分代码,而不必手动编写迁移。" #. type: Fenced code block (shell) #: ../src/guide/databases/db-migrations.md @@ -684,7 +698,7 @@ msgstr "" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "That would generate the following:" -msgstr "" +msgstr "这将生成以下内容:" #. type: Fenced code block (php) #: ../src/guide/databases/db-migrations.md @@ -728,48 +742,48 @@ msgstr "" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Commands available are:" -msgstr "" +msgstr "可用的命令有:" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "create - empty migration." -msgstr "" +msgstr "create — 空迁移。" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "table - creating a table. Use `--fields` specify a list of fields to use. Types could be specified as well such as `id:primaryKey,name:string:defaultValue(\"Alex\"),user_id:integer:foreignKey,category_id2:integer:foreignKey(category id2)`." -msgstr "" +msgstr "table — 创建一张表。使用 `--fields` 指定字段列表。也可以指定类型,例如 `id:primaryKey,name:string:defaultValue(\"Alex\"),user_id:integer:foreignKey,category_id2:integer:foreignKey(category id2)`。" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "dropTable - dropping a table." -msgstr "" +msgstr "dropTable — 删除一张表。" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "addColumn - adding a column." -msgstr "" +msgstr "addColumn — 添加一列。" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "dropColumn - dropping a column." -msgstr "" +msgstr "dropColumn — 删除一列。" #. type: Bullet: '- ' #: ../src/guide/databases/db-migrations.md msgid "junction - creating a junction table. Use `--and` specify a second table." -msgstr "" +msgstr "junction — 创建关联表。使用 `--and` 指定第二张表。" #. type: Title ## #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Applying Migrations" -msgstr "" +msgstr "应用迁移" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "To upgrade a database to its latest structure, you should apply all available new migrations using the following command:" -msgstr "" +msgstr "要将数据库升级到最新结构,应使用以下命令应用所有可用的新迁移:" #. type: Fenced code block #: ../src/guide/databases/db-migrations.md @@ -780,17 +794,17 @@ msgstr "" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "This command will list all migrations that have not been applied so far. If you confirm that you want to apply these migrations, it will run the `up()` method in every new migration class, one after another, in the order of their timestamp values. If any of the migrations fails, the command will quit without applying the rest of the migrations." -msgstr "" +msgstr "此命令将列出迄今为止尚未应用的所有迁移。如果您确认要应用这些迁移,它将按时间戳顺序依次运行每个新迁移类的 `up()` 方法。如果任何迁移失败,该命令将退出,而不会应用其余的迁移。" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "For each migration that has been successfully applied, the command will insert a row into a database table named `migration` to record the successful application of the migration. This will allow the migration tool to identify which migrations have been applied and which have not." -msgstr "" +msgstr "对于每个成功应用的迁移,该命令将在名为 `migration` 的数据库表中插入一行,以记录迁移的成功应用。这将允许迁移工具识别哪些迁移已经应用,哪些还没有。" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Sometimes, you may only want to apply one or a few new migrations, instead of all available migrations. You can do so by specifying the number of migrations that you want to apply when running the command. For example, the following command will try to apply the next three available migrations:" -msgstr "" +msgstr "有时,您可能只想应用一个或几个新迁移,而不是所有可用的迁移。您可以在运行命令时指定要应用的迁移数量来实现此目的。例如,以下命令将尝试应用接下来的三个可用迁移:" #. type: Fenced code block #: ../src/guide/databases/db-migrations.md @@ -802,12 +816,12 @@ msgstr "" #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Reverting Migrations " -msgstr "" +msgstr "回滚迁移 " #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "To revert (undo) one or multiple migrations that have been applied before, you can run the following command:" -msgstr "" +msgstr "要回滚(撤销)之前已应用的一个或多个迁移,可以运行以下命令:" #. type: Fenced code block #: ../src/guide/databases/db-migrations.md @@ -825,17 +839,19 @@ msgid "" "> Note: Not all migrations are reversible. Trying to revert such migrations will cause an error and stop the\n" "entire reverting process.\n" msgstr "" +"> 注意:并非所有迁移都是可逆的。尝试回滚此类迁移将导致错误并停止\n" +"整个回滚过程。\n" #. type: Title ## #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Redoing Migrations " -msgstr "" +msgstr "重做迁移 " #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Redoing migrations means first reverting the specified migrations and then applying again. This can be done as follows:" -msgstr "" +msgstr "重做迁移是指先回滚指定的迁移,然后再重新应用。可以按如下方式操作:" #. type: Fenced code block #: ../src/guide/databases/db-migrations.md @@ -850,18 +866,18 @@ msgstr "" #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "> Note: If a migration is not reversible, you will not be able to redo it.\n" -msgstr "" +msgstr "> 注意:如果迁移不可逆,您将无法重做它。\n" #. type: Title ## #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Listing Migrations " -msgstr "" +msgstr "列出迁移 " #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "To list which migrations have been applied and which are not, you may use the following commands:" -msgstr "" +msgstr "要列出哪些迁移已应用、哪些未应用,可以使用以下命令:" #. type: Fenced code block #: ../src/guide/databases/db-migrations.md @@ -880,14 +896,14 @@ msgstr "" #: ../src/guide/databases/db-migrations.md #, no-wrap msgid "Upgrading from Yii 2.0" -msgstr "" +msgstr "从 Yii 2.0 升级" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "Migrations in Yii 2.0 and the [yiisoft/db-migration](https://github.com/yiisoft/db-migration/) package are not compatible, and the `migration` table is also not compatible." -msgstr "" +msgstr "Yii 2.0 中的迁移与 [yiisoft/db-migration](https://github.com/yiisoft/db-migration/) 包不兼容,`migration` 表也不兼容。" #. type: Plain text #: ../src/guide/databases/db-migrations.md msgid "A probable solution is to use structure dumps and rename the old `migration` table. Upon the initial execution of migrations, a new `migration` table with new fields will be created. All further changes in the database schema are applied using the new `migration` component and recorded in the new migration table." -msgstr "" +msgstr "一个可行的解决方案是使用结构转储并重命名旧的 `migration` 表。在初次执行迁移时,将创建一个具有新字段的新 `migration` 表。此后数据库模式的所有变更都使用新的 `migration` 组件应用,并记录在新的迁移表中。" diff --git a/_translations/po/zh-CN/guide_glossary.md.po b/_translations/po/zh-CN/guide_glossary.md.po index cc1f6b6b..31a6788a 100644 --- a/_translations/po/zh-CN/guide_glossary.md.po +++ b/_translations/po/zh-CN/guide_glossary.md.po @@ -30,7 +30,7 @@ msgstr "" #. type: Plain text #: ../src/guide/glossary.md msgid "Alias is a string used by Yii to refer to the class or directory such as `@app/vendor`. Read more in [\"Aliases\"](concept/aliases.md)." -msgstr "" +msgstr "别名是 Yii 用于引用类或目录的字符串,例如 `@app/vendor`。详见[“别名”](concept/aliases.md)。" #. type: Title ## #: ../src/guide/glossary.md @@ -41,7 +41,7 @@ msgstr "" #. type: Plain text #: ../src/guide/glossary.md msgid "Asset refers to a resource file. Typically, it contains JavaScript or CSS code but can be any static content accessed via HTTP. Read more in [\"Assets\"](views/asset.md)." -msgstr "" +msgstr "资源是指资源文件。通常包含 JavaScript 或 CSS 代码,但也可以是任何通过 HTTP 访问的静态内容。详见[“资源”](views/asset.md)。" #. type: Title # #: ../src/guide/glossary.md @@ -58,7 +58,7 @@ msgstr "" #. type: Plain text #: ../src/guide/glossary.md msgid "The Configuration may refer either to the process of setting properties of an object or to a configuration file that stores settings for an object, or a class of objects. Read more in [\"Configuration\"](concept/configuration.md)." -msgstr "" +msgstr "配置既可以指设置对象属性的过程,也可以指存储对象或一类对象设置的配置文件。详见[“配置”](concept/configuration.md)。" #. type: Title # #: ../src/guide/glossary.md @@ -75,7 +75,7 @@ msgstr "" #. type: Plain text #: ../src/guide/glossary.md msgid "Dependency Injection is a programming technique where an object injects a dependent object. Read more in [\"Dependency injection and container\"](concept/di-container.md)." -msgstr "" +msgstr "依赖注入是一种编程技术,通过该技术将依赖对象注入到另一个对象中。详见[“依赖注入与容器”](concept/di-container.md)。" #. type: Title # #: ../src/guide/glossary.md @@ -92,7 +92,7 @@ msgstr "" #. type: Plain text #: ../src/guide/glossary.md msgid "Installation is a process of preparing something to work either by following a readme file or by executing a specially prepared script. In the case of Yii, it's setting permissions and fulfilling software requirements." -msgstr "" +msgstr "安装是按照 readme 文件或执行专门准备的脚本来使软件正常运行的过程。对于 Yii 而言,主要是设置权限和满足软件依赖要求。" #. type: Title # #: ../src/guide/glossary.md @@ -109,7 +109,7 @@ msgstr "" #. type: Plain text #: ../src/guide/glossary.md msgid "Middleware is a processor in the request processing stack. Given a request, it may either produce a response or do some action and pass processing to the next middleware. Read more in [\"Middleware\"](structure/middleware.md)." -msgstr "" +msgstr "中间件是请求处理栈中的一个处理器。对于给定的请求,它既可以直接生成响应,也可以执行某些操作后将处理传递给下一个中间件。详见[“中间件”](structure/middleware.md)。" #. type: Title ## #: ../src/guide/glossary.md @@ -120,7 +120,7 @@ msgstr "" #. type: Plain text #: ../src/guide/glossary.md msgid "The module is a namespace that groups some code based on a use-case. It's typically used within the main application and may contain any source code, define additional URL handlers or console commands." -msgstr "" +msgstr "模块是根据使用场景对代码进行分组的命名空间。它通常在主应用程序中使用,可以包含任意源代码、定义额外的 URL 处理器或控制台命令。" #. type: Title # #: ../src/guide/glossary.md @@ -137,7 +137,7 @@ msgstr "" #. type: Plain text #: ../src/guide/glossary.md msgid "Namespace refers to a [PHP language feature](https://www.php.net/manual/en/language.namespaces.php) to group multiple classes under a certain name." -msgstr "" +msgstr "命名空间是指一种 [PHP 语言特性](https://www.php.net/manual/en/language.namespaces.php),用于将多个类归组到某个特定名称下。" #. type: Title # #: ../src/guide/glossary.md @@ -154,7 +154,7 @@ msgstr "" #. type: Plain text #: ../src/guide/glossary.md msgid "A package usually refers to [Composer package](https://getcomposer.org/doc/). It's code ready for reuse and redistribution installable automatically via package manager." -msgstr "" +msgstr "包通常指 [Composer 包](https://getcomposer.org/doc/),是可通过包管理器自动安装的、已准备好复用和再分发的代码。" #. type: Title # #: ../src/guide/glossary.md @@ -171,7 +171,7 @@ msgstr "" #. type: Plain text #: ../src/guide/glossary.md msgid "The rule usually refers to a validation rule of the [yiisoft/validator](https://github.com/yiisoft/validator) package. It holds a set of parameters for checking if a data set is valid. \"Rule handler\" does the actual processing." -msgstr "" +msgstr "规则通常指 [yiisoft/validator](https://github.com/yiisoft/validator) 包的验证规则。它持有一组用于检查数据集是否有效的参数。“规则处理器”负责实际执行处理。" #. type: Title # #: ../src/guide/glossary.md @@ -188,7 +188,7 @@ msgstr "" #. type: Plain text #: ../src/guide/glossary.md msgid "A queue is similar to a stack. Queue follows First-In-First-Out methodology. Yii has a [yiisoft/queue](https://github.com/yiisoft/queue) package." -msgstr "" +msgstr "队列类似于栈,遵循先进先出(FIFO)原则。Yii 提供了 [yiisoft/queue](https://github.com/yiisoft/queue) 包。" #. type: Title # #: ../src/guide/glossary.md @@ -205,4 +205,4 @@ msgstr "" #. type: Plain text #: ../src/guide/glossary.md msgid "A Vendor is an organization or individual developer providing code in the form of packages. It also may refer to [Composer's `vendor` directory](https://getcomposer.org/doc/)." -msgstr "" +msgstr "Vendor 是指以包的形式提供代码的组织或个人开发者。也可以指 [Composer 的 `vendor` 目录](https://getcomposer.org/doc/)。" diff --git a/_translations/po/zh-CN/guide_index.md.po b/_translations/po/zh-CN/guide_index.md.po index e7157917..36f04e97 100644 --- a/_translations/po/zh-CN/guide_index.md.po +++ b/_translations/po/zh-CN/guide_index.md.po @@ -19,576 +19,576 @@ msgstr "" #: ../src/guide/caching/overview.md ../src/guide/index.md #, no-wrap msgid "Caching" -msgstr "" +msgstr "缓存" #. type: Title # #: ../src/guide/index.md #, no-wrap msgid "The definitive guide to Yii3" -msgstr "" +msgstr "Yii3 权威指南" #. type: Plain text #: ../src/guide/index.md msgid "We release this guide under the [Terms of Yii Documentation](https://www.yiiframework.com/license#docs)." -msgstr "" +msgstr "本指南遵循 [Yii 文档条款](https://www.yiiframework.com/license#docs) 发布。" #. type: Title ## #: ../src/guide/index.md #, no-wrap msgid "Introduction" -msgstr "" +msgstr "介绍" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[About Yii](intro/what-is-yii.md)" -msgstr "" +msgstr "[关于 Yii](intro/what-is-yii.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Upgrading from version 2.0](intro/upgrade-from-v2.md)" -msgstr "" +msgstr "[从 2.0 版本升级](intro/upgrade-from-v2.md)" #. type: Title ## #: ../src/guide/index.md #, no-wrap msgid "Getting started" -msgstr "" +msgstr "入门" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[What do you need to know?](start/prerequisites.md)" -msgstr "" +msgstr "[你需要了解什么?](start/prerequisites.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Creating a project](start/creating-project.md)" -msgstr "" +msgstr "[创建项目](start/creating-project.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Running applications](start/workflow.md)" -msgstr "" +msgstr "[运行应用](start/workflow.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Saying hello](start/hello.md)" -msgstr "" +msgstr "[说 Hello](start/hello.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Working with forms](start/forms.md)" -msgstr "" +msgstr "[使用表单](start/forms.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Working with databases](start/databases.md)" -msgstr "" +msgstr "[使用数据库](start/databases.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Generating code with Gii](start/gii.md) TODO" -msgstr "" +msgstr "[使用 Gii 生成代码](start/gii.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Looking ahead](start/looking-ahead.md)" -msgstr "" +msgstr "[展望未来](start/looking-ahead.md)" #. type: Title ### #: ../src/guide/index.md ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Application structure" -msgstr "" +msgstr "应用结构" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Application structure overview](structure/overview.md)" -msgstr "" +msgstr "[应用结构概述](structure/overview.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Entry scripts](structure/entry-script.md)" -msgstr "" +msgstr "[入口脚本](structure/entry-script.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Application](structure/application.md)" -msgstr "" +msgstr "[应用](structure/application.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Service components](structure/service.md)" -msgstr "" +msgstr "[服务组件](structure/service.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Actions](structure/action.md)" -msgstr "" +msgstr "[动作](structure/action.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Domain](structure/domain.md)" -msgstr "" +msgstr "[领域](structure/domain.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Middleware](structure/middleware.md)" -msgstr "" +msgstr "[中间件](structure/middleware.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Packages](structure/package.md)" -msgstr "" +msgstr "[包](structure/package.md)" #. type: Title ## #: ../src/guide/index.md #, no-wrap msgid "Key concepts" -msgstr "" +msgstr "核心概念" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Class autoloading](concept/autoloading.md)" -msgstr "" +msgstr "[类自动加载](concept/autoloading.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Dependency injection container](concept/di-container.md)" -msgstr "" +msgstr "[依赖注入容器](concept/di-container.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Configuration](concept/configuration.md)" -msgstr "" +msgstr "[配置](concept/configuration.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Aliases](concept/aliases.md)" -msgstr "" +msgstr "[别名](concept/aliases.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Events](concept/events.md)" -msgstr "" +msgstr "[事件](concept/events.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Immutability](concept/immutability.md)" -msgstr "" +msgstr "[不可变性](concept/immutability.md)" #. type: Title ## #: ../src/guide/index.md #, no-wrap msgid "Handling requests" -msgstr "" +msgstr "处理请求" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Routing and URL generation](runtime/routing.md)" -msgstr "" +msgstr "[路由和 URL 生成](runtime/routing.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Request](runtime/request.md)" -msgstr "" +msgstr "[请求](runtime/request.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Response](runtime/response.md)" -msgstr "" +msgstr "[响应](runtime/response.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Sessions](runtime/sessions.md)" -msgstr "" +msgstr "[会话](runtime/sessions.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Cookies](runtime/cookies.md)" -msgstr "" +msgstr "[Cookies](runtime/cookies.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Handling errors](runtime/handling-errors.md)" -msgstr "" +msgstr "[错误处理](runtime/handling-errors.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Logging](runtime/logging.md)" -msgstr "" +msgstr "[日志](runtime/logging.md)" #. type: Title # #: ../src/guide/index.md ../src/guide/views/view.md #, no-wrap msgid "Views" -msgstr "" +msgstr "视图" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[View](views/view.md)" -msgstr "" +msgstr "[视图](views/view.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Template engines](views/template-engines.md) TODO: verify!" -msgstr "" +msgstr "[模板引擎](views/template-engines.md) TODO: verify!" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[View injections](views/view-injections.md)" -msgstr "" +msgstr "[视图注入](views/view-injections.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Scripts, styles and metatags](views/script-style-meta.md) TODO: verify!" -msgstr "" +msgstr "[脚本、样式和元标签](views/script-style-meta.md) TODO: verify!" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Assets](views/asset.md) TODO: verify!" -msgstr "" +msgstr "[资源](views/asset.md) TODO: verify!" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Widgets](views/widget.md) TODO: verify!" -msgstr "" +msgstr "[小部件](views/widget.md) TODO: verify!" #. type: Title # #: ../src/guide/index.md ../src/guide/start/databases.md #, no-wrap msgid "Working with databases" -msgstr "" +msgstr "使用数据库" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Yii DB](https://github.com/yiisoft/db/blob/master/docs/guide/en/README.md)" -msgstr "" +msgstr "[Yii DB](https://github.com/yiisoft/db/blob/master/docs/guide/en/README.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Active Record](https://github.com/yiisoft/active-record/blob/master/README.md)" -msgstr "" +msgstr "[Active Record](https://github.com/yiisoft/active-record/blob/master/README.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Migrations](databases/db-migrations.md) TODO: verify/update!" -msgstr "" +msgstr "[迁移](databases/db-migrations.md) TODO: verify/update!" #. type: Title ## #: ../src/guide/index.md #, no-wrap msgid "Getting data from users" -msgstr "" +msgstr "从用户获取数据" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Creating forms](input/forms.md) TODO" -msgstr "" +msgstr "[创建表单](input/forms.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Validating input](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md)" -msgstr "" +msgstr "[验证输入](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Uploading files](input/file-upload.md) TODO" -msgstr "" +msgstr "[上传文件](input/file-upload.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Collecting tabular input](input/tabular-input.md) TODO" -msgstr "" +msgstr "[收集表格输入](input/tabular-input.md) TODO" #. type: Title ## #: ../src/guide/index.md #, no-wrap msgid "Displaying data" -msgstr "" +msgstr "显示数据" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Data formatting](output/formatting.md) TODO" -msgstr "" +msgstr "[数据格式化](output/formatting.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Pagination](output/pagination.md) TODO" -msgstr "" +msgstr "[分页](output/pagination.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Sorting](output/sorting.md) TODO" -msgstr "" +msgstr "[排序](output/sorting.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Data providers](output/data-providers.md) TODO" -msgstr "" +msgstr "[数据提供者](output/data-providers.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Data widgets](output/data-widgets.md) TODO" -msgstr "" +msgstr "[数据小部件](output/data-widgets.md) TODO" #. type: Title # #: ../src/guide/index.md ../src/guide/security/overview.md #, no-wrap msgid "Security" -msgstr "" +msgstr "安全" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Security overview](security/overview.md)" -msgstr "" +msgstr "[安全概述](security/overview.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Authentication](security/authentication.md)" -msgstr "" +msgstr "[认证](security/authentication.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Authorization](security/authorization.md) TODO: verify and complete!" -msgstr "" +msgstr "[授权](security/authorization.md) TODO: verify and complete!" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Working with passwords](security/passwords.md)" -msgstr "" +msgstr "[使用 passwords](security/passwords.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Cryptography](security/cryptography.md)" -msgstr "" +msgstr "[加密](security/cryptography.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Best practices](security/best-practices.md)" -msgstr "" +msgstr "[最佳实践](security/best-practices.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Caching overview](caching/overview.md)" -msgstr "" +msgstr "[缓存概述](caching/overview.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Data caching](caching/data.md)" -msgstr "" +msgstr "[数据缓存](caching/data.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Fragment caching](caching/fragment.md) TODO" -msgstr "" +msgstr "[片段缓存](caching/fragment.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Page caching](caching/page.md) TODO" -msgstr "" +msgstr "[页面缓存](caching/page.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[HTTP caching](caching/http.md) TODO" -msgstr "" +msgstr "[HTTP 缓存](caching/http.md) TODO" #. type: Title ## #: ../src/guide/index.md #, no-wrap msgid "REST APIs" -msgstr "" +msgstr "REST APIs" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Quick start](rest/quick-start.md) TODO" -msgstr "" +msgstr "[快速开始](rest/quick-start.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Resources](rest/resources.md) TODO" -msgstr "" +msgstr "[资源](rest/resources.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Controllers](rest/controllers.md) TODO" -msgstr "" +msgstr "[控制器](rest/controllers.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Routing](rest/routing.md) TODO" -msgstr "" +msgstr "[路由](rest/routing.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Authentication](rest/authentication.md) TODO" -msgstr "" +msgstr "[认证](rest/authentication.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Rate limiting](rest/rate-limiting.md) TODO" -msgstr "" +msgstr "[速率限制](rest/rate-limiting.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Versioning](rest/versioning.md) TODO" -msgstr "" +msgstr "[版本控制](rest/versioning.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Error handling](rest/error-handling.md) TODO" -msgstr "" +msgstr "[错误处理](rest/error-handling.md) TODO" #. type: Title ## #: ../src/guide/index.md #, no-wrap msgid "Development tools" -msgstr "" +msgstr "开发工具" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "Debug toolbar and debugger" -msgstr "" +msgstr "调试工具栏和调试器" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "Generating code using Gii" -msgstr "" +msgstr "使用 Gii 生成代码" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "Generating API documentation" -msgstr "" +msgstr "生成 API 文档" #. type: Title ## #: ../src/guide/index.md #, no-wrap msgid "Testing" -msgstr "" +msgstr "测试" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Testing overview](testing/overview.md) TODO" -msgstr "" +msgstr "[测试概述](testing/overview.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Testing environment setup](testing/environment-setup.md) TODO" -msgstr "" +msgstr "[测试环境设置](testing/environment-setup.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Unit tests](testing/unit.md) TODO" -msgstr "" +msgstr "[单元测试](testing/unit.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Functional tests](testing/functional.md) TODO" -msgstr "" +msgstr "[功能测试](testing/functional.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Acceptance tests](testing/acceptance.md) TODO" -msgstr "" +msgstr "[验收测试](testing/acceptance.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Fixtures](testing/fixtures.md) TODO" -msgstr "" +msgstr "[固件](testing/fixtures.md) TODO" #. type: Title ## #: ../src/guide/index.md #, no-wrap msgid "Special topics" -msgstr "" +msgstr "特殊主题" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Console applications](tutorial/console-applications.md)" -msgstr "" +msgstr "[控制台应用](tutorial/console-applications.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Internationalization](tutorial/i18n.md) TODO" -msgstr "" +msgstr "[国际化](tutorial/i18n.md) TODO" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Mailing](tutorial/mailing.md)" -msgstr "" +msgstr "[邮件](tutorial/mailing.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Performance tuning](tutorial/performance-tuning.md)" -msgstr "" +msgstr "[性能调优](tutorial/performance-tuning.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Using Yii with event loop](tutorial/using-with-event-loop.md)" -msgstr "" +msgstr "[在事件循环中使用 Yii](tutorial/using-with-event-loop.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Using Yii with RoadRunner](tutorial/using-yii-with-roadrunner.md)" -msgstr "" +msgstr "[在 RoadRunner 中使用 Yii](tutorial/using-yii-with-roadrunner.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Using Yii with Swoole](tutorial/using-yii-with-swoole.md)" -msgstr "" +msgstr "[在 Swoole 中使用 Yii](tutorial/using-yii-with-swoole.md)" #. type: Title ## #: ../src/guide/index.md #, no-wrap msgid "Helpers" -msgstr "" +msgstr "助手类" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Arrays](https://github.com/yiisoft/arrays/)" -msgstr "" +msgstr "[数组](https://github.com/yiisoft/arrays/)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Files](https://github.com/yiisoft/files/)" -msgstr "" +msgstr "[文件](https://github.com/yiisoft/files/)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Html](https://github.com/yiisoft/html/)" -msgstr "" +msgstr "[Html](https://github.com/yiisoft/html/)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Json](https://github.com/yiisoft/json)" -msgstr "" +msgstr "[Json](https://github.com/yiisoft/json)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Network utilities](https://github.com/yiisoft/network-utilities/)" -msgstr "" +msgstr "[网络工具](https://github.com/yiisoft/network-utilities/)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[VarDumper](https://github.com/yiisoft/var-dumper)" -msgstr "" +msgstr "[VarDumper](https://github.com/yiisoft/var-dumper)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Strings](https://github.com/yiisoft/strings)" -msgstr "" +msgstr "[字符串](https://github.com/yiisoft/strings)" #. type: Title ## #: ../src/guide/index.md #, no-wrap msgid "Extras" -msgstr "" +msgstr "额外内容" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Cookbook](../cookbook/index.md)" -msgstr "" +msgstr "[实用手册](../cookbook/index.md)" #. type: Bullet: '- ' #: ../src/guide/index.md msgid "[Glossary](glossary.md)" -msgstr "" +msgstr "[术语表](glossary.md)" diff --git a/_translations/po/zh-CN/guide_intro_upgrade-from-v2.md.po b/_translations/po/zh-CN/guide_intro_upgrade-from-v2.md.po index 68b76911..79b6abe2 100644 --- a/_translations/po/zh-CN/guide_intro_upgrade-from-v2.md.po +++ b/_translations/po/zh-CN/guide_intro_upgrade-from-v2.md.po @@ -19,13 +19,13 @@ msgstr "" #: ../src/guide/index.md ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Application structure" -msgstr "" +msgstr "应用结构" #. type: Title # #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Upgrading from Version 2.0" -msgstr "" +msgstr "从 2.0 版本升级" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md @@ -34,99 +34,101 @@ msgid "" "> If you haven't used Yii 2.0, you can skip this section and get directly to \"[getting started](../start/prerequisites.md)\"\n" "> section.\n" msgstr "" +"> 如果您未曾使用过 Yii 2.0,可以跳过本节,直接阅读“[入门](../start/prerequisites.md)”\n" +"> 章节。\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "While sharing some common ideas and values, Yii3 is conceptually different from Yii 2.0. There is no easy upgrade path, so first [check maintenance policy and end-of-life dates for Yii 2.0](https://www.yiiframework.com/release-cycle) and consider starting new projects on Yii3 while keeping existing ones on Yii 2.0." -msgstr "" +msgstr "尽管 Yii3 与 Yii 2.0 有一些共同的理念和价值观,但两者在概念上存在显著差异。升级并无捷径,建议先[查看 Yii 2.0 的维护策略和生命周期终止日期](https://www.yiiframework.com/release-cycle),并考虑将新项目迁移到 Yii3,同时保持现有项目继续使用 Yii 2.0。" #. type: Title ## #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "PHP requirements" -msgstr "" +msgstr "PHP 要求" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii3 requires PHP 8.2 or above. As a result, there are language features used that weren't used in Yii 2.0:" -msgstr "" +msgstr "Yii3 要求 PHP 8.2 或更高版本。因此,它使用了 Yii 2.0 中未使用的语言特性:" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Type declarations](https://www.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration)" -msgstr "" +msgstr "[类型声明](https://www.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Return type declarations](https://www.php.net/manual/en/functions.returning-values.php#functions.returning-values.type-declaration)" -msgstr "" +msgstr "[返回类型声明](https://www.php.net/manual/en/functions.returning-values.php#functions.returning-values.type-declaration)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Class constant visibility](https://www.php.net/manual/en/language.oop5.constants.php)" -msgstr "" +msgstr "[类常量可见性](https://www.php.net/manual/en/language.oop5.constants.php)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Named arguments](https://www.php.net/manual/en/functions.arguments.php#functions.named-arguments)" -msgstr "" +msgstr "[命名参数](https://www.php.net/manual/en/functions.arguments.php#functions.named-arguments)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Anonymous classes](https://www.php.net/manual/en/language.oop5.anonymous.php)" -msgstr "" +msgstr "[匿名类](https://www.php.net/manual/en/language.oop5.anonymous.php)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[::class](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.class)" -msgstr "" +msgstr "[::class](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.class)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Generators](https://www.php.net/manual/en/language.generators.php)" -msgstr "" +msgstr "[生成器](https://www.php.net/manual/en/language.generators.php)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Variadic functions](https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list)" -msgstr "" +msgstr "[可变参数函数](https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Readonly properties](https://www.php.net/manual/en/language.oop5.properties.php#language.oop5.properties.readonly-properties)" -msgstr "" +msgstr "[只读属性](https://www.php.net/manual/en/language.oop5.properties.php#language.oop5.properties.readonly-properties)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Readonly classes](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.readonly)" -msgstr "" +msgstr "[只读类](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.readonly)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Constructor property promotion](https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.constructor.promotion)" -msgstr "" +msgstr "[构造函数属性提升](https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.constructor.promotion)" #. type: Bullet: '- ' #: ../src/guide/intro/upgrade-from-v2.md msgid "[Attributes](https://www.php.net/manual/en/language.attributes.php)" -msgstr "" +msgstr "[注解](https://www.php.net/manual/en/language.attributes.php)" #. type: Title ## #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Preliminary refactoring" -msgstr "" +msgstr "预备重构" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "It's a good idea to refactor your Yii 2.0 project before porting it to Yii3. That would both make porting easier and benefit the project in question while it's not moved to Yii3 yet." -msgstr "" +msgstr "在将 Yii 2.0 项目迁移到 Yii3 之前,先进行重构是个好主意。这既能简化迁移过程,也能在项目尚未切换到 Yii3 时直接受益。" #. type: Title ### #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Use DI instead of the service locator" -msgstr "" +msgstr "使用 DI 替代服务定位器" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md @@ -135,6 +137,8 @@ msgid "" "Since Yii3 is forcing you to inject dependencies, it's a good idea to prepare and switch from using\n" "service locator (`Yii::$app->`) to [DI container](https://www.yiiframework.com/doc/guide/2.0/en/concept-di-container).\n" msgstr "" +"由于 Yii3 强制要求注入依赖,建议提前做好准备,将\n" +"服务定位器(`Yii::$app->`)切换为 [DI 容器](https://www.yiiframework.com/doc/guide/2.0/en/concept-di-container)。\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md @@ -143,22 +147,24 @@ msgid "" "If usage of DI container is problematic for whatever reason, consider moving all calls to `Yii::$app->` to controller\n" "actions and widgets and passing dependencies manually from a controller to what needs them.\n" msgstr "" +"如果因某种原因使用 DI 容器存在困难,可以考虑将所有 `Yii::$app->` 调用迁移到控制器\n" +"动作和小部件中,并从控制器手动将依赖传递给需要它的对象。\n" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "See [Dependency injection and container](../concept/di-container.md) for an explanation of the idea." -msgstr "" +msgstr "有关该理念的说明,请参阅[依赖注入与容器](../concept/di-container.md)。" #. type: Title ### #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Introduce repositories for getting data" -msgstr "" +msgstr "引入仓储层获取数据" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Since Active Record isn't the only way to work with a database in Yii3, consider introducing repositories that would hide details of getting data and gather them in a single place. You can later redo it:" -msgstr "" +msgstr "由于 Active Record 并非 Yii3 中操作数据库的唯一方式,建议引入仓储层来隐藏数据获取的实现细节,并将其集中管理。后续可以随时对其进行重构:" #. type: Fenced code block (php) #: ../src/guide/intro/upgrade-from-v2.md @@ -183,84 +189,84 @@ msgstr "" #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Separate domain layer from infrastructure" -msgstr "" +msgstr "将领域层与基础设施层分离" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "In case you have a rich complicated domain, it's a good idea to separate it from infrastructure provided by a framework that's all the business logic has to go to framework-independent classes." -msgstr "" +msgstr "如果您的应用拥有复杂的领域逻辑,建议将其与框架提供的基础设施层分离,即所有业务逻辑应放入与框架无关的类中。" #. type: Title ### #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Move more into components" -msgstr "" +msgstr "将更多逻辑移入组件" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii3 services are conceptually similar to Yii 2.0 components, so it's a good idea to move reusable parts of your application into components." -msgstr "" +msgstr "Yii3 的服务在概念上与 Yii 2.0 的组件类似,因此建议将应用程序中可复用的部分移入组件。" #. type: Title ## #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Things to learn" -msgstr "" +msgstr "需要学习的内容" #. type: Title ## #: ../src/guide/intro/upgrade-from-v2.md ../src/guide/start/prerequisites.md #, no-wrap msgid "Docker" -msgstr "" +msgstr "Docker" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Default application templates are using [Docker](https://www.docker.com/get-started/) to run application. It's a good idea to learn how to use it and use it for your own projects since it provides a lot of benefits:" -msgstr "" +msgstr "默认应用程序模板使用 [Docker](https://www.docker.com/get-started/) 来运行应用程序。建议学习并在自己的项目中使用 Docker,因为它提供了许多好处:" #. type: Bullet: '1. ' #: ../src/guide/intro/upgrade-from-v2.md msgid "Exactly the same environment as in production." -msgstr "" +msgstr "与生产环境完全相同的运行环境。" #. type: Bullet: '2. ' #: ../src/guide/intro/upgrade-from-v2.md msgid "No need to install anything except Docker itself." -msgstr "" +msgstr "除 Docker 本身外,无需安装任何其他软件。" #. type: Bullet: '3. ' #: ../src/guide/intro/upgrade-from-v2.md msgid "Environment is per application, not per server." -msgstr "" +msgstr "环境按应用程序隔离,而非按服务器共享。" #. type: Title ### #: ../src/guide/intro/upgrade-from-v2.md #, no-wrap msgid "Environment variables" -msgstr "" +msgstr "环境变量" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Yii3 application templates are using [environment variables](https://en.wikipedia.org/wiki/Environment_variable) to configure parts of the application. The concept is [very handy for Dockerized applications](https://12factor.net/) but might be alien to users of Yii 1.1 and Yii 2.0." -msgstr "" +msgstr "Yii3 应用程序模板使用 [环境变量](https://en.wikipedia.org/wiki/Environment_variable) 来配置应用程序的各个部分。这一概念对于[容器化应用程序非常实用](https://12factor.net/),但对于 Yii 1.1 和 Yii 2.0 的用户来说可能较为陌生。" #. type: Title # #: ../src/guide/intro/upgrade-from-v2.md ../src/guide/structure/action.md #, no-wrap msgid "Actions" -msgstr "" +msgstr "动作" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Unlike Yii 2.0, Yii3 does not require controllers. Instead, it uses [actions](../structure/action.md), which are any callables. You can organize these into controllers similar to Yii 2, but it's not required." -msgstr "" +msgstr "与 Yii 2.0 不同,Yii3 不要求使用控制器。它改为使用 [动作](../structure/action.md),动作可以是任意可调用对象。您可以像 Yii 2 那样将动作组织到控制器中,但这并非必须。" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Suggested Yii3 application structure is different from Yii 2.0. It's described in [application structure](../structure/overview.md)." -msgstr "" +msgstr "Yii3 建议的应用程序结构与 Yii 2.0 有所不同,详见 [应用程序结构](../structure/overview.md)。" #. type: Plain text #: ../src/guide/intro/upgrade-from-v2.md msgid "Despite that, Yii3 is flexible, so it's still possible to use a structure similar to Yii 2.0 with Yii3." -msgstr "" +msgstr "尽管如此,Yii3 具有良好的灵活性,仍然可以在 Yii3 中使用类似 Yii 2.0 的结构。" diff --git a/_translations/po/zh-CN/guide_intro_what-is-yii.md.po b/_translations/po/zh-CN/guide_intro_what-is-yii.md.po index 9feaf2a5..4ffec18c 100644 --- a/_translations/po/zh-CN/guide_intro_what-is-yii.md.po +++ b/_translations/po/zh-CN/guide_intro_what-is-yii.md.po @@ -29,59 +29,59 @@ msgstr "Yii 是一个通用的 Web 编程框架。你可以使用它来开发各 #: ../src/guide/intro/what-is-yii.md #, no-wrap msgid "What is Yii" -msgstr "" +msgstr "什么是 Yii" #. type: Title ## #: ../src/guide/intro/what-is-yii.md #, no-wrap msgid "What's Yii best for" -msgstr "" +msgstr "Yii 最擅长什么" #. type: Title ## #: ../src/guide/intro/what-is-yii.md #, no-wrap msgid "How does Yii compare with other frameworks?" -msgstr "" +msgstr "Yii 与其他框架相比如何?" #. type: Plain text #: ../src/guide/intro/what-is-yii.md msgid "If you're already familiar with another framework, you may appreciate knowing how Yii compares:" -msgstr "" +msgstr "如果您已经熟悉其他框架,您可能会想了解 Yii 与它们的比较:" #. type: Bullet: '- ' #: ../src/guide/intro/what-is-yii.md msgid "Yii takes the [philosophy of being practical and helpful](../../internals/001-yii-values.md) achieving:" -msgstr "" +msgstr "Yii 秉持 [务实和有益的理念](../../internals/001-yii-values.md),致力于实现:" #. type: Bullet: ' - ' #: ../src/guide/intro/what-is-yii.md msgid "Performance in both development and execution." -msgstr "" +msgstr "开发和执行两方面的高性能。" #. type: Bullet: ' - ' #: ../src/guide/intro/what-is-yii.md msgid "Convenient customizable defaults." -msgstr "" +msgstr "方便可定制的默认配置。" #. type: Bullet: ' - ' #: ../src/guide/intro/what-is-yii.md msgid "Practice-orientation." -msgstr "" +msgstr "实践导向。" #. type: Bullet: ' - ' #: ../src/guide/intro/what-is-yii.md msgid "Simplicity." -msgstr "" +msgstr "简洁性。" #. type: Bullet: ' - ' #: ../src/guide/intro/what-is-yii.md msgid "Explicitness." -msgstr "" +msgstr "明确性。" #. type: Bullet: ' - ' #: ../src/guide/intro/what-is-yii.md msgid "Consistency." -msgstr "" +msgstr "一致性。" #. type: Plain text #: ../src/guide/intro/what-is-yii.md @@ -96,50 +96,57 @@ msgid "" " take advantage of Yii's solid architecture to use or develop redistributable packages.\n" "- High performance is always a primary goal of Yii.\n" msgstr "" +" Yii 不会为了追随某些设计模式而过度设计。\n" +"- Yii 广泛使用 PSR 接口,能够复用 PHP 社区的成果,甚至在需要时替换核心实现。\n" +"- Yii 既是一套类库,也是一个全栈框架,提供了许多经过验证的即用功能:\n" +" 缓存、日志、模板引擎、数据抽象、开发工具、代码生成等。\n" +"- Yii 具有高度可扩展性。您可以自定义或替换核心代码的任何部分,也可以\n" +" 利用 Yii 的稳固架构来使用或开发可再发布的包。\n" +"- 高性能始终是 Yii 的首要目标。\n" #. type: Plain text #: ../src/guide/intro/what-is-yii.md msgid "Yii is backed up by a [strong core developer team](https://www.yiiframework.com/team/) financially backed from an [OpenCollective foundation](https://opencollective.com/yiisoft), as well as a large community of professionals constantly contributing to Yii's development. The Yii developer team keeps a close eye on the latest Web development trends and on the best practices and features found in other frameworks and projects. The most relevant best practices and features found elsewhere are incorporated into the core framework and exposed via simple and elegant interfaces." -msgstr "" +msgstr "Yii 由一支 [强大的核心开发团队](https://www.yiiframework.com/team/) 支撑,并获得 [OpenCollective 基金会](https://opencollective.com/yiisoft) 的资金支持,同时拥有一个持续为 Yii 发展做出贡献的庞大专业社区。Yii 开发团队密切关注最新的 Web 开发趋势,以及其他框架和项目中发现的最佳实践和功能。在其他地方发现的最相关的最佳实践和功能都被融入核心框架,并通过简洁优雅的接口对外暴露。" #. type: Title ## #: ../src/guide/intro/what-is-yii.md #, no-wrap msgid "Yii versions" -msgstr "" +msgstr "Yii 版本" #. type: Plain text #: ../src/guide/intro/what-is-yii.md msgid "Yii currently has three major versions available: 1.1, 2.0, and 3.0." -msgstr "" +msgstr "Yii 目前有三个主要版本:1.1、2.0 和 3.0。" #. type: Bullet: '- ' #: ../src/guide/intro/what-is-yii.md msgid "Version 1.1 is the old generation and is now in the feature freeze bugfix mode." -msgstr "" +msgstr "1.1 版本是旧一代,目前处于功能冻结的错误修复模式。" #. type: Bullet: '- ' #: ../src/guide/intro/what-is-yii.md msgid "Version 2.0 is a current stable version in the feature freeze bugfix mode." -msgstr "" +msgstr "2.0 版本是当前稳定版本,处于功能冻结的错误修复模式。" #. type: Bullet: '- ' #: ../src/guide/intro/what-is-yii.md msgid "Version 3.0 is the current version in development. This guide is mainly about version 3." -msgstr "" +msgstr "3.0 版本是目前正在开发的版本。本指南主要介绍第 3 个版本。" #. type: Title ## #: ../src/guide/intro/what-is-yii.md #, no-wrap msgid "Requirements and prerequisites" -msgstr "" +msgstr "要求和先决条件" #. type: Plain text #: ../src/guide/intro/what-is-yii.md msgid "Yii3 requires PHP 8.2 or above, but some packages work with older PHP, such as PHP 7.4." -msgstr "" +msgstr "Yii3 需要 PHP 8.2 或更高版本,但某些包也可以与较旧的 PHP 一起使用,例如 PHP 7.4。" #. type: Plain text #: ../src/guide/intro/what-is-yii.md msgid "Using Yii requires basic knowledge of object-oriented programming (OOP), as Yii is a pure OOP-based framework. Yii3 also makes use of the latest PHP features, such as type declarations and generators. Understanding these concepts will help you pick up Yii3 faster." -msgstr "" +msgstr "使用 Yii 需要具备面向对象编程(OOP)的基础知识,因为 Yii 是一个纯 OOP 框架。Yii3 还利用了最新的 PHP 特性,例如类型声明和生成器。理解这些概念将帮助您更快地上手 Yii3。" diff --git a/_translations/po/zh-CN/guide_runtime_cookies.md.po b/_translations/po/zh-CN/guide_runtime_cookies.md.po index 0bff4572..422c1a13 100644 --- a/_translations/po/zh-CN/guide_runtime_cookies.md.po +++ b/_translations/po/zh-CN/guide_runtime_cookies.md.po @@ -19,23 +19,23 @@ msgstr "" #: en/runtime/cookies.md #, no-wrap msgid "Cookies" -msgstr "" +msgstr "Cookie" #. type: Plain text #: en/runtime/cookies.md msgid "Cookies are for persisting data between requests by sending it to the client browser using HTTP headers. The client sends data back to the server in request headers. Thus, cookies are handy to store small amounts of data, such as tokens or flags." -msgstr "" +msgstr "Cookie 用于通过 HTTP 头将数据发送到客户端浏览器,以在请求之间持久化数据。客户端在请求头中将数据发回服务器。因此,Cookie 非常适合存储少量数据,例如令牌或标志位。" #. type: Title ## #: en/runtime/cookies.md #, no-wrap msgid "Reading cookies" -msgstr "" +msgstr "读取 Cookie" #. type: Plain text #: en/runtime/cookies.md msgid "You could obtain Cookie values from server request that's available as route handler (such as controller action) argument:" -msgstr "" +msgstr "您可以从作为路由处理器(例如控制器操作)参数提供的服务器请求中获取 Cookie 值:" #. type: Fenced code block (php) #: en/runtime/cookies.md @@ -52,12 +52,12 @@ msgstr "" #. type: Plain text #: en/runtime/cookies.md msgid "In addition to getting cookie values directly from the server request, you can also use the [yiisoft/request-provider](https://github.com/yiisoft/request-provider) package, which provides a more structured way to handle cookies through the `\\Yiisoft\\RequestProvider\\RequestCookieProvider`. This approach can simplify your code and improve readability." -msgstr "" +msgstr "除了直接从服务器请求获取 Cookie 值外,您还可以使用 [yiisoft/request-provider](https://github.com/yiisoft/request-provider) 包,该包通过 `\\Yiisoft\\RequestProvider\\RequestCookieProvider` 提供了一种更结构化的 Cookie 处理方式,能简化代码并提高可读性。" #. type: Plain text #: en/runtime/cookies.md msgid "Here’s an example of how to work with cookies using the `\\Yiisoft\\RequestProvider\\RequestCookieProvider`:" -msgstr "" +msgstr "以下是使用 `\\Yiisoft\\RequestProvider\\RequestCookieProvider` 处理 Cookie 的示例:" #. type: Fenced code block (php) #: en/runtime/cookies.md @@ -104,28 +104,28 @@ msgstr "" #. type: Plain text #: en/runtime/cookies.md msgid "After forming a cookie call `addToResponse()` passing an instance of `\\Psr\\Http\\Message\\ResponseInterface` to add corresponding HTTP headers to it." -msgstr "" +msgstr "构造好 Cookie 后,调用 `addToResponse()` 并传入 `\\Psr\\Http\\Message\\ResponseInterface` 实例,以将相应的 HTTP 头添加到响应中。" #. type: Title ## #: en/runtime/cookies.md #, no-wrap msgid "Signing and encrypting cookies" -msgstr "" +msgstr "签名与加密 Cookie" #. type: Plain text #: en/runtime/cookies.md msgid "To prevent the substitution of the cookie value, the package provides two implementations:" -msgstr "" +msgstr "为防止 Cookie 值被篡改,该包提供了两种实现:" #. type: Plain text #: en/runtime/cookies.md msgid "`Yiisoft\\Cookies\\CookieSigner` - signs each cookie with a unique prefix hash based on the value of the cookie and a secret key. `Yiisoft\\Cookies\\CookieEncryptor` - encrypts each cookie with a secret key." -msgstr "" +msgstr "`Yiisoft\\Cookies\\CookieSigner` — 使用基于 Cookie 值和密钥的唯一前缀哈希对每个 Cookie 进行签名。`Yiisoft\\Cookies\\CookieEncryptor` — 使用密钥对每个 Cookie 进行加密。" #. type: Plain text #: en/runtime/cookies.md msgid "Encryption is more secure than signing but has lower performance." -msgstr "" +msgstr "加密比签名更安全,但性能较低。" #. type: Fenced code block (php) #: en/runtime/cookies.md @@ -146,7 +146,7 @@ msgstr "" #. type: Plain text #: en/runtime/cookies.md msgid "To validate and get back the pure value, use the `validate()` and `decrypt()` method." -msgstr "" +msgstr "要验证并还原纯净值,请使用 `validate()` 和 `decrypt()` 方法。" #. type: Fenced code block (php) #: en/runtime/cookies.md @@ -159,7 +159,7 @@ msgstr "" #. type: Plain text #: en/runtime/cookies.md msgid "If the cookie value is tampered with or hasn't been signed/encrypted before, a `\\RuntimeException` will be thrown. Therefore, if you aren't sure that the cookie value was signed/encrypted earlier, first use the `isSigned()` and `isEncrypted()` methods, respectively." -msgstr "" +msgstr "如果 Cookie 值被篡改,或之前未经过签名/加密,则会抛出 `\\RuntimeException`。因此,如果不确定 Cookie 值之前是否已签名/加密,请先分别使用 `isSigned()` 和 `isEncrypted()` 方法进行检查。" #. type: Fenced code block (php) #: en/runtime/cookies.md @@ -177,43 +177,43 @@ msgstr "" #. type: Plain text #: en/runtime/cookies.md msgid "It makes sense to sign or encrypt the value of a cookie if you store important data that a user shouldn't change." -msgstr "" +msgstr "如果 Cookie 中存储了用户不应修改的重要数据,对其值进行签名或加密是有必要的。" #. type: Title ### #: en/runtime/cookies.md #, no-wrap msgid "Automating encryption and signing" -msgstr "" +msgstr "自动化加密与签名" #. type: Plain text #: en/runtime/cookies.md msgid "To automate the encryption/signing and decryption/validation of cookie values, use an instance of `Yiisoft\\Cookies\\CookieMiddleware`, which is [PSR-15](https://www.php-fig.org/psr/psr-15/) middleware." -msgstr "" +msgstr "要自动化 Cookie 值的加密/签名和解密/验证,请使用 `Yiisoft\\Cookies\\CookieMiddleware` 实例,它是符合 [PSR-15](https://www.php-fig.org/psr/psr-15/) 规范的中间件。" #. type: Plain text #: en/runtime/cookies.md msgid "This middleware provides the following features:" -msgstr "" +msgstr "该中间件提供以下功能:" #. type: Bullet: '- ' #: en/runtime/cookies.md msgid "Validates and decrypts the cookie parameter values from the request." -msgstr "" +msgstr "验证并解密请求中的 Cookie 参数值。" #. type: Bullet: '- ' #: en/runtime/cookies.md msgid "Excludes the cookie parameter from the request if it was tampered with and logs information about it." -msgstr "" +msgstr "如果 Cookie 参数被篡改,则将其从请求中排除并记录相关信息。" #. type: Bullet: '- ' #: en/runtime/cookies.md msgid "Encrypts/signs cookie values and replaces their clean values in the `Set-Cookie` headers in the response." -msgstr "" +msgstr "对 Cookie 值进行加密/签名,并在响应的 `Set-Cookie` 头中替换原始值。" #. type: Plain text #: en/runtime/cookies.md msgid "In order for the middleware to know which values of which cookies need to be encrypted/signed, an array of settings must be passed to its constructor. The array keys are cookie name patterns and values are constant values of `CookieMiddleware::ENCRYPT` or `CookieMiddleware::SIGN`." -msgstr "" +msgstr "为了让中间件知道哪些 Cookie 的值需要加密/签名,必须向其构造函数传入一个配置数组。数组的键是 Cookie 名称匹配模式,值为 `CookieMiddleware::ENCRYPT` 或 `CookieMiddleware::SIGN` 常量。" #. type: Fenced code block (php) #: en/runtime/cookies.md @@ -235,12 +235,12 @@ msgstr "" #. type: Plain text #: en/runtime/cookies.md msgid "For more information on using the wildcard pattern, see the [yiisoft/strings](https://github.com/yiisoft/strings#wildcardpattern-usage) package." -msgstr "" +msgstr "有关通配符模式用法的更多信息,请参阅 [yiisoft/strings](https://github.com/yiisoft/strings#wildcardpattern-usage) 包。" #. type: Plain text #: en/runtime/cookies.md msgid "Creating and using middleware:" -msgstr "" +msgstr "创建并使用中间件:" #. type: Fenced code block (php) #: en/runtime/cookies.md @@ -277,35 +277,35 @@ msgstr "" #. type: Plain text #: en/runtime/cookies.md msgid "If the `$cookiesSettings` array is empty, no cookies will be encrypted and signed." -msgstr "" +msgstr "如果 `$cookiesSettings` 数组为空,则不会对任何 Cookie 进行加密或签名。" #. type: Title ## #: en/runtime/cookies.md #, no-wrap msgid "Cookies security" -msgstr "" +msgstr "Cookie 安全" #. type: Plain text #: en/runtime/cookies.md msgid "You should configure each cookie to be secure. Important security settings are:" -msgstr "" +msgstr "应将每个 Cookie 配置为安全的。重要的安全设置包括:" #. type: Bullet: '- ' #: en/runtime/cookies.md msgid "`httpOnly`. Setting it to `true` would prevent JavaScript to access cookie value." -msgstr "" +msgstr "`httpOnly`。设为 `true` 可防止 JavaScript 访问 Cookie 值。" #. type: Bullet: '- ' #: en/runtime/cookies.md msgid "`secure`. Setting it to `true` would prevent sending cookie via `HTTP`. It will be sent via `HTTPS` only." -msgstr "" +msgstr "`secure`。设为 `true` 可防止通过 `HTTP` 发送 Cookie,仅允许通过 `HTTPS` 发送。" #. type: Bullet: '- ' #: en/runtime/cookies.md msgid "`sameSite`, if set to either `SAME_SITE_LAX` or `SAME_SITE_STRICT` would prevent sending a cookie in cross-site browsing context. `SAME_SITE_LAX` would prevent cookie sending during CSRF-prone request methods (e.g., POST, PUT, PATCH, etc.). `SAME_SITE_STRICT` would prevent cookies sending for all methods." -msgstr "" +msgstr "`sameSite`,设为 `SAME_SITE_LAX` 或 `SAME_SITE_STRICT` 可防止在跨站浏览上下文中发送 Cookie。`SAME_SITE_LAX` 会阻止在易受 CSRF 攻击的请求方法(如 POST、PUT、PATCH 等)中发送 Cookie;`SAME_SITE_STRICT` 会阻止所有方法发送 Cookie。" #. type: Bullet: '- ' #: en/runtime/cookies.md msgid "Sign or encrypt the value of the cookie to prevent spoofing of values if the data in the value shouldn't be tampered with." -msgstr "" +msgstr "如果 Cookie 值中的数据不应被篡改,请对其进行签名或加密,以防止值被伪造。" diff --git a/_translations/po/zh-CN/guide_runtime_handling-errors.md.po b/_translations/po/zh-CN/guide_runtime_handling-errors.md.po index 0340dbd4..edc81e7d 100644 --- a/_translations/po/zh-CN/guide_runtime_handling-errors.md.po +++ b/_translations/po/zh-CN/guide_runtime_handling-errors.md.po @@ -19,83 +19,83 @@ msgstr "" #: ../src/guide/runtime/handling-errors.md #, no-wrap msgid "Handling errors" -msgstr "" +msgstr "错误处理" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "Yii has a [yiisoft/error-handler](https://github.com/yiisoft/error-handler) package that makes error handling a much more pleasant experience than before. In particular, the Yii error handler provides the following:" -msgstr "" +msgstr "Yii 提供了 [yiisoft/error-handler](https://github.com/yiisoft/error-handler) 包,使错误处理体验大为改善。Yii 错误处理器具体提供了以下功能:" #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "[PSR-15](https://www.php-fig.org/psr/psr-15/) middleware for catching unhandled errors." -msgstr "" +msgstr "用于捕获未处理错误的 [PSR-15](https://www.php-fig.org/psr/psr-15/) 中间件。" #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "PSR-15 middleware for mapping certain exceptions to custom responses." -msgstr "" +msgstr "用于将特定异常映射到自定义响应的 PSR-15 中间件。" #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "Production and debug modes." -msgstr "" +msgstr "生产模式和调试模式。" #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "Debug mode displays details, stacktrace, has dark and light themes and handy buttons to search for error without typing." -msgstr "" +msgstr "调试模式显示详细信息和堆栈跟踪,提供深色和浅色主题,以及无需输入即可搜索错误的快捷按钮。" #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "Takes PHP settings into account." -msgstr "" +msgstr "考虑 PHP 配置设置。" #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "Handles out of memory errors, fatal errors, warnings, notices, and exceptions." -msgstr "" +msgstr "处理内存溢出错误、致命错误、警告、通知和异常。" #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "Can use any [PSR-3](https://www.php-fig.org/psr/psr-3/) compatible logger for error logging." -msgstr "" +msgstr "可使用任何兼容 [PSR-3](https://www.php-fig.org/psr/psr-3/) 的日志记录器记录错误。" #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "Detects a response format based on a mime type of the request." -msgstr "" +msgstr "根据请求的 MIME 类型自动检测响应格式。" #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "Supports responding with HTML, plain text, JSON, XML, and headers out of the box." -msgstr "" +msgstr "开箱即支持 HTML、纯文本、JSON、XML 和响应头格式的响应。" #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "You can implement your own error rendering for extra types." -msgstr "" +msgstr "您可以为其他类型实现自定义错误渲染。" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "This guide describes how to use the error handler in the [Yii framework](https://www.yiiframework.com/), for information about using it separate from Yii, see the [package description](https://github.com/yiisoft/error-handler)." -msgstr "" +msgstr "本指南介绍如何在 [Yii 框架](https://www.yiiframework.com/)中使用错误处理器。若要了解独立于 Yii 使用的信息,请参阅[包说明](https://github.com/yiisoft/error-handler)。" #. type: Title ## #: ../src/guide/runtime/handling-errors.md #, no-wrap msgid "Using error handler" -msgstr "" +msgstr "使用错误处理器" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "The error handler consists of two parts. One part is `Yiisoft\\ErrorHandler\\Middleware\\ErrorCatcher` middleware that, when registered, catches exceptions that may appear during middleware stack execution and passes them to the handler. Another part is the error handler itself, `Yiisoft\\ErrorHandler\\ErrorHandler`, that's catching exceptions occurring outside the middleware stack and fatal errors. The handler also converts warnings and notices to exceptions and does more handy things." -msgstr "" +msgstr "错误处理器由两部分组成。第一部分是 `Yiisoft\\ErrorHandler\\Middleware\\ErrorCatcher` 中间件,注册后可捕获中间件栈执行过程中出现的异常并将其传递给处理器。另一部分是错误处理器本身 `Yiisoft\\ErrorHandler\\ErrorHandler`,用于捕获中间件栈之外的异常和致命错误。处理器还会将警告和通知转换为异常,并执行更多便捷操作。" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "Error handler is registered in the application itself. Usually it happens in `ApplicationRunner`. By default, the handler configuration comes from the container. You may configure it in the application configuration, `config/web.php` like the following:" -msgstr "" +msgstr "错误处理器在应用程序本身中注册,通常在 `ApplicationRunner` 中完成。默认情况下,处理器的配置来自容器。您可以在应用配置 `config/web.php` 中按如下方式配置:" #. type: Fenced code block (php) #: ../src/guide/runtime/handling-errors.md @@ -134,7 +134,7 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "As aforementioned, the error handler turns all non-fatal PHP errors into catchable exceptions (`Yiisoft\\ErrorHandler\\Exception\\ErrorException`). This means you can use the following code to deal with PHP errors:" -msgstr "" +msgstr "如前所述,错误处理器会将所有非致命 PHP 错误转换为可捕获的异常(`Yiisoft\\ErrorHandler\\Exception\\ErrorException`)。这意味着您可以使用以下代码处理 PHP 错误:" #. type: Fenced code block (php) #: ../src/guide/runtime/handling-errors.md @@ -151,7 +151,7 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "The package has another middleware, `Yiisoft\\ErrorHandler\\Middleware\\ExceptionResponder`. This middleware maps certain exceptions to custom responses. Configure it in the application configuration as follows:" -msgstr "" +msgstr "该包还有另一个中间件 `Yiisoft\\ErrorHandler\\Middleware\\ExceptionResponder`,用于将特定异常映射到自定义响应。在应用配置中按如下方式配置:" #. type: Fenced code block (php) #: ../src/guide/runtime/handling-errors.md @@ -180,53 +180,53 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "Note that when configuring application middleware stack, you must place `Yiisoft\\ErrorHandler\\Middleware\\ExceptionResponder` before `Yiisoft\\ErrorHandler\\Middleware\\ErrorCatcher`." -msgstr "" +msgstr "请注意,在配置应用中间件栈时,必须将 `Yiisoft\\ErrorHandler\\Middleware\\ExceptionResponder` 放在 `Yiisoft\\ErrorHandler\\Middleware\\ErrorCatcher` 之前。" #. type: Title ## #: ../src/guide/runtime/handling-errors.md #, no-wrap msgid "Rendering error data" -msgstr "" +msgstr "渲染错误数据" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "One of the renderers could render error data into a certain format. The following renderers are available out of the box:" -msgstr "" +msgstr "渲染器可将错误数据渲染为特定格式。以下渲染器开箱即用:" #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "`Yiisoft\\ErrorHandler\\Renderer\\HeaderRenderer` - Renders error into HTTP headers. It's used for `HEAD` request." -msgstr "" +msgstr "`Yiisoft\\ErrorHandler\\Renderer\\HeaderRenderer` - 将错误渲染为 HTTP 响应头,用于 `HEAD` 请求。" #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "`Yiisoft\\ErrorHandler\\Renderer\\HtmlRenderer` - Renders error into HTML." -msgstr "" +msgstr "`Yiisoft\\ErrorHandler\\Renderer\\HtmlRenderer` - 将错误渲染为 HTML。" #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "`Yiisoft\\ErrorHandler\\Renderer\\JsonRenderer` - Renders error into JSON." -msgstr "" +msgstr "`Yiisoft\\ErrorHandler\\Renderer\\JsonRenderer` - 将错误渲染为 JSON。" #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "`Yiisoft\\ErrorHandler\\Renderer\\PlainTextRenderer` - Renders error into plain text." -msgstr "" +msgstr "`Yiisoft\\ErrorHandler\\Renderer\\PlainTextRenderer` - 将错误渲染为纯文本。" #. type: Bullet: '- ' #: ../src/guide/runtime/handling-errors.md msgid "`Yiisoft\\ErrorHandler\\Renderer\\XmlRenderer` - Renders error into XML." -msgstr "" +msgstr "`Yiisoft\\ErrorHandler\\Renderer\\XmlRenderer` - 将错误渲染为 XML。" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "The renderer produces detailed error data depending on whether debug mode is enabled or disabled." -msgstr "" +msgstr "渲染器根据是否启用调试模式生成详细程度不同的错误数据。" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "An Example of header rendering with a debugging mode turned off:" -msgstr "" +msgstr "调试模式关闭时,响应头渲染示例:" #. type: Fenced code block #: ../src/guide/runtime/handling-errors.md @@ -240,7 +240,7 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "An Example of header rendering with a debugging mode turned on:" -msgstr "" +msgstr "调试模式开启时,响应头渲染示例:" #. type: Fenced code block #: ../src/guide/runtime/handling-errors.md @@ -258,7 +258,7 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "Example of JSON rendering output with a debugging mode turned off:" -msgstr "" +msgstr "调试模式关闭时,JSON 渲染输出示例:" #. type: Fenced code block (json) #: ../src/guide/runtime/handling-errors.md @@ -269,7 +269,7 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "An Example of JSON rendering output with debugging mode turned on:" -msgstr "" +msgstr "调试模式开启时,JSON 渲染输出示例:" #. type: Fenced code block (json) #: ../src/guide/runtime/handling-errors.md @@ -302,48 +302,48 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "Example of HTML rendering with debugging mode turned off:" -msgstr "" +msgstr "调试模式关闭时,HTML 渲染示例:" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "![View production](/images/guide/runtime/view-production.png)" -msgstr "" +msgstr "![生产模式视图](/images/guide/runtime/view-production.png)" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "Example of HTML rendering with debugging mode on and a light theme:" -msgstr "" +msgstr "调试模式开启且使用浅色主题时,HTML 渲染示例:" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "![View development with light theme](/images/guide/runtime/view-development-light.png)" -msgstr "" +msgstr "![开发模式视图(浅色主题)](/images/guide/runtime/view-development-light.png)" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "Example of HTML rendering with debugging mode on and a dark theme:" -msgstr "" +msgstr "调试模式开启且使用深色主题时,HTML 渲染示例:" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "![View development with dark theme](/images/guide/runtime/view-development-dark.png)" -msgstr "" +msgstr "![开发模式视图(深色主题)](/images/guide/runtime/view-development-dark.png)" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "The error catcher chooses how to render an exception based on `accept` HTTP header. If it's `text/html` or any unknown content type, it will use the error or exception HTML template to display errors. For other mime types, the error handler will choose different renderers that you register within the error catcher. By default, it supports JSON, XML, and plain text." -msgstr "" +msgstr "错误捕获器根据 `accept` HTTP 请求头决定如何渲染异常。若为 `text/html` 或未知内容类型,将使用错误或异常 HTML 模板显示错误。对于其他 MIME 类型,错误处理器会选择您在错误捕获器中注册的不同渲染器。默认支持 JSON、XML 和纯文本。" #. type: Title ### #: ../src/guide/runtime/handling-errors.md #, no-wrap msgid "Implementing your own renderer" -msgstr "" +msgstr "实现自定义渲染器" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "You may customize the error response format by providing your own instance of `Yiisoft\\ErrorHandler\\ThrowableRendererInterface` when registering error catcher middleware." -msgstr "" +msgstr "在注册错误捕获器中间件时,可以通过提供自己的 `Yiisoft\\ErrorHandler\\ThrowableRendererInterface` 实例来自定义错误响应格式。" #. type: Fenced code block (php) #: ../src/guide/runtime/handling-errors.md @@ -373,7 +373,7 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "You may configure it in the application configuration `config/web.php`:" -msgstr "" +msgstr "可以在应用配置 `config/web.php` 中进行配置:" #. type: Fenced code block (php) #: ../src/guide/runtime/handling-errors.md @@ -405,12 +405,12 @@ msgstr "" #: ../src/guide/runtime/handling-errors.md #, no-wrap msgid "Friendly exceptions" -msgstr "" +msgstr "友好异常" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "Yii error renderer supports [friendly exceptions](https://github.com/yiisoft/friendly-exception) that make error handling an even more pleasant experience for your team. The idea is to offer a readable name and possible solutions to the problem:" -msgstr "" +msgstr "Yii 错误渲染器支持[友好异常](https://github.com/yiisoft/friendly-exception),让团队的错误处理体验更佳。其理念是为问题提供可读的名称和可能的解决方案:" #. type: Fenced code block (php) #: ../src/guide/runtime/handling-errors.md @@ -437,4 +437,4 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/handling-errors.md msgid "When the application throws such an exception, the error renderer would display the name and the solution if the debug mode is on." -msgstr "" +msgstr "当应用程序抛出此类异常时,若调试模式已开启,错误渲染器将显示名称和解决方案。" diff --git a/_translations/po/zh-CN/guide_runtime_logging.md.po b/_translations/po/zh-CN/guide_runtime_logging.md.po index d31eee9a..67e5cdd5 100644 --- a/_translations/po/zh-CN/guide_runtime_logging.md.po +++ b/_translations/po/zh-CN/guide_runtime_logging.md.po @@ -19,53 +19,53 @@ msgstr "" #: ../src/guide/runtime/logging.md #, no-wrap msgid "Logging" -msgstr "" +msgstr "日志" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Yii relies on [PSR-3 interfaces](https://www.php-fig.org/psr/psr-3/) for logging, so you could configure any PSR-3 compatible logging library to do the actual job." -msgstr "" +msgstr "Yii 依赖 [PSR-3 接口](https://www.php-fig.org/psr/psr-3/) 进行日志记录,因此您可以配置任何兼容 PSR-3 的日志库来完成实际工作。" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Yii provides its own logger that's highly customizable and extensible. Using it, you can log various types of messages, filter them, and gather them at different targets, such as files or emails." -msgstr "" +msgstr "Yii 提供了自己的日志记录器,具有高度的可定制性和可扩展性。使用它,您可以记录各种类型的消息,对其进行过滤,并将其收集到不同的目标中,例如文件或电子邮件。" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Using the Yii logging framework involves the following steps:" -msgstr "" +msgstr "使用 Yii 日志框架涉及以下步骤:" #. type: Bullet: '* ' #: ../src/guide/runtime/logging.md msgid "Record [log messages](#log-messages) at various places in your code;" -msgstr "" +msgstr "在代码的各个位置记录 [日志消息](#log-messages);" #. type: Bullet: '* ' #: ../src/guide/runtime/logging.md msgid "Configure [log targets](#log-targets) in the application configuration to filter and export log messages;" -msgstr "" +msgstr "在应用配置中配置 [日志目标](#log-targets),以过滤和导出日志消息;" #. type: Bullet: '* ' #: ../src/guide/runtime/logging.md msgid "Examine the filtered logged messages exported by different targets (e.g. the Yii debugger)." -msgstr "" +msgstr "检查由不同目标导出的已过滤日志消息(例如 Yii 调试器)。" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "In this section, the focus in on the first two steps." -msgstr "" +msgstr "本节重点介绍前两个步骤。" #. type: Title ## #: ../src/guide/runtime/logging.md #, no-wrap msgid "Log Messages " -msgstr "" +msgstr "日志消息 " #. type: Plain text #: ../src/guide/runtime/logging.md msgid "To record log messages, you need an instance of PSR-3 logger. A class that writes log messages should receive it as a dependency:" -msgstr "" +msgstr "要记录日志消息,您需要一个 PSR-3 日志记录器实例。需要写入日志消息的类应通过依赖注入的方式接收它:" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -85,52 +85,52 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Recording a log message is as simple as calling one of the following logging methods that correspond to log levels:" -msgstr "" +msgstr "记录日志消息非常简单,只需调用以下对应不同日志级别的方法之一:" #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`emergency` - System is unusable." -msgstr "" +msgstr "`emergency` — 系统不可用。" #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`alert` - Action must be taken immediately. Example: Entire website down, database unavailable, etc. This should trigger the SMS alerts and wake you up." -msgstr "" +msgstr "`alert` — 必须立即采取行动。示例:整个网站宕机、数据库不可用等。这类事件应触发短信告警并将您唤醒。" #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`critical` - Critical conditions. Example: Application component unavailable, unexpected exception." -msgstr "" +msgstr "`critical` — 严重状态。示例:应用程序组件不可用、意外异常。" #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`error` - Runtime errors that don't require immediate action but should typically be logged and monitored." -msgstr "" +msgstr "`error` — 不需要立即处理但通常应记录和监控的运行时错误。" #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`warning` - Exceptional occurrences that aren't errors. Example: Use of deprecated APIs, poor use of an API, undesirable things that aren't necessarily wrong." -msgstr "" +msgstr "`warning` — 非错误的异常情况。示例:使用已废弃的 API、不当使用 API、不理想但不一定错误的情况。" #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`notice` - Normal but significant events." -msgstr "" +msgstr "`notice` — 正常但值得关注的事件。" #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`info` - Interesting events. Example: User logs in, SQL logs." -msgstr "" +msgstr "`info` — 值得关注的事件。示例:用户登录、SQL 日志。" #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`debug` - Detailed debug information." -msgstr "" +msgstr "`debug` — 详细的调试信息。" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Each method has two arguments. The first is a message. The Second is a context array that typically has structured data that doesn't fit a message well but still does offer important information. In case you provide an exception as context, you should pass the \"exception\" key. Another special key is \"category.\" Categories are handy to better organize and filter log messages." -msgstr "" +msgstr "每个方法有两个参数。第一个是消息内容。第二个是上下文数组,通常包含不适合放入消息中但仍然重要的结构化数据。如果以异常作为上下文,应传入 \"exception\" 键。另一个特殊键是 \"category\"(分类),分类有助于更好地组织和过滤日志消息。" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -156,12 +156,12 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "When deciding on a category for a message, you may choose a hierarchical naming scheme, which will make it easier for [log targets](#log-targets) to filter messages based on their categories. A simple yet effective naming scheme is to use the PHP magic constant `__METHOD__` for the category names. This is also the approach used in the core Yii framework code." -msgstr "" +msgstr "在为消息选择分类时,可以采用层级命名方案,这将便于 [日志目标](#log-targets) 按分类过滤消息。一种简单而有效的命名方案是使用 PHP 魔术常量 `__METHOD__` 作为分类名称,Yii 框架核心代码也采用了这种方式。" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "The `__METHOD__` constant evaluates as the name of the method (prefixed with the fully qualified class name) where the constant appears. For example, it's equal to the string `'App\\\\Service\\\\MyService::serve'` if the above line of code is called within this method." -msgstr "" +msgstr "`__METHOD__` 常量的值为其所在方法的名称(前缀为完整类名)。例如,如果上述代码在该方法中调用,其值等于字符串 `'App\\\\Service\\\\MyService::serve'`。" #. type: Plain text #: ../src/guide/runtime/logging.md @@ -170,27 +170,29 @@ msgid "" "> [!IMPORTANT]\n" "> The logging methods described above are actually shortcuts to the [[\\Psr\\Log\\LoggerInterface::log()]].\n" msgstr "" +"> [!IMPORTANT]\n" +"> 上述日志方法实际上是 [[\\Psr\\Log\\LoggerInterface::log()]] 的快捷方式。\n" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Note that PSR-3 package provides `\\Psr\\Log\\NullLogger` class that provides the same set of methods but doesn't log anything. That means that you don't have to check if logger is configured with `if ($logger !== null)` and, instead, can assume that logger is always present." -msgstr "" +msgstr "请注意,PSR-3 包提供了 `\\Psr\\Log\\NullLogger` 类,该类提供相同的方法集但不记录任何内容。这意味着您无需通过 `if ($logger !== null)` 检查日志记录器是否已配置,而可以始终假定日志记录器存在。" #. type: Title ## #: ../src/guide/runtime/logging.md #, no-wrap msgid "Log targets " -msgstr "" +msgstr "日志目标 " #. type: Plain text #: ../src/guide/runtime/logging.md msgid "A log target is an instance of a class that extends the [[\\Yiisoft\\Log\\Target]]. It filters the log messages by their severity levels and categories and then exports them to some medium. For example, a [[\\Yiisoft\\Log\\Target\\File\\FileTarget|file target]]exports the filtered log messages to a file, while a [[Yiisoft\\Log\\Target\\Email\\EmailTarget|email target]] exports the log messages to specified email addresses." -msgstr "" +msgstr "日志目标是继承自 [[\\Yiisoft\\Log\\Target]] 的类的实例。它按严重级别和分类过滤日志消息,然后将其导出到某种介质。例如,[[\\Yiisoft\\Log\\Target\\File\\FileTarget|文件目标]]将过滤后的日志消息导出到文件,而 [[Yiisoft\\Log\\Target\\Email\\EmailTarget|邮件目标]]则将日志消息发送到指定的电子邮件地址。" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "You can register many log targets in an application by configuring them through the `\\Yiisoft\\Log\\Logger` constructor:" -msgstr "" +msgstr "您可以通过 `\\Yiisoft\\Log\\Logger` 构造函数配置多个日志目标并在应用中注册它们:" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -214,12 +216,12 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "In the above code, two log targets are registered:" -msgstr "" +msgstr "在上述代码中,注册了两个日志目标:" #. type: Bullet: '* ' #: ../src/guide/runtime/logging.md msgid "the first target selects error and warning messages and writes them to `/path/to/app.log` file;" -msgstr "" +msgstr "第一个目标选择 error 和 warning 消息并将其写入 `/path/to/app.log` 文件;" #. type: Plain text #: ../src/guide/runtime/logging.md @@ -228,87 +230,89 @@ msgid "" "* the second target selects emergency, alert, and critical messages under the categories whose names start with\n" "`Yiisoft\\Cache\\`, and sends them in an email to both `admin@example.com` and `developer@example.com`.\n" msgstr "" +"* 第二个目标选择分类名称以 `Yiisoft\\Cache\\` 开头的 emergency、alert 和 critical 消息,\n" +"并通过电子邮件发送给 `admin@example.com` 和 `developer@example.com`。\n" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Yii comes with the following built-in log targets. Please refer to the API documentation about these classes to learn how to configure and use them." -msgstr "" +msgstr "Yii 内置了以下日志目标。请参阅这些类的 API 文档了解如何配置和使用它们。" #. type: Bullet: '* ' #: ../src/guide/runtime/logging.md msgid "[[\\Yiisoft\\Log\\PsrTarget]]: passes log messages to another PSR-3 compatible logger." -msgstr "" +msgstr "[[\\Yiisoft\\Log\\PsrTarget]]:将日志消息传递给另一个兼容 PSR-3 的日志记录器。" #. type: Bullet: '* ' #: ../src/guide/runtime/logging.md msgid "[[\\Yiisoft\\Log\\StreamTarget]]: writes log messages into a specified output stream." -msgstr "" +msgstr "[[\\Yiisoft\\Log\\StreamTarget]]:将日志消息写入指定的输出流。" #. type: Bullet: '* ' #: ../src/guide/runtime/logging.md msgid "[[\\Yiisoft\\Log\\Target\\Db\\DbTarget]]: saves log messages in database." -msgstr "" +msgstr "[[\\Yiisoft\\Log\\Target\\Db\\DbTarget]]:将日志消息保存到数据库。" #. type: Bullet: '* ' #: ../src/guide/runtime/logging.md msgid "[[\\Yiisoft\\Log\\Target\\Email\\EmailTarget]]: sends log messages to pre-specified email addresses." -msgstr "" +msgstr "[[\\Yiisoft\\Log\\Target\\Email\\EmailTarget]]:将日志消息发送到预先指定的电子邮件地址。" #. type: Bullet: '* ' #: ../src/guide/runtime/logging.md msgid "[[\\Yiisoft\\Log\\Target\\File\\FileTarget]]: saves log messages in files." -msgstr "" +msgstr "[[\\Yiisoft\\Log\\Target\\File\\FileTarget]]:将日志消息保存到文件。" #. type: Bullet: '* ' #: ../src/guide/runtime/logging.md msgid "[[\\Yiisoft\\Log\\Target\\Syslog\\SyslogTarget]]: saves log messages to syslog by calling the PHP function `syslog()`." -msgstr "" +msgstr "[[\\Yiisoft\\Log\\Target\\Syslog\\SyslogTarget]]:通过调用 PHP 函数 `syslog()` 将日志消息保存到系统日志。" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "In the following, we will describe the features common to all log targets." -msgstr "" +msgstr "下面将介绍所有日志目标共有的功能。" #. type: Title ### #: ../src/guide/runtime/logging.md #, no-wrap msgid "Message Filtering " -msgstr "" +msgstr "消息过滤 " #. type: Plain text #: ../src/guide/runtime/logging.md msgid "For each log target, you can configure its levels and categories to specify which severity levels and categories of the messages the target should process." -msgstr "" +msgstr "对于每个日志目标,您可以配置其级别和分类,以指定该目标应处理哪些严重级别和分类的消息。" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "The target `setLevels()` method takes an array consisting of one or several of `\\Psr\\Log\\LogLevel` constants." -msgstr "" +msgstr "目标的 `setLevels()` 方法接受一个由一个或多个 `\\Psr\\Log\\LogLevel` 常量组成的数组。" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "By default, the target will process messages of *any* severity level." -msgstr "" +msgstr "默认情况下,目标将处理*任意*严重级别的消息。" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "The target `setCategories()` method takes an array consisting of message category names or patterns. A target will only process messages whose category can be found or match one of the patterns in this array. A category pattern is a category name prefix with an asterisk `*` at its end. A category name matches a category pattern if it starts with the same prefix of the pattern. For example, `Yiisoft\\Cache\\Cache::set` and `Yiisoft\\Cache\\Cache::get` both match the pattern `Yiisoft\\Cache\\*`." -msgstr "" +msgstr "目标的 `setCategories()` 方法接受一个由消息分类名称或模式组成的数组。目标只处理分类能在该数组中找到或匹配其中某个模式的消息。分类模式是以星号 `*` 结尾的分类名称前缀。如果分类名称以模式的相同前缀开头,则该名称与该模式匹配。例如,`Yiisoft\\Cache\\Cache::set` 和 `Yiisoft\\Cache\\Cache::get` 都匹配模式 `Yiisoft\\Cache\\*`。" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "By default, the target will process messages of *any* category." -msgstr "" +msgstr "默认情况下,目标将处理*任意*分类的消息。" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Besides allowing the categories by the `setCategories()` method, you may also deny certain categories by the `setExcept()` method. If the category of a message is found or matches one of the patterns in this property, the target will NOT process it." -msgstr "" +msgstr "除了通过 `setCategories()` 方法允许某些分类外,您还可以通过 `setExcept()` 方法排除某些分类。如果消息的分类在该属性中被找到或匹配其中某个模式,目标将不处理该消息。" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "The following target configuration specifies that the target should only process error and warning messages under the categories whose names match either `Yiisoft\\Cache\\*` or `App\\Exceptions\\HttpException:*`, but not `App\\Exceptions\\HttpException:404`." -msgstr "" +msgstr "以下目标配置指定该目标只处理分类名称匹配 `Yiisoft\\Cache\\*` 或 `App\\Exceptions\\HttpException:*` 但不匹配 `App\\Exceptions\\HttpException:404` 的 error 和 warning 消息。" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -324,12 +328,12 @@ msgstr "" #: ../src/guide/runtime/logging.md #, no-wrap msgid "Message Formatting " -msgstr "" +msgstr "消息格式化 " #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Log targets export the filtered log messages in a certain format. For example, if you install a log target of the class [[\\Yiisoft\\Log\\Target\\File\\FileTarget]], you may find a log message similar to the following in the log file:" -msgstr "" +msgstr "日志目标以特定格式导出过滤后的日志消息。例如,如果安装了 [[\\Yiisoft\\Log\\Target\\File\\FileTarget]] 类的日志目标,可以在日志文件中找到类似如下的日志消息:" #. type: Fenced code block #: ../src/guide/runtime/logging.md @@ -347,7 +351,7 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "By default, log messages have the following format:" -msgstr "" +msgstr "默认情况下,日志消息的格式如下:" #. type: Fenced code block #: ../src/guide/runtime/logging.md @@ -358,7 +362,7 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "You may customize this format by calling [[\\Yiisoft\\Log\\Target::setFormat()|setFormat()]] method, which takes a PHP callable returning a custom-formatted message." -msgstr "" +msgstr "您可以通过调用 [[\\Yiisoft\\Log\\Target::setFormat()|setFormat()]] 方法来自定义此格式,该方法接受一个返回自定义格式消息的 PHP 可调用对象。" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -381,7 +385,7 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "In addition, if you're comfortable with the default message format but need to change the timestamp format or add custom data to the message, you can call the [[\\Yiisoft\\Log\\Target::setTimestampFormat()|setTimestampFormat()]] and [[\\Yiisoft\\Log\\Target::setPrefix()|setPrefix()]] methods. For example, the following code changes the timestamp format and configures a log target to prefix each log message with the current user ID (IP address and Session ID are removed for privacy reasons)." -msgstr "" +msgstr "此外,如果您对默认消息格式满意,但需要更改时间戳格式或向消息添加自定义数据,可以调用 [[\\Yiisoft\\Log\\Target::setTimestampFormat()|setTimestampFormat()]] 和 [[\\Yiisoft\\Log\\Target::setPrefix()|setPrefix()]] 方法。例如,以下代码更改了时间戳格式,并配置日志目标为每条日志消息添加当前用户 ID 前缀(出于隐私原因,IP 地址和 Session ID 已移除)。" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -407,7 +411,7 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "The PHP callable that's passed to the [[\\Yiisoft\\Log\\Target::setFormat()|setFormat()]] and [[\\Yiisoft\\Log\\Target::setPrefix()|setPrefix()]] methods has the following signature:" -msgstr "" +msgstr "传递给 [[\\Yiisoft\\Log\\Target::setFormat()|setFormat()]] 和 [[\\Yiisoft\\Log\\Target::setPrefix()|setPrefix()]] 方法的 PHP 可调用对象具有以下签名:" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -425,6 +429,10 @@ msgid "" "For example, the following log target configuration specifies that only the\n" "value of the `$_SERVER` variable will be appended to the log messages.\n" msgstr "" +"除消息前缀外,日志目标还会向每条日志消息追加一些公共上下文信息。\n" +"您可以通过调用目标的 [[\\Yiisoft\\Log\\Target::setCommonContext()|setCommonContext()]]\n" +"方法来调整此行为,传入希望包含的 `key => value` 格式的数据数组。\n" +"例如,以下日志目标配置指定只将 `$_SERVER` 变量的值追加到日志消息中。\n" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -438,12 +446,12 @@ msgstr "" #: ../src/guide/runtime/logging.md #, no-wrap msgid "Message Trace Level " -msgstr "" +msgstr "消息追踪级别 " #. type: Plain text #: ../src/guide/runtime/logging.md msgid "During development, it's often desirable to see where each log message is coming from. You can achieve this by calling the [[\\Yiisoft\\Log\\Logger::setTraceLevel()|setTraceLevel()]] method like the following:" -msgstr "" +msgstr "在开发过程中,了解每条日志消息的来源通常很有必要。您可以通过如下方式调用 [[\\Yiisoft\\Log\\Logger::setTraceLevel()|setTraceLevel()]] 方法来实现:" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -456,7 +464,7 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "This application configuration sets the trace level to be 3, so each log message will be appended with at most three levels of the call stack at which the log message is recorded. You can also set a list of paths to exclude from the trace by calling the [[\\Yiisoft\\Log\\Logger::setExcludedTracePaths()|setExcludedTracePaths()]] method." -msgstr "" +msgstr "此应用配置将追踪级别设置为 3,因此每条日志消息最多会附加记录该消息时的三层调用栈。您还可以通过调用 [[\\Yiisoft\\Log\\Logger::setExcludedTracePaths()|setExcludedTracePaths()]] 方法设置要从追踪中排除的路径列表。" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -474,17 +482,20 @@ msgid "" "> Getting call stack information isn't trivial. Therefore, you should only use this feature during development\n" "or when debugging an application.\n" msgstr "" +"> [!IMPORTANT]\n" +"> 获取调用栈信息并非轻量操作。因此,您应仅在开发阶段\n" +"或调试应用程序时使用此功能。\n" #. type: Title ### #: ../src/guide/runtime/logging.md #, no-wrap msgid "Message flushing and exporting " -msgstr "" +msgstr "消息刷新与导出 " #. type: Plain text #: ../src/guide/runtime/logging.md msgid "As aforementioned, log messages are maintained in an array by [[\\Yiisoft\\Log\\Logger|logger object]]. To limit the memory consumption by this array, the logger will flush the recorded messages to the [log targets](#log-targets) each time the array accumulates a certain number of log messages. You can customize this number by calling the [[\\Yiisoft\\Log\\Logger::setFlushInterval()]] method:" -msgstr "" +msgstr "如前所述,日志消息由 [[\\Yiisoft\\Log\\Logger|日志对象]] 维护在一个数组中。为限制该数组的内存占用,每当数组累积到一定数量的日志消息时,日志记录器会将已记录的消息刷新到[日志目标](#log-targets)。您可以通过调用 [[\\Yiisoft\\Log\\Logger::setFlushInterval()]] 方法自定义此数量:" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -502,6 +513,9 @@ msgid "" "> Message flushing also occurs when the application ends,\n" "which ensures log targets can receive complete log messages.\n" msgstr "" +"> [!IMPORTANT]\n" +"> 消息刷新也会在应用程序结束时发生,\n" +"这确保日志目标能接收到完整的日志消息。\n" #. type: Plain text #: ../src/guide/runtime/logging.md @@ -513,6 +527,11 @@ msgid "" "[[\\Yiisoft\\Log\\Target::setExportInterval()|setExportInterval()]] method of individual\n" "[log targets](#log-targets), like the following:\n" msgstr "" +"当 [[\\Yiisoft\\Log\\Logger|日志对象]] 将日志消息刷新到 [日志目标](#log-targets) 时,\n" +"消息并不会立即被导出。消息导出只在日志目标\n" +"累积了一定数量的已过滤消息后才会发生。您可以通过调用各个\n" +"[日志目标](#log-targets) 的 [[\\Yiisoft\\Log\\Target::setExportInterval()|setExportInterval()]] 方法\n" +"来自定义此数量,如下所示:\n" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -525,7 +544,7 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Because of the flushing and exporting level setting, by default when you call any logging method, you will NOT see the log message immediately in the log targets. This could be a problem for some long-running console applications. To make each log message appear immediately in the log targets, you should set both flush interval and export interval to be 1, as shown below:" -msgstr "" +msgstr "由于刷新和导出间隔的设置,默认情况下调用任何日志方法时,您不会立即在日志目标中看到该日志消息。这对某些长期运行的控制台应用程序可能是个问题。要使每条日志消息立即出现在日志目标中,应将刷新间隔和导出间隔都设置为 1,如下所示:" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -545,17 +564,19 @@ msgid "" "> [!NOTE]\n" "> Frequent message flushing and exporting will degrade the performance of your application.\n" msgstr "" +"> [!NOTE]\n" +"> 频繁的消息刷新和导出会降低应用程序的性能。\n" #. type: Title ### #: ../src/guide/runtime/logging.md #, no-wrap msgid "Toggling log targets " -msgstr "" +msgstr "启用/禁用日志目标 " #. type: Plain text #: ../src/guide/runtime/logging.md msgid "You can enable or disable a log target by calling its [[\\Yiisoft\\Log\\Target::enable()|enable()] ] and [[\\Yiisoft\\Log\\Target::disable()|disable()]] methods. You may do so via the log target configuration or by the following PHP statement in your code:" -msgstr "" +msgstr "您可以通过调用日志目标的 [[\\Yiisoft\\Log\\Target::enable()|enable()]] 和 [[\\Yiisoft\\Log\\Target::disable()|disable()]] 方法来启用或禁用它。您可以通过日志目标配置或在代码中使用以下 PHP 语句来实现:" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md @@ -574,48 +595,48 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "To check whether the log target is enabled, call the `isEnabled()` method. You also may pass callable to [[\\Yiisoft\\Log\\Target::setEnabled()|setEnabled()]] to define a dynamic condition for whether the log target should be enabled or not." -msgstr "" +msgstr "要检查日志目标是否已启用,可调用 `isEnabled()` 方法。您还可以向 [[\\Yiisoft\\Log\\Target::setEnabled()|setEnabled()]] 传入可调用对象,以动态定义日志目标的启用条件。" #. type: Title ### #: ../src/guide/runtime/logging.md #, no-wrap msgid "Creating new targets " -msgstr "" +msgstr "创建新目标 " #. type: Plain text #: ../src/guide/runtime/logging.md msgid "Creating a new log target class is straightforward. You mainly need to implement the [[\\Yii\\Log\\Target::export()]] abstract method that sends all accumulated log messages to a designated medium." -msgstr "" +msgstr "创建新的日志目标类非常简单。您主要需要实现 [[\\Yii\\Log\\Target::export()]] 抽象方法,该方法负责将所有累积的日志消息发送到指定的介质。" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "The following protected methods will also be available for child targets:" -msgstr "" +msgstr "以下受保护的方法也可在子目标中使用:" #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`getMessages` - Get a list of log messages ([[\\Yii\\Log\\Message]] instances)." -msgstr "" +msgstr "`getMessages` — 获取日志消息列表([[\\Yii\\Log\\Message]] 实例)。" #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`getFormattedMessages` - Get a list of log messages formatted as strings." -msgstr "" +msgstr "`getFormattedMessages` — 获取格式化为字符串的日志消息列表。" #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`formatMessages` - Get all log messages formatted as a string." -msgstr "" +msgstr "`formatMessages` — 获取所有日志消息格式化后的单个字符串。" #. type: Bullet: '- ' #: ../src/guide/runtime/logging.md msgid "`getCommonContext` - Get an array with common context data in the `key => value` format." -msgstr "" +msgstr "`getCommonContext` — 获取包含公共上下文数据的 `key => value` 格式数组。" #. type: Plain text #: ../src/guide/runtime/logging.md msgid "For more details, you may refer to any of the log target classes included in the package." -msgstr "" +msgstr "更多详情,请参阅包中包含的任意日志目标类。" #. type: Plain text #: ../src/guide/runtime/logging.md @@ -625,6 +646,9 @@ msgid "" "> Instead of creating your own loggers, you may try any PSR-3 compatible logger such\n" "as [Monolog](https://github.com/Seldaek/monolog) by using [[\\Yii\\Log\\PsrTarget]].\n" msgstr "" +"> [!TIP]\n" +"> 无需自己创建日志记录器,您可以通过 [[\\Yii\\Log\\PsrTarget]] 使用任何兼容 PSR-3 的日志库,\n" +"例如 [Monolog](https://github.com/Seldaek/monolog)。\n" #. type: Fenced code block (php) #: ../src/guide/runtime/logging.md diff --git a/_translations/po/zh-CN/guide_runtime_request.md.po b/_translations/po/zh-CN/guide_runtime_request.md.po index a7722cca..b0d68737 100644 --- a/_translations/po/zh-CN/guide_runtime_request.md.po +++ b/_translations/po/zh-CN/guide_runtime_request.md.po @@ -19,12 +19,12 @@ msgstr "" #: en/runtime/request.md #, no-wrap msgid "Request" -msgstr "" +msgstr "请求" #. type: Plain text #: en/runtime/request.md msgid "HTTP request has a method, URI, a set of headers and a body:" -msgstr "" +msgstr "HTTP 请求包含方法、URI、一组请求头以及正文:" #. type: Fenced code block #: en/runtime/request.md @@ -44,12 +44,12 @@ msgstr "" #. type: Plain text #: en/runtime/request.md msgid "The method is `POST`, URI is `/contact`. Extra headers are specifying host, preferred language and encoding. The body could be anything. In this case, it's a JSON payload." -msgstr "" +msgstr "方法为 `POST`,URI 为 `/contact`。额外的请求头指定了主机、首选语言和编码。正文可以是任何内容,此处为 JSON 数据。" #. type: Plain text #: en/runtime/request.md msgid "Yii uses [PSR-7 `ServerRequest`](https://www.php-fig.org/psr/psr-7/) as request representation. The object is available in controller actions and other types of middleware:" -msgstr "" +msgstr "Yii 使用 [PSR-7 `ServerRequest`](https://www.php-fig.org/psr/psr-7/) 作为请求的表示。该对象可在控制器操作和其他类型的中间件中使用:" #. type: Fenced code block (php) #: en/runtime/request.md @@ -65,12 +65,12 @@ msgstr "" #: en/runtime/request.md #, no-wrap msgid "Method" -msgstr "" +msgstr "方法" #. type: Plain text #: en/runtime/request.md msgid "The method could be obtained from a request object:" -msgstr "" +msgstr "可以从请求对象中获取方法:" #. type: Fenced code block (php) #: en/runtime/request.md @@ -81,7 +81,7 @@ msgstr "" #. type: Plain text #: en/runtime/request.md msgid "Usually it's one of the:" -msgstr "" +msgstr "通常是以下之一:" #. type: Bullet: '- ' #: en/runtime/request.md @@ -121,7 +121,7 @@ msgstr "" #. type: Plain text #: en/runtime/request.md msgid "In case you want to make sure the request method is of a certain type, there is a special class with method names:" -msgstr "" +msgstr "如果需要判断请求方法是否为某种类型,可以使用包含方法名称的专用类:" #. type: Fenced code block (php) #: en/runtime/request.md @@ -143,42 +143,42 @@ msgstr "" #. type: Plain text #: en/runtime/request.md msgid "A URI has:" -msgstr "" +msgstr "URI 包含以下部分:" #. type: Bullet: '- ' #: en/runtime/request.md msgid "Scheme (`http`, `https`)" -msgstr "" +msgstr "协议(`http`、`https`)" #. type: Bullet: '- ' #: en/runtime/request.md msgid "Host (`yiiframework.com`)" -msgstr "" +msgstr "主机(`yiiframework.com`)" #. type: Bullet: '- ' #: en/runtime/request.md msgid "Port (`80`, `443`)" -msgstr "" +msgstr "端口(`80`、`443`)" #. type: Bullet: '- ' #: en/runtime/request.md msgid "Path (`/posts/1`)" -msgstr "" +msgstr "路径(`/posts/1`)" #. type: Bullet: '- ' #: en/runtime/request.md msgid "Query string (`page=1&sort=+id`)" -msgstr "" +msgstr "查询字符串(`page=1&sort=+id`)" #. type: Bullet: '- ' #: en/runtime/request.md msgid "Fragment (`#anchor`)" -msgstr "" +msgstr "片段(`#anchor`)" #. type: Plain text #: en/runtime/request.md msgid "You can obtain `UriInterface` from request like the following:" -msgstr "" +msgstr "您可以按如下方式从请求中获取 `UriInterface`:" #. type: Fenced code block (php) #: en/runtime/request.md @@ -189,7 +189,7 @@ msgstr "" #. type: Plain text #: en/runtime/request.md msgid "Then you can get various details from its methods:" -msgstr "" +msgstr "然后您可以通过其方法获取各类详细信息:" #. type: Bullet: '- ' #: en/runtime/request.md @@ -235,12 +235,12 @@ msgstr "" #: en/runtime/request.md en/runtime/response.md #, no-wrap msgid "Headers" -msgstr "" +msgstr "头部" #. type: Plain text #: en/runtime/request.md msgid "There are various methods to inspect request headers. To get all headers as an array:" -msgstr "" +msgstr "有多种方法可以查看请求头。获取所有请求头的数组:" #. type: Fenced code block (php) #: en/runtime/request.md @@ -255,7 +255,7 @@ msgstr "" #. type: Plain text #: en/runtime/request.md msgid "To get a single header:" -msgstr "" +msgstr "获取单个请求头:" #. type: Fenced code block (php) #: en/runtime/request.md @@ -266,7 +266,7 @@ msgstr "" #. type: Plain text #: en/runtime/request.md msgid "Also, you could get value as a comma-separated string instead of an array. That's especially handy if a header has a single value:" -msgstr "" +msgstr "也可以获取逗号分隔的字符串形式而非数组,当请求头只有单个值时尤为方便:" #. type: Fenced code block (php) #: en/runtime/request.md @@ -281,7 +281,7 @@ msgstr "" #. type: Plain text #: en/runtime/request.md msgid "To check if a header is present in the request:" -msgstr "" +msgstr "检查请求中是否存在某个请求头:" #. type: Fenced code block (php) #: en/runtime/request.md @@ -301,7 +301,7 @@ msgstr "正文" #. type: Plain text #: en/runtime/request.md msgid "There are two methods to get body contents. The first is getting the body as it is without parsing:" -msgstr "" +msgstr "有两种方式获取正文内容。第一种是直接获取未解析的原始正文:" #. type: Fenced code block (php) #: en/runtime/request.md @@ -312,12 +312,12 @@ msgstr "" #. type: Plain text #: en/runtime/request.md msgid "The `$body` would be an instance of `Psr\\Http\\Message\\StreamInterface`." -msgstr "" +msgstr "`$body` 是 `Psr\\Http\\Message\\StreamInterface` 的实例。" #. type: Plain text #: en/runtime/request.md msgid "Also, you could get a parsed body:" -msgstr "" +msgstr "也可以获取已解析的正文:" #. type: Fenced code block (php) #: en/runtime/request.md @@ -328,7 +328,7 @@ msgstr "" #. type: Plain text #: en/runtime/request.md msgid "Parsing depends on PSR-7 implementation and may require middleware for custom body formats." -msgstr "" +msgstr "解析取决于 PSR-7 的具体实现,对于自定义正文格式可能需要中间件支持。" #. type: Fenced code block (php) #: en/runtime/request.md @@ -362,12 +362,12 @@ msgstr "" #: en/runtime/request.md #, no-wrap msgid "File uploads" -msgstr "" +msgstr "文件上传" #. type: Plain text #: en/runtime/request.md msgid "Uploaded files that user submitted from a form with `enctype` attribute equals to `multipart/form-data` are handled via special request method:" -msgstr "" +msgstr "用户通过 `enctype` 属性为 `multipart/form-data` 的表单上传的文件,可通过专用请求方法处理:" #. type: Fenced code block (php) #: en/runtime/request.md @@ -385,9 +385,9 @@ msgstr "" #: en/runtime/request.md #, no-wrap msgid "Attributes" -msgstr "" +msgstr "属性" #. type: Plain text #: en/runtime/request.md msgid "Application middleware may set custom request attributes using `withAttribute()` method. You can get these attributes with `getAttribute()`." -msgstr "" +msgstr "应用中间件可以使用 `withAttribute()` 方法设置自定义请求属性,并通过 `getAttribute()` 获取这些属性。" diff --git a/_translations/po/zh-CN/guide_runtime_response.md.po b/_translations/po/zh-CN/guide_runtime_response.md.po index 80b7ed33..de428629 100644 --- a/_translations/po/zh-CN/guide_runtime_response.md.po +++ b/_translations/po/zh-CN/guide_runtime_response.md.po @@ -19,7 +19,7 @@ msgstr "" #: ../src/guide/runtime/request.md ../src/guide/runtime/response.md #, no-wrap msgid "Headers" -msgstr "" +msgstr "头部" #. type: Title ## #: ../src/guide/runtime/request.md ../src/guide/runtime/response.md @@ -32,12 +32,12 @@ msgstr "正文" #: ../src/guide/runtime/response.md #, no-wrap msgid "Response" -msgstr "" +msgstr "响应" #. type: Plain text #: ../src/guide/runtime/response.md msgid "HTTP response has status code and message, a set of headers and a body:" -msgstr "" +msgstr "HTTP 响应包含状态码和消息、一组响应头以及正文:" #. type: Fenced code block #: ../src/guide/runtime/response.md @@ -57,12 +57,12 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/response.md msgid "Yii uses [PSR-7 `Response`](https://www.php-fig.org/psr/psr-7/) in the web application to represent response." -msgstr "" +msgstr "Yii 在 Web 应用程序中使用 [PSR-7 `Response`](https://www.php-fig.org/psr/psr-7/) 来表示响应。" #. type: Plain text #: ../src/guide/runtime/response.md msgid "The object should be constructed and returned as a result of the execution of controller actions or other middleware. Usually, the middleware has a response factory injected into its constructor." -msgstr "" +msgstr "该对象应在控制器操作或其他中间件执行后构建并返回。通常,中间件会通过构造函数注入一个响应工厂。" #. type: Fenced code block (php) #: ../src/guide/runtime/response.md @@ -93,12 +93,12 @@ msgstr "" #: ../src/guide/runtime/response.md #, no-wrap msgid "Status code" -msgstr "" +msgstr "状态码" #. type: Plain text #: ../src/guide/runtime/response.md msgid "You can set a status code like the following:" -msgstr "" +msgstr "您可以按如下方式设置状态码:" #. type: Fenced code block (php) #: ../src/guide/runtime/response.md @@ -112,12 +112,12 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/response.md msgid "Majority of status codes are available from `Status` class for convenience and readability." -msgstr "" +msgstr "大多数状态码可通过 `Status` 类获取,以便于使用和提高可读性。" #. type: Plain text #: ../src/guide/runtime/response.md msgid "You can set headers like this:" -msgstr "" +msgstr "您可以按如下方式设置响应头:" #. type: Fenced code block (php) #: ../src/guide/runtime/response.md @@ -128,7 +128,7 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/response.md msgid "If there is a need to append a header value to the existing header:" -msgstr "" +msgstr "如果需要向已有响应头追加值:" #. type: Fenced code block (php) #: ../src/guide/runtime/response.md @@ -139,7 +139,7 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/response.md msgid "And, if needed, headers could be removed:" -msgstr "" +msgstr "如果需要,也可以移除响应头:" #. type: Fenced code block (php) #: ../src/guide/runtime/response.md @@ -150,12 +150,12 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/response.md msgid "Response body is an object implementing `Psr\\Http\\Message\\StreamInterface`." -msgstr "" +msgstr "响应正文是一个实现 `Psr\\Http\\Message\\StreamInterface` 的对象。" #. type: Plain text #: ../src/guide/runtime/response.md msgid "You can write to it via the interface itself:" -msgstr "" +msgstr "您可以通过该接口直接写入内容:" #. type: Fenced code block (php) #: ../src/guide/runtime/response.md @@ -169,13 +169,13 @@ msgstr "" #: ../src/guide/runtime/response.md #, no-wrap msgid "Examples" -msgstr "" +msgstr "示例" #. type: Title ### #: ../src/guide/runtime/response.md #, no-wrap msgid "Redirecting" -msgstr "" +msgstr "重定向" #. type: Fenced code block (php) #: ../src/guide/runtime/response.md @@ -191,7 +191,7 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/response.md msgid "Note that there are different statuses used for redirection:" -msgstr "" +msgstr "请注意,重定向使用不同的状态码:" #. type: Plain text #: ../src/guide/runtime/response.md @@ -205,12 +205,19 @@ msgid "" "| 307 | `Status::TEMPORARY_REDIRECT` | Like 302, but guarantees the HTTP method won't change. |\n" "| 303 | `Status::SEE_OTHER` | After form submissions to prevent duplicate submissions if the user refreshes. Explicitly tells to use `GET` for the redirect, even if the original request was `POST`. |\n" msgstr "" +"| 代码 | 用法 | 用途 |\n" +"|------|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------|\n" +"| 301 | `Status::MOVED_PERMANENTLY` | URL 结构已永久更改。搜索引擎更新索引,浏览器缓存结果。 |\n" +"| 308 | `Status::PERMANENT_REDIRECT` | 类似 301,但保证 HTTP 方法不会改变。 |\n" +"| 302 | `Status::FOUND` | 临时更改,例如维护页面。原始 URL 应继续用于未来请求,搜索引擎通常不更新索引。 |\n" +"| 307 | `Status::TEMPORARY_REDIRECT` | 类似 302,但保证 HTTP 方法不会改变。 |\n" +"| 303 | `Status::SEE_OTHER` | 表单提交后防止用户刷新时重复提交。明确指定重定向使用 `GET`,即使原始请求是 `POST`。 |\n" #. type: Title ### #: ../src/guide/runtime/response.md #, no-wrap msgid "Responding with JSON" -msgstr "" +msgstr "返回 JSON 响应" #. type: Fenced code block (php) #: ../src/guide/runtime/response.md diff --git a/_translations/po/zh-CN/guide_runtime_routing.md.po b/_translations/po/zh-CN/guide_runtime_routing.md.po index 1186e72d..7b285fc4 100644 --- a/_translations/po/zh-CN/guide_runtime_routing.md.po +++ b/_translations/po/zh-CN/guide_runtime_routing.md.po @@ -19,33 +19,33 @@ msgstr "" #: ../src/guide/runtime/routing.md #, no-wrap msgid "Routing and URL generation" -msgstr "" +msgstr "路由与 URL 生成" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Usually, a Yii application processes certain requests with certain handlers. It selects a handler based on the request URL. The part of the application that does the job is a router, and the process of selecting a handler, instantiating it and running a handler method is *routing*." -msgstr "" +msgstr "通常,Yii 应用程序使用特定的处理器处理特定的请求。它根据请求 URL 选择处理器。应用程序中负责此工作的部分是路由器,而选择处理器、实例化并调用处理器方法的过程就是*路由*。" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "The reverse process of routing is *URL generation*, which creates a URL from a given named route and the associated query parameters. When you later request the created URL, the routing process can resolve it back into the original route and query parameters." -msgstr "" +msgstr "路由的逆过程是 *URL 生成*,它根据给定的命名路由和相关查询参数创建 URL。当您之后请求所生成的 URL 时,路由过程可以将其解析回原始路由和查询参数。" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Routing and URL generation are separate services, but they use a common set of routes for both URL matching and URL generation." -msgstr "" +msgstr "路由和 URL 生成是独立的服务,但它们共用同一套路由配置来进行 URL 匹配和 URL 生成。" #. type: Title ## #: ../src/guide/runtime/routing.md #, no-wrap msgid "Configuring routes" -msgstr "" +msgstr "配置路由" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "By configuring routes, you can let your application recognize arbitrary URL formats without modifying your existing application code. You can configure routes in `/config/routes.php`. The structure of the file is the following:" -msgstr "" +msgstr "通过配置路由,您可以让应用程序识别任意 URL 格式,而无需修改现有应用代码。您可以在 `/config/routes.php` 中配置路由,文件结构如下:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -68,7 +68,7 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "The file returns an array of routes. When defining a route, you start with a method corresponding to a certain HTTP request type:" -msgstr "" +msgstr "该文件返回一个路由数组。定义路由时,您从与某种 HTTP 请求类型对应的方法开始:" #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md @@ -108,7 +108,7 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "If you need many methods, you can use `methods()`:" -msgstr "" +msgstr "如果需要支持多个方法,可以使用 `methods()`:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -132,27 +132,27 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "All these methods accept a route pattern and a handler. The route pattern defines how the router matches the URL when routing and how it generates URL based on route name and parameters. You will learn about the actual syntax later in this guide. You could specify a handler as:" -msgstr "" +msgstr "所有这些方法都接受一个路由模式和一个处理器。路由模式定义了路由器在匹配 URL 时的规则,以及如何根据路由名称和参数生成 URL。本指南后续将介绍具体语法。处理器可以指定为:" #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "[Middleware](../structure/middleware.md) class name." -msgstr "" +msgstr "[中间件](../structure/middleware.md) 类名。" #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "Handler action (an array of [HandlerClass, handlerMethod])." -msgstr "" +msgstr "处理器操作(`[HandlerClass, handlerMethod]` 数组)。" #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "A callable." -msgstr "" +msgstr "可调用对象。" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "In case of a handler action, a class of type `HandlerClass` is instantiated and its `handlerMethod` is called:" -msgstr "" +msgstr "当使用处理器操作时,会实例化 `HandlerClass` 类型的类并调用其 `handlerMethod`:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -173,7 +173,7 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "The callable is called as is:" -msgstr "" +msgstr "可调用对象直接被调用:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -189,12 +189,12 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "For handler action and callable typed parameters are automatically injected using the dependency injection container passed to the route." -msgstr "" +msgstr "对于处理器操作和可调用对象,类型化参数会通过传递给路由的依赖注入容器自动注入。" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Get current request and handler by type-hinting for `ServerRequestInterface` and `RequestHandlerInterface`. You could add extra handlers to wrap primary one with `middleware()` method:" -msgstr "" +msgstr "通过对 `ServerRequestInterface` 和 `RequestHandlerInterface` 进行类型提示,可以获取当前请求和处理器。您可以使用 `middleware()` 方法添加额外的处理器来包装主处理器:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -218,12 +218,12 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Check [\"the middleware\"](../structure/middleware.md) guide to learn more about how to implement middleware." -msgstr "" +msgstr "查阅[“中间件”](../structure/middleware.md)指南,了解更多关于如何实现中间件的内容。" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "This is especially useful when grouping routes:" -msgstr "" +msgstr "在对路由进行分组时,这尤其有用:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -258,17 +258,17 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Router executes `ApiDataWrapper` before handling any URL starting with `/api`." -msgstr "" +msgstr "路由器在处理任何以 `/api` 开头的 URL 之前,都会先执行 `ApiDataWrapper`。" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "You could name a route with a `name()` method. It's a good idea to choose a route name based on the handler's name." -msgstr "" +msgstr "您可以使用 `name()` 方法为路由命名。建议根据处理器的名称来选择路由名称。" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "You can set a default value for a route parameter. For example:" -msgstr "" +msgstr "您可以为路由参数设置默认值,例如:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -293,39 +293,39 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "This configuration would result in a match with both `/user` and `/user/123`. In both cases `CurrentRoute` service will contain `id` argument filled. In the first case it will be default `42` and in the second case it will be `123`." -msgstr "" +msgstr "此配置将同时匹配 `/user` 和 `/user/123`。两种情况下,`CurrentRoute` 服务都会填充 `id` 参数。第一种情况使用默认值 `42`,第二种情况使用 `123`。" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "In cause URL should be valid for a single host, you can specify it with `host()`." -msgstr "" +msgstr "如果 URL 只对特定主机有效,可以使用 `host()` 指定主机。" #. type: Title ## #: ../src/guide/runtime/routing.md #, no-wrap msgid "Routing " -msgstr "" +msgstr "路由 " #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Yii routing is flexible, and internally it may use different routing implementations. The actual matching algorithm may vary, but the basic idea stays the same." -msgstr "" +msgstr "Yii 路由非常灵活,内部可以使用不同的路由实现。实际的匹配算法可能有所不同,但基本思路是一致的。" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Router matches routes defined in config from top to bottom. If there is a match, further matching isn't performed and the router executes the route handler to get the response. If there is no match at all, router passes handling to the next middleware in the [application middleware set](../structure/middleware.md)." -msgstr "" +msgstr "路由器从上到下匹配配置中定义的路由。一旦匹配成功,就不再继续匹配,路由器会执行路由处理器以获取响应。如果完全没有匹配,路由器会将处理传递给[应用中间件集合](../structure/middleware.md)中的下一个中间件。" #. type: Title ## #: ../src/guide/runtime/routing.md #, no-wrap msgid "Generating URLs " -msgstr "" +msgstr "生成 URL " #. type: Plain text #: ../src/guide/runtime/routing.md msgid "To generate URL based on a route, a route should have a name:" -msgstr "" +msgstr "要根据路由生成 URL,路由必须有名称:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -349,7 +349,7 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "The generation looks like the following:" -msgstr "" +msgstr "生成方式如下:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -382,39 +382,39 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "In the above code, we get a generator instance with the help of [automatic dependency injection](../concept/di-container.md) that works with action handlers. In another service, you can get the instance with similar constructor injection. In views URL generator is available as `$url`." -msgstr "" +msgstr "在上述代码中,我们借助适用于操作处理器的[自动依赖注入](../concept/di-container.md)获取生成器实例。在其他服务中,可以通过类似的构造函数注入获取实例。在视图中,URL 生成器以 `$url` 变量的形式提供。" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Then we use `generate()` method to get actual URL. It accepts a route name and an array of named query parameters. The code will return \"/test/submit/42.\" If you need absolute URL, use `generateAbsolute()` instead." -msgstr "" +msgstr "然后使用 `generate()` 方法获取实际 URL,它接受路由名称和一个命名查询参数数组。上述代码将返回 \"/test/submit/42\"。如果需要绝对 URL,请改用 `generateAbsolute()`。" #. type: Title ## #: ../src/guide/runtime/routing.md #, no-wrap msgid "Route patterns " -msgstr "" +msgstr "路由模式 " #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Route patterns used depend on the underlying implementation used. The default implementation is [nikic/FastRoute](https://github.com/nikic/FastRoute)." -msgstr "" +msgstr "所使用的路由模式取决于底层实现。默认实现为 [nikic/FastRoute](https://github.com/nikic/FastRoute)。" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Basic patterns are static like `/test`. That means they must match exactly in order for a route match." -msgstr "" +msgstr "基本模式是静态的,如 `/test`,这意味着必须完全匹配才能成功路由。" #. type: Title ### #: ../src/guide/runtime/routing.md #, no-wrap msgid "Named Parameters " -msgstr "" +msgstr "命名参数 " #. type: Plain text #: ../src/guide/runtime/routing.md msgid "A pattern can include one or more named parameters which are specified in the pattern in the format of `{ParamName:RegExp}`, where `ParamName` specifies the parameter name and `RegExp` is an optional regular expression used to match parameter values. If `RegExp` isn't specified, it means the parameter value should be a string without any slash." -msgstr "" +msgstr "模式中可以包含一个或多个命名参数,格式为 `{ParamName:RegExp}`,其中 `ParamName` 指定参数名称,`RegExp` 是用于匹配参数值的可选正则表达式。如果未指定 `RegExp`,则表示参数值应为不含斜杠的字符串。" #. type: Plain text #: ../src/guide/runtime/routing.md @@ -423,21 +423,23 @@ msgid "" "> [!NOTE]\n" "> You can only use regular expressions inside parameters. The rest of the pattern is considered plain text.\n" msgstr "" +"> [!NOTE]\n" +"> 您只能在参数内部使用正则表达式,模式的其余部分被视为纯文本。\n" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "You can't use capturing groups. For example `{lang:(en|de)}` isn't a valid placeholder, because `()` is a capturing group. Instead, you can use either `{lang:en|de}` or `{lang:(?:en|de)}`." -msgstr "" +msgstr "不能使用捕获组。例如 `{lang:(en|de)}` 不是有效的占位符,因为 `()` 是捕获组。应改用 `{lang:en|de}` 或 `{lang:(?:en|de)}`。" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "On a route match router fills the associated request attributes with values matching the corresponding parts of the URL. When you use the rule to create a URL, it will take the values of the provided parameters and insert them at the places where the parameters are declared." -msgstr "" +msgstr "路由匹配时,路由器会用 URL 中对应部分的值填充相关请求属性。当使用规则生成 URL 时,它会取所提供参数的值并将其插入参数声明的位置。" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Let's use some examples to illustrate how named parameters work. Assume you've declared the following three patterns:" -msgstr "" +msgstr "让我们通过示例来说明命名参数的工作方式。假设您声明了以下三个模式:" #. type: Bullet: '1. ' #: ../src/guide/runtime/routing.md @@ -457,27 +459,27 @@ msgstr "" #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "`/posts` match the second pattern;" -msgstr "" +msgstr "`/posts` 匹配第二个模式;" #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "`/posts/2014/php` match a first pattern. Parameters are the `year` whose value is 2014 and the `category` whose value is `php`;" -msgstr "" +msgstr "`/posts/2014/php` 匹配第一个模式,参数 `year` 的值为 2014,`category` 的值为 `php`;" #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "`/post/100` match a third pattern. The `id` parameter value is 100;" -msgstr "" +msgstr "`/post/100` 匹配第三个模式,`id` 参数值为 100;" #. type: Bullet: '- ' #: ../src/guide/runtime/routing.md msgid "`/posts/php` doesn't match." -msgstr "" +msgstr "`/posts/php` 不匹配任何模式。" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "When generating URLs, you should use the following parameters:" -msgstr "" +msgstr "生成 URL 时,应使用以下参数:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -492,12 +494,12 @@ msgstr "" #: ../src/guide/runtime/routing.md #, no-wrap msgid "Optional parts " -msgstr "" +msgstr "可选部分 " #. type: Plain text #: ../src/guide/runtime/routing.md msgid "You should wrap optional pattern parts with `[` and `]`. For example, `/posts[/{id}]` pattern would match both `http://example.com/posts` and `http://example.com/posts/42`. Router would fill `id` argument of `CurrentRoute` service in the second case only. In this case, you could specify the default value:" -msgstr "" +msgstr "可选模式部分应用 `[` 和 `]` 包裹。例如,`/posts[/{id}]` 模式可以同时匹配 `http://example.com/posts` 和 `http://example.com/posts/42`。路由器只在第二种情况下填充 `CurrentRoute` 服务的 `id` 参数。此时可以指定默认值:" #. type: Fenced code block (php) #: ../src/guide/runtime/routing.md @@ -511,4 +513,4 @@ msgstr "" #. type: Plain text #: ../src/guide/runtime/routing.md msgid "Optional parts are only supported in a trailing position, not in the middle of a route." -msgstr "" +msgstr "可选部分只支持在路由末尾,不支持在路由中间。" diff --git a/_translations/po/zh-CN/guide_runtime_sessions.md.po b/_translations/po/zh-CN/guide_runtime_sessions.md.po index 9deb8144..e3780921 100644 --- a/_translations/po/zh-CN/guide_runtime_sessions.md.po +++ b/_translations/po/zh-CN/guide_runtime_sessions.md.po @@ -19,17 +19,17 @@ msgstr "" #: en/runtime/sessions.md #, no-wrap msgid "Sessions" -msgstr "" +msgstr "会话" #. type: Plain text #: en/runtime/sessions.md msgid "Sessions persist data between requests without passing them to the client and back. Yii has [a session package](https://github.com/yiisoft/session) to work with session data." -msgstr "" +msgstr "会话在请求之间持久化数据,无需将数据传递给客户端再传回。Yii 提供了 [会话包](https://github.com/yiisoft/session) 来处理会话数据。" #. type: Plain text #: en/runtime/sessions.md msgid "To add it to your application, use composer:" -msgstr "" +msgstr "要将其添加到应用程序,请使用 composer:" #. type: Fenced code block (shell) #: en/runtime/sessions.md @@ -41,17 +41,17 @@ msgstr "" #: en/runtime/sessions.md #, no-wrap msgid "Configuring middleware" -msgstr "" +msgstr "配置中间件" #. type: Plain text #: en/runtime/sessions.md msgid "To keep a session between requests, you need to add `SessionMiddleware` to your route group or application middlewares. You should prefer a route group when you have both API with token-based authentication and regular web routes in the same application. Having it this way avoids starting the session for API endpoints." -msgstr "" +msgstr "要在请求之间保持会话,需要将 `SessionMiddleware` 添加到路由组或应用程序中间件中。当应用程序同时包含基于令牌认证的 API 和常规 Web 路由时,优先选择路由组。这样可以避免为 API 端点启动会话。" #. type: Plain text #: en/runtime/sessions.md msgid "To add a session for a certain group of routes, edit `config/routes.php` like the following:" -msgstr "" +msgstr "要为特定路由组添加会话,请按如下方式编辑 `config/routes.php`:" #. type: Fenced code block (php) #: en/runtime/sessions.md @@ -76,7 +76,7 @@ msgstr "" #. type: Plain text #: en/runtime/sessions.md msgid "To add a session to the whole application, edit `config/application.php` like the following:" -msgstr "" +msgstr "要为整个应用程序添加会话,请按如下方式编辑 `config/application.php`:" #. type: Fenced code block (php) #: en/runtime/sessions.md @@ -105,7 +105,7 @@ msgstr "" #: en/runtime/sessions.md #, no-wrap msgid "Opening and closing session" -msgstr "" +msgstr "开启和关闭会话" #. type: Fenced code block (php) #: en/runtime/sessions.md @@ -131,11 +131,14 @@ msgid "" "> Closing session as early as possible is a good practice since many session implementations are blocking other\n" "> requests while the session is open.\n" msgstr "" +"> [!NOTE]\n" +"> 尽早关闭会话是一个良好实践,因为许多会话实现在会话开启期间\n" +"> 会阻塞其他请求。\n" #. type: Plain text #: en/runtime/sessions.md msgid "There are two more ways to close a session:" -msgstr "" +msgstr "关闭会话还有两种方式:" #. type: Fenced code block (php) #: en/runtime/sessions.md @@ -155,12 +158,12 @@ msgstr "" #: en/runtime/sessions.md #, no-wrap msgid "Working with session data" -msgstr "" +msgstr "处理会话数据" #. type: Plain text #: en/runtime/sessions.md msgid "Usually you will use the following methods to work with session data:" -msgstr "" +msgstr "通常您将使用以下方法处理会话数据:" #. type: Fenced code block (php) #: en/runtime/sessions.md @@ -197,17 +200,17 @@ msgstr "" #: en/runtime/sessions.md #, no-wrap msgid "Flash messages" -msgstr "" +msgstr "闪存消息" #. type: Plain text #: en/runtime/sessions.md msgid "In case you need some data to remain in session until read, such as in case of displaying a message on the next page, \"flash\" messages are what you need. A flash message is a special type of data that's available only in the current request and the next request. After that, it will be deleted automatically." -msgstr "" +msgstr "如果您需要某些数据在会话中保留直到被读取(例如在下一页显示消息),那么“闪存”消息正是您所需要的。闪存消息是一种特殊类型的数据,仅在当前请求和下一个请求中可用,之后将被自动删除。" #. type: Plain text #: en/runtime/sessions.md msgid "`FlashInteface` usage is the following:" -msgstr "" +msgstr "`FlashInterface` 的用法如下:" #. type: Fenced code block (php) #: en/runtime/sessions.md @@ -229,12 +232,12 @@ msgstr "" #: en/runtime/sessions.md #, no-wrap msgid "Custom session storage" -msgstr "" +msgstr "自定义会话存储" #. type: Plain text #: en/runtime/sessions.md msgid "When using `Yiisoft\\Session\\Session`, you can use your own storage implementation:" -msgstr "" +msgstr "使用 `Yiisoft\\Session\\Session` 时,您可以使用自定义存储实现:" #. type: Fenced code block (php) #: en/runtime/sessions.md @@ -247,4 +250,4 @@ msgstr "" #. type: Plain text #: en/runtime/sessions.md msgid "Custom storage must implement `\\SessionHandlerInterface`." -msgstr "" +msgstr "自定义存储必须实现 `\\SessionHandlerInterface`。" diff --git a/_translations/po/zh-CN/guide_security_authentication.md.po b/_translations/po/zh-CN/guide_security_authentication.md.po index 3becc701..a5243acf 100644 --- a/_translations/po/zh-CN/guide_security_authentication.md.po +++ b/_translations/po/zh-CN/guide_security_authentication.md.po @@ -19,37 +19,37 @@ msgstr "" #: ../src/guide/security/authentication.md #, no-wrap msgid "Authentication" -msgstr "" +msgstr "认证" #. type: Plain text #: ../src/guide/security/authentication.md msgid "Authentication is the process of verifying the identity of a user. It usually uses an identifier (for example, a username or an email address) and a secret token (such as a password or an access token) to judge if the user is the one whom he claims as. Authentication is the basis of the login feature." -msgstr "" +msgstr "认证是验证用户身份的过程。它通常使用标识符(例如用户名或电子邮件地址)和 secret 令牌(例如 password 或访问令牌)来判断用户是否是其声称的人。认证是登录功能的基础。" #. type: Plain text #: ../src/guide/security/authentication.md msgid "Yii provides an authentication framework which wires up various components to support login. To use this framework, you mainly need to do the following work:" -msgstr "" +msgstr "Yii 提供了一个认证框架,它连接各种组件以支持登录。要使用此框架,您主要需要执行以下工作:" #. type: Bullet: '* ' #: ../src/guide/security/authentication.md msgid "Configure the `Yiisoft\\User\\CurrentUser` service;" -msgstr "" +msgstr "配置 `Yiisoft\\User\\CurrentUser` 服务;" #. type: Bullet: '* ' #: ../src/guide/security/authentication.md msgid "Create a class implementing the `\\Yiisoft\\Auth\\IdentityInterface` interface;" -msgstr "" +msgstr "创建一个实现 `\\Yiisoft\\Auth\\IdentityInterface` 接口的类;" #. type: Bullet: '* ' #: ../src/guide/security/authentication.md msgid "Create a class implementing the `\\Yiisoft\\Auth\\IdentityRepositoryInterface` interface;" -msgstr "" +msgstr "创建一个实现 `\\Yiisoft\\Auth\\IdentityRepositoryInterface` 接口的类;" #. type: Plain text #: ../src/guide/security/authentication.md msgid "To use the `Yiisoft\\User\\CurrentUser` service, install [yiisoft/user](https://github.com/yiisoft/user) package:" -msgstr "" +msgstr "要使用 `Yiisoft\\User\\CurrentUser` 服务,请安装 [yiisoft/user](https://github.com/yiisoft/user) 包:" #. type: Fenced code block (shell) #: ../src/guide/security/authentication.md @@ -61,12 +61,12 @@ msgstr "" #: ../src/guide/security/authentication.md #, no-wrap msgid "Configuring `Yiisoft\\User\\CurrentUser`" -msgstr "" +msgstr "配置 `Yiisoft\\User\\CurrentUser`" #. type: Plain text #: ../src/guide/security/authentication.md msgid "The `Yiisoft\\User\\CurrentUser` application service manages the user authentication status. It depends on `Yiisoft\\Auth\\IdentityRepositoryInterface` that should return an instance of `\\Yiisoft\\Auth\\IdentityInterface` which has the actual authentication logic." -msgstr "" +msgstr "`Yiisoft\\User\\CurrentUser` 应用服务管理用户认证状态。它依赖于 `Yiisoft\\Auth\\IdentityRepositoryInterface`,该接口应返回一个包含实际认证逻辑的 `\\Yiisoft\\Auth\\IdentityInterface` 实例。" #. type: Fenced code block (php) #: ../src/guide/security/authentication.md @@ -98,22 +98,22 @@ msgstr "" #: ../src/guide/security/authentication.md #, no-wrap msgid "Implementing`\\Yiisoft\\Auth\\IdentityInterface` " -msgstr "" +msgstr "实现 `\\Yiisoft\\Auth\\IdentityInterface` " #. type: Plain text #: ../src/guide/security/authentication.md msgid "The identity class must implement the `\\Yiisoft\\Auth\\IdentityInterface` which has a single method:" -msgstr "" +msgstr "身份类必须实现 `\\Yiisoft\\Auth\\IdentityInterface` 接口,该接口只有一个方法:" #. type: Bullet: '* ' #: ../src/guide/security/authentication.md msgid "[[yii\\web\\IdentityInterface::getId()|getId()]]: it returns the ID of the user represented by this identity instance." -msgstr "" +msgstr "[[yii\\web\\IdentityInterface::getId()|getId()]]:它返回此身份实例所代表的用户的 ID。" #. type: Plain text #: ../src/guide/security/authentication.md msgid "In the following example, an identity class is implemented as a pure PHP object." -msgstr "" +msgstr "在以下示例中,身份类被实现为一个纯 PHP 对象。" #. type: Fenced code block (php) #: ../src/guide/security/authentication.md @@ -143,27 +143,27 @@ msgstr "" #: ../src/guide/security/authentication.md #, no-wrap msgid "Implementing`\\Yiisoft\\Auth\\IdentityRepositoryInterface` " -msgstr "" +msgstr "实现 `\\Yiisoft\\Auth\\IdentityRepositoryInterface` " #. type: Plain text #: ../src/guide/security/authentication.md msgid "The identity repository class must implement the `\\Yiisoft\\Auth\\IdentityRepositoryInterface` which has the following methods:" -msgstr "" +msgstr "身份仓库类必须实现 `\\Yiisoft\\Auth\\IdentityRepositoryInterface` 接口,该接口具有以下方法:" #. type: Bullet: '* ' #: ../src/guide/security/authentication.md msgid "`findIdentity(string $id): ?IdentityInterface`: it looks for an instance of the identity class using the specified ID. This method is used when you need to keep the login status via session." -msgstr "" +msgstr "`findIdentity(string $id): ?IdentityInterface`:它使用指定的 ID 查找身份类的实例。当您需要通过会话保持登录状态时使用此方法。" #. type: Bullet: '* ' #: ../src/guide/security/authentication.md msgid "`findIdentityByToken(string $token, string $type): ?IdentityInterface`: it looks for an instance of the identity class using the specified access token. This method is used when you need to authenticate a user by a single secret token (for example, in a stateless REST API)." -msgstr "" +msgstr "`findIdentityByToken(string $token, string $type): ?IdentityInterface`:它使用指定的访问令牌查找身份类的实例。当您需要通过单个 secret 令牌(例如,在无状态 REST API 中)对用户进行认证时使用此方法。" #. type: Plain text #: ../src/guide/security/authentication.md msgid "A dummy implementation may look like the following:" -msgstr "" +msgstr "一个示例实现可能如下所示:" #. type: Fenced code block (php) #: ../src/guide/security/authentication.md @@ -216,12 +216,12 @@ msgstr "" #: ../src/guide/security/authentication.md #, no-wrap msgid "Using `Yiisoft\\User\\CurrentUser`" -msgstr "" +msgstr "使用 `Yiisoft\\User\\CurrentUser`" #. type: Plain text #: ../src/guide/security/authentication.md msgid "You can use `Yiisoft\\User\\CurrentUser` service to get current user identity. As any service, it could be auto-wired in either action handler constructor or method:" -msgstr "" +msgstr "您可以使用 `Yiisoft\\User\\CurrentUser` 服务来获取当前用户身份。与任何服务一样,它可以在操作处理器的构造函数或方法中自动装配:" #. type: Fenced code block (php) #: ../src/guide/security/authentication.md @@ -249,12 +249,12 @@ msgstr "" #. type: Plain text #: ../src/guide/security/authentication.md msgid "`isGuest()` determines if user is logged in or not. `getIdentity()` returns an instance of identity." -msgstr "" +msgstr "`isGuest()` 判断用户是否已登录。`getIdentity()` 返回一个身份实例。" #. type: Plain text #: ../src/guide/security/authentication.md msgid "To log in a user, you may use the following code:" -msgstr "" +msgstr "要登录用户,您可以使用以下代码:" #. type: Fenced code block (php) #: ../src/guide/security/authentication.md @@ -269,12 +269,12 @@ msgstr "" #. type: Plain text #: ../src/guide/security/authentication.md msgid "The `login()` method sets the identity to the User service. It stores identity into session so user authentication status is maintained." -msgstr "" +msgstr "`login()` 方法将身份设置到用户服务。它将身份存储到会话中,以便维护用户认证状态。" #. type: Plain text #: ../src/guide/security/authentication.md msgid "To log out a user, call" -msgstr "" +msgstr "要注销用户,请调用" #. type: Fenced code block (php) #: ../src/guide/security/authentication.md @@ -288,17 +288,17 @@ msgstr "" #: ../src/guide/security/authentication.md #, no-wrap msgid "Protecting Routes" -msgstr "" +msgstr "保护路由" #. type: Plain text #: ../src/guide/security/authentication.md msgid "The `Yiisoft\\Auth\\Middleware\\Authentication` middleware can be used to restrict access to a given route to authenticated users only." -msgstr "" +msgstr "`Yiisoft\\Auth\\Middleware\\Authentication` 中间件可用于将对给定路由的访问限制为仅限已认证用户。" #. type: Plain text #: ../src/guide/security/authentication.md msgid "First, configure the `Yiisoft\\Auth\\AuthenticationMethodInterface`:" -msgstr "" +msgstr "首先,配置 `Yiisoft\\Auth\\AuthenticationMethodInterface`:" #. type: Fenced code block (php) #: ../src/guide/security/authentication.md @@ -316,7 +316,7 @@ msgstr "" #. type: Plain text #: ../src/guide/security/authentication.md msgid "Then, apply the `Yiisoft\\Auth\\Middleware\\Authentication` middleware to a route:" -msgstr "" +msgstr "然后,将 `Yiisoft\\Auth\\Middleware\\Authentication` 中间件应用到路由:" #. type: Fenced code block (php) #: ../src/guide/security/authentication.md @@ -334,7 +334,7 @@ msgstr "" #: ../src/guide/security/authentication.md #, no-wrap msgid " Or to a group of routes:\n" -msgstr "" +msgstr " 或应用到一组路由:\n" #. type: Fenced code block (php) #: ../src/guide/security/authentication.md @@ -358,34 +358,34 @@ msgstr "" #: ../src/guide/security/authentication.md #, no-wrap msgid "Authentication Events " -msgstr "" +msgstr "认证事件 " #. type: Plain text #: ../src/guide/security/authentication.md msgid "The user service raises a few events during the login and logout processes." -msgstr "" +msgstr "用户服务在登录和注销过程中会触发一些事件。" #. type: Bullet: '* ' #: ../src/guide/security/authentication.md msgid "`\\Yiisoft\\User\\Event\\BeforeLogin`: raised at the beginning of `login()`. If the event handler calls `invalidate()` on an event object, the login process will be cancelled." -msgstr "" +msgstr "`\\Yiisoft\\User\\Event\\BeforeLogin`:在 `login()` 开始时触发。如果事件处理器在事件对象上调用 `invalidate()`,登录过程将被取消。" #. type: Bullet: '* ' #: ../src/guide/security/authentication.md msgid "`\\Yiisoft\\User\\Event\\AfterLogin`: raised after a successful login." -msgstr "" +msgstr "`\\Yiisoft\\User\\Event\\AfterLogin`:在成功登录后触发。" #. type: Bullet: '* ' #: ../src/guide/security/authentication.md msgid "`\\Yiisoft\\User\\Event\\BeforeLogout`: raised at the beginning of `logout()`. If the event handler calls `invalidate()` on an event object, the logout process will be cancelled." -msgstr "" +msgstr "`\\Yiisoft\\User\\Event\\BeforeLogout`:在 `logout()` 开始时触发。如果事件处理器在事件对象上调用 `invalidate()`,注销过程将被取消。" #. type: Bullet: '* ' #: ../src/guide/security/authentication.md msgid "`\\Yiisoft\\User\\Event\\AfterLogout`: raised after a successful logout." -msgstr "" +msgstr "`\\Yiisoft\\User\\Event\\AfterLogout`:在成功注销后触发。" #. type: Plain text #: ../src/guide/security/authentication.md msgid "You may respond to these events to implement features such as login audit, online user statistics. For example, in the handler for `\\Yiisoft\\User\\Event\\AfterLogin`, you may record the login time and IP address in the `user` database table." -msgstr "" +msgstr "您可以响应这些事件来实现登录审计、在线用户统计等功能。例如,在 `\\Yiisoft\\User\\Event\\AfterLogin` 的处理器中,您可以在 `user` 数据库表中记录登录时间和 IP 地址。" diff --git a/_translations/po/zh-CN/guide_security_authorization.md.po b/_translations/po/zh-CN/guide_security_authorization.md.po index 71f84913..0a3e2f09 100644 --- a/_translations/po/zh-CN/guide_security_authorization.md.po +++ b/_translations/po/zh-CN/guide_security_authorization.md.po @@ -19,23 +19,23 @@ msgstr "" #: ../src/guide/security/authorization.md #, no-wrap msgid "Authorization" -msgstr "" +msgstr "授权" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Authorization is the process of verifying that a user has enough permission to do something." -msgstr "" +msgstr "授权是验证用户是否有足够权限执行某项操作的过程。" #. type: Title ## #: ../src/guide/security/authorization.md #, no-wrap msgid "Checking for permission " -msgstr "" +msgstr "检查权限 " #. type: Plain text #: ../src/guide/security/authorization.md msgid "You can check if a user has certain permissions by using `\\Yiisoft\\User\\CurrentUser` service:" -msgstr "" +msgstr "您可以使用 `\\Yiisoft\\User\\CurrentUser` 服务来检查用户是否具有特定权限:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -81,101 +81,101 @@ msgstr "" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Behind the scenes, `Yiisoft\\User\\CurrentUser::can()` method calls `Yiisoft\\Access\\AccessCheckerInterface::userHasPermission()` so you should provide an implementation in dependency container in order for it to work." -msgstr "" +msgstr "在幕后,`Yiisoft\\User\\CurrentUser::can()` 方法调用 `Yiisoft\\Access\\AccessCheckerInterface::userHasPermission()`,因此您应该在依赖容器中提供一个实现才能使其工作。" #. type: Title ## #: ../src/guide/security/authorization.md #, no-wrap msgid "Role-based access control (RBAC) " -msgstr "" +msgstr "基于角色的访问控制 (RBAC) " #. type: Plain text #: ../src/guide/security/authorization.md msgid "Role-Based Access Control (RBAC) provides a simple yet powerful centralized access control. Please refer to the [Wikipedia](https://en.wikipedia.org/wiki/Role-based_access_control) for details about comparing RBAC with other more traditional access control schemes." -msgstr "" +msgstr "基于角色的访问控制 (RBAC) 提供了一种简单而强大的集中式访问控制。有关 RBAC 与其他更传统的访问控制方案的比较详情,请参阅 [Wikipedia](https://en.wikipedia.org/wiki/Role-based_access_control)。" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Yii implements a General Hierarchical RBAC, following the [NIST RBAC model](https://csrc.nist.gov/CSRC/media/Publications/conference-paper/2000/07/26/the-nist-model-for-role-based-access-control-towards-a-unified-/documents/sandhu-ferraiolo-kuhn-00.pdf)." -msgstr "" +msgstr "Yii 实现了通用分层 RBAC,遵循 [NIST RBAC 模型](https://csrc.nist.gov/CSRC/media/Publications/conference-paper/2000/07/26/the-nist-model-for-role-based-access-control-towards-a-unified-/documents/sandhu-ferraiolo-kuhn-00.pdf)。" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Using RBAC involves two parts of work. The first part is to build up the RBAC authorization data, and the second part is to use the authorization data to perform access check in places where it's necessary. Since RBAC implements `\\Yiisoft\\Access\\AccessCheckerInterface`, using it's similar to using any other implementation of an access checker." -msgstr "" +msgstr "使用 RBAC 涉及两部分工作。第一部分是构建 RBAC 授权数据,第二部分是在必要的地方使用授权数据执行访问检查。由于 RBAC 实现了 `\\Yiisoft\\Access\\AccessCheckerInterface`,使用它类似于使用任何其他访问检查器的实现。" #. type: Plain text #: ../src/guide/security/authorization.md msgid "To ease description next, there are some basic RBAC concepts first." -msgstr "" +msgstr "为了便于接下来的描述,首先介绍一些基本的 RBAC 概念。" #. type: Title ### #: ../src/guide/security/authorization.md #, no-wrap msgid "Basic concepts " -msgstr "" +msgstr "基本概念 " #. type: Plain text #: ../src/guide/security/authorization.md msgid "A role represents a collection of *permissions* (for example, creating posts, updating posts). You may assign a role to one or many users. To check if a user has a specified permission, you may check if the user has a role with that permission." -msgstr "" +msgstr "角色代表一组*权限*(例如,创建文章、更新文章)。您可以将角色分配给一个或多个用户。要检查用户是否具有指定的权限,您可以检查用户是否具有包含该权限的角色。" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Associated with each role or permission, there may be a *rule*. A rule represents a piece of code that an access checker will execute to decide if the corresponding role or permission applies to the current user. For example, the \"update post\" permission may have a rule that checks if the current user is the post creator. During access checking, if the user is NOT the post creator, there's no \"update post\" permission." -msgstr "" +msgstr "每个角色或权限可能关联一个*规则*。规则代表访问检查器将执行的一段代码,用于决定相应的角色或权限是否适用于当前用户。例如,“更新文章”权限可能有一个规则来检查当前用户是否是文章创建者。在访问检查期间,如果用户不是文章创建者,则没有“更新文章”权限。" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Both roles and permissions are in a hierarchy. In particular, a role may consist of other roles or permissions. And a permission may consist of other permissions. Yii implements a *partial order* hierarchy which includes the more special *tree* hierarchy. While a role can contain a permission, it isn't `true` vice versa." -msgstr "" +msgstr "角色和权限都处于层次结构中。特别是,一个角色可以由其他角色或权限组成。一个权限可以由其他权限组成。Yii 实现了*偏序*层次结构,其中包括更特殊的*树*层次结构。虽然角色可以包含权限,但反之则不成立。" #. type: Title ### #: ../src/guide/security/authorization.md #, no-wrap msgid "Configuring RBAC " -msgstr "" +msgstr "配置 RBAC " #. type: Plain text #: ../src/guide/security/authorization.md msgid "Yii RBAC requires storage to be provided." -msgstr "" +msgstr "Yii RBAC 需要提供存储。" #. type: Plain text #: ../src/guide/security/authorization.md msgid "One of the following storages could be installed:" -msgstr "" +msgstr "可以安装以下存储之一:" #. type: Bullet: '- ' #: ../src/guide/security/authorization.md msgid "[PHP storage](https://github.com/yiisoft/rbac-php) - PHP file storage;" -msgstr "" +msgstr "[PHP storage](https://github.com/yiisoft/rbac-php) — PHP 文件存储;" #. type: Bullet: '- ' #: ../src/guide/security/authorization.md msgid "[DB storage](https://github.com/yiisoft/rbac-db) - database storage based on [Yii DB](https://github.com/yiisoft/db);" -msgstr "" +msgstr "[DB storage](https://github.com/yiisoft/rbac-db) — 基于 [Yii DB](https://github.com/yiisoft/db) 的数据库存储;" #. type: Bullet: '- ' #: ../src/guide/security/authorization.md msgid "[Cycle DB storage](https://github.com/yiisoft/rbac-cycle-db) - database storage based on [Cycle DBAL](https://github.com/cycle/database)." -msgstr "" +msgstr "[Cycle DB storage](https://github.com/yiisoft/rbac-cycle-db) — 基于 [Cycle DBAL](https://github.com/cycle/database) 的数据库存储。" #. type: Plain text #: ../src/guide/security/authorization.md msgid "You can also provide your own storage using the [yiisoft/rbac](https://github.com/yiisoft/rbac) package." -msgstr "" +msgstr "您还可以使用 [yiisoft/rbac](https://github.com/yiisoft/rbac) 包提供自己的存储。" #. type: Title #### #: ../src/guide/security/authorization.md #, no-wrap msgid "Configuring RBAC with the [PHP storage](https://github.com/yiisoft/rbac-php) " -msgstr "" +msgstr "使用 [PHP storage](https://github.com/yiisoft/rbac-php) 配置 RBAC " #. type: Plain text #: ../src/guide/security/authorization.md msgid "Install [yiisoft/rbac-php](https://github.com/yiisoft/rbac-php) package:" -msgstr "" +msgstr "安装 [yiisoft/rbac-php](https://github.com/yiisoft/rbac-php) 包:" #. type: Fenced code block #: ../src/guide/security/authorization.md @@ -186,7 +186,7 @@ msgstr "" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Before we set off to define authorization data and perform access checking, you need to configure the `Yiisoft\\Access\\AccessCheckerInterface` in dependency container:" -msgstr "" +msgstr "在开始定义授权数据和执行访问检查之前,您需要在依赖容器中配置 `Yiisoft\\Access\\AccessCheckerInterface`:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -225,18 +225,18 @@ msgstr "" #. type: Plain text #: ../src/guide/security/authorization.md msgid "`Yiisoft\\Rbac\\Manager` uses PHP script files to store authorization data. Make sure the directory and all the files in it are writable by the Web server process if you want to change permission hierarchy online." -msgstr "" +msgstr "`Yiisoft\\Rbac\\Manager` 使用 PHP 脚本文件来存储授权数据。如果您想在线更改权限层次结构,请确保该目录及其中的所有文件都可由 Web 服务器进程写入。" #. type: Title #### #: ../src/guide/security/authorization.md #, no-wrap msgid "Configuring RBAC with the [DB storage](https://github.com/yiisoft/rbac-db) " -msgstr "" +msgstr "使用 [DB storage](https://github.com/yiisoft/rbac-db) 配置 RBAC " #. type: Plain text #: ../src/guide/security/authorization.md msgid "Install [yiisoft/rbac-db](https://github.com/yiisoft/rbac-db) package:" -msgstr "" +msgstr "安装 [yiisoft/rbac-db](https://github.com/yiisoft/rbac-db) 包:" #. type: Fenced code block #: ../src/guide/security/authorization.md @@ -255,11 +255,17 @@ msgid "" " - [Microsoft SQL Server](https://github.com/yiisoft/db-mssql)\n" " - [Oracle](https://github.com/yiisoft/db-oracle)\n" msgstr "" +"安装以下驱动程序之一:\n" +" - [SQLite](https://github.com/yiisoft/db-sqlite)(最低要求版本为 3.8.3)\n" +" - [MySQL](https://github.com/yiisoft/db-mysql)\n" +" - [PostgreSQL](https://github.com/yiisoft/db-pgsql)\n" +" - [Microsoft SQL Server](https://github.com/yiisoft/db-mssql)\n" +" - [Oracle](https://github.com/yiisoft/db-oracle)\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "[Configure connection](https://yiisoft.github.io/docs/guide/start/databases.html#configuring-connection)." -msgstr "" +msgstr "[配置连接](https://yiisoft.github.io/docs/guide/start/databases.html#configuring-connection)。" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -283,7 +289,7 @@ msgstr "" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Add the RBAC [DB storage](https://github.com/yiisoft/rbac-db) migration paths to params.php:" -msgstr "" +msgstr "将 RBAC [DB storage](https://github.com/yiisoft/rbac-db) 迁移路径添加到 params.php:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -303,7 +309,7 @@ msgstr "" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Apply migrations:" -msgstr "" +msgstr "应用迁移:" #. type: Fenced code block #: ../src/guide/security/authorization.md @@ -315,68 +321,68 @@ msgstr "" #: ../src/guide/security/authorization.md #, no-wrap msgid "Building authorization data " -msgstr "" +msgstr "构建授权数据 " #. type: Plain text #: ../src/guide/security/authorization.md msgid "Building authorization data is all about the following tasks:" -msgstr "" +msgstr "构建授权数据涉及以下任务:" #. type: Bullet: '- ' #: ../src/guide/security/authorization.md msgid "defining roles and permissions;" -msgstr "" +msgstr "定义角色和权限;" #. type: Bullet: '- ' #: ../src/guide/security/authorization.md msgid "establishing relations between roles and permissions;" -msgstr "" +msgstr "建立角色和权限之间的关系;" #. type: Bullet: '- ' #: ../src/guide/security/authorization.md msgid "defining rules;" -msgstr "" +msgstr "定义规则;" #. type: Bullet: '- ' #: ../src/guide/security/authorization.md msgid "associating rules with roles and permissions;" -msgstr "" +msgstr "将规则与角色和权限关联;" #. type: Bullet: '- ' #: ../src/guide/security/authorization.md msgid "assigning roles to users." -msgstr "" +msgstr "将角色分配给用户。" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Depending on authorization flexibility requirements, you can do the tasks in different ways. If only developers change your permission hierarchy, you can use either migrations or a console command. Migration advantage is that you could execute it along with other migrations. The Console command advantage is that you have a good overview of the hierarchy in the code without a need to read many migrations." -msgstr "" +msgstr "根据授权灵活性要求,您可以以不同的方式完成这些任务。如果只有开发人员更改您的权限层次结构,您可以使用迁移或控制台命令。迁移的优点是您可以与其他迁移一起执行它。控制台命令的优点是您可以在代码中很好地概览层次结构,而无需阅读许多迁移。" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Either way, in the end, you'll get the following RBAC hierarchy:" -msgstr "" +msgstr "无论哪种方式,最终您都会得到以下 RBAC 层次结构:" #. type: Plain text #: ../src/guide/security/authorization.md msgid "![Simple RBAC hierarchy](/images/guide/security/rbac-hierarchy-1.svg \"Simple RBAC hierarchy\")" -msgstr "" +msgstr "![简单的 RBAC 层次结构](/images/guide/security/rbac-hierarchy-1.svg \"简单的 RBAC 层次结构\")" #. type: Plain text #: ../src/guide/security/authorization.md msgid "In case you want to build permission hierarchy dynamically, you need a UI or a console command. The API used to build the hierarchy itself won't be different." -msgstr "" +msgstr "如果您想动态构建权限层次结构,则需要 UI 或控制台命令。用于构建层次结构本身的 API 不会有所不同。" #. type: Title ### #: ../src/guide/security/authorization.md #, no-wrap msgid "Using console command" -msgstr "" +msgstr "使用控制台命令" #. type: Plain text #: ../src/guide/security/authorization.md msgid "If your permission hierarchy doesn't change at all, and you have a fixed number of users, you can create a [console command](../tutorial/console-applications.md) that will initialize authorization data once via APIs offered by `\\Yiisoft\\Rbac\\ManagerInterface`:" -msgstr "" +msgstr "如果您的权限层次结构根本不会改变,并且您有固定数量的用户,则可以创建一个[控制台命令](../tutorial/console-applications.md),通过 `\\Yiisoft\\Rbac\\ManagerInterface` 提供的 API 一次性初始化授权数据:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -452,7 +458,7 @@ msgstr "" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Add the command to `config/console/commands.php`:" -msgstr "" +msgstr "将命令添加到 `config/console/commands.php`:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -467,7 +473,7 @@ msgstr "" #. type: Plain text #: ../src/guide/security/authorization.md msgid "You can execute the command above from the console the following way:" -msgstr "" +msgstr "您可以通过以下方式从控制台执行上述命令:" #. type: Fenced code block #: ../src/guide/security/authorization.md @@ -482,28 +488,30 @@ msgid "" "> If you don't want to hardcode what users have certain roles, don't put `->assign()` calls into the command. Instead,\n" " create either UI or console command to manage assignments.\n" msgstr "" +"> 如果您不想硬编码哪些用户具有某些角色,请不要在命令中放入 `->assign()` 调用。相反,\n" +" 创建 UI 或控制台命令来管理分配。\n" #. type: Title #### #: ../src/guide/security/authorization.md #, no-wrap msgid "Using migrations" -msgstr "" +msgstr "使用迁移" #. type: Plain text #: ../src/guide/security/authorization.md #, no-wrap msgid "**TODO**: finish it when migrations are implemented.\n" -msgstr "" +msgstr "**TODO**:在实现迁移时完成它。\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "You can use [migrations](../databases/db-migrations.md) to initialize and change hierarchy via APIs offered by `\\Yiisoft\\Rbac\\ManagerInterface`." -msgstr "" +msgstr "您可以使用 [迁移](../databases/db-migrations.md) 通过 `\\Yiisoft\\Rbac\\ManagerInterface` 提供的 API 初始化和更改层次结构。" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Create new migration using `APP_ENV=dev ./yii migrate:create init_rbac` then implement creating a hierarchy:" -msgstr "" +msgstr "使用 `APP_ENV=dev ./yii migrate:create init_rbac` 创建新迁移,然后实现创建层次结构:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -571,33 +579,35 @@ msgid "" "> If you don't want to hardcode which users have certain roles, don't put `->assign()` calls in migrations. Instead,\n" " create either UI or console command to manage assignments.\n" msgstr "" +"> 如果您不想硬编码哪些用户具有某些角色,请不要在迁移中放入 `->assign()` 调用。相反,\n" +" 创建 UI 或控制台命令来管理分配。\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "You could apply migration by using `APP_ENV=dev ./yii migrate:up`." -msgstr "" +msgstr "您可以使用 `APP_ENV=dev ./yii migrate:up` 应用迁移。" #. type: Title ## #: ../src/guide/security/authorization.md #, no-wrap msgid "Assigning roles to users" -msgstr "" +msgstr "将角色分配给用户" #. type: Plain text #: ../src/guide/security/authorization.md #, no-wrap msgid "TODO: update when signup implemented in demo / template.\n" -msgstr "" +msgstr "TODO:在演示/模板中实现注册时更新。\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "The author can create a post, admin can update the post and do everything the author can." -msgstr "" +msgstr "作者可以创建文章,管理员可以更新文章并执行作者可以执行的所有操作。" #. type: Plain text #: ../src/guide/security/authorization.md msgid "If your application allows user signup, you need to assign roles to these new users at once. For example, in order for all signed-up users to become authors in your advanced project template, you need to change `frontend\\models\\SignupForm::signup()` as follows:" -msgstr "" +msgstr "如果您的应用程序允许用户注册,您需要立即将角色分配给这些新用户。例如,为了让所有注册用户在您的高级项目模板中成为作者,您需要按如下方式更改 `frontend\\models\\SignupForm::signup()`:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -629,18 +639,18 @@ msgstr "" #. type: Plain text #: ../src/guide/security/authorization.md msgid "For applications that require complex access control with dynamically updated authorization data (such as an admin panel), you many need to develop special user interfaces using APIs offered by `Yiisoft\\Rbac\\Manager`." -msgstr "" +msgstr "对于需要复杂访问控制和动态更新授权数据的应用程序(例如管理面板),您可能需要使用 `Yiisoft\\Rbac\\Manager` 提供的 API 开发特殊的用户界面。" #. type: Title ### #: ../src/guide/security/authorization.md #, no-wrap msgid "Using rules " -msgstr "" +msgstr "使用规则 " #. type: Plain text #: ../src/guide/security/authorization.md msgid "As aforementioned, rules add extra constraint to roles and permissions. A rule is a class extending from `\\Yiisoft\\Rbac\\Rule`. It must implement the `execute()` method. In the hierarchy you've created before, the author can't edit his own post. Let's fix it. First, you need a rule to verify that the user is the post author:" -msgstr "" +msgstr "如前所述,规则为角色和权限添加了额外的约束。规则是从 `\\Yiisoft\\Rbac\\Rule` 扩展的类。它必须实现 `execute()` 方法。在您之前创建的层次结构中,作者无法编辑自己的文章。让我们修复它。首先,您需要一个规则来验证用户是文章作者:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -668,7 +678,7 @@ msgstr "" #. type: Plain text #: ../src/guide/security/authorization.md msgid "The rule checks if user created the `post`. Create a special permission `updateOwnPost` in the command you've used before:" -msgstr "" +msgstr "该规则检查用户是否创建了 `post`。在您之前使用的命令中创建一个特殊权限 `updateOwnPost`:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -696,23 +706,23 @@ msgstr "" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Now you've got the following hierarchy:" -msgstr "" +msgstr "现在您得到了以下层次结构:" #. type: Plain text #: ../src/guide/security/authorization.md msgid "![RBAC hierarchy with a rule](/images/guide/security/rbac-hierarchy-2.svg \"RBAC hierarchy with a rule\")" -msgstr "" +msgstr "![带有规则的 RBAC 层次结构](/images/guide/security/rbac-hierarchy-2.svg \"带有规则的 RBAC 层次结构\")" #. type: Title ### #: ../src/guide/security/authorization.md #, no-wrap msgid "Access check " -msgstr "" +msgstr "访问检查 " #. type: Plain text #: ../src/guide/security/authorization.md msgid "The check is done similarly to how it was done in the first section of this guide:" -msgstr "" +msgstr "检查的方式与本指南第一部分中的方式类似:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -757,22 +767,22 @@ msgstr "" #. type: Plain text #: ../src/guide/security/authorization.md msgid "The difference is that now checking for a user's own post is part of the RBAC." -msgstr "" +msgstr "不同之处在于,现在检查用户自己的文章是 RBAC 的一部分。" #. type: Plain text #: ../src/guide/security/authorization.md msgid "If the current user is Jane with `ID=1` you are starting at `createPost` and trying to get to `Jane`:" -msgstr "" +msgstr "如果当前用户是 Jane,`ID=1`,您从 `createPost` 开始并尝试到达 `Jane`:" #. type: Plain text #: ../src/guide/security/authorization.md msgid "![Access check](/images/guide/security/rbac-access-check-1.svg \"Access check\")" -msgstr "" +msgstr "![访问检查](/images/guide/security/rbac-access-check-1.svg \"访问检查\")" #. type: Plain text #: ../src/guide/security/authorization.md msgid "To check if a user can update a post, you need to pass an extra parameter that's required by `AuthorRule` described before:" -msgstr "" +msgstr "要检查用户是否可以更新文章,您需要传递之前描述的 `AuthorRule` 所需的额外参数:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md @@ -786,12 +796,12 @@ msgstr "" #. type: Plain text #: ../src/guide/security/authorization.md msgid "Here is what happens if the current user is John:" -msgstr "" +msgstr "如果当前用户是 John,会发生以下情况:" #. type: Plain text #: ../src/guide/security/authorization.md msgid "![Access check](/images/guide/security/rbac-access-check-2.svg \"Access check\")" -msgstr "" +msgstr "![访问检查](/images/guide/security/rbac-access-check-2.svg \"访问检查\")" #. type: Plain text #: ../src/guide/security/authorization.md @@ -802,27 +812,31 @@ msgid "" "`['post' => $post]`.\n" "If everything is fine, you will get to `author` assigned to John.\n" msgstr "" +"您从 `updatePost` 开始并通过 `updateOwnPost`。要通过访问检查,`AuthorRule`\n" +"应该从其 `execute()` 方法返回 `true`。该方法从 `can()` 方法调用接收其 `$params`,因此值为\n" +"`['post' => $post]`。\n" +"如果一切正常,您将到达分配给 John 的 `author`。\n" #. type: Plain text #: ../src/guide/security/authorization.md msgid "In the case of Jane, it's a bit simpler since she is an admin:" -msgstr "" +msgstr "在 Jane 的情况下,这更简单,因为她是管理员:" #. type: Plain text #: ../src/guide/security/authorization.md msgid "![Access check](/images/guide/security/rbac-access-check-3.svg \"Access check\")" -msgstr "" +msgstr "![访问检查](/images/guide/security/rbac-access-check-3.svg \"访问检查\")" #. type: Title ## #: ../src/guide/security/authorization.md #, no-wrap msgid "Implementing your own access checker" -msgstr "" +msgstr "实现您自己的访问检查器" #. type: Plain text #: ../src/guide/security/authorization.md msgid "If RBAC doesn't suit your needs, you can implement your own access checker without changing the application code:" -msgstr "" +msgstr "如果 RBAC 不适合您的需求,您可以在不更改应用程序代码的情况下实现自己的访问检查器:" #. type: Fenced code block (php) #: ../src/guide/security/authorization.md diff --git a/_translations/po/zh-CN/guide_security_best-practices.md.po b/_translations/po/zh-CN/guide_security_best-practices.md.po index 5f806e09..60e9702a 100644 --- a/_translations/po/zh-CN/guide_security_best-practices.md.po +++ b/_translations/po/zh-CN/guide_security_best-practices.md.po @@ -30,44 +30,44 @@ msgstr "参考资料" #: ../src/guide/security/best-practices.md #, no-wrap msgid "Security best practices" -msgstr "" +msgstr "安全最佳实践" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Below, we'll review common security principles and describe how to avoid threats when developing applications using Yii. Most of these principles aren't unique to Yii alone but apply to website or software development in general, so you will also find links for further reading on the general ideas behind these." -msgstr "" +msgstr "下面,我们将回顾常见的安全原则,并描述在使用 Yii 开发应用程序时如何避免威胁。这些原则中的大多数并非 Yii 独有,而是适用于一般的网站或软件开发,因此您还会找到有关这些背后一般思想的进一步阅读链接。" #. type: Title ## #: ../src/guide/security/best-practices.md #, no-wrap msgid "Basic principles" -msgstr "" +msgstr "基本原则" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "There are two main principles when it comes to security no matter which application is being developed:" -msgstr "" +msgstr "无论开发哪种应用程序,在安全方面都有两个主要原则:" #. type: Bullet: '1. ' #: ../src/guide/security/best-practices.md msgid "Filter input." -msgstr "" +msgstr "过滤输入。" #. type: Bullet: '2. ' #: ../src/guide/security/best-practices.md msgid "Escape output." -msgstr "" +msgstr "转义输出。" #. type: Title ### #: ../src/guide/security/best-practices.md #, no-wrap msgid "Filter input" -msgstr "" +msgstr "过滤输入" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Filter input means that you should never consider input safe, and you should always check if the value you've got is actually among allowed ones. For example, if you know that you sort by three fields `title`, `created_at` and `status` and the field came from user input, it's better to check the value you've got right where you're receiving it. In terms of basic PHP, that would look like the following:" -msgstr "" +msgstr "过滤输入意味着您永远不应该认为输入是安全的,您应该始终检查您获得的值是否确实在允许的值之中。例如,如果您知道您按三个字段 `title`、`created_at` 和 `status` 排序,并且该字段来自用户输入,最好在接收它的地方检查您获得的值。就基本 PHP 而言,看起来如下:" #. type: Fenced code block (php) #: ../src/guide/security/best-practices.md @@ -82,12 +82,12 @@ msgstr "" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "In Yii, most probably you'll use form validation to do similar checks." -msgstr "" +msgstr "在 Yii 中,您很可能会使用表单验证来进行类似的检查。" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Further reading on the topic:" -msgstr "" +msgstr "有关该主题的进一步阅读:" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md @@ -103,7 +103,7 @@ msgstr "" #: ../src/guide/security/best-practices.md #, no-wrap msgid "Escape output" -msgstr "" +msgstr "转义输出" #. type: Plain text #: ../src/guide/security/best-practices.md @@ -115,6 +115,11 @@ msgid "" "In the context of JavaScript or SQL, it will be a different set of characters.\n" "Since it's error-prone to escape manually, Yii provides various tools to perform escaping in different contexts.\n" msgstr "" +"转义输出意味着,根据您使用数据的上下文,\n" +"您应该在其前面加上特殊字符以消除其特殊含义。\n" +"在 HTML 上下文中,您应该转义 `<`、`>` 和类似的特殊字符。\n" +"在 JavaScript 或 SQL 的上下文中,它将是一组不同的字符。\n" +"由于手动转义容易出错,Yii 提供了各种工具来在不同上下文中执行转义。\n" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md @@ -135,12 +140,12 @@ msgstr "" #: ../src/guide/security/best-practices.md #, no-wrap msgid "Avoiding SQL injections" -msgstr "" +msgstr "避免 SQL 注入" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "SQL injection happens when you form a query text by concatenating unescaped strings such as the following:" -msgstr "" +msgstr "SQL 注入发生在您通过连接未转义的字符串来形成查询文本时,如下所示:" #. type: Fenced code block (php) #: ../src/guide/security/best-practices.md @@ -153,7 +158,7 @@ msgstr "" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Instead of supplying correct username attacker could give your applications something like `'; DROP TABLE user; --`. The Resulting SQL will be the following:" -msgstr "" +msgstr "攻击者可以给您的应用程序提供类似 `'; DROP TABLE user; --` 的内容,而不是提供正确的用户名。结果 SQL 将如下所示:" #. type: Fenced code block (sql) #: ../src/guide/security/best-practices.md @@ -164,17 +169,17 @@ msgstr "" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "This is a valid query that will search for users with empty username and then will drop `user` table most probably resulting in a broken website and data loss (you've set up regular backups, right?)." -msgstr "" +msgstr "这是一个有效的查询,它将搜索用户名为空的用户,然后删除 `user` 表,很可能导致网站损坏和数据丢失(您已经设置了定期备份,对吧?)。" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Make sure to either use PDO prepared statements directly or ensure that the library you prefer is doing it. In the case of prepared statements, it's impossible to manipulate the query as was demonstrated above." -msgstr "" +msgstr "确保直接使用 PDO 预处理语句,或确保您喜欢的库正在这样做。在预处理语句的情况下,不可能像上面演示的那样操纵查询。" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "If you use data to specify column names or table names, the best thing to do is to allow only a predefined set of values:" -msgstr "" +msgstr "如果您使用数据来指定列名或表名,最好的做法是只允许预定义的值集:" #. type: Fenced code block (php) #: ../src/guide/security/best-practices.md @@ -199,7 +204,7 @@ msgstr "" #: ../src/guide/security/best-practices.md #, no-wrap msgid "Avoiding XSS" -msgstr "" +msgstr "避免 XSS" #. type: Plain text #: ../src/guide/security/best-practices.md @@ -211,26 +216,31 @@ msgid "" "in a browser. Depending on the website instead of innocent alert, such a script could send messages using your name or even\n" "perform bank transactions.\n" msgstr "" +"XSS 或跨站脚本攻击发生在向浏览器输出 HTML 时输出未正确转义的情况下。例如,\n" +"如果用户可以输入他的名字,而不是 `Alexander`,他输入 ``,每个\n" +"输出用户名而不转义它的页面都将执行 JavaScript `alert('Hello!');`,导致警告框在\n" +"浏览器中弹出。根据网站的不同,这样的脚本可以使用您的名字发送消息,甚至\n" +"执行银行交易,而不是无害的警告。\n" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Avoiding XSS is quite easy in Yii. There are two cases:" -msgstr "" +msgstr "在 Yii 中避免 XSS 非常容易。有两种情况:" #. type: Bullet: '1. ' #: ../src/guide/security/best-practices.md msgid "You want to output data as plain text." -msgstr "" +msgstr "您想将数据输出为纯文本。" #. type: Bullet: '2. ' #: ../src/guide/security/best-practices.md msgid "You want to output data as HTML." -msgstr "" +msgstr "您想将数据输出为 HTML。" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "If all you need is plain text, then escaping is as easy as the following:" -msgstr "" +msgstr "如果您只需要纯文本,那么转义就像下面这样简单:" #. type: Fenced code block (php) #: ../src/guide/security/best-practices.md @@ -241,18 +251,18 @@ msgstr "" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "If it should be HTML, you could get some help from [HtmlPurifier](http://htmlpurifier.org/). Note that HtmlPurifier processing is quite heavy, so consider adding caching." -msgstr "" +msgstr "如果它应该是 HTML,您可以从 [HtmlPurifier](http://htmlpurifier.org/) 获得一些帮助。请注意,HtmlPurifier 处理相当繁重,因此请考虑添加缓存。" #. type: Title ## #: ../src/guide/security/best-practices.md #, no-wrap msgid "Avoiding CSRF" -msgstr "" +msgstr "避免 CSRF" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "CSRF is an abbreviation for cross-site request forgery. The idea is that many applications assume that requests coming from a user browser are made by the user themselves. This assumption could be false." -msgstr "" +msgstr "CSRF 是跨站请求伪造的缩写。其思想是许多应用程序假设来自用户浏览器的请求是由用户自己发出的。这个假设可能是错误的。" #. type: Plain text #: ../src/guide/security/best-practices.md @@ -264,6 +274,11 @@ msgid "" "requesting an image or requesting a page so when the user opens a page with such a manipulated `` tag,\n" "the browser will send the GET request to that URL and the user will be logged out from `an.example.com`.\n" msgstr "" +"例如,网站 `an.example.com` 有一个 `/logout` URL,当使用简单的 GET 请求访问时,会将用户注销。只要\n" +"它是由用户自己请求的,一切都很好,但有一天坏人以某种方式在用户经常访问的论坛上发布\n" +"``。浏览器在\n" +"请求图像或请求页面之间没有任何区别,因此当用户打开带有这样一个被操纵的 `` 标签的页面时,\n" +"浏览器将向该 URL 发送 GET 请求,用户将从 `an.example.com` 注销。\n" #. type: Plain text #: ../src/guide/security/best-practices.md @@ -280,31 +295,41 @@ msgid "" "Unfortunately, this won't save you, because an attacker\n" "can put some JavaScript code instead of `` tag, which allows sending POST requests to that URL as well.\n" msgstr "" +"这就是 CSRF 攻击工作原理的基本思想。有人可能会说注销用户不是什么严重的事情。\n" +"然而,这只是一个例子。\n" +"使用这种方法可以做更多的事情。\n" +"例如,触发付款或更改数据。想象一下某个网站有一个 URL\n" +"`http://an.example.com/purse/transfer?to=anotherUser&amount=2000`。使用 GET 请求访问它,会导致\n" +"从授权用户帐户向用户 `anotherUser` 转账 $2000。\n" +"您知道浏览器总是会发送 GET 请求来加载图像,\n" +"因此您可以更改代码以仅接受该 URL 上的 POST 请求。\n" +"不幸的是,这不会拯救您,因为攻击者\n" +"可以放置一些 JavaScript 代码而不是 `` 标签,这也允许向该 URL 发送 POST 请求。\n" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "For this reason, Yii applies extra mechanisms to protect against CSRF attacks." -msgstr "" +msgstr "因此,Yii 应用额外的机制来防止 CSRF 攻击。" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "To avoid CSRF, you should always:" -msgstr "" +msgstr "为了避免 CSRF,您应该始终:" #. type: Bullet: '1. ' #: ../src/guide/security/best-practices.md msgid "Follow HTTP specification. GET shouldn't change the application state. See [RFC2616](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html) for more details." -msgstr "" +msgstr "遵循 HTTP 规范。GET 不应该改变应用程序状态。有关更多详细信息,请参阅 [RFC2616](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html)。" #. type: Bullet: '2. ' #: ../src/guide/security/best-practices.md msgid "Keep Yii CSRF protection enabled." -msgstr "" +msgstr "保持 Yii CSRF 保护启用。" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Yii has CSRF protection as `Yiisoft\\Yii\\Web\\Middleware\\Csrf` middleware. Make sure it's in your application middleware stack." -msgstr "" +msgstr "Yii 将 CSRF 保护作为 `Yiisoft\\Yii\\Web\\Middleware\\Csrf` 中间件。确保它在您的应用程序中间件堆栈中。" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md @@ -320,7 +345,7 @@ msgstr "" #: ../src/guide/security/best-practices.md #, no-wrap msgid "Avoiding file exposure" -msgstr "" +msgstr "避免文件暴露" #. type: Plain text #: ../src/guide/security/best-practices.md @@ -329,32 +354,34 @@ msgid "" "By default, server webroot is meant to be pointed to `public` directory where `index.php` is. In the case of shared hosting\n" " environments, it could be impossible to achieve, so you'll end up with all the code, configs and logs in server webroot.\n" msgstr "" +"默认情况下,服务器 webroot 应该指向 `index.php` 所在的 `public` 目录。在共享托管\n" +"环境的情况下,这可能无法实现,因此您最终会将所有代码、配置和日志放在服务器 webroot 中。\n" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "If so, remember to deny access to everything except `web`. If it's impossible, consider hosting your application elsewhere." -msgstr "" +msgstr "如果是这样,请记住拒绝访问除 `web` 之外的所有内容。如果不可能,请考虑在其他地方托管您的应用程序。" #. type: Title ## #: ../src/guide/security/best-practices.md #, no-wrap msgid "Avoiding debug info and tools in production" -msgstr "" +msgstr "避免在生产环境中使用调试信息和工具" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "In debug mode, Yii shows quite verbose errors which are certainly helpful for development. The thing is that these verbose errors are handy for attacker as well since these could reveal database structure, configuration values and parts of your code." -msgstr "" +msgstr "在调试模式下,Yii 显示相当详细的错误,这对开发肯定有帮助。问题是这些详细的错误对攻击者也很方便,因为它们可能会泄露数据库结构、配置值和部分代码。" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Never run production applications with debugger or Gii accessible to everyone. One could use it to get information about database structure, code and to simply rewrite code with what's generated by Gii." -msgstr "" +msgstr "永远不要在调试器或 Gii 可供所有人访问的情况下运行生产应用程序。有人可以使用它来获取有关数据库结构、代码的信息,并简单地用 Gii 生成的内容重写代码。" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "You should avoid the debug toolbar in production unless necessary. It exposes all the application and config details possible. If you absolutely need it, check twice you restrict access to your IP only." -msgstr "" +msgstr "除非必要,否则应避免在生产环境中使用调试工具栏。它会暴露所有可能的应用程序和配置详细信息。如果您绝对需要它,请仔细检查您是否仅限制对您的 IP 的访问。" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md @@ -370,44 +397,44 @@ msgstr "" #: ../src/guide/security/best-practices.md #, no-wrap msgid "Using secure connection over TLS" -msgstr "" +msgstr "通过 TLS 使用安全连接" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Yii provides features that rely on cookies and/or PHP sessions. These can be vulnerable in case your connection is compromised. The risk is reduced if the app uses secure connection via TLS (often referred to as [SSL](https://en.wikipedia.org/wiki/Transport_Layer_Security))." -msgstr "" +msgstr "Yii 提供依赖于 cookie 和/或 PHP 会话的功能。如果您的连接受到威胁,这些可能会受到攻击。如果应用程序通过 TLS 使用安全连接(通常称为 [SSL](https://en.wikipedia.org/wiki/Transport_Layer_Security)),则风险会降低。" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Nowadays, anyone can get a certificate for free and automatically update it thanks to [Let's Encrypt](https://letsencrypt.org/)." -msgstr "" +msgstr "如今,任何人都可以免费获得证书并自动更新它,这要归功于 [Let's Encrypt](https://letsencrypt.org/)。" #. type: Title ## #: ../src/guide/security/best-practices.md #, no-wrap msgid "Secure server configuration" -msgstr "" +msgstr "安全的服务器配置" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "The purpose of this section is to highlight risks that need to be considered when creating a server configuration for serving a Yii-based website. Besides the points covered here, there may be other security-related configuration options to be considered, so don't consider this section to be complete." -msgstr "" +msgstr "本节的目的是强调在为基于 Yii 的网站创建服务器配置时需要考虑的风险。除了这里涵盖的要点之外,可能还有其他与安全相关的配置选项需要考虑,因此不要认为本节是完整的。" #. type: Title ### #: ../src/guide/security/best-practices.md #, no-wrap msgid "Avoiding `Host`-header attacks" -msgstr "" +msgstr "避免 `Host` 头攻击" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "If the webserver is configured to serve the same site independent of the value of the `Host` header, this information mayn't be reliable and [may be faked by the user sending the HTTP request](https://www.acunetix.com/vulnerabilities/web/host-header-attack). In such situations, you should fix your webserver configuration to serve the site only for specified host names." -msgstr "" +msgstr "如果 Web 服务器配置为独立于 `Host` 头的值提供相同的站点,则此信息可能不可靠,并且[可能被发送 HTTP 请求的用户伪造](https://www.acunetix.com/vulnerabilities/web/host-header-attack)。在这种情况下,您应该修复您的 Web 服务器配置,以仅为指定的主机名提供站点。" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "For more information about the server configuration, please refer to the documentation of your webserver:" -msgstr "" +msgstr "有关服务器配置的更多信息,请参阅您的 Web 服务器的文档:" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md @@ -423,12 +450,12 @@ msgstr "" #: ../src/guide/security/best-practices.md #, no-wrap msgid "Configuring SSL peer validation" -msgstr "" +msgstr "配置 SSL 对等验证" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "There is a typical misconception about how to solve SSL certificate validation issues such as:" -msgstr "" +msgstr "关于如何解决 SSL 证书验证问题存在一个典型的误解,例如:" #. type: Fenced code block #: ../src/guide/security/best-practices.md @@ -439,7 +466,7 @@ msgstr "" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "or" -msgstr "" +msgstr "或" #. type: Fenced code block #: ../src/guide/security/best-practices.md @@ -450,17 +477,17 @@ msgstr "" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Many sources wrongly suggest disabling SSL peer verification. That shouldn't be ever done since it enables man-in-the middle type of attacks. Instead, PHP should be configured properly:" -msgstr "" +msgstr "许多来源错误地建议禁用 SSL 对等验证。这永远不应该这样做,因为它会启用中间人类型的攻击。相反,应该正确配置 PHP:" #. type: Bullet: '1. ' #: ../src/guide/security/best-practices.md msgid "Download [https://curl.haxx.se/ca/cacert.pem](https://curl.haxx.se/ca/cacert.pem)." -msgstr "" +msgstr "下载 [https://curl.haxx.se/ca/cacert.pem](https://curl.haxx.se/ca/cacert.pem)。" #. type: Bullet: '2. ' #: ../src/guide/security/best-practices.md msgid "Add the following to your php.ini:" -msgstr "" +msgstr "将以下内容添加到您的 php.ini:" #. type: Fenced code block #: ../src/guide/security/best-practices.md @@ -473,7 +500,7 @@ msgstr "" #. type: Plain text #: ../src/guide/security/best-practices.md msgid "Note that you should keep the file up to date." -msgstr "" +msgstr "请注意,您应该保持文件最新。" #. type: Bullet: '- ' #: ../src/guide/security/best-practices.md diff --git a/_translations/po/zh-CN/guide_security_cryptography.md.po b/_translations/po/zh-CN/guide_security_cryptography.md.po index 59786cdf..7342bbdc 100644 --- a/_translations/po/zh-CN/guide_security_cryptography.md.po +++ b/_translations/po/zh-CN/guide_security_cryptography.md.po @@ -19,32 +19,32 @@ msgstr "" #: en/security/cryptography.md #, no-wrap msgid "Cryptography" -msgstr "" +msgstr "加密" #. type: Plain text #: en/security/cryptography.md msgid "In this section, we'll review the following security aspects:" -msgstr "" +msgstr "在本节中,我们将回顾以下安全方面:" #. type: Bullet: '- ' #: en/security/cryptography.md msgid "Generating random data" -msgstr "" +msgstr "生成随机数据" #. type: Bullet: '- ' #: en/security/cryptography.md msgid "Encryption and Decryption" -msgstr "" +msgstr "加密和解密" #. type: Bullet: '- ' #: en/security/cryptography.md msgid "Confirming Data Integrity" -msgstr "" +msgstr "确认数据完整性" #. type: Plain text #: en/security/cryptography.md msgid "To use these features, you need to install `yiisoft/security` package:" -msgstr "" +msgstr "要使用这些功能,您需要安装 `yiisoft/security` 包:" #. type: Fenced code block #: en/security/cryptography.md @@ -56,12 +56,12 @@ msgstr "" #: en/security/cryptography.md #, no-wrap msgid "Generating pseudorandom data" -msgstr "" +msgstr "生成伪随机数据" #. type: Plain text #: en/security/cryptography.md msgid "Pseudorandom data are useful in many situations. For example, when resetting a password via email, you need to generate a token, save it to the database, and send it via email to the end user, which in turn will allow them to prove ownership of that account. It's important that this token be unique and hard to guess, else there is a possibility that an attacker can predict the token's value and reset the user's password." -msgstr "" +msgstr "伪随机数据在许多情况下都很有用。例如,当通过电子邮件重置密码时,您需要生成一个令牌,将其保存到数据库,并通过电子邮件发送给最终用户,这反过来将允许他们证明对该帐户的所有权。重要的是,此令牌必须是唯一的且难以猜测,否则攻击者有可能预测令牌的值并重置用户的密码。" #. type: Plain text #: en/security/cryptography.md @@ -77,33 +77,33 @@ msgstr "" #. type: Plain text #: en/security/cryptography.md msgid "The code above would give you a random string consisting of 42 characters." -msgstr "" +msgstr "上面的代码将为您提供一个由 42 个字符组成的随机字符串。" #. type: Plain text #: en/security/cryptography.md msgid "If you need bytes or integers, use PHP functions directly:" -msgstr "" +msgstr "如果您需要字节或整数,请直接使用 PHP 函数:" #. type: Bullet: '- ' #: en/security/cryptography.md msgid "`random_bytes()` for bytes. Note that the output may not be ASCII." -msgstr "" +msgstr "使用 `random_bytes()` 生成字节。请注意,输出可能不是 ASCII。" #. type: Bullet: '- ' #: en/security/cryptography.md msgid "`random_int()` for integers." -msgstr "" +msgstr "`random_int()` 用于整数。" #. type: Title ## #: en/security/cryptography.md #, no-wrap msgid "Encryption and decryption" -msgstr "" +msgstr "加密和解密" #. type: Plain text #: en/security/cryptography.md msgid "Yii provides convenient helper functions to encrypt/decrypt data using a secret key. The data is passed through the encryption function so that only the person who has the secret key will be able to decrypt it. For example, you need to store some information in your database, but you need to make sure only the user who has the secret key can view it (even if one compromises the application database):" -msgstr "" +msgstr "Yii 提供了方便的辅助函数,使用密钥加密/解密数据。数据通过加密函数传递,以便只有拥有密钥的人才能解密它。例如,您需要在数据库中存储一些信息,但您需要确保只有拥有密钥的用户才能查看它(即使有人破坏了应用程序数据库):" #. type: Fenced code block (php) #: en/security/cryptography.md @@ -118,7 +118,7 @@ msgstr "" #. type: Plain text #: en/security/cryptography.md msgid "Decrypting it:" -msgstr "" +msgstr "解密它:" #. type: Fenced code block (php) #: en/security/cryptography.md @@ -133,7 +133,7 @@ msgstr "" #. type: Plain text #: en/security/cryptography.md msgid "You could use a key instead of a password:" -msgstr "" +msgstr "您可以使用密钥而不是密码:" #. type: Fenced code block (php) #: en/security/cryptography.md @@ -159,17 +159,17 @@ msgstr "" #: en/security/cryptography.md #, no-wrap msgid "Confirming data integrity" -msgstr "" +msgstr "确认数据完整性" #. type: Plain text #: en/security/cryptography.md msgid "There are situations in which you need to verify that your data hasn't been tampered with by a third party or even corrupted in some way. Yii provides a way to confirm data integrity by MAC signing." -msgstr "" +msgstr "在某些情况下,您需要验证您的数据没有被第三方篡改,甚至以某种方式损坏。Yii 提供了一种通过 MAC 签名确认数据完整性的方法。" #. type: Plain text #: en/security/cryptography.md msgid "The `$key` should be present at both sending and receiving sides. On the sending side:" -msgstr "" +msgstr "`$key` 应该在发送端和接收端都存在。在发送端:" #. type: Fenced code block (php) #: en/security/cryptography.md @@ -183,7 +183,7 @@ msgstr "" #. type: Plain text #: en/security/cryptography.md msgid "On the receiving side:" -msgstr "" +msgstr "在接收端:" #. type: Fenced code block (php) #: en/security/cryptography.md @@ -202,17 +202,17 @@ msgstr "" #: en/security/cryptography.md #, no-wrap msgid "Masking token length" -msgstr "" +msgstr "掩码令牌长度" #. type: Plain text #: en/security/cryptography.md msgid "Masking a token helps to mitigate a BREACH attack by randomizing how the token outputted on each request. A random mask is applied to the token, making the string always unique." -msgstr "" +msgstr "掩码令牌有助于通过随机化每个请求上令牌的输出方式来缓解 BREACH 攻击。对令牌应用随机掩码,使字符串始终唯一。" #. type: Plain text #: en/security/cryptography.md msgid "To mask a token:" -msgstr "" +msgstr "要掩码令牌:" #. type: Fenced code block (php) #: en/security/cryptography.md @@ -223,7 +223,7 @@ msgstr "" #. type: Plain text #: en/security/cryptography.md msgid "To get the original value from the masked one:" -msgstr "" +msgstr "要从掩码中获取原始值:" #. type: Fenced code block (php) #: en/security/cryptography.md diff --git a/_translations/po/zh-CN/guide_security_overview.md.po b/_translations/po/zh-CN/guide_security_overview.md.po index f2316dfe..23bcc3f0 100644 --- a/_translations/po/zh-CN/guide_security_overview.md.po +++ b/_translations/po/zh-CN/guide_security_overview.md.po @@ -19,49 +19,49 @@ msgstr "" #: en/security/overview.md #, no-wrap msgid "Security" -msgstr "" +msgstr "安全" #. type: Plain text #: en/security/overview.md msgid "Good security is vital to the health and success of any application. Unfortunately, many developers cut corners when it comes to security, either due to a lack of understanding or because implementation is too much of a hurdle. To make your Yii-powered application as secure as possible, Yii has included several excellent and easy-to-use security features." -msgstr "" +msgstr "良好的安全性对于任何应用程序的健康和成功至关重要。不幸的是,许多开发人员在安全方面偷工减料,要么是由于缺乏理解,要么是因为实施起来太困难。为了使您的 Yii 驱动的应用程序尽可能安全,Yii 包含了几个出色且易于使用的安全功能。" #. type: Bullet: '* ' #: en/security/overview.md msgid "[Authentication](authentication.md)" -msgstr "" +msgstr "[认证](authentication.md)" #. type: Bullet: '* ' #: en/security/overview.md msgid "[Authorization](authorization.md)" -msgstr "" +msgstr "[授权](authorization.md)" #. type: Bullet: '* ' #: en/security/overview.md msgid "[Working with Passwords](passwords.md)" -msgstr "" +msgstr "[使用 Passwords](passwords.md)" #. type: Bullet: '* ' #: en/security/overview.md msgid "[Cryptography](cryptography.md)" -msgstr "" +msgstr "[加密](cryptography.md)" #. type: Bullet: '* ' #: en/security/overview.md msgid "[Best Practices](best-practices.md)" -msgstr "" +msgstr "[最佳实践](best-practices.md)" #. type: Bullet: '* ' #: en/security/overview.md msgid "[Trusted request](trusted-request.md)" -msgstr "" +msgstr "[可信请求](trusted-request.md)" #. type: Plain text #: en/security/overview.md msgid "See also:" -msgstr "" +msgstr "另请参阅:" #. type: Bullet: '* ' #: en/security/overview.md msgid "[Views security](../views/view.md#security)" -msgstr "" +msgstr "[视图安全](../views/view.md#security)" diff --git a/_translations/po/zh-CN/guide_security_passwords.md.po b/_translations/po/zh-CN/guide_security_passwords.md.po index fddbacf8..95cad5ef 100644 --- a/_translations/po/zh-CN/guide_security_passwords.md.po +++ b/_translations/po/zh-CN/guide_security_passwords.md.po @@ -19,22 +19,22 @@ msgstr "" #: en/security/passwords.md #, no-wrap msgid "Working with passwords" -msgstr "" +msgstr "使用密码" #. type: Plain text #: en/security/passwords.md msgid "Most developers know that passwords can't be stored in plain text, but many developers believe it's still safe to hash passwords using `md5`, `sha1` or `sha256` etc. There was a time when using the aforementioned hashing algorithms was enough, but modern hardware makes it possible to reverse such hashes and even stronger ones using brute force attacks." -msgstr "" +msgstr "大多数开发人员知道密码不能以纯文本形式存储,但许多开发人员认为使用 `md5`、`sha1` 或 `sha256` 等对密码进行哈希处理仍然是安全的。曾经有一段时间,使用上述哈希算法就足够了,但现代硬件使得可以使用暴力攻击来逆向这些哈希甚至更强的哈希。" #. type: Plain text #: en/security/passwords.md msgid "To offer increased security for user passwords, even in the worst case scenario (when one breaches your application), you need to use a hashing algorithm that's resilient against brute force attacks. The best current choice is `argon2`. Yii `yiisoft/security` package make securely generate and verify hashes easier and ensure the best possible hashing solution used." -msgstr "" +msgstr "为了为用户密码提供更高的安全性,即使在最坏的情况下(当有人破坏您的应用程序时),您需要使用能够抵御暴力攻击的哈希算法。目前最好的选择是 `argon2`。Yii `yiisoft/security` 包使安全生成和验证哈希变得更容易,并确保使用最佳的哈希解决方案。" #. type: Plain text #: en/security/passwords.md msgid "To use it, you need to require the package first:" -msgstr "" +msgstr "要使用它,您需要首先安装该包:" #. type: Fenced code block #: en/security/passwords.md @@ -45,7 +45,7 @@ msgstr "" #. type: Plain text #: en/security/passwords.md msgid "When a user provides a password for the first time (e.g., upon registration), the password needs to be hashed and stored:" -msgstr "" +msgstr "当用户第一次提供密码时(例如,注册时),需要对密码进行哈希处理并存储:" #. type: Fenced code block (php) #: en/security/passwords.md @@ -60,7 +60,7 @@ msgstr "" #. type: Plain text #: en/security/passwords.md msgid "When a user attempts to log in, the submitted password must be verified against the previously hashed and stored password:" -msgstr "" +msgstr "当用户尝试登录时,提交的密码必须与之前哈希和存储的密码进行验证:" #. type: Fenced code block (php) #: en/security/passwords.md diff --git a/_translations/po/zh-CN/guide_security_trusted-request.md.po b/_translations/po/zh-CN/guide_security_trusted-request.md.po index afb7985b..9fe0d07f 100644 --- a/_translations/po/zh-CN/guide_security_trusted-request.md.po +++ b/_translations/po/zh-CN/guide_security_trusted-request.md.po @@ -19,22 +19,22 @@ msgstr "" #: en/security/trusted-request.md #, no-wrap msgid "Trusted request" -msgstr "" +msgstr "可信请求" #. type: Plain text #: en/security/trusted-request.md msgid "Getting user information, like a host and IP address, will work out of the box in a normal setup where a single webserver is used to serve the website. If your Yii application, however, runs behind a reverse proxy, you need to add configuration to retrieve this information as the direct client is now the proxy, and the user IP address is passed to the Yii application by a header set by the proxy." -msgstr "" +msgstr "在使用单个 Web 服务器为网站提供服务的正常设置中,获取用户信息(如主机和 IP 地址)将开箱即用。但是,如果您的 Yii 应用程序在反向代理后面运行,则需要添加配置来检索此信息,因为直接客户端现在是代理,用户 IP 地址由代理设置的标头传递给 Yii 应用程序。" #. type: Plain text #: en/security/trusted-request.md msgid "You shouldn't blindly trust headers provided by proxies unless you explicitly trust the proxy. Yii supports configuring trusted proxies via the `Yiisoft\\Yii\\Web\\Middleware\\TrustedHostsNetworkResolver`. You should add it to [middleware stack](../structure/middleware.md)." -msgstr "" +msgstr "除非您明确信任代理,否则不应盲目信任代理提供的标头。Yii 支持通过 `Yiisoft\\Yii\\Web\\Middleware\\TrustedHostsNetworkResolver` 配置可信代理。您应该将其添加到[中间件堆栈](../structure/middleware.md)。" #. type: Plain text #: en/security/trusted-request.md msgid "The following is a request config for an application that runs behind an array of reverse proxies, which are located in the `10.0.2.0/24` IP network:" -msgstr "" +msgstr "以下是在一组反向代理后面运行的应用程序的请求配置,这些代理位于 `10.0.2.0/24` IP 网络中:" #. type: Fenced code block (php) #: en/security/trusted-request.md @@ -47,12 +47,12 @@ msgstr "" #. type: Plain text #: en/security/trusted-request.md msgid "The proxy sends the IP in the `X-Forwarded-For` header by default, and the protocol (`http` or `https`) is in `X-Forwarded-Proto`." -msgstr "" +msgstr "代理默认在 `X-Forwarded-For` 标头中发送 IP,协议(`http` 或 `https`)在 `X-Forwarded-Proto` 中。" #. type: Plain text #: en/security/trusted-request.md msgid "In case your proxies are using different headers, you can use the request configuration to adjust these, e.g.:" -msgstr "" +msgstr "如果您的代理使用不同的标头,您可以使用请求配置来调整这些,例如:" #. type: Fenced code block (php) #: en/security/trusted-request.md @@ -73,4 +73,4 @@ msgstr "" #. type: Plain text #: en/security/trusted-request.md msgid "With the above configuration, `X-ProxyUser-Ip` and `Front-End-Https` headers are used to get user IP and protocol." -msgstr "" +msgstr "使用上述配置,`X-ProxyUser-Ip` 和 `Front-End-Https` 标头用于获取用户 IP 和协议。" diff --git a/_translations/po/zh-CN/guide_start_creating-project.md.po b/_translations/po/zh-CN/guide_start_creating-project.md.po index 92c2cd22..33c884e7 100644 --- a/_translations/po/zh-CN/guide_start_creating-project.md.po +++ b/_translations/po/zh-CN/guide_start_creating-project.md.po @@ -19,12 +19,12 @@ msgstr "" #: ../src/guide/start/creating-project.md #, no-wrap msgid "Creating a project" -msgstr "" +msgstr "创建项目" #. type: Plain text #: ../src/guide/start/creating-project.md msgid "In this guide we'll provide commands for both [Docker](https://docs.docker.com/get-started/get-docker/) and the built-in dev server with everything installed locally." -msgstr "" +msgstr "在本指南中,我们将提供 [Docker](https://docs.docker.com/get-started/get-docker/) 和本地安装所有内容的内置开发服务器的命令。" #. type: Plain text #: ../src/guide/start/creating-project.md @@ -34,16 +34,19 @@ msgid "" "> If you want to use another web server,\n" "> see [\"Configuring web servers\"](../../cookbook/configuring-webservers/general.md).\n" msgstr "" +"> [!NOTE]\n" +"> 如果你想使用其他 Web 服务器,\n" +"> 请参阅 [\"配置 Web 服务器\"](../../cookbook/configuring-webservers/general.md)。\n" #. type: Plain text #: ../src/guide/start/creating-project.md msgid "We recommend starting with a project template that's a minimal working Yii project implementing some basic features. It can serve as a good starting point for your projects." -msgstr "" +msgstr "我们建议从项目模板开始,这是一个实现了一些基本功能的最小可工作的 Yii 项目。它可以作为你项目的良好起点。" #. type: Plain text #: ../src/guide/start/creating-project.md msgid "You can create a new project from a template using the [Composer](https://getcomposer.org) package manager:" -msgstr "" +msgstr "你可以使用 [Composer](https://getcomposer.org) 包管理器从模板创建一个新项目:" #. type: Fenced code block (sh) #: ../src/guide/start/creating-project.md @@ -54,7 +57,7 @@ msgstr "" #. type: Plain text #: ../src/guide/start/creating-project.md msgid "Docker users can run the following commands:" -msgstr "" +msgstr "Docker 用户可以运行以下命令:" #. type: Fenced code block (sh) #: ../src/guide/start/creating-project.md @@ -69,7 +72,7 @@ msgstr "" #. type: Plain text #: ../src/guide/start/creating-project.md msgid "If you want development version instead of release one:" -msgstr "" +msgstr "如果你想要开发版本而不是发布版本:" #. type: Fenced code block (sh) #: ../src/guide/start/creating-project.md @@ -84,7 +87,7 @@ msgstr "" #. type: Plain text #: ../src/guide/start/creating-project.md msgid "This installs the latest stable version of the Yii project template in a directory named `your_project`. You can choose a different directory name if you want." -msgstr "" +msgstr "这将在名为 `your_project` 的目录中安装最新稳定版本的 Yii 项目模板。如果你愿意,可以选择不同的目录名称。" #. type: Plain text #: ../src/guide/start/creating-project.md @@ -94,11 +97,14 @@ msgid "" "> If you want to install the latest development version of Yii, you may add `--stability=dev` to the command.\n" "> Don't use the development version of Yii for production because it may break your running code.\n" msgstr "" +"> [!TIP]\n" +"> 如果你想安装最新的 Yii 开发版本,可以在命令中添加 `--stability=dev`。\n" +"> 不要在生产环境中使用 Yii 的开发版本,因为它可能会破坏你正在运行的代码。\n" #. type: Plain text #: ../src/guide/start/creating-project.md msgid "Go into the newly created directory and run:" -msgstr "" +msgstr "进入新创建的目录并运行:" #. type: Fenced code block (sh) #: ../src/guide/start/creating-project.md @@ -109,7 +115,7 @@ msgstr "" #. type: Plain text #: ../src/guide/start/creating-project.md msgid "For Windows Command Prompt users, run:" -msgstr "" +msgstr "对于 Windows 命令提示符用户,运行:" #. type: Fenced code block (cmd) #: ../src/guide/start/creating-project.md @@ -122,7 +128,7 @@ msgstr "" #. type: Plain text #: ../src/guide/start/creating-project.md msgid "For Windows PowerShell users, run:" -msgstr "" +msgstr "对于 Windows PowerShell 用户,运行:" #. type: Fenced code block (powershell) #: ../src/guide/start/creating-project.md @@ -135,7 +141,7 @@ msgstr "" #. type: Plain text #: ../src/guide/start/creating-project.md msgid "For Docker users, run:" -msgstr "" +msgstr "对于 Docker 用户,运行:" #. type: Fenced code block (sh) #: ../src/guide/start/creating-project.md @@ -146,7 +152,7 @@ msgstr "" #. type: Plain text #: ../src/guide/start/creating-project.md msgid "Open your browser to the URL `http://localhost/`." -msgstr "" +msgstr "在浏览器中打开 URL `http://localhost/`。" #. type: Plain text #: ../src/guide/start/creating-project.md @@ -156,8 +162,11 @@ msgid "" "> The HTTP server listens on port 80. If that port is already in use, specify the port via `--port` or, in case of Docker,\n" "> `DEV_PORT` in the `docker/.env` file.\n" msgstr "" +"> [!NOTE]\n" +"> HTTP 服务器监听 80 端口。如果该端口已被占用,请通过 `--port` 指定端口,或者在 Docker 的情况下,\n" +"> 在 `docker/.env` 文件中设置 `DEV_PORT`。\n" #. type: Plain text #: ../src/guide/start/creating-project.md msgid "![Successful Installation of Yii](/images/guide/start/app-installed.png)" -msgstr "" +msgstr "![成功安装 Yii](/images/guide/start/app-installed.png)" diff --git a/_translations/po/zh-CN/guide_start_databases.md.po b/_translations/po/zh-CN/guide_start_databases.md.po index e8151021..3ae73ef5 100644 --- a/_translations/po/zh-CN/guide_start_databases.md.po +++ b/_translations/po/zh-CN/guide_start_databases.md.po @@ -35,12 +35,12 @@ msgstr "" #: ../src/guide/index.md ../src/guide/start/databases.md #, no-wrap msgid "Working with databases" -msgstr "" +msgstr "使用数据库" #. type: Plain text #: ../src/guide/start/databases.md msgid "Yii doesn't dictate using a particular database or storage for your application. There are many ways you can work with relational databases:" -msgstr "" +msgstr "Yii 不强制您的应用程序使用特定的数据库或存储。有许多方式可以使用关系型数据库:" #. type: Bullet: '- ' #: ../src/guide/start/databases.md @@ -70,7 +70,7 @@ msgstr "" #. type: Plain text #: ../src/guide/start/databases.md msgid "For non-relational ones, there are usually official libraries available:" -msgstr "" +msgstr "对于非关系型数据库,通常也有官方库可用:" #. type: Bullet: '- ' #: ../src/guide/start/databases.md @@ -90,23 +90,23 @@ msgstr "" #. type: Plain text #: ../src/guide/start/databases.md msgid "In this guide, we will focus on working with relational databases using Yii DB. We'll use PostgreSQL to implement a simple CRUD (create read update delete)." -msgstr "" +msgstr "在本指南中,我们将重点介绍使用 Yii DB 处理关系型数据库。我们将使用 PostgreSQL 实现一个简单的 CRUD(创建、读取、更新、删除)。" #. type: Title ## #: ../src/guide/start/databases.md #, no-wrap msgid "Installing PostgreSQL" -msgstr "" +msgstr "安装 PostgreSQL" #. type: Plain text #: ../src/guide/start/databases.md msgid "You need to install PostgreSQL. If you prefer not to use Docker, [get the installer from official website](https://www.postgresql.org/download/), install it and create a database." -msgstr "" +msgstr "您需要安装 PostgreSQL。如果您不想使用 Docker,请[从官方网站获取安装程序](https://www.postgresql.org/download/),安装它并创建数据库。" #. type: Plain text #: ../src/guide/start/databases.md msgid "If you use Docker, it is a bit simpler. Modify `docker/dev/compose.yml`:" -msgstr "" +msgstr "如果您使用 Docker,则稍微简单一些。修改 `docker/dev/compose.yml`:" #. type: Fenced code block (yaml) #: ../src/guide/start/databases.md @@ -157,7 +157,7 @@ msgstr "" #. type: Plain text #: ../src/guide/start/databases.md msgid "Note that we add `depends_on` so application waits for database to be up." -msgstr "" +msgstr "请注意,我们添加了 `depends_on`,使应用程序等待数据库启动。" #. type: Plain text #: ../src/guide/start/databases.md @@ -166,11 +166,13 @@ msgid "" "> [!IMPORTANT]\n" "> Also, we'll need a `pdo_pgsql` extension to communicate with PostgreSQL. You can enable it locally in `php.ini`.\n" msgstr "" +"> [!IMPORTANT]\n" +"> 此外,我们还需要 `pdo_pgsql` 扩展来与 PostgreSQL 通信。您可以在本地的 `php.ini` 中启用它。\n" #. type: Plain text #: ../src/guide/start/databases.md msgid "If you use Docker, check `docker/Dockerfile` and add `pdo_pgsql` in `install-php-extensions` list:" -msgstr "" +msgstr "如果您使用 Docker,请检查 `docker/Dockerfile` 并在 `install-php-extensions` 列表中添加 `pdo_pgsql`:" #. type: Fenced code block (dockerfile) #: ../src/guide/start/databases.md @@ -195,7 +197,7 @@ msgstr "" #. type: Plain text #: ../src/guide/start/databases.md msgid "Then rebuild PHP image with" -msgstr "" +msgstr "然后使用以下命令重新构建 PHP 镜像:" #. type: Fenced code block (sh) #: ../src/guide/start/databases.md @@ -207,29 +209,28 @@ msgstr "" #: ../src/guide/start/databases.md #, no-wrap msgid "Configuring connection" -msgstr "" +msgstr "配置连接" #. type: Plain text #: ../src/guide/start/databases.md msgid "Now that we have the database, it's time to define the connection." -msgstr "" +msgstr "现在我们有了数据库,是时候定义连接了。" #. type: Plain text #: ../src/guide/start/databases.md msgid "First we need a package to be installed:" -msgstr "" +msgstr "首先,我们需要安装一个包:" #. type: Fenced code block (sh) #: ../src/guide/start/databases.md -#, fuzzy, no-wrap -#| msgid "composer require yiisoft/yii-sentry --prefer-dist\n" +#, no-wrap msgid "make composer require yiisoft/db-pgsql:2.*\n" -msgstr "composer require yiisoft/yii-sentry --prefer-dist\n" +msgstr "" #. type: Plain text #: ../src/guide/start/databases.md msgid "Now create `config/common/di/db-pgsql.php`:" -msgstr "" +msgstr "现在创建 `config/common/di/db-pgsql.php`:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -260,7 +261,7 @@ msgstr "" #. type: Plain text #: ../src/guide/start/databases.md msgid "And define parameters in `config/common/params.php`. For Docker that would be:" -msgstr "" +msgstr "并在 `config/common/params.php` 中定义参数。对于 Docker,参数如下:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -281,38 +282,38 @@ msgstr "" #. type: Plain text #: ../src/guide/start/databases.md msgid "`db` host is resolved automatically within the Docker network." -msgstr "" +msgstr "`db` 主机在 Docker 网络中自动解析。" #. type: Plain text #: ../src/guide/start/databases.md msgid "For local installation without Docker the host in Dsn would be `localhost`. You'll have to adjust the rest to match how you configured the database." -msgstr "" +msgstr "对于不使用 Docker 的本地安装,Dsn 中的主机为 `localhost`。您需要根据数据库的配置方式调整其余部分。" #. type: Title ## #: ../src/guide/start/databases.md #, no-wrap msgid "Creating and applying migrations" -msgstr "" +msgstr "创建和应用迁移" #. type: Plain text #: ../src/guide/start/databases.md msgid "For the initial state of the application and for further database changes, it is a good idea to use migrations. These are files that create database changes. Applied migrations are tracked in the database, allowing us to know the current state and which migrations remain to be applied." -msgstr "" +msgstr "对于应用程序的初始状态以及后续的数据库变更,使用迁移是个好主意。这些文件描述数据库变更。已应用的迁移在数据库中进行跟踪,使我们了解当前状态以及哪些迁移尚未应用。" #. type: Plain text #: ../src/guide/start/databases.md msgid "To use migrations we need another package installed:" -msgstr "" +msgstr "要使用迁移,我们需要安装另一个包:" #. type: Plain text #: ../src/guide/start/databases.md msgid "Create a directory to store migrations `src/Migration` right in the project root. Add the following configuration to `config/common/params.php`:" -msgstr "" +msgstr "在项目根目录中创建用于存储迁移的目录 `src/Migration`。将以下配置添加到 `config/common/params.php`:" #. type: Plain text #: ../src/guide/start/databases.md msgid "Now you can use `make yii migrate:create page` to create a new migration. For our example we need a `page` table with some columns:" -msgstr "" +msgstr "现在您可以使用 `make yii migrate:create page` 创建新迁移。在我们的示例中,需要一个带有若干列的 `page` 表:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -353,12 +354,12 @@ msgstr "" #. type: Plain text #: ../src/guide/start/databases.md msgid "The `M251102141707Page` name of the migration class is generated so replace the `Page` suffix with the actual migration name. The `M251102141707` prefix is needed to find and sort migrations in the order they were added." -msgstr "" +msgstr "迁移类的名称 `M251102141707Page` 是自动生成的,请将 `Page` 后缀替换为实际的迁移名称。`M251102141707` 前缀用于按添加顺序查找和排序迁移。" #. type: Plain text #: ../src/guide/start/databases.md msgid "Note that we use UUID as the primary key. We are going to generate these IDs ourselves instead of relying on database so we'll need an extra compose package for that." -msgstr "" +msgstr "请注意,我们使用 UUID 作为主键。我们将自己生成这些 ID,而不是依赖数据库,因此需要额外安装一个 composer 包。" #. type: Fenced code block (shell) #: ../src/guide/start/databases.md @@ -369,23 +370,23 @@ msgstr "" #. type: Plain text #: ../src/guide/start/databases.md msgid "While the storage space is a bit bigger than using int, the workflow with such IDs is beneficial. Since you generate the ID yourself so you can define a set of related data and save it in a single transaction. The entities that define this set of data in the code are often called an \"aggregate\"." -msgstr "" +msgstr "虽然存储空间比使用 int 稍大,但这种 ID 的工作流程很有益处。由于 ID 由您自己生成,因此您可以定义一组相关数据并在单个事务中保存。在代码中定义这组数据的实体通常称为“聚合”。" #. type: Plain text #: ../src/guide/start/databases.md msgid "Apply the migration with `make yii migrate:up`." -msgstr "" +msgstr "使用 `make yii migrate:up` 应用迁移。" #. type: Title ## #: ../src/guide/start/databases.md #, no-wrap msgid "An entity" -msgstr "" +msgstr "实体" #. type: Plain text #: ../src/guide/start/databases.md msgid "Now that you have a table it is time to define an entity in the code. Create `src/Web/Page/Page.php`:" -msgstr "" +msgstr "现在您有了表,是时候在代码中定义实体了。创建 `src/Web/Page/Page.php`:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -438,17 +439,17 @@ msgstr "" #: ../src/guide/structure/service.md #, no-wrap msgid "Repository" -msgstr "" +msgstr "仓库" #. type: Plain text #: ../src/guide/start/databases.md msgid "Now that we have entity, we need a place for methods to save an entity, delete it and select either a single page or multiple pages." -msgstr "" +msgstr "现在我们有了实体,我们需要一个地方来存放保存实体、删除实体以及选择单个或多个页面的方法。" #. type: Plain text #: ../src/guide/start/databases.md msgid "Create `src/Web/Page/PageRepository.php`:" -msgstr "" +msgstr "创建 `src/Web/Page/PageRepository.php`:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -549,64 +550,64 @@ msgstr "" #. type: Plain text #: ../src/guide/start/databases.md msgid "In this repository there are both methods to get data and `save()` to do insert or update. DB returns raw data as arrays but our repository automatically creates entities from this raw data so later we operate typed data." -msgstr "" +msgstr "此仓库中既有获取数据的方法,也有用于插入或更新的 `save()` 方法。数据库以数组形式返回原始数据,但我们的仓库会自动从原始数据中创建实体,这样后续操作的就是类型化数据。" #. type: Title ## #: ../src/guide/start/databases.md #, no-wrap msgid "Actions and routes" -msgstr "" +msgstr "操作和路由" #. type: Plain text #: ../src/guide/start/databases.md msgid "We need some actions to:" -msgstr "" +msgstr "我们需要以下操作:" #. type: Bullet: '1. ' #: ../src/guide/start/databases.md msgid "List all pages." -msgstr "" +msgstr "列出所有页面。" #. type: Bullet: '2. ' #: ../src/guide/start/databases.md msgid "View a page." -msgstr "" +msgstr "查看页面。" #. type: Bullet: '3. ' #: ../src/guide/start/databases.md msgid "Delete a page." -msgstr "" +msgstr "删除页面。" #. type: Bullet: '4. ' #: ../src/guide/start/databases.md msgid "Create a page." -msgstr "" +msgstr "创建页面。" #. type: Bullet: '5. ' #: ../src/guide/start/databases.md msgid "Update a page." -msgstr "" +msgstr "更新页面。" #. type: Plain text #: ../src/guide/start/databases.md msgid "Then we need routing for all these." -msgstr "" +msgstr "然后我们需要为这些操作配置路由。" #. type: Plain text #: ../src/guide/start/databases.md msgid "Let's tackle these one by one." -msgstr "" +msgstr "让我们逐一解决。" #. type: Title ### #: ../src/guide/start/databases.md #, no-wrap msgid "List all pages" -msgstr "" +msgstr "列出所有页面" #. type: Plain text #: ../src/guide/start/databases.md msgid "Create `src/Web/Page/ListAction.php`:" -msgstr "" +msgstr "创建 `src/Web/Page/ListAction.php`:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -642,7 +643,7 @@ msgstr "" #. type: Plain text #: ../src/guide/start/databases.md msgid "Define list view in `src/Web/Page/list.php`:" -msgstr "" +msgstr "在 `src/Web/Page/list.php` 中定义列表视图:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -672,12 +673,12 @@ msgstr "" #: ../src/guide/start/databases.md #, no-wrap msgid "View a page" -msgstr "" +msgstr "查看页面" #. type: Plain text #: ../src/guide/start/databases.md msgid "Create `src/Web/Page/ViewAction.php`:" -msgstr "" +msgstr "创建 `src/Web/Page/ViewAction.php`:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -722,7 +723,7 @@ msgstr "" #. type: Plain text #: ../src/guide/start/databases.md msgid "Now, a template in `src/Web/Page/view.php`:" -msgstr "" +msgstr "现在,在 `src/Web/Page/view.php` 中创建模板:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -761,18 +762,18 @@ msgstr "" #. type: Plain text #: ../src/guide/start/databases.md msgid "In this view we have a form that submits a request for page deletion. Handing it with `GET` is common as well, but it is very wrong. Since deletion changes data, it needs to be handled by one of the non-idempotent HTTP methods. We use POST and a form in our example, but it could be `DELETE` and async request made with JavaScript. The button could be later styled properly to look similar to the \"Edit\"." -msgstr "" +msgstr "在此视图中,我们有一个提交页面删除请求的表单。用 `GET` 处理也很常见,但这是非常错误的做法。由于删除会更改数据,它需要由非幂等的 HTTP 方法之一来处理。我们的示例中使用了 POST 和表单,但也可以使用 `DELETE` 和 JavaScript 发起的异步请求。该按钮后续可以适当设置样式,使其看起来类似于“编辑”按钮。" #. type: Title ### #: ../src/guide/start/databases.md #, no-wrap msgid "Delete a page" -msgstr "" +msgstr "删除页面" #. type: Plain text #: ../src/guide/start/databases.md msgid "Create `src/Web/Page/DeleteAction.php`:" -msgstr "" +msgstr "创建 `src/Web/Page/DeleteAction.php`:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -816,12 +817,12 @@ msgstr "" #: ../src/guide/start/databases.md #, no-wrap msgid "Create or update a page" -msgstr "" +msgstr "创建或更新页面" #. type: Plain text #: ../src/guide/start/databases.md msgid "First of all, we need a form at `src/Web/Page/Form.php`:" -msgstr "" +msgstr "首先,我们需要在 `src/Web/Page/Form.php` 创建一个表单:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -852,7 +853,7 @@ msgstr "" #. type: Plain text #: ../src/guide/start/databases.md msgid "Then an action. Create `src/Web/Page/EditAction.php`:" -msgstr "" +msgstr "然后创建一个操作。创建 `src/Web/Page/EditAction.php`:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -940,17 +941,17 @@ msgstr "" #: ../src/guide/start/databases.md #, no-wrap msgid "Note that `Uuid::uuid7()->toString()` won't work for MySQL and you'll need bytes instead, `Uuid::uuid7()->getBytes()`.\n" -msgstr "" +msgstr "请注意,`Uuid::uuid7()->toString()` 在 MySQL 中不适用,您需要改用字节形式,即 `Uuid::uuid7()->getBytes()`。\n" #. type: Plain text #: ../src/guide/start/databases.md msgid "In the above we use a special slug in the URL for new pages so the URL looks like `http://localhost/pages/new`. If the page isn't new, we pre-fill the form with the data from the database. Similar to how we did in [Working with forms](forms.md), we handle the form submission. After successful save we redirect to the page view." -msgstr "" +msgstr "在上面,我们在 URL 中为新页面使用了特殊的 slug,因此 URL 看起来像 `http://localhost/pages/new`。如果页面不是新的,我们会从数据库中预填充表单数据。与[使用表单](forms.md)中的操作类似,我们处理表单提交。保存成功后,我们重定向到页面视图。" #. type: Plain text #: ../src/guide/start/databases.md msgid "Now, a template in `src/Web/Page/edit.php`:" -msgstr "" +msgstr "现在,在 `src/Web/Page/edit.php` 中创建模板:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -988,12 +989,12 @@ msgstr "" #: ../src/guide/start/databases.md #, no-wrap msgid "Routing" -msgstr "" +msgstr "路由" #. type: Plain text #: ../src/guide/start/databases.md msgid "Adjust `config/common/routes.php`:" -msgstr "" +msgstr "调整 `config/common/routes.php`:" #. type: Fenced code block (php) #: ../src/guide/start/databases.md @@ -1039,15 +1040,15 @@ msgstr "" #. type: Plain text #: ../src/guide/start/databases.md msgid "Note that we've grouped all page-related routes with a group under `/pages` prefix. That is a convenient way to both not to repeat yourself and add some extra middleware, such as authentication, to the whole group." -msgstr "" +msgstr "请注意,我们将所有与页面相关的路由分组到 `/pages` 前缀下。这是一种方便的方式,既避免重复,又可以为整个组添加额外的中间件(例如认证)。" #. type: Title ## #: ../src/guide/start/databases.md #, no-wrap msgid "Trying it out" -msgstr "" +msgstr "试试看" #. type: Plain text #: ../src/guide/start/databases.md msgid "Now try it out by opening `http://localhost/pages` in your browser." -msgstr "" +msgstr "现在通过在浏览器中打开 `http://localhost/pages` 来试试看。" diff --git a/_translations/po/zh-CN/guide_start_demo-apps.md.po b/_translations/po/zh-CN/guide_start_demo-apps.md.po index 6d79159a..38effb9c 100644 --- a/_translations/po/zh-CN/guide_start_demo-apps.md.po +++ b/_translations/po/zh-CN/guide_start_demo-apps.md.po @@ -17,34 +17,33 @@ msgstr "" #. type: Title # #: ../src/guide/start/demo-apps.md -#, fuzzy, no-wrap -#| msgid "Deploy the application" +#, no-wrap msgid "Demo Applications" -msgstr "部署应用程序" +msgstr "演示应用程序" #. type: Plain text #: ../src/guide/start/demo-apps.md msgid "There are several demo applications that showcase different architectural approaches and framework capabilities." -msgstr "" +msgstr "以下是几个演示不同架构方式和框架功能的示例应用程序。" #. type: Plain text #: ../src/guide/start/demo-apps.md #, no-wrap msgid "**[Demo Blog](https://github.com/yiisoft/demo-blog) — Layered DDD architecture**\n" -msgstr "" +msgstr "**[Demo Blog](https://github.com/yiisoft/demo-blog) — 分层 DDD 架构**\n" #. type: Plain text #: ../src/guide/start/demo-apps.md msgid "A blog application demonstrating a layered architecture following Domain-Driven Design (DDD) principles. This demo is a good starting point if you want to learn how to structure a Yii3 application with a clear separation of concerns between domain, application, and infrastructure layers." -msgstr "" +msgstr "这是一个遵循领域驱动设计(DDD)原则的分层架构博客应用程序。如果您想学习如何在领域层、应用层和基础设施层之间清晰分离关注点来构建 Yii3 应用程序,此示例是一个很好的起点。" #. type: Plain text #: ../src/guide/start/demo-apps.md #, no-wrap msgid "**[Demo Diary](https://github.com/yiisoft/demo-diary) — Vertical slices architecture**\n" -msgstr "" +msgstr "**[Demo Diary](https://github.com/yiisoft/demo-diary) — 垂直切片架构**\n" #. type: Plain text #: ../src/guide/start/demo-apps.md msgid "A diary application built using the vertical slices architecture pattern. In this approach, each feature is implemented end-to-end rather than being split across horizontal layers, making it easier to add or modify features independently." -msgstr "" +msgstr "这是一个采用垂直切片架构模式构建的日记应用程序。在这种方式中,每个功能从头到尾完整实现,而不是按水平层拆分,从而更易于独立添加或修改功能。" diff --git a/_translations/po/zh-CN/guide_start_forms.md.po b/_translations/po/zh-CN/guide_start_forms.md.po index 40d0c2bb..60fcabc0 100644 --- a/_translations/po/zh-CN/guide_start_forms.md.po +++ b/_translations/po/zh-CN/guide_start_forms.md.po @@ -19,43 +19,43 @@ msgstr "" #: ../src/guide/start/forms.md #, no-wrap msgid "Working with forms" -msgstr "" +msgstr "使用表单" #. type: Plain text #: ../src/guide/start/forms.md msgid "This section continues to improve on \"Saying Hello.\" Instead of using URL, you will now ask a user for a message via form." -msgstr "" +msgstr "本节继续改进“打招呼”功能。不再使用 URL,而是通过表单向用户请求消息。" #. type: Plain text #: ../src/guide/start/forms.md msgid "Through this tutorial, you will learn how to:" -msgstr "" +msgstr "通过本教程,您将学习如何:" #. type: Bullet: '* ' #: ../src/guide/start/forms.md msgid "Create a form model to represent the data entered by a user through a form." -msgstr "" +msgstr "创建表单模型来表示用户通过表单输入的数据。" #. type: Bullet: '* ' #: ../src/guide/start/forms.md msgid "Declare rules to validate the data entered." -msgstr "" +msgstr "声明规则来验证输入的数据。" #. type: Bullet: '* ' #: ../src/guide/start/forms.md msgid "Build an HTML form in a view." -msgstr "" +msgstr "在视图中构建 HTML 表单。" #. type: Title ## #: ../src/guide/start/forms.md #, no-wrap msgid "Installing form package" -msgstr "" +msgstr "安装表单包" #. type: Plain text #: ../src/guide/start/forms.md msgid "To install form package, issue the following command in your application directory:" -msgstr "" +msgstr "要安装表单包,请在应用程序目录中执行以下命令:" #. type: Fenced code block #: ../src/guide/start/forms.md @@ -66,7 +66,7 @@ msgstr "" #. type: Plain text #: ../src/guide/start/forms.md msgid "For Docker that would be:" -msgstr "" +msgstr "对于 Docker,命令如下:" #. type: Fenced code block #: ../src/guide/start/forms.md @@ -78,12 +78,12 @@ msgstr "" #: ../src/guide/start/forms.md #, no-wrap msgid "Creating a form " -msgstr "" +msgstr "创建表单 " #. type: Plain text #: ../src/guide/start/forms.md msgid "The data to be requested from the user will be represented by a `Form` class as shown below and saved in the file `/src/Web/Echo/Form.php`:" -msgstr "" +msgstr "将从用户处请求的数据将由如下所示的 `Form` 类表示,并保存在文件 `/src/Web/Echo/Form.php` 中:" #. type: Fenced code block (php) #: ../src/guide/start/forms.md @@ -110,23 +110,23 @@ msgstr "" #. type: Plain text #: ../src/guide/start/forms.md msgid "In the above example, the `Form` has a single string property `$message` which length should be at least of two characters. There's also a custom label for the property." -msgstr "" +msgstr "在上面的示例中,`Form` 有一个单独的字符串属性 `$message`,其长度至少应为两个字符。该属性还有一个自定义标签。" #. type: Title ## #: ../src/guide/start/forms.md #, no-wrap msgid "Using the form " -msgstr "" +msgstr "使用表单 " #. type: Plain text #: ../src/guide/start/forms.md msgid "Now that you have a form, use it in your action from \"[Saying Hello](hello.md)\"." -msgstr "" +msgstr "现在您有了一个表单,在“[打招呼](hello.md)”中的操作中使用它。" #. type: Plain text #: ../src/guide/start/forms.md msgid "Here's what you end up with in `/src/Web/Echo/Action.php`:" -msgstr "" +msgstr "以下是 `/src/Web/Echo/Action.php` 中的最终结果:" #. type: Fenced code block (php) #: ../src/guide/start/forms.md @@ -166,12 +166,12 @@ msgstr "" #. type: Plain text #: ../src/guide/start/forms.md msgid "Instead of reading from route, you fill your form from request's POST data and validate it with the help of `FormHydrator`. Next you pass the form to the view." -msgstr "" +msgstr "您不再从路由中读取数据,而是从请求的 POST 数据填充表单,并借助 `FormHydrator` 进行验证。然后将表单传递给视图。" #. type: Plain text #: ../src/guide/start/forms.md msgid "For the form to function we need to allow both GET to render the form and POST to send the data. Adjust your route in `config/common/routes.php`:" -msgstr "" +msgstr "为使表单正常工作,我们需要同时允许 GET(用于渲染表单)和 POST(用于发送数据)。调整 `config/common/routes.php` 中的路由:" #. type: Fenced code block (php) #: ../src/guide/start/forms.md @@ -203,12 +203,12 @@ msgstr "" #: ../src/guide/start/forms.md #, no-wrap msgid "Adjusting view" -msgstr "" +msgstr "调整视图" #. type: Plain text #: ../src/guide/start/forms.md msgid "To render a form, you need to change your view, `src/Web/Echo/template.php`:" -msgstr "" +msgstr "要渲染表单,您需要修改视图 `src/Web/Echo/template.php`:" #. type: Fenced code block (php) #: ../src/guide/start/forms.md @@ -246,12 +246,12 @@ msgstr "" #. type: Plain text #: ../src/guide/start/forms.md msgid "If the form is valid, you display a message. The rest initializes and renders the form." -msgstr "" +msgstr "如果表单有效,则显示消息。其余部分初始化并渲染表单。" #. type: Plain text #: ../src/guide/start/forms.md msgid "First, you initialize `$htmlForm` with the POST type and the action URL generated with the help from the URL generator. You can access it as `$urlGenerator` in all views. You also need to pass the CSRF token to the form, which is also available in every view as `$csrf` thanks to the view injections listed in `config/common/params.php`:" -msgstr "" +msgstr "首先,您使用 POST 类型和借助 URL 生成器生成的操作 URL 初始化 `$htmlForm`。您可以在所有视图中以 `$urlGenerator` 访问它。您还需要将 CSRF 令牌传递给表单,由于 `config/common/params.php` 中列出的视图注入,它也可以在每个视图中以 `$csrf` 的形式访问:" #. type: Fenced code block (php) #: ../src/guide/start/forms.md @@ -267,28 +267,28 @@ msgstr "" #. type: Plain text #: ../src/guide/start/forms.md msgid "The template renders the CSRF token value as a hidden input to ensure that the request originates from the form page and not from another website. It will be submitted along with POST form data. Omitting it would result in [HTTP response code 422](https://tools.ietf.org/html/rfc4918#section-11.2)." -msgstr "" +msgstr "模板将 CSRF 令牌值渲染为隐藏输入,以确保请求来自表单页面而非其他网站。它将与 POST 表单数据一起提交。省略它将导致 [HTTP 响应码 422](https://tools.ietf.org/html/rfc4918#section-11.2)。" #. type: Plain text #: ../src/guide/start/forms.md msgid "You use `Field::text()` to output \"message\" field, so it takes care about filling the value, escaping it, rendering field label and validation errors." -msgstr "" +msgstr "您使用 `Field::text()` 输出“message”字段,它会负责填充值、转义、渲染字段标签和验证错误。" #. type: Plain text #: ../src/guide/start/forms.md msgid "Now, in case you submit an empty message, you will get a validation error: \"The message to be echoed must contain at least 2 characters.\"" -msgstr "" +msgstr "现在,如果您提交空消息,将会收到验证错误:“要回显的消息必须至少包含 2 个字符。”" #. type: Title ## #: ../src/guide/start/forms.md #, no-wrap msgid "Trying it Out " -msgstr "" +msgstr "试试看 " #. type: Plain text #: ../src/guide/start/forms.md msgid "To see how it works, use your browser to access the following URL:" -msgstr "" +msgstr "要查看其工作原理,请使用浏览器访问以下 URL:" #. type: Fenced code block #: ../src/guide/start/forms.md @@ -299,40 +299,40 @@ msgstr "" #. type: Plain text #: ../src/guide/start/forms.md msgid "You will see a page with a form input field and a label that indicates what data to enter. Also, the form has a \"submit\" button labeled \"Say\". If you click the \"submit\" button without entering anything, you will see that the field is required. If you enter a single character, the form displays an error message next to the problematic input field." -msgstr "" +msgstr "您将看到一个包含表单输入字段和标签的页面,标签指示要输入什么数据。此外,表单有一个标有“Say”的“提交”按钮。如果您不输入任何内容就点击“提交”按钮,将看到该字段是必填的。如果您输入单个字符,表单会在有问题的输入字段旁边显示错误消息。" #. type: Plain text #: ../src/guide/start/forms.md msgid "![Form with a validation error](/images/guide/start/form-error.png)" -msgstr "" +msgstr "![表单验证错误](/images/guide/start/form-error.png)" #. type: Plain text #: ../src/guide/start/forms.md msgid "After you enter a valid message and click the \"submit\" button, the page echoes the data that you entered." -msgstr "" +msgstr "在您输入有效消息并点击“提交”按钮后,页面将回显您输入的数据。" #. type: Plain text #: ../src/guide/start/forms.md msgid "![Form with a success message](/images/guide/start/form-success.png)" -msgstr "" +msgstr "![表单成功消息](/images/guide/start/form-success.png)" #. type: Title ## #: ../src/guide/start/forms.md ../src/guide/start/hello.md #, no-wrap msgid "Summary " -msgstr "" +msgstr "总结 " #. type: Plain text #: ../src/guide/start/forms.md msgid "In this section of the guide, you've learned how to create a form model class to represent the user data and validate said data." -msgstr "" +msgstr "在本指南的这一节中,您已学习了如何创建表单模型类来表示用户数据并验证该数据。" #. type: Plain text #: ../src/guide/start/forms.md msgid "You've also learned how to get data from users and how to display data back in the browser. This is a task that could take you a lot of time when developing an application, but Yii provides powerful widgets to make this task easy." -msgstr "" +msgstr "您还学习了如何从用户获取数据以及如何在浏览器中显示数据。这是开发应用程序时可能花费大量时间的任务,但 Yii 提供了强大的小部件来使这项任务变得容易。" #. type: Plain text #: ../src/guide/start/forms.md msgid "In the next section, you will learn how to work with databases, which are needed in nearly every application." -msgstr "" +msgstr "在下一节中,您将学习如何使用数据库,这在几乎每个应用程序中都是必需的。" diff --git a/_translations/po/zh-CN/guide_start_gii.md.po b/_translations/po/zh-CN/guide_start_gii.md.po index b9581441..64905049 100644 --- a/_translations/po/zh-CN/guide_start_gii.md.po +++ b/_translations/po/zh-CN/guide_start_gii.md.po @@ -19,7 +19,7 @@ msgstr "" #: ../src/guide/start/gii.md #, no-wrap msgid "Generating code with Gii" -msgstr "" +msgstr "使用 Gii 生成代码" #. type: Plain text #: ../src/guide/start/gii.md @@ -28,3 +28,5 @@ msgid "" "> [!NOTE]\n" "> Gii is under development and will be available later.\n" msgstr "" +"> [!NOTE]\n" +"> Gii 正在开发中,稍后将可使用。\n" diff --git a/_translations/po/zh-CN/guide_start_hello.md.po b/_translations/po/zh-CN/guide_start_hello.md.po index 9a45fd3b..e157f712 100644 --- a/_translations/po/zh-CN/guide_start_hello.md.po +++ b/_translations/po/zh-CN/guide_start_hello.md.po @@ -19,59 +19,59 @@ msgstr "" #: ../src/guide/start/forms.md ../src/guide/start/hello.md #, no-wrap msgid "Summary " -msgstr "" +msgstr "总结 " #. type: Title # #: ../src/guide/start/hello.md #, no-wrap msgid "Saying hello" -msgstr "" +msgstr "说声 Hello" #. type: Plain text #: ../src/guide/start/hello.md msgid "This section describes how to create a new \"Hello\" page in your application. It's a simple page that will echo back whatever you pass to it or, if nothing passed, will just say \"Hello!\"." -msgstr "" +msgstr "本节描述如何在应用程序中创建一个新的“Hello”页面。这是一个简单的页面,它会回显您传递给它的任何内容,或者如果没有传递任何内容,则显示“Hello!”。" #. type: Plain text #: ../src/guide/start/hello.md msgid "To achieve this goal, you will define a route and create [a handler](../structure/handler.md) that does the job and forms the response. Then you will improve it to use [view](../views/view.md) for building the response." -msgstr "" +msgstr "为实现这个目标,您将定义一个路由并创建一个 [处理器](../structure/handler.md) 来完成工作并形成响应。然后您将改进它,使用[视图](../views/view.md)来构建响应。" #. type: Plain text #: ../src/guide/start/hello.md msgid "Through this tutorial, you will learn three things:" -msgstr "" +msgstr "通过本教程,您将学习三件事:" #. type: Bullet: '1. ' #: ../src/guide/start/hello.md msgid "How to create a handler to respond to a request." -msgstr "" +msgstr "如何创建处理器来响应请求。" #. type: Bullet: '2. ' #: ../src/guide/start/hello.md msgid "How to map URL to the handler." -msgstr "" +msgstr "如何将 URL 映射到处理器。" #. type: Bullet: '3. ' #: ../src/guide/start/hello.md msgid "How to use [view](../views/view.md) to compose the response's content." -msgstr "" +msgstr "如何使用 [视图](../views/view.md) 来组成响应的内容。" #. type: Title ## #: ../src/guide/start/hello.md #, no-wrap msgid "Creating a handler " -msgstr "" +msgstr "创建处理器 " #. type: Plain text #: ../src/guide/start/hello.md msgid "For the \"Hello\" task, you will create a handler class that reads a `message` parameter from the request and displays that message back to the user. If the request doesn't provide a `message` parameter, the action will display the default \"Hello\" message." -msgstr "" +msgstr "对于“Hello”任务,您将创建一个处理器类,从请求中读取 `message` 参数并将该消息显示给用户。如果请求没有提供 `message` 参数,操作将显示默认的“Hello”消息。" #. type: Plain text #: ../src/guide/start/hello.md msgid "Create `src/Web/Echo/Action.php`:" -msgstr "" +msgstr "创建 `src/Web/Echo/Action.php`:" #. type: Fenced code block (php) #: ../src/guide/start/hello.md @@ -109,23 +109,23 @@ msgstr "" #. type: Plain text #: ../src/guide/start/hello.md msgid "In your example, the `__invoke` method receives the `$message` parameter that with the help of `RouteArgument` attribute gets the message from URL. The value defaults to `\"Hello!\"`. If the request is made to `/say/Goodbye`, the action assigns the value \"Goodbye\" to the `$message` variable." -msgstr "" +msgstr "在您的示例中,`__invoke` 方法接收 `$message` 参数,借助 `RouteArgument` 属性从 URL 中获取消息。该值默认为 `“Hello!”`。如果请求发送到 `/say/Goodbye`,操作将值“Goodbye”赋给 `$message` 变量。" #. type: Plain text #: ../src/guide/start/hello.md msgid "The application passes the response through the [middleware stack](../structure/middleware.md) to the emitter that outputs the response to the end user." -msgstr "" +msgstr "应用程序将响应通过[中间件栈](../structure/middleware.md)传递给发射器,由发射器将响应输出给最终用户。" #. type: Title ## #: ../src/guide/start/hello.md #, no-wrap msgid "Configuring router" -msgstr "" +msgstr "配置路由器" #. type: Plain text #: ../src/guide/start/hello.md msgid "Now, to map your handler to URL, you need to add a route in `config/common/routes.php`:" -msgstr "" +msgstr "现在,要将处理器映射到 URL,您需要在 `config/common/routes.php` 中添加路由:" #. type: Fenced code block (php) #: ../src/guide/start/hello.md @@ -155,49 +155,49 @@ msgstr "" #. type: Plain text #: ../src/guide/start/hello.md msgid "In the above, you map the `/say[/{message}]` pattern to `\\App\\Web\\Echo\\Action`. For a request, the router creates an instance and calls the `__invoke()` method. The `{message}` part of the pattern writes anything specified in this place to the `message` request attribute. `[]` marks this part of the pattern as optional." -msgstr "" +msgstr "在上面,您将 `/say[/{message}]` 模式映射到 `\\App\\Web\\Echo\\Action`。对于请求,路由器创建一个实例并调用 `__invoke()` 方法。模式中的 `{message}` 部分将此处指定的任何内容写入 `message` 请求属性。`[]` 将模式的这部分标记为可选。" #. type: Plain text #: ../src/guide/start/hello.md msgid "You also give a `echo/say` name to this route to be able to generate URLs pointing to it." -msgstr "" +msgstr "您还为此路由指定了 `echo/say` 名称,以便能够生成指向它的 URL。" #. type: Title ## #: ../src/guide/start/hello.md #, no-wrap msgid "Trying it out " -msgstr "" +msgstr "试试看 " #. type: Plain text #: ../src/guide/start/hello.md msgid "After creating the action and the view open `http://localhost/say/Hello+World` in your browser." -msgstr "" +msgstr "创建操作和视图后,在浏览器中打开 `http://localhost/say/Hello+World`。" #. type: Plain text #: ../src/guide/start/hello.md msgid "This URL displays a page with \"The message is: Hello World\"." -msgstr "" +msgstr "此 URL 显示一个包含“The message is: Hello World”的页面。" #. type: Plain text #: ../src/guide/start/hello.md msgid "If you omit the `message` parameter in the URL, the page displays \"The message is: Hello!\"." -msgstr "" +msgstr "如果您在 URL 中省略 `message` 参数,页面将显示“The message is: Hello!”。" #. type: Title ## #: ../src/guide/start/hello.md #, no-wrap msgid "Creating a View Template " -msgstr "" +msgstr "创建视图模板 " #. type: Plain text #: ../src/guide/start/hello.md msgid "Usually, the task is more complicated than printing out \"hello world\" and involves rendering some complex HTML. For this task, it's handy to use view templates. They're scripts you write to generate a response's body." -msgstr "" +msgstr "通常,任务比打印“hello world”更复杂,涉及渲染一些复杂的 HTML。对于这项任务,使用视图模板很方便。它们是您编写的用于生成响应主体的脚本。" #. type: Plain text #: ../src/guide/start/hello.md msgid "For the \"Hello\" task, create a `src/Web/Echo/template.php` template that prints the `message` parameter received from the action method:" -msgstr "" +msgstr "对于“Hello”任务,创建一个 `src/Web/Echo/template.php` 模板,打印从操作方法接收的 `message` 参数:" #. type: Fenced code block (php) #: ../src/guide/start/hello.md ../src/guide/views/view.md @@ -214,17 +214,17 @@ msgstr "" #. type: Plain text #: ../src/guide/start/hello.md msgid "In the above code, the `message` parameter uses HTML encoding before you print it. You need that because the parameter comes from an end user and is vulnerable to [cross-site scripting (XSS) attacks](https://en.wikipedia.org/wiki/Cross-site_scripting) by embedding malicious JavaScript in the parameter." -msgstr "" +msgstr "在上面的代码中,`message` 参数在打印之前使用 HTML 编码。这是必要的,因为该参数来自最终用户,通过在参数中嵌入恶意 JavaScript 容易受到 [跨站脚本(XSS)攻击](https://en.wikipedia.org/wiki/Cross-site_scripting)。" #. type: Plain text #: ../src/guide/start/hello.md msgid "Naturally, you may put more content in the `say` view. The content can consist of HTML tags, plain text, and even PHP statements. In fact, the view service executes the `say` view as a PHP script." -msgstr "" +msgstr "当然,您可以在 `say` 视图中放置更多内容。内容可以由 HTML 标签、纯文本甚至 PHP 语句组成。实际上,视图服务将 `say` 视图作为 PHP 脚本执行。" #. type: Plain text #: ../src/guide/start/hello.md msgid "To use the view, you need to change `src/Web/Echo/Action.php`:" -msgstr "" +msgstr "要使用视图,您需要修改 `src/Web/Echo/Action.php`:" #. type: Fenced code block (php) #: ../src/guide/start/hello.md ../src/guide/views/view.md @@ -261,24 +261,24 @@ msgstr "" #. type: Plain text #: ../src/guide/start/hello.md msgid "Now open your browser and check it again. You should see the similar text but with a layout applied." -msgstr "" +msgstr "现在打开浏览器再次查看。您应该看到类似的文本,但已应用布局。" #. type: Plain text #: ../src/guide/start/hello.md msgid "Also, you've separated the part about how it works and part of how it's presented. In the larger applications, it helps a lot to deal with complexity." -msgstr "" +msgstr "此外,您已将其工作方式与呈现方式分离。在较大的应用程序中,这对处理复杂性很有帮助。" #. type: Plain text #: ../src/guide/start/hello.md msgid "In this section, you've touched the handler and template parts of the typical web application. You created a handler as part of a class to handle a specific request. You also created a view to compose the response's content. In this simple example, no data source was involved as the only data used was the `message` parameter." -msgstr "" +msgstr "在本节中,您接触了典型 Web 应用程序的处理器和模板部分。您创建了一个处理器类来处理特定请求。您还创建了一个视图来组成响应的内容。在这个简单的示例中,没有涉及数据源,因为使用的唯一数据是 `message` 参数。" #. type: Plain text #: ../src/guide/start/hello.md msgid "You've also learned about routing in Yii, which acts as the bridge between user requests and handlers." -msgstr "" +msgstr "您还了解了 Yii 中的路由,它充当用户请求和处理器之间的桥梁。" #. type: Plain text #: ../src/guide/start/hello.md msgid "In the next section, you will learn how to fetch data and add a new page containing an HTML form." -msgstr "" +msgstr "在下一节中,您将学习如何获取数据并添加一个包含 HTML 表单的新页面。" diff --git a/_translations/po/zh-CN/guide_start_looking-ahead.md.po b/_translations/po/zh-CN/guide_start_looking-ahead.md.po index 2b094e1a..330a9fa8 100644 --- a/_translations/po/zh-CN/guide_start_looking-ahead.md.po +++ b/_translations/po/zh-CN/guide_start_looking-ahead.md.po @@ -19,9 +19,9 @@ msgstr "" #: ../src/guide/start/looking-ahead.md #, no-wrap msgid "Looking ahead" -msgstr "" +msgstr "展望未来" #. type: Plain text #: ../src/guide/start/looking-ahead.md msgid "If you've read through the entire \"Getting Started\" chapter, you have now created a complete Yii application. In the process, you've learned how to implement some commonly necessary features, such as getting data from users via an HTML form, fetching data from a database, and displaying data in a paginated fashion. You've also learned how to use [Gii](gii.md) to generate code automatically. Using Gii for code generation turns the bulk of your Web development process into a task as simple as just filling out some forms." -msgstr "" +msgstr "如果您已经通读了整个“入门”章节,那么您现在已经创建了一个完整的 Yii 应用程序。在此过程中,您学会了如何实现一些常见的必要功能,例如通过 HTML 表单从用户处获取数据、从数据库中获取数据以及以分页方式显示数据。您还学会了如何使用 [Gii](gii.md) 自动生成代码。使用 Gii 生成代码,可以将大部分 Web 开发工作简化为仅需填写几个表单的简单任务。" diff --git a/_translations/po/zh-CN/guide_start_prerequisites.md.po b/_translations/po/zh-CN/guide_start_prerequisites.md.po index 643f9b01..6b231f9e 100644 --- a/_translations/po/zh-CN/guide_start_prerequisites.md.po +++ b/_translations/po/zh-CN/guide_start_prerequisites.md.po @@ -19,18 +19,18 @@ msgstr "" #: ../src/guide/intro/upgrade-from-v2.md ../src/guide/start/prerequisites.md #, no-wrap msgid "Docker" -msgstr "" +msgstr "Docker" #. type: Title # #: ../src/guide/start/prerequisites.md #, no-wrap msgid "What do you need to know?" -msgstr "" +msgstr "你需要了解什么?" #. type: Plain text #: ../src/guide/start/prerequisites.md msgid "The Yii learning curve isn't as steep as other PHP frameworks, but still, there are some things you should learn before starting with Yii." -msgstr "" +msgstr "Yii 的学习曲线不像其他 PHP 框架那样陡峭,但在开始使用 Yii 之前,仍然有一些东西你应该学习。" #. type: Title ## #: ../src/guide/start/prerequisites.md @@ -41,39 +41,39 @@ msgstr "" #. type: Plain text #: ../src/guide/start/prerequisites.md msgid "Yii is a PHP framework, so make sure you [read and understand language reference](https://www.php.net/manual/en/langref.php)." -msgstr "" +msgstr "Yii 是一个 PHP 框架,所以请确保你[阅读并理解语言参考](https://www.php.net/manual/en/langref.php)。" #. type: Title ## #: ../src/guide/start/prerequisites.md #, no-wrap msgid "Object-oriented programming" -msgstr "" +msgstr "面向对象编程" #. type: Plain text #: ../src/guide/start/prerequisites.md msgid "You need a basic understanding of object-oriented programming. If you're not familiar with it, check one of the many tutorials available such as [the one from tuts+](https://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762)." -msgstr "" +msgstr "你需要对面向对象编程有基本的了解。如果你不熟悉它,可以查看许多可用的教程,例如 [tuts+ 的教程](https://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762)。" #. type: Plain text #: ../src/guide/start/prerequisites.md msgid "When you develop with Yii, you write code in an object-oriented fashion, so make sure you're familiar with [PHP OOP support](https://www.php.net/manual/en/language.oop5.php)." -msgstr "" +msgstr "当你使用 Yii 开发时,你会以面向对象的方式编写代码,所以请确保你熟悉 [PHP OOP 支持](https://www.php.net/manual/en/language.oop5.php)。" #. type: Plain text #: ../src/guide/start/prerequisites.md msgid "Note that the more complicated your application is, the more advanced OOP concepts you should learn to successfully manage that complexity." -msgstr "" +msgstr "请注意,你的应用程序越复杂,你就应该学习更高级的 OOP 概念来成功管理这种复杂性。" #. type: Title ## #: ../src/guide/start/prerequisites.md #, no-wrap msgid "Command line and Composer" -msgstr "" +msgstr "命令行和 Composer" #. type: Plain text #: ../src/guide/start/prerequisites.md msgid "Yii extensively uses the de-facto standard PHP package manager, [Composer](https://getcomposer.org) so make sure you read and understand its [guide](https://getcomposer.org/doc/01-basic-usage.md). If you aren't familiar with using the command line, it's time to start trying. Once you learn the basics, you'll never want to work without it." -msgstr "" +msgstr "Yii 广泛使用事实上的标准 PHP 包管理器 [Composer](https://getcomposer.org),所以请确保你阅读并理解它的[指南](https://getcomposer.org/doc/01-basic-usage.md)。如果你不熟悉使用命令行,现在是时候开始尝试了。一旦你学会了基础知识,你就再也不想没有它了。" #. type: Title ## #: ../src/guide/start/prerequisites.md @@ -84,14 +84,14 @@ msgstr "" #. type: Plain text #: ../src/guide/start/prerequisites.md msgid "Since Yii is a web framework and the web largely uses HTTP, it's a good idea to [learn more about it](https://developer.mozilla.org/en-US/docs/Web/HTTP)." -msgstr "" +msgstr "由于 Yii 是一个 Web 框架,而 Web 主要使用 HTTP,所以[了解更多关于它的信息](https://developer.mozilla.org/en-US/docs/Web/HTTP)是个好主意。" #. type: Plain text #: ../src/guide/start/prerequisites.md msgid "The default application template leverages Docker, so we recommend that you [read and understand the concepts](https://docs.docker.com/get-started/)." -msgstr "" +msgstr "默认的应用程序模板利用了 Docker,所以我们建议你[阅读并理解这些概念](https://docs.docker.com/get-started/)。" #. type: Plain text #: ../src/guide/start/prerequisites.md msgid "Also, you will benefit from familiarizing yourself with [twelve-factor app](https://12factor.net/) principles." -msgstr "" +msgstr "此外,熟悉 [twelve-factor app](https://12factor.net/) 原则也会让你受益。" diff --git a/_translations/po/zh-CN/guide_start_workflow.md.po b/_translations/po/zh-CN/guide_start_workflow.md.po index 41f1fa1d..9acedcdd 100644 --- a/_translations/po/zh-CN/guide_start_workflow.md.po +++ b/_translations/po/zh-CN/guide_start_workflow.md.po @@ -19,28 +19,28 @@ msgstr "" #: ../src/guide/start/workflow.md #, no-wrap msgid "Running applications" -msgstr "" +msgstr "运行应用" #. type: Plain text #: ../src/guide/start/workflow.md msgid "After installing Yii, you have a working Yii application. This section introduces the application's built-in functionality, how the code is organized, and how the application handles requests in general." -msgstr "" +msgstr "安装 Yii 后,你就有了一个可工作的 Yii 应用程序。本节介绍应用程序的内置功能、代码的组织方式以及应用程序如何处理请求。" #. type: Plain text #: ../src/guide/start/workflow.md msgid "Note that unlike the framework itself, after you install a project template, it's all yours. You're free to add or delete code and overall change it as you need." -msgstr "" +msgstr "请注意,与框架本身不同,安装项目模板后,它就完全属于你了。你可以自由地添加或删除代码,并根据需要进行整体更改。" #. type: Title ## #: ../src/guide/start/workflow.md #, no-wrap msgid "Functionality " -msgstr "" +msgstr "功能 " #. type: Plain text #: ../src/guide/start/workflow.md msgid "The installed application contains only one page, accessible at `http://localhost/`. It shares a common layout that you can reuse on further pages." -msgstr "" +msgstr "安装的应用程序只包含一个页面,可通过 `http://localhost/` 访问。它共享一个通用布局,你可以在其他页面上重用。" #. type: Plain text #: ../src/guide/start/workflow.md @@ -52,22 +52,27 @@ msgid "" "debugging information, such as log messages, response statuses, the database queries run, and so on.\n" "-->\n" msgstr "" +"\n" #. type: Plain text #: ../src/guide/start/workflow.md msgid "In addition to the web application, you can access a console script via `APP_ENV=dev ./yii` or, in case of Docker, `make yii`. Use this script to run background and maintenance tasks for the application, which the [Console Application Section](../tutorial/console-applications.md) describes." -msgstr "" +msgstr "除了 Web 应用程序外,你还可以通过 `APP_ENV=dev ./yii` 或在 Docker 的情况下通过 `make yii` 访问控制台脚本。使用此脚本运行应用程序的后台和维护任务,[控制台应用程序部分](../tutorial/console-applications.md)对此进行了描述。" #. type: Title ## #: ../src/guide/start/workflow.md #, no-wrap msgid "Application structure " -msgstr "" +msgstr "应用结构 " #. type: Plain text #: ../src/guide/start/workflow.md msgid "The most important directories and files in your application are (assuming the application's root directory is `app`):" -msgstr "" +msgstr "应用程序中最重要的目录和文件是(假设应用程序的根目录是 `app`):" #. type: Fenced code block #: ../src/guide/start/workflow.md @@ -100,37 +105,63 @@ msgid "" "Makefile Config for make command.\n" "yii Console application entry point.\n" msgstr "" +"assets/ 资源包源文件。\n" +"config/ 配置文件。\n" +" common/ 通用配置和 DI 定义。\n" +" console/ 控制台特定配置。\n" +" environments/ 环境特定配置(dev/test/prod)。\n" +" web/ Web 特定配置。\n" +"docker/ Docker 特定文件。\n" +"public/ 可从互联网公开访问的文件。\n" +" assets/ 已发布/编译的资源。\n" +" index.php 入口脚本。\n" +"runtime/ 运行时生成的文件。\n" +"src/ 应用程序源代码。\n" +" Console/ 控制台命令。\n" +" Shared/ Web 和控制台应用程序之间共享的代码。\n" +" Web/ Web 特定代码(动作、处理器、布局)。\n" +" Shared/ 共享的 Web 组件。\n" +" Layout/ 布局组件和模板。\n" +" Environment.php 环境配置类。\n" +"tests/ 应用程序的 Codeception 测试集。\n" +" Console/ 控制台命令测试。\n" +" Functional/ 功能测试。\n" +" Unit/ 单元测试。\n" +" Web/ Web 动作测试。\n" +"vendor/ 已安装的 Composer 包。\n" +"Makefile make 命令的配置。\n" +"yii 控制台应用程序入口点。\n" #. type: Plain text #: ../src/guide/start/workflow.md msgid "In general, the files in the application fall into two groups: those under `app/public` and those under other directories. You can access the former directly via HTTP (i.e., in a browser), while you shouldn't expose the latter." -msgstr "" +msgstr "一般来说,应用程序中的文件分为两组:`app/public` 下的文件和其他目录下的文件。你可以通过 HTTP(即在浏览器中)直接访问前者,而不应该暴露后者。" #. type: Plain text #: ../src/guide/start/workflow.md msgid "Each application has an entry script `public/index.php`, the only web-accessible PHP script in the application. The entry script uses an [application runner](https://github.com/yiisoft/yii-runner) to create an instance of an incoming request with the help of one of PSR-7 packages and passes it to an [application](../structure/application.md) instance. The application executes a set of middleware sequentially to process the request. It then passes the result to the emitter, which sends the response to the browser." -msgstr "" +msgstr "每个应用程序都有一个入口脚本 `public/index.php`,这是应用程序中唯一可通过 Web 访问的 PHP 脚本。入口脚本使用[应用程序运行器](https://github.com/yiisoft/yii-runner)在 PSR-7 包之一的帮助下创建传入请求的实例,并将其传递给[应用程序](../structure/application.md)实例。应用程序按顺序执行一组中间件来处理请求。然后将结果传递给发射器,发射器将响应发送到浏览器。" #. type: Plain text #: ../src/guide/start/workflow.md msgid "Depending on the middleware you use, the application may behave differently. By default, a router uses the requested URL and configuration to choose a handler and execute it to produce a response." -msgstr "" +msgstr "根据你使用的中间件,应用程序的行为可能会有所不同。默认情况下,路由器使用请求的 URL 和配置来选择处理器并执行它以生成响应。" #. type: Plain text #: ../src/guide/start/workflow.md msgid "You can learn more about the application template from the [yiisoft/app package documentation](https://github.com/yiisoft/app/blob/master/README.md)." -msgstr "" +msgstr "你可以从 [yiisoft/app 包文档](https://github.com/yiisoft/app/blob/master/README.md)中了解更多关于应用程序模板的信息。" #. type: Title ## #: ../src/guide/start/workflow.md #, no-wrap msgid "Request Lifecycle " -msgstr "" +msgstr "请求生命周期 " #. type: Plain text #: ../src/guide/start/workflow.md msgid "The following diagram shows how an application handles a request." -msgstr "" +msgstr "下图显示了应用程序如何处理请求。" #. type: Fenced code block (mermaid) #: ../src/guide/start/workflow.md @@ -151,43 +182,57 @@ msgid "" " app -->|Response| emitter\n" " emitter --> user\n" msgstr "" +"flowchart LR\n" +" user[用户客户端] --> index\n" +" index[index.php] --> DI[初始化依赖容器]\n" +" config[配置] -.-> DI\n" +" DI --> RequestFactory[请求工厂]\n" +" RequestFactory -->|请求| app[应用程序]\n" +" app -->|请求| middleware[中间件]\n" +" middleware -->|请求| router[路由器]\n" +" router -->|请求| action[动作处理器]\n" +" action -->|响应| emitter[SapiEmitter]\n" +" router -->|响应| emitter\n" +" middleware -->|响应| emitter\n" +" app -->|响应| emitter\n" +" emitter --> user\n" #. type: Bullet: '1. ' #: ../src/guide/start/workflow.md msgid "A user makes a request to the [entry script](../structure/entry-script.md) `public/index.php`." -msgstr "" +msgstr "用户向 [入口脚本](../structure/entry-script.md) `public/index.php` 发出请求。" #. type: Bullet: '2. ' #: ../src/guide/start/workflow.md msgid "The entry script with the help of the application runner loads the container [configuration](../concept/configuration.md) and creates an [application](../structure/application.md) instance and services necessary to handle the request." -msgstr "" +msgstr "入口脚本在应用程序运行器的帮助下加载容器 [配置](../concept/configuration.md),并创建处理请求所需的 [应用程序](../structure/application.md) 实例和服务。" #. type: Bullet: '3. ' #: ../src/guide/start/workflow.md msgid "Request factory creates a request object based on a raw request that came from a user." -msgstr "" +msgstr "请求工厂根据来自用户的原始请求创建请求对象。" #. type: Bullet: '4. ' #: ../src/guide/start/workflow.md msgid "Application passes a request object through a middleware array configured. One of these is typically a router." -msgstr "" +msgstr "应用程序将请求对象传递给配置的中间件数组。其中之一通常是路由器。" #. type: Bullet: '5. ' #: ../src/guide/start/workflow.md msgid "The Router finds out what handler to execute based on request and configuration." -msgstr "" +msgstr "路由器根据请求和配置确定要执行的处理器。" #. type: Bullet: '6. ' #: ../src/guide/start/workflow.md msgid "The handler may load some data, possibly from a database." -msgstr "" +msgstr "处理器可能会加载一些数据,可能来自数据库。" #. type: Bullet: '7. ' #: ../src/guide/start/workflow.md msgid "The handler forms a response by using data. Either directly or with the help of the view package." -msgstr "" +msgstr "处理器使用数据形成响应。可以直接形成,也可以借助视图包。" #. type: Bullet: '8. ' #: ../src/guide/start/workflow.md msgid "Emitter receives the response and takes care of sending the response to the user's browser." -msgstr "" +msgstr "发射器接收响应并负责将响应发送到用户的浏览器。" diff --git a/_translations/po/zh-CN/guide_structure_action.md.po b/_translations/po/zh-CN/guide_structure_action.md.po index ce452a9b..517714ba 100644 --- a/_translations/po/zh-CN/guide_structure_action.md.po +++ b/_translations/po/zh-CN/guide_structure_action.md.po @@ -19,17 +19,17 @@ msgstr "" #: ../src/guide/structure/action.md #, no-wrap msgid "Actions" -msgstr "" +msgstr "动作" #. type: Plain text #: ../src/guide/structure/action.md msgid "In a web application, the request URL determines what's executed. Matching is made by a router configured with multiple routes. Each route can be attached to a middleware that, given request, produces a response. Since middleware overall could be chained and can pass actual handling to the next middleware, we call the middleware actually doing the job an action." -msgstr "" +msgstr "在 Web 应用程序中,请求 URL 决定了要执行的内容。匹配由配置了多条路由的路由器完成。每条路由可以绑定一个中间件,该中间件接收请求并产生响应。由于中间件可以链式调用并将实际处理传递给下一个中间件,我们将真正执行任务的中间件称为动作。" #. type: Plain text #: ../src/guide/structure/action.md msgid "There are multiple ways to describe an action. The simplest one is using a closure:" -msgstr "" +msgstr "描述动作有多种方式,最简单的是使用闭包:" #. type: Fenced code block (php) #: ../src/guide/structure/action.md @@ -49,7 +49,7 @@ msgstr "" #. type: Plain text #: ../src/guide/structure/action.md msgid "It's fine for simple handling since any more complicated one would require getting dependencies, so a good idea would be moving the handling to a class method. Callback middleware could be used for the purpose:" -msgstr "" +msgstr "对于简单的处理,这种方式完全可以,但更复杂的处理通常需要获取依赖,因此将处理逻辑移至类方法是一个好主意。为此可以使用回调中间件:" #. type: Fenced code block (php) #: ../src/guide/structure/action.md @@ -63,7 +63,7 @@ msgstr "" #. type: Plain text #: ../src/guide/structure/action.md msgid "The class itself would be like:" -msgstr "" +msgstr "该类的结构如下:" #. type: Fenced code block (php) #: ../src/guide/structure/action.md @@ -84,7 +84,7 @@ msgstr "" #. type: Plain text #: ../src/guide/structure/action.md msgid "For many cases, it makes sense to group handling for many routes into a single class:" -msgstr "" +msgstr "在许多情况下,将多条路由的处理逻辑归入一个类是合理的:" #. type: Fenced code block (php) #: ../src/guide/structure/action.md @@ -99,7 +99,7 @@ msgstr "" #. type: Plain text #: ../src/guide/structure/action.md msgid "The class itself would look like the following:" -msgstr "" +msgstr "该类的结构如下所示:" #. type: Fenced code block (php) #: ../src/guide/structure/action.md @@ -126,13 +126,13 @@ msgstr "" #. type: Plain text #: ../src/guide/structure/action.md msgid "We usually call such a class \"controller.\"" -msgstr "" +msgstr "我们通常将这样的类称为“控制器”。" #. type: Title ## #: ../src/guide/structure/action.md #, no-wrap msgid "Autowiring" -msgstr "" +msgstr "自动注入" #. type: Plain text #: ../src/guide/structure/action.md @@ -141,6 +141,8 @@ msgid "" "Both constructors of action-classes and action-methods are automatically getting services from\n" " the dependency injection container:\n" msgstr "" +"动作类的构造函数和动作方法都可以自动从\n" +" 依赖注入容器中获取服务:\n" #. type: Fenced code block (php) #: ../src/guide/structure/action.md @@ -175,4 +177,4 @@ msgstr "" #. type: Plain text #: ../src/guide/structure/action.md msgid "In the above example `PostRepository` is injected automatically via constructor. That means it is available in every action. Logger is injected into `index` action only." -msgstr "" +msgstr "在上面的示例中,`PostRepository` 通过构造函数自动注入,因此在每个动作中都可用。而 Logger 仅注入到 `index` 动作中。" diff --git a/_translations/po/zh-CN/guide_structure_application.md.po b/_translations/po/zh-CN/guide_structure_application.md.po index fde4bda9..90a85c7a 100644 --- a/_translations/po/zh-CN/guide_structure_application.md.po +++ b/_translations/po/zh-CN/guide_structure_application.md.po @@ -19,29 +19,29 @@ msgstr "" #: ../src/guide/structure/application.md #, no-wrap msgid "Application" -msgstr "" +msgstr "应用" #. type: Plain text #: ../src/guide/structure/application.md msgid "The primary purpose of the web application and its runner in Yii3 is to process requests to get responses." -msgstr "" +msgstr "Yii3 中 Web 应用程序及其运行器的主要目的是处理请求以获取响应。" #. type: Plain text #: ../src/guide/structure/application.md msgid "Typically, the runtime consists of:" -msgstr "" +msgstr "通常,运行时由以下部分组成:" #. type: Bullet: '1. ' #: ../src/guide/structure/application.md msgid "Startup. Get config, create an instance of container and do additional environment initialization such as registering error handler, so it can handle errors occurring. Fire `ApplicationStartup` event." -msgstr "" +msgstr "启动。获取配置,创建容器实例,并进行额外的环境初始化,例如注册错误处理器以处理发生的错误。触发 `ApplicationStartup` 事件。" #. type: Bullet: '2. ' #: ../src/guide/structure/application.md msgid "Handle requests via passing request objects to middleware dispatcher to execute [middleware stack](middleware.md) and get a response object. In usual PHP applications, it's done once. In [environments such as RoadRunner](../tutorial/using-with-event-loop.md), it could be done multiple times with the same application instance. Response object is converted into an actual HTTP response by using emitter. Fire `AfterEmit` event." -msgstr "" +msgstr "通过将请求对象传递给中间件调度器来处理请求,以执行[中间件栈](middleware.md)并获取响应对象。在普通的 PHP 应用程序中,这只执行一次。在 [RoadRunner 等环境](../tutorial/using-with-event-loop.md)中,可以使用同一应用程序实例执行多次。响应对象通过发射器转换为实际的 HTTP 响应。触发 `AfterEmit` 事件。" #. type: Bullet: '3. ' #: ../src/guide/structure/application.md msgid "Shutdown. Fire `ApplicationShutdown` event." -msgstr "" +msgstr "关闭。触发 `ApplicationShutdown` 事件。" diff --git a/_translations/po/zh-CN/guide_structure_domain.md.po b/_translations/po/zh-CN/guide_structure_domain.md.po index 17bfaa95..6f70891a 100644 --- a/_translations/po/zh-CN/guide_structure_domain.md.po +++ b/_translations/po/zh-CN/guide_structure_domain.md.po @@ -31,13 +31,13 @@ msgstr "参考资料" #: ../src/guide/structure/service.md #, no-wrap msgid "Repository" -msgstr "" +msgstr "仓库" #. type: Title # #: ../src/guide/structure/domain.md #, no-wrap msgid "Domain" -msgstr "" +msgstr "领域" #. type: Plain text #: ../src/guide/structure/domain.md @@ -48,6 +48,10 @@ msgid "" "operates these entities. To focus on the complex part of the problem, domain is, ideally, separated from\n" " the infrastructure part of the system (that's how to save data into a database, how to form HTTP response, etc.).\n" msgstr "" +"领域或领域模型是使项目独特的东西。考虑到正在解决的问题的需求和术语\n" +"(问题上下文),您构建一个由实体、它们的关系以及操作这些实体的逻辑组成的\n" +"抽象。为了专注于问题的复杂部分,领域理想情况下应与\n" +"系统的基础设施部分分离(即如何将数据保存到数据库、如何形成 HTTP 响应等)。\n" #. type: Plain text #: ../src/guide/structure/domain.md @@ -59,132 +63,137 @@ msgid "" "> The individual concepts of domain design below could be applied separately, so make sure to check these even if your\n" "> project isn't that complicated. \n" msgstr "" +"> [!NOTE]\n" +"> 这种隔离适用于复杂系统。如果您的项目领域基本上是对一组记录的创建/读取/更新/删除,\n" +"> 没有太多复杂逻辑,那么将复杂解决方案应用于简单问题是没有意义的。\n" +"> 下面的领域设计的各个概念可以单独应用,因此即使您的\n" +"> 项目没有那么复杂,也请确保查看这些内容。\n" #. type: Title ## #: ../src/guide/structure/domain.md #, no-wrap msgid "Bounded context" -msgstr "" +msgstr "限界上下文" #. type: Plain text #: ../src/guide/structure/domain.md msgid "It's nearly impossible to build a model that solves multiple problems that aren't too complicated by itself. Therefore, it's a good practice to divide the domain into several use-cases and have a separate model for each use-case. Such separated models are called \"bounded contexts.\"" -msgstr "" +msgstr "几乎不可能构建一个能解决多个问题且本身不太复杂的模型。因此,将领域划分为几个用例并为每个用例建立单独的模型是一种良好实践。这种分离的模型被称为“限界上下文”。" #. type: Title ## #: ../src/guide/structure/domain.md #, no-wrap msgid "Building blocks" -msgstr "" +msgstr "构建块" #. type: Plain text #: ../src/guide/structure/domain.md msgid "There are various building blocks that are typically used when describing domain models. It isn't mandatory to use them all." -msgstr "" +msgstr "在描述领域模型时,通常使用各种构建块。并非必须使用所有构建块。" #. type: Bullet: '- ' #: ../src/guide/structure/domain.md ../src/guide/structure/service.md #, no-wrap msgid "Entity" -msgstr "" +msgstr "实体" #. type: Plain text #: ../src/guide/structure/domain.md msgid "Entity is a uniquely identifiable object such as user, product, payment, etc. When comparing them, you're checking ID, not the attribute values. If there are two objects with different attributes but the same ID, they're considered being the same thing." -msgstr "" +msgstr "实体是可唯一标识的对象,例如用户、产品、付款等。比较它们时,您检查的是 ID,而不是属性值。如果有两个属性不同但 ID 相同的对象,则认为它们是同一个事物。" #. type: Title ### #: ../src/guide/structure/domain.md #, no-wrap msgid "Value object" -msgstr "" +msgstr "值对象" #. type: Plain text #: ../src/guide/structure/domain.md msgid "Value object describes an object by its characteristics. For example, a price that consists of value and currency. When comparing such objects, you're checking actual values. If they match, an object is considered to be the same." -msgstr "" +msgstr "值对象通过其特征来描述对象。例如,由数值和货币组成的价格。比较此类对象时,您检查的是实际值。如果它们匹配,则认为对象相同。" #. type: Title ### #: ../src/guide/structure/domain.md #, no-wrap msgid "Aggregate" -msgstr "" +msgstr "聚合" #. type: Plain text #: ../src/guide/structure/domain.md msgid "Aggregate is a set of domain objects such as entities and value objects and additional data that could be treated as a single unit. It usually represents a compound object from a domain model such as shop order or HR person dossier." -msgstr "" +msgstr "聚合是一组可视为单一单元的领域对象(如实体、值对象)和附加数据。它通常代表领域模型中的复合对象,例如商店订单或人力资源人员档案。" #. type: Plain text #: ../src/guide/structure/domain.md msgid "One of the components of an aggregate is called a root. The root identifies an aggregate as a whole and should be used to access it." -msgstr "" +msgstr "聚合的一个组件称为根。根将聚合标识为一个整体,应通过根来访问聚合。" #. type: Title ### #: ../src/guide/structure/domain.md #, no-wrap msgid "Domain event" -msgstr "" +msgstr "领域事件" #. type: Plain text #: ../src/guide/structure/domain.md msgid "An aggregate, while processed, may raise events. For example, when order is confirmed, `OrderConfirmed` event would be risen so other parts of the system may react on these." -msgstr "" +msgstr "聚合在处理过程中可能会引发事件。例如,当订单确认时,会触发 `OrderConfirmed` 事件,以便系统的其他部分可以响应这些事件。" #. type: Title ### #: ../src/guide/structure/domain.md #, no-wrap msgid "Data transfer object" -msgstr "" +msgstr "数据传输对象" #. type: Plain text #: ../src/guide/structure/domain.md msgid "Data transfer object or DTO is an object whose only purpose is to hold data as it is. It's commonly used to pass data between different services." -msgstr "" +msgstr "数据传输对象(DTO)是一种仅用于保存数据的对象。它通常用于在不同服务之间传递数据。" #. type: Title ### #: ../src/guide/structure/domain.md #, no-wrap msgid "Service" -msgstr "" +msgstr "服务" #. type: Plain text #: ../src/guide/structure/domain.md msgid "Service is a class that contains a standalone operation within the context of your domain model. See \"[service components](service.md)\"." -msgstr "" +msgstr "服务是一个包含领域模型上下文中独立操作的类。请参阅“[服务组件](service.md)”。" #. type: Plain text #: ../src/guide/structure/domain.md msgid "The repository task is to abstract away how domain objects are obtained. These are usually separated into two parts: an interface that stays in the domain layer and an implementation that's situated in the infrastructure layer. In such a way, domain doesn't care how data is obtained and saved and may be focused around the complicated business logic instead." -msgstr "" +msgstr "仓库的任务是抽象化获取领域对象的方式。这些通常分为两部分:保留在领域层的接口和位于基础设施层的实现。这样,领域不关心如何获取和保存数据,可以专注于复杂的业务逻辑。" #. type: Plain text #: ../src/guide/structure/domain.md msgid "Repository is usually implemented as a service." -msgstr "" +msgstr "仓库通常作为服务实现。" #. type: Title ### #: ../src/guide/structure/domain.md #, no-wrap msgid "Instantiating building blocks" -msgstr "" +msgstr "实例化构建块" #. type: Plain text #: ../src/guide/structure/domain.md msgid "Entity, value object, aggregate, and domain events aren't services and shouldn't be instantiated through DI container. Using `new` is the way to go with these." -msgstr "" +msgstr "实体、值对象、聚合和领域事件不是服务,不应通过 DI 容器实例化。使用 `new` 是实例化这些对象的正确方式。" #. type: Bullet: '- ' #: ../src/guide/structure/domain.md msgid "[BoundedContext by Martin Fowler](https://martinfowler.com/bliki/BoundedContext.html)" -msgstr "" +msgstr "[Martin Fowler 的限界上下文](https://martinfowler.com/bliki/BoundedContext.html)" #. type: Bullet: '- ' #: ../src/guide/structure/domain.md msgid "[ValueObject by Martin Fowler](https://martinfowler.com/bliki/ValueObject.html)" -msgstr "" +msgstr "[Martin Fowler 的值对象](https://martinfowler.com/bliki/ValueObject.html)" #. type: Bullet: '- ' #: ../src/guide/structure/domain.md msgid "[Aggregate by Marting Fowler](https://martinfowler.com/bliki/DDD_Aggregate.html)" -msgstr "" +msgstr "[Martin Fowler 的聚合](https://martinfowler.com/bliki/DDD_Aggregate.html)" diff --git a/_translations/po/zh-CN/guide_structure_entry-script.md.po b/_translations/po/zh-CN/guide_structure_entry-script.md.po index 00539229..4ae1e82f 100644 --- a/_translations/po/zh-CN/guide_structure_entry-script.md.po +++ b/_translations/po/zh-CN/guide_structure_entry-script.md.po @@ -19,68 +19,68 @@ msgstr "" #: ../src/guide/structure/entry-script.md #, no-wrap msgid "Entry scripts" -msgstr "" +msgstr "入口脚本" #. type: Plain text #: ../src/guide/structure/entry-script.md msgid "Entry scripts are the first step in the application bootstrapping process. An application (either Web application or console application) has a single entry script. End users make requests to entry scripts which instantiate application instances and forward the requests to them." -msgstr "" +msgstr "入口脚本是应用程序引导过程的第一步。每个应用程序(无论是 Web 应用程序还是控制台应用程序)都只有一个入口脚本。最终用户向入口脚本发起请求,入口脚本负责实例化应用程序并将请求转发给它。" #. type: Plain text #: ../src/guide/structure/entry-script.md msgid "Entry scripts for Web applications must be stored under Web-accessible directories so that they can be accessed by end users. They're often named as `index.php`, but can also use any other names, provided Web servers can locate them." -msgstr "" +msgstr "Web 应用程序的入口脚本必须存储在 Web 可访问目录下,以便最终用户能够访问。文件名通常为 `index.php`,但也可以使用其他名称,只要 Web 服务器能够找到即可。" #. type: Plain text #: ../src/guide/structure/entry-script.md msgid "Entry script for console application is `./yii`." -msgstr "" +msgstr "控制台应用程序的入口脚本为 `./yii`。" #. type: Plain text #: ../src/guide/structure/entry-script.md msgid "Entry scripts mainly perform the following work with the help of `ApplicationRunner`:" -msgstr "" +msgstr "入口脚本借助 `ApplicationRunner` 主要完成以下工作:" #. type: Bullet: '* ' #: ../src/guide/structure/entry-script.md msgid "Register [Composer autoloader](https://getcomposer.org/doc/01-basic-usage.md#autoloading);" -msgstr "" +msgstr "注册 [Composer 自动加载器](https://getcomposer.org/doc/01-basic-usage.md#autoloading);" #. type: Bullet: '* ' #: ../src/guide/structure/entry-script.md msgid "Obtain configuration;" -msgstr "" +msgstr "获取配置;" #. type: Bullet: '* ' #: ../src/guide/structure/entry-script.md msgid "Use configuration to initialize a dependency injection container;" -msgstr "" +msgstr "使用配置初始化依赖注入容器;" #. type: Bullet: '* ' #: ../src/guide/structure/entry-script.md msgid "Get an instance of the request." -msgstr "" +msgstr "获取请求实例。" #. type: Bullet: '* ' #: ../src/guide/structure/entry-script.md msgid "Pass it to `Application` to handle and get a response from it." -msgstr "" +msgstr "将请求传递给 `Application` 处理并获取响应。" #. type: Bullet: '* ' #: ../src/guide/structure/entry-script.md msgid "With the help of an emitter that transforms a response object into an actual HTTP response that's sent to the client browser." -msgstr "" +msgstr "借助发射器将响应对象转换为实际的 HTTP 响应并发送给客户端浏览器。" #. type: Title ## #: ../src/guide/structure/entry-script.md #, no-wrap msgid "Web Applications " -msgstr "" +msgstr "Web 应用程序 " #. type: Plain text #: ../src/guide/structure/entry-script.md msgid "The following is the code in the entry script for the application template:" -msgstr "" +msgstr "以下是应用程序模板中入口脚本的代码:" #. type: Fenced code block (php) #: ../src/guide/structure/entry-script.md @@ -116,12 +116,12 @@ msgstr "" #: ../src/guide/structure/entry-script.md #, no-wrap msgid "Console Applications " -msgstr "" +msgstr "控制台应用程序 " #. type: Plain text #: ../src/guide/structure/entry-script.md msgid "Similarly, the following is the code for the entry script of a console application:" -msgstr "" +msgstr "类似地,以下是控制台应用程序入口脚本的代码:" #. type: Fenced code block (php) #: ../src/guide/structure/entry-script.md @@ -174,19 +174,19 @@ msgstr "" #: ../src/guide/structure/entry-script.md #, no-wrap msgid "Alternative runtimes" -msgstr "" +msgstr "其他运行时" #. type: Plain text #: ../src/guide/structure/entry-script.md msgid "For alternative runtimes such as RoadRunner or Swoole, special entry scripts should be used. See:" -msgstr "" +msgstr "对于 RoadRunner 或 Swoole 等其他运行时,需要使用专用的入口脚本。请参阅:" #. type: Bullet: '- ' #: ../src/guide/structure/entry-script.md msgid "[Using Yii with RoadRunner](../tutorial/using-yii-with-roadrunner.md)" -msgstr "" +msgstr "[在 RoadRunner 中使用 Yii](../tutorial/using-yii-with-roadrunner.md)" #. type: Bullet: '- ' #: ../src/guide/structure/entry-script.md msgid "[Using Yii with Swoole](../tutorial/using-yii-with-swoole.md)" -msgstr "" +msgstr "[在 Swoole 中使用 Yii](../tutorial/using-yii-with-swoole.md)" diff --git a/_translations/po/zh-CN/guide_structure_middleware.md.po b/_translations/po/zh-CN/guide_structure_middleware.md.po index f133d097..d7f741d8 100644 --- a/_translations/po/zh-CN/guide_structure_middleware.md.po +++ b/_translations/po/zh-CN/guide_structure_middleware.md.po @@ -19,68 +19,68 @@ msgstr "" #: ../src/guide/structure/middleware.md #, no-wrap msgid "Middleware" -msgstr "" +msgstr "中间件" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "Yii works with HTTP using the abstraction layer built around [PSR-7 HTTP message interfaces](https://www.php-fig.org/psr/psr-7/) and [PSR-15 request handler/middleware interfaces](https://www.php-fig.org/psr/psr-15/)." -msgstr "" +msgstr "Yii 通过基于 [PSR-7 HTTP 消息接口](https://www.php-fig.org/psr/psr-7/) 和 [PSR-15 请求处理器/中间件接口](https://www.php-fig.org/psr/psr-15/) 构建的抽象层来处理 HTTP。" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "The application is composed of one or several middleware. Middleware runs between request and response. When the URL is requested, the request object is passed to the middleware dispatcher that starts executing middleware one after another. Each middleware, given the request, can:" -msgstr "" +msgstr "应用程序由一个或多个中间件组成。中间件在请求和响应之间运行。当 URL 被请求时,请求对象被传递给中间件调度器,后者开始逐个执行中间件。每个中间件在给定请求的情况下可以:" #. type: Bullet: '- ' #: ../src/guide/structure/middleware.md msgid "Pass the request to the next middleware performing some work before / after it." -msgstr "" +msgstr "将请求传递给下一个中间件,并在其之前/之后执行一些工作。" #. type: Bullet: '- ' #: ../src/guide/structure/middleware.md msgid "Form the response and return it." -msgstr "" +msgstr "形成响应并返回它。" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "Depending on middleware used, application behavior may vary significantly." -msgstr "" +msgstr "根据所使用的中间件,应用程序的行为可能会有很大差异。" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "![Middleware](/images/guide/middleware.svg)" -msgstr "" +msgstr "![中间件](/images/guide/middleware.svg)" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "In the above each next middleware wraps the previous middleware. Alternatively, it could be presented as follows:" -msgstr "" +msgstr "在上图中,每个后续中间件都包裹着前一个中间件。或者,它也可以如下所示:" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "![Middleware](/images/guide/middleware_alternative.svg)" -msgstr "" +msgstr "![中间件](/images/guide/middleware_alternative.svg)" #. type: Title ## #: ../src/guide/structure/middleware.md #, no-wrap msgid "Using middleware" -msgstr "" +msgstr "使用中间件" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "Any [PSR-15](https://www.php-fig.org/psr/psr-15/) compatible middleware could be used with Yii, and there are many. Say, you need to add basic authentication to one of the application URLs. URL-dependent middleware is configured using router, so you need to change the router factory." -msgstr "" +msgstr "任何与 [PSR-15](https://www.php-fig.org/psr/psr-15/) 兼容的中间件都可以与 Yii 一起使用,而且有很多。比如,您需要为应用程序的某个 URL 添加基本身份验证。依赖 URL 的中间件使用路由器配置,因此您需要修改路由器工厂。" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "Authentication middleware is implemented by `middlewares/http-authentication` package so execute `composer require middlewares/http-authentication` in the application root directory." -msgstr "" +msgstr "身份验证中间件由 `middlewares/http-authentication` 包实现,因此在应用程序根目录中执行 `composer require middlewares/http-authentication`。" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "Now register the middleware in DI container configuration `config/web.php`:" -msgstr "" +msgstr "现在在 DI 容器配置 `config/web.php` 中注册中间件:" #. type: Fenced code block (php) #: ../src/guide/structure/middleware.md @@ -102,7 +102,7 @@ msgstr "" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "In the `config/routes.php`, add new route:" -msgstr "" +msgstr "在 `config/routes.php` 中,添加新路由:" #. type: Fenced code block (php) #: ../src/guide/structure/middleware.md @@ -129,12 +129,12 @@ msgstr "" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "When configuring routing, you're binding `/basic-auth` URL to a chain of middleware consisting of basic authentication, and the action itself. A chain is a special middleware that executes all the middleware it's configured with." -msgstr "" +msgstr "配置路由时,您将 `/basic-auth` URL 绑定到由基本身份验证和操作本身组成的中间件链。链是一种特殊的中间件,它执行其配置的所有中间件。" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "The action itself could be the following:" -msgstr "" +msgstr "操作本身可以如下所示:" #. type: Fenced code block (php) #: ../src/guide/structure/middleware.md @@ -151,12 +151,12 @@ msgstr "" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "Basic authentication middleware wrote to request `username` attribute, so you can access the data if needed." -msgstr "" +msgstr "基本身份验证中间件将 `username` 写入请求属性,因此您可以在需要时访问该数据。" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "To apply middleware to application overall regardless of URL, adjust `config/application.php`:" -msgstr "" +msgstr "要将中间件应用于整个应用程序(不考虑 URL),请调整 `config/application.php`:" #. type: Fenced code block (php) #: ../src/guide/structure/middleware.md @@ -187,12 +187,12 @@ msgstr "" #: ../src/guide/structure/middleware.md #, no-wrap msgid "Creating your own middleware" -msgstr "" +msgstr "创建自己的中间件" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "To create middleware, you need to implement a single `process` method of `Psr\\Http\\Server\\MiddlewareInterface`:" -msgstr "" +msgstr "要创建中间件,您需要实现 `Psr\\Http\\Server\\MiddlewareInterface` 的单个 `process` 方法:" #. type: Fenced code block (php) #: ../src/guide/structure/middleware.md @@ -203,18 +203,18 @@ msgstr "" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "There are multiple ways to handle a request, and choosing one depends on what the middleware should achieve." -msgstr "" +msgstr "处理请求有多种方式,选择哪种取决于中间件应实现的目标。" #. type: Title ### #: ../src/guide/structure/middleware.md #, no-wrap msgid "Forming a response directly" -msgstr "" +msgstr "直接形成响应" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "To respond directly, one needs a response factory passed via constructor:" -msgstr "" +msgstr "要直接响应,需要通过构造函数传递响应工厂:" #. type: Fenced code block (php) #: ../src/guide/structure/middleware.md @@ -250,7 +250,7 @@ msgstr "" #: ../src/guide/structure/middleware.md #, no-wrap msgid "Delegating handling to the next middleware" -msgstr "" +msgstr "将处理委托给下一个中间件" #. type: Plain text #: ../src/guide/structure/middleware.md @@ -259,6 +259,8 @@ msgid "" "If middleware either isn't intended to form a response or change the request or can't do anything this time,\n" "handling could be left to the next middleware in the stack: \n" msgstr "" +"如果中间件既不打算形成响应或更改请求,也无法在此时执行任何操作,\n" +"则可以将处理留给栈中的下一个中间件:\n" #. type: Fenced code block (php) #: ../src/guide/structure/middleware.md @@ -273,7 +275,7 @@ msgstr "" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "In case you need to pass data to the next middleware, you can use request attributes:" -msgstr "" +msgstr "如果您需要将数据传递给下一个中间件,可以使用请求属性:" #. type: Fenced code block (php) #: ../src/guide/structure/middleware.md @@ -286,7 +288,7 @@ msgstr "" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "To get it in the next middleware:" -msgstr "" +msgstr "要在下一个中间件中获取它:" #. type: Fenced code block (php) #: ../src/guide/structure/middleware.md @@ -298,12 +300,12 @@ msgstr "" #: ../src/guide/structure/middleware.md #, no-wrap msgid "Capturing response to manipulate it" -msgstr "" +msgstr "捕获响应以操作它" #. type: Plain text #: ../src/guide/structure/middleware.md msgid "You may want to capture the response to manipulate it. It could be useful for adding CORS headers, gzipping content, etc." -msgstr "" +msgstr "您可能希望捕获响应以对其进行操作。这对于添加 CORS 标头、gzip 压缩内容等非常有用。" #. type: Fenced code block (php) #: ../src/guide/structure/middleware.md diff --git a/_translations/po/zh-CN/guide_structure_overview.md.po b/_translations/po/zh-CN/guide_structure_overview.md.po index f43dd389..67b21cc7 100644 --- a/_translations/po/zh-CN/guide_structure_overview.md.po +++ b/_translations/po/zh-CN/guide_structure_overview.md.po @@ -20,92 +20,92 @@ msgstr "" #: ../src/en/guide/views/script-style-meta.md #, no-wrap msgid "Overview" -msgstr "" +msgstr "概述" #. type: Plain text #: ../src/en/guide/structure/overview.md msgid "Yii applications code is typically grouped into modules by context. In each module there could be grouping by type." -msgstr "" +msgstr "Yii 应用程序代码通常按上下文分组到模块中。在每个模块中,可以按类型进行进一步分组。" #. type: Plain text #: ../src/en/guide/structure/overview.md msgid "For example, if the application is an online store, the context could be:" -msgstr "" +msgstr "例如,如果应用程序是一个在线商店,上下文可以是:" #. type: Bullet: '- ' #: ../src/en/guide/structure/overview.md msgid "Customer" -msgstr "" +msgstr "客户" #. type: Bullet: ' - ' #: ../src/en/guide/structure/overview.md msgid "Profile" -msgstr "" +msgstr "个人资料" #. type: Bullet: ' - ' #: ../src/en/guide/structure/overview.md msgid "Products list" -msgstr "" +msgstr "产品列表" #. type: Bullet: ' - ' #: ../src/en/guide/structure/overview.md msgid "Checkout" -msgstr "" +msgstr "结账" #. type: Bullet: '- ' #: ../src/en/guide/structure/overview.md msgid "Logistics" -msgstr "" +msgstr "物流" #. type: Bullet: '- ' #: ../src/en/guide/structure/overview.md msgid "Delivery" -msgstr "" +msgstr "配送" #. type: Bullet: ' - ' #: ../src/en/guide/structure/overview.md msgid "Addresses" -msgstr "" +msgstr "地址" #. type: Bullet: '- ' #: ../src/en/guide/structure/overview.md msgid "Helpdesk" -msgstr "" +msgstr "帮助台" #. type: Bullet: ' - ' #: ../src/en/guide/structure/overview.md msgid "Support" -msgstr "" +msgstr "支持" #. type: Bullet: ' - ' #: ../src/en/guide/structure/overview.md msgid "Claims" -msgstr "" +msgstr "索赔" #. type: Bullet: ' - ' #: ../src/en/guide/structure/overview.md msgid "Returns" -msgstr "" +msgstr "退货" #. type: Bullet: '- ' #: ../src/en/guide/structure/overview.md msgid "Accounting" -msgstr "" +msgstr "财务" #. type: Bullet: ' - ' #: ../src/en/guide/structure/overview.md msgid "Transactions" -msgstr "" +msgstr "交易" #. type: Bullet: ' - ' #: ../src/en/guide/structure/overview.md msgid "Taxes" -msgstr "" +msgstr "税务" #. type: Plain text #: ../src/en/guide/structure/overview.md msgid "For a \"Customer\" context, residing under `App\\Customer` namespace, structure would be:" -msgstr "" +msgstr "对于位于 `App\\Customer` 命名空间下的“Customer”上下文,结构将是:" #. type: Fenced code block #: ../src/en/guide/structure/overview.md @@ -128,33 +128,49 @@ msgid "" " Checkout/ <-- module namespace\n" " CheckoutController.php\n" msgstr "" +"App/\n" +" Customer/ <-- 模块命名空间\n" +" Entity/\n" +" Customer.php <-- \"Profile\" 和 \"Checkout\" 共用的实体\n" +" Profile/\n" +" Widget/\n" +" Gravatar.php\n" +" ProfileRepository.php <-- 仓库通常特定于上下文\n" +" ProfileController.php <-- \"Customer\\Profile\" 入口点\n" +" ProductList/ <-- 模块命名空间\n" +" Entity/ <-- \"Customer\\ProductList\" 特有的实体\n" +" Category.php\n" +" Product.php\n" +" ProductsListController.php <-- \"Customer\\ProductList\" 入口点\n" +" Checkout/ <-- 模块命名空间\n" +" CheckoutController.php\n" #. type: Plain text #: ../src/en/guide/structure/overview.md msgid "A context may include sub-contexts. If a class is shared by multiple contexts, it's moved to the ancestor of both contexts." -msgstr "" +msgstr "一个上下文可以包含子上下文。如果一个类被多个上下文共享,它将被移动到两个上下文的共同祖先中。" #. type: Plain text #: ../src/en/guide/structure/overview.md msgid "A context may have [an entry point known as \"action\" or \"controller\"](action.md). Its job is to take [a request instance](../runtime/request.md), pass it to [domain layer](domain.md) in a suitable format, and create [a response](../runtime/response.md) based on domain layer return." -msgstr "" +msgstr "一个上下文可以有 [一个称为“动作”或“控制器”的入口点](action.md)。它的工作是获取[请求实例](../runtime/request.md),以适当的格式将其传递给 [领域层](domain.md),并根据领域层的返回创建 [响应](../runtime/response.md)。" #. type: Plain text #: ../src/en/guide/structure/overview.md msgid "Besides, Yii applications also have the following:" -msgstr "" +msgstr "此外,Yii 应用程序还具有以下内容:" #. type: Bullet: '* ' #: ../src/en/guide/structure/overview.md msgid "[entry scripts](entry-script.md): they're PHP scripts that are directly accessible by end users. They're responsible for starting a request handling cycle. Typically, a single entry script is handling the whole application." -msgstr "" +msgstr "[入口脚本](entry-script.md):它们是最终用户可以直接访问的 PHP 脚本。它们负责启动请求处理周期。通常,单个入口脚本处理整个应用程序。" #. type: Bullet: '* ' #: ../src/en/guide/structure/overview.md msgid "[services](service.md): they're typically stateless objects registered within dependency container and provide various action methods." -msgstr "" +msgstr "[服务](service.md):它们通常是在依赖容器中注册的无状态对象,并提供各种操作方法。" #. type: Bullet: '* ' #: ../src/en/guide/structure/overview.md msgid "[middleware](middleware.md): they represent a code that needs to be invoked before and after the actual handling of each request by action handlers." -msgstr "" +msgstr "[中间件](middleware.md):它们表示需要在操作处理器实际处理每个请求之前和之后调用的代码。" diff --git a/_translations/po/zh-CN/guide_structure_package.md.po b/_translations/po/zh-CN/guide_structure_package.md.po index f93aae08..1de7d7c3 100644 --- a/_translations/po/zh-CN/guide_structure_package.md.po +++ b/_translations/po/zh-CN/guide_structure_package.md.po @@ -19,28 +19,28 @@ msgstr "" #: ../src/guide/structure/package.md #, no-wrap msgid "Packages" -msgstr "" +msgstr "包" #. type: Plain text #: ../src/guide/structure/package.md msgid "Reusable code could be released as [a Composer package](https://getcomposer.org/doc/05-repositories.md#package). It could be an infrastructure library, a module representing one of the application contexts or, basically, any reusable code." -msgstr "" +msgstr "可复用的代码可以作为 [Composer 包](https://getcomposer.org/doc/05-repositories.md#package)发布。它可以是一个基础设施库、代表某个应用上下文的模块,或者基本上任何可复用的代码。" #. type: Title ## #: ../src/guide/structure/package.md #, no-wrap msgid "Using packages " -msgstr "" +msgstr "使用包 " #. type: Plain text #: ../src/guide/structure/package.md msgid "By default, Composer installs packages registered on [Packagist](https://packagist.org/) — the biggest repository for open source PHP packages. You can look for packages on Packagist. You may also [create your own repository](https://getcomposer.org/doc/05-repositories.md#repository) and configure Composer to use it. This is useful if you're developing private packages that you want to share within your projects only." -msgstr "" +msgstr "默认情况下,Composer 会安装在 [Packagist](https://packagist.org/) 上注册的包——这是最大的开源 PHP 包仓库。您可以在 Packagist 上搜索包。您也可以[创建自己的仓库](https://getcomposer.org/doc/05-repositories.md#repository)并配置 Composer 使用它,这在开发只在项目内部共享的私有包时非常有用。" #. type: Plain text #: ../src/guide/structure/package.md msgid "Packages installed by Composer are stored in the `vendor` directory of your project. Because the Composer is a dependency manager, when it installs a package, it will also install all its dependent packages." -msgstr "" +msgstr "Composer 安装的包存储在项目的 `vendor` 目录中。由于 Composer 是一个依赖管理器,在安装某个包时,它也会同时安装该包所依赖的所有包。" #. type: Plain text #: ../src/guide/structure/package.md @@ -49,11 +49,13 @@ msgid "" "> [!WARNING]\n" "> `vendor` directory of your application should never be modified.\n" msgstr "" +"> [!WARNING]\n" +"> 永远不要手动修改应用程序的 `vendor` 目录。\n" #. type: Plain text #: ../src/guide/structure/package.md msgid "A package could be installed with the following command:" -msgstr "" +msgstr "可以使用以下命令安装包:" #. type: Fenced code block #: ../src/guide/structure/package.md @@ -64,54 +66,54 @@ msgstr "" #. type: Plain text #: ../src/guide/structure/package.md msgid "After it's done, Composer modifies `composer.json` and `composer.lock`. The former defines what packages to install, and their version constraints the latter stores a snapshot of exact versions actually installed." -msgstr "" +msgstr "完成后,Composer 会修改 `composer.json` 和 `composer.lock`。前者定义要安装的包及其版本约束,后者存储实际安装的精确版本快照。" #. type: Plain text #: ../src/guide/structure/package.md msgid "Classes from the package will be available immediately via [autoloading](../concept/autoloading.md)." -msgstr "" +msgstr "包中的类可以通过[自动加载](../concept/autoloading.md)立即使用。" #. type: Title ## #: ../src/guide/structure/package.md #, no-wrap msgid "Creating packages " -msgstr "" +msgstr "创建包 " #. type: Plain text #: ../src/guide/structure/package.md msgid "You may consider creating a package when you feel the need to share with other people your great code. A package can contain any code you like, such as a helper class, a widget, a service, middleware, the whole module, etc." -msgstr "" +msgstr "当您希望与他人共享优质代码时,可以考虑创建一个包。包可以包含任何代码,例如辅助类、小部件、服务、中间件、完整模块等。" #. type: Plain text #: ../src/guide/structure/package.md msgid "Below are the basic steps you may follow." -msgstr "" +msgstr "以下是基本步骤。" #. type: Bullet: '1. ' #: ../src/guide/structure/package.md msgid "Create a project for your package and host it on a VCS repository, such as [GitHub.com](https://github.com). The development and maintenance work for the package should be done on this repository." -msgstr "" +msgstr "为您的包创建一个项目,并将其托管在 VCS 仓库(例如 [GitHub.com](https://github.com))上。包的开发和维护工作应在该仓库中进行。" #. type: Bullet: '2. ' #: ../src/guide/structure/package.md msgid "Under the root directory of the project, create a file named `composer.json` as required by Composer. Please refer to the next subsection for more details." -msgstr "" +msgstr "在项目根目录下,按照 Composer 的要求创建 `composer.json` 文件。详情请参阅下一小节。" #. type: Bullet: '3. ' #: ../src/guide/structure/package.md msgid "Register your package with a Composer repository, such as [Packagist](https://packagist.org/), so that other users can find and install your package using Composer." -msgstr "" +msgstr "将您的包注册到 Composer 仓库(例如 [Packagist](https://packagist.org/)),以便其他用户能够通过 Composer 找到并安装您的包。" #. type: Title ### #: ../src/guide/structure/package.md #, no-wrap msgid "`composer.json` " -msgstr "" +msgstr "`composer.json` " #. type: Plain text #: ../src/guide/structure/package.md msgid "Each Composer package must have a `composer.json` file in its root directory. The file contains the metadata about the package. You may find the complete specification about this file in the [Composer Manual](https://getcomposer.org/doc/01-basic-usage.md#composer-json-project-setup). The following example shows the `composer.json` file for the `yiisoft/yii-widgets` package:" -msgstr "" +msgstr "每个 Composer 包的根目录下必须有一个 `composer.json` 文件,该文件包含包的元数据。您可以在 [Composer 手册](https://getcomposer.org/doc/01-basic-usage.md#composer-json-project-setup)中找到该文件的完整规范。以下示例展示了 `yiisoft/yii-widgets` 包的 `composer.json` 文件:" #. type: Fenced code block (json) #: ../src/guide/structure/package.md @@ -194,12 +196,12 @@ msgstr "" #: ../src/guide/structure/package.md #, no-wrap msgid "Package Name " -msgstr "" +msgstr "包名 " #. type: Plain text #: ../src/guide/structure/package.md msgid "Each Composer package should have a package name which uniquely identifies the package among all others. The format of package names is `vendorName/projectName`. For example, in the package name `yiisoft/queue`, the vendor name, and the project name are `yiisoft` and `queue`, respectively." -msgstr "" +msgstr "每个 Composer 包都应有一个唯一标识该包的包名。包名的格式为 `vendorName/projectName`。例如,在包名 `yiisoft/queue` 中,供应商名称为 `yiisoft`,项目名称为 `queue`。" #. type: Plain text #: ../src/guide/structure/package.md @@ -208,33 +210,35 @@ msgid "" "> [!WARNING]\n" "> Don't use `yiisoft` as your vendor name as it's reserved for use by the Yii itself.\n" msgstr "" +"> [!WARNING]\n" +"> 不要使用 `yiisoft` 作为您的供应商名称,该名称为 Yii 框架自身保留。\n" #. type: Plain text #: ../src/guide/structure/package.md msgid "We recommend you prefix `yii-` to the project name for packages that aren't able to work as general PHP packages and require Yii application. This will allow users to more easily tell whether a package is Yii specific." -msgstr "" +msgstr "对于无法作为通用 PHP 包使用、必须依赖 Yii 应用程序的包,我们建议在项目名称前加上 `yii-` 前缀,以便用户更容易判断某个包是否为 Yii 专属包。" #. type: Title #### #: ../src/guide/structure/package.md #, no-wrap msgid "Dependencies " -msgstr "" +msgstr "依赖 " #. type: Plain text #: ../src/guide/structure/package.md msgid "If your extension depends on other packages, you should list them in `require` section of `composer.json`. Make sure you also list appropriate version constraints (e.g. `^1.0`, `@stable`) for each dependent package. Use stable dependencies when your extension is released in a stable version." -msgstr "" +msgstr "如果您的扩展依赖其他包,应在 `composer.json` 的 `require` 部分列出它们,并为每个依赖包指定适当的版本约束(例如 `^1.0`、`@stable`)。当扩展发布稳定版本时,应使用稳定版本的依赖。" #. type: Title #### #: ../src/guide/structure/package.md #, no-wrap msgid "Class Autoloading " -msgstr "" +msgstr "类自动加载 " #. type: Plain text #: ../src/guide/structure/package.md msgid "In order for your classes to be autoloaded, you should specify the `autoload` entry in the `composer.json` file, like shown below:" -msgstr "" +msgstr "要使您的类能够被自动加载,需要在 `composer.json` 文件中指定 `autoload` 条目,如下所示:" #. type: Fenced code block (json) #: ../src/guide/structure/package.md @@ -254,88 +258,88 @@ msgstr "" #. type: Plain text #: ../src/guide/structure/package.md msgid "You may list one or multiple root namespaces and their corresponding file paths." -msgstr "" +msgstr "您可以列出一个或多个根命名空间及其对应的文件路径。" #. type: Title ### #: ../src/guide/structure/package.md #, no-wrap msgid "Recommended Practices " -msgstr "" +msgstr "推荐实践 " #. type: Plain text #: ../src/guide/structure/package.md msgid "Because packages are meant to be used by other people, you often need to make an extra effort during development. Below, we introduce some common and recommended practices in creating high-quality extensions." -msgstr "" +msgstr "由于包是供他人使用的,在开发过程中往往需要付出额外的努力。以下介绍一些创建高质量扩展的常见推荐实践。" #. type: Title #### #: ../src/guide/structure/package.md #, no-wrap msgid "Testing " -msgstr "" +msgstr "测试 " #. type: Plain text #: ../src/guide/structure/package.md msgid "You want your package to run flawlessly without bringing problems to other people. To reach this goal, you should test your extension before releasing it to the public." -msgstr "" +msgstr "您希望自己的包能够无缺陷运行,不给他人带来问题。为此,应在公开发布前对扩展进行充分测试。" #. type: Plain text #: ../src/guide/structure/package.md msgid "It's recommended that you create various test cases to cover your extension code rather than relying on manual tests. Each time before you release a new version of your package, you may run these test cases to make sure everything is in good shape. For more details, please refer to the [Testing](../testing/overview.md) section." -msgstr "" +msgstr "建议编写各种测试用例来覆盖扩展代码,而不是依赖手动测试。每次发布新版本前,运行这些测试用例以确保一切正常。更多详情请参阅[测试](../testing/overview.md)章节。" #. type: Title #### #: ../src/guide/structure/package.md #, no-wrap msgid "Versioning " -msgstr "" +msgstr "版本管理 " #. type: Plain text #: ../src/guide/structure/package.md msgid "You should give each release of your extension a version number (e.g. `1.0.1`). We recommend you follow the [semantic versioning](https://semver.org) practice when determining what version numbers should be used." -msgstr "" +msgstr "应为扩展的每个发布版本指定版本号(例如 `1.0.1`)。在确定版本号时,我们建议遵循[语义化版本](https://semver.org)规范。" #. type: Title #### #: ../src/guide/structure/package.md #, no-wrap msgid "Releasing " -msgstr "" +msgstr "发布 " #. type: Plain text #: ../src/guide/structure/package.md msgid "To let other people know about your package, you need to release it to the public." -msgstr "" +msgstr "要让他人了解您的包,需要将其公开发布。" #. type: Plain text #: ../src/guide/structure/package.md msgid "If it's the first time you're releasing a package, you should register it in a Composer repository, such as [Packagist](https://packagist.org/). After that, all you need to do is create a release tag (for example, `v1.0.1`) on the VCS repository of your extension and notify the Composer repository about the new release. People will then be able to find the new release and install or update the package through the Composer repository." -msgstr "" +msgstr "如果是首次发布包,应将其注册到 Composer 仓库(例如 [Packagist](https://packagist.org/))。之后,只需在扩展的 VCS 仓库上创建发布标签(例如 `v1.0.1`)并通知 Composer 仓库有新版本即可。其他人就能通过 Composer 仓库找到新版本并安装或更新该包。" #. type: Plain text #: ../src/guide/structure/package.md msgid "In the release of your package, in addition to code files, you should also consider including the following to help other people learn about and use your extension:" -msgstr "" +msgstr "在发布包时,除代码文件外,还应考虑包含以下内容,以帮助他人了解和使用您的扩展:" #. type: Bullet: '* ' #: ../src/guide/structure/package.md msgid "A readme file in the package root directory: it describes what your extension does and how to install and use it. We recommend you write it in [Markdown](https://daringfireball.net/projects/markdown/) format and name the file as `README.md`." -msgstr "" +msgstr "包根目录下的 readme 文件:描述扩展的功能及安装和使用方法。建议使用 [Markdown](https://daringfireball.net/projects/markdown/) 格式编写,并命名为 `README.md`。" #. type: Bullet: '* ' #: ../src/guide/structure/package.md msgid "A changelog file in the package root directory: it lists what changes are made in each release. The file may be written in Markdown format and named as `CHANGELOG.md`." -msgstr "" +msgstr "包根目录下的 changelog 文件:列出每个版本的变更内容。文件可使用 Markdown 格式编写,命名为 `CHANGELOG.md`。" #. type: Bullet: '* ' #: ../src/guide/structure/package.md msgid "An upgrade file in the package root directory: it gives the instructions on how to upgrade from older releases of the extension. The file may be written in Markdown format and named as `UPGRADE.md`." -msgstr "" +msgstr "包根目录下的 upgrade 文件:提供从旧版本升级的说明。文件可使用 Markdown 格式编写,命名为 `UPGRADE.md`。" #. type: Bullet: '* ' #: ../src/guide/structure/package.md msgid "Tutorials, demos, screenshots, etc.: these are needed if your extension provides many features that can't be fully covered in the readme file." -msgstr "" +msgstr "教程、演示、截图等:如果扩展提供的功能较多,无法在 readme 文件中完整说明,则需要这些补充材料。" #. type: Bullet: '* ' #: ../src/guide/structure/package.md msgid "API documentation: your code should be well-documented to allow other people to more easily read and understand it." -msgstr "" +msgstr "API 文档:代码应有完善的文档注释,以便他人更容易阅读和理解。" diff --git a/_translations/po/zh-CN/guide_structure_service.md.po b/_translations/po/zh-CN/guide_structure_service.md.po index 81377ac9..24fbe9e4 100644 --- a/_translations/po/zh-CN/guide_structure_service.md.po +++ b/_translations/po/zh-CN/guide_structure_service.md.po @@ -20,24 +20,24 @@ msgstr "" #: ../../guide/en/structure/service.md #, no-wrap msgid "Repository" -msgstr "" +msgstr "仓库" #. type: Bullet: '- ' #: ../../guide/en/structure/domain.md ../../guide/en/structure/service.md #, no-wrap msgid "Entity" -msgstr "" +msgstr "实体" #. type: Title # #: ../../guide/en/structure/service.md #, no-wrap msgid "Service components" -msgstr "" +msgstr "服务组件" #. type: Plain text #: ../../guide/en/structure/service.md msgid "Application may get complicated, so it makes sense to extract focused parts of business logic or infrastructure into service components. They're typically injected into other components or action handlers. It's usually done via autowiring:" -msgstr "" +msgstr "应用程序可能会变得复杂,因此将业务逻辑或基础设施的专注部分提取到服务组件中是有意义的。它们通常被注入到其他组件或操作处理器中。这通常通过自动装配来完成:" #. type: Fenced code block (php) #: ../../guide/en/structure/service.md @@ -57,7 +57,7 @@ msgstr "" #. type: Plain text #: ../../guide/en/structure/service.md msgid "Yii3 doesn't technically imply any limitations on how you build services. In general, there's no need to extend from a base class or implement a certain interface:" -msgstr "" +msgstr "Yii3 在技术上对如何构建服务没有任何限制。通常,无需从基类继承或实现特定接口:" #. type: Fenced code block (php) #: ../../guide/en/structure/service.md @@ -81,38 +81,38 @@ msgstr "" #. type: Plain text #: ../../guide/en/structure/service.md msgid "Services either perform a task or return data. They're created once, put into a DI container and then could be used multiple times. Because of that, it's a good idea to keep your services stateless that's both service itself and any of its dependencies shouldn't hold state. You can ensure it by using `readonly` PHP keyword at class level." -msgstr "" +msgstr "服务要么执行任务,要么返回数据。它们被创建一次,放入 DI 容器,然后可以多次使用。因此,保持服务无状态是个好主意,即服务本身及其任何依赖都不应保持状态。您可以通过在类级别使用 PHP 的 `readonly` 关键字来确保这一点。" #. type: Title ## #: ../../guide/en/structure/service.md #, no-wrap msgid "Service dependencies and configuration" -msgstr "" +msgstr "服务依赖和配置" #. type: Plain text #: ../../guide/en/structure/service.md msgid "Services should always define all their dependencies on other services via `__construct()`. It both allows you to use a service right away after it's created and serves as an indicator of a service doing too much if there are too many dependencies." -msgstr "" +msgstr "服务应始终通过 `__construct()` 定义对其他服务的所有依赖。这既允许您在服务创建后立即使用它,也可以在依赖太多时作为服务承担过多职责的提示。" #. type: Bullet: '- ' #: ../../guide/en/structure/service.md msgid "After the service is created, it shouldn't be re-configured in runtime." -msgstr "" +msgstr "服务创建后,不应在运行时重新配置。" #. type: Bullet: '- ' #: ../../guide/en/structure/service.md msgid "DI container instance usually **shouldn't** be injected as a dependency. Prefer concrete interfaces." -msgstr "" +msgstr "DI 容器实例通常**不应该**作为依赖注入。优先使用具体接口。" #. type: Bullet: '- ' #: ../../guide/en/structure/service.md msgid "In case of complicated or \"heavy\" initialization, try to postpone it until the service method is called." -msgstr "" +msgstr "如果初始化复杂或“繁重”,请尝试推迟到服务方法被调用时再进行。" #. type: Plain text #: ../../guide/en/structure/service.md msgid "The same is valid for configuration values. They should be provided as a constructor argument. Related values could be grouped together into value objects. For example, database connection usually requires DSN string, username and password. These three could be combined into Dsn class:" -msgstr "" +msgstr "配置值也同样适用。它们应作为构造函数参数提供。相关值可以组合到值对象中。例如,数据库连接通常需要 DSN 字符串、用户名和密码。这三个可以合并到 Dsn 类中:" #. type: Fenced code block (php) #: ../../guide/en/structure/service.md @@ -142,12 +142,12 @@ msgstr "" #: ../../guide/en/structure/service.md #, no-wrap msgid "Service methods" -msgstr "" +msgstr "服务方法" #. type: Plain text #: ../../guide/en/structure/service.md msgid "Service method usually does something. It could be a simple thing repeated exactly, but usually it depends on the context. For example:" -msgstr "" +msgstr "服务方法通常执行某些操作。它可能是完全重复的简单事情,但通常取决于上下文。例如:" #. type: Fenced code block (php) #: ../../guide/en/structure/service.md @@ -171,25 +171,25 @@ msgstr "" #. type: Plain text #: ../../guide/en/structure/service.md msgid "There's a service that is saving posts into permanent storage such as a database. An object allowing communication with a concrete storage is always the same, so it's injected using constructor while the post saved could vary, so it's passed as a method argument." -msgstr "" +msgstr "有一个将帖子保存到数据库等永久存储的服务。允许与具体存储通信的对象始终相同,因此使用构造函数注入;而要保存的帖子可能不同,因此作为方法参数传递。" #. type: Title ## #: ../../guide/en/structure/service.md #, no-wrap msgid "Is everything a service?" -msgstr "" +msgstr "一切都是服务吗?" #. type: Plain text #: ../../guide/en/structure/service.md msgid "Often it makes sense to choose another class type to place your code into. Check:" -msgstr "" +msgstr "通常选择另一种类类型来放置您的代码更合适。请检查:" #. type: Bullet: '- ' #: ../../guide/en/structure/service.md msgid "Widget" -msgstr "" +msgstr "小部件" #. type: Bullet: '- ' #: ../../guide/en/structure/service.md msgid "[Middleware](middleware.md)" -msgstr "" +msgstr "[中间件](middleware.md)" diff --git a/_translations/po/zh-CN/guide_tutorial_console-applications.md.po b/_translations/po/zh-CN/guide_tutorial_console-applications.md.po index d33deb39..24c96d11 100644 --- a/_translations/po/zh-CN/guide_tutorial_console-applications.md.po +++ b/_translations/po/zh-CN/guide_tutorial_console-applications.md.po @@ -30,17 +30,17 @@ msgstr "参考资料" #: ../src/guide/tutorial/console-applications.md #, no-wrap msgid "Console applications" -msgstr "" +msgstr "控制台应用程序" #. type: Plain text #: ../src/guide/tutorial/console-applications.md msgid "Console applications are mainly used to create utility, background processing and maintenance tasks." -msgstr "" +msgstr "控制台应用程序主要用于创建实用工具、后台处理和维护任务。" #. type: Plain text #: ../src/guide/tutorial/console-applications.md msgid "To get support for console application in your project, get `yiisoft/yii-console` via composer:" -msgstr "" +msgstr "要在项目中获得控制台应用程序支持,请通过 composer 获取 `yiisoft/yii-console`:" #. type: Fenced code block #: ../src/guide/tutorial/console-applications.md @@ -51,7 +51,7 @@ msgstr "" #. type: Plain text #: ../src/guide/tutorial/console-applications.md msgid "After it's installed, you can access the entry point as" -msgstr "" +msgstr "安装后,您可以通过以下方式访问入口点:" #. type: Fenced code block #: ../src/guide/tutorial/console-applications.md @@ -62,12 +62,12 @@ msgstr "" #. type: Plain text #: ../src/guide/tutorial/console-applications.md msgid "Out of the box only `serve` command is available. It's starting PHP built-in web server to serve the application locally." -msgstr "" +msgstr "开箱即用只有 `serve` 命令可用。它启动 PHP 内置 Web 服务器在本地提供应用程序服务。" #. type: Plain text #: ../src/guide/tutorial/console-applications.md msgid "Commands are executed with `symfony/console`. To create your own console command, you need to define a command:" -msgstr "" +msgstr "命令使用 `symfony/console` 执行。要创建自己的控制台命令,您需要定义一个命令:" #. type: Fenced code block (php) #: ../src/guide/tutorial/console-applications.md @@ -112,7 +112,7 @@ msgstr "" #. type: Plain text #: ../src/guide/tutorial/console-applications.md msgid "Now register the command in `config/params.php`:" -msgstr "" +msgstr "现在在 `config/params.php` 中注册该命令:" #. type: Fenced code block (php) #: ../src/guide/tutorial/console-applications.md @@ -130,7 +130,7 @@ msgstr "" #. type: Plain text #: ../src/guide/tutorial/console-applications.md msgid "After it's done, the command could be executed as" -msgstr "" +msgstr "完成后,命令可以通过以下方式执行:" #. type: Fenced code block #: ../src/guide/tutorial/console-applications.md @@ -141,4 +141,4 @@ msgstr "" #. type: Bullet: '- ' #: ../src/guide/tutorial/console-applications.md msgid "[Symfony Console component guide](https://symfony.com/doc/current/components/console.html)" -msgstr "" +msgstr "[Symfony Console 组件指南](https://symfony.com/doc/current/components/console.html)" diff --git a/_translations/po/zh-CN/guide_tutorial_mailing.md.po b/_translations/po/zh-CN/guide_tutorial_mailing.md.po index 804abb55..101054be 100644 --- a/_translations/po/zh-CN/guide_tutorial_mailing.md.po +++ b/_translations/po/zh-CN/guide_tutorial_mailing.md.po @@ -19,33 +19,33 @@ msgstr "" #: en/tutorial/mailing.md #, no-wrap msgid "Mailing" -msgstr "" +msgstr "邮件发送" #. type: Plain text #: en/tutorial/mailing.md msgid "Yii simplifies the composition and sending of email messages using the [yiisoft/mailer](https://github.com/yiisoft/mailer) package. This package provides content composition functionality and a basic interface for sending emails. By default, the package includes a file mailer that writes email contents into a file instead of sending them. This is particularly useful during the initial stages of application development." -msgstr "" +msgstr "Yii 通过 [yiisoft/mailer](https://github.com/yiisoft/mailer) 包简化了电子邮件的编写与发送。该包提供了内容组织功能和基本的邮件发送接口。默认情况下,包内置了一个文件邮件发送器,它将邮件内容写入文件而非实际发送,在应用程序开发初期非常实用。" #. type: Plain text #: en/tutorial/mailing.md msgid "To send actual emails, you can use the [Symfony Mailer](https://github.com/yiisoft/mailer-symfony) implementation, which is used in the examples below." -msgstr "" +msgstr "要发送真实的电子邮件,可以使用 [Symfony Mailer](https://github.com/yiisoft/mailer-symfony) 实现,以下示例均基于此实现。" #. type: Title ## #: en/tutorial/mailing.md #, no-wrap msgid "Configuring the Mailer" -msgstr "" +msgstr "配置邮件发送器" #. type: Plain text #: en/tutorial/mailing.md msgid "The mailer service allows you to create a message instance, populate it with data, and send it. Typically, you get an instance from the DI container as `Yiisoft\\Mailer\\MailerInterface`." -msgstr "" +msgstr "邮件发送器服务允许您创建消息实例、填充数据并发送。通常通过 DI 容器以 `Yiisoft\\Mailer\\MailerInterface` 的形式获取实例。" #. type: Plain text #: en/tutorial/mailing.md msgid "You can also create an instance manually as follows:" -msgstr "" +msgstr "您也可以按如下方式手动创建实例:" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -66,34 +66,34 @@ msgstr "" #. type: Plain text #: en/tutorial/mailing.md msgid "The `Yiisoft\\Mailer\\MailerInterface` provides two main methods:" -msgstr "" +msgstr "`Yiisoft\\Mailer\\MailerInterface` 提供了两个主要方法:" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`send()` - Sends the given email message." -msgstr "" +msgstr "`send()` - 发送指定的电子邮件消息。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`sendMultiple()` - Sends many messages at once." -msgstr "" +msgstr "`sendMultiple()` - 一次性发送多条消息。" #. type: Title ## #: en/tutorial/mailing.md #, no-wrap msgid "Creating a Message" -msgstr "" +msgstr "创建消息" #. type: Title ### #: en/tutorial/mailing.md #, no-wrap msgid "Simple Text Message" -msgstr "" +msgstr "简单文本消息" #. type: Plain text #: en/tutorial/mailing.md msgid "To create a simple message with a text body, use `Yiisoft\\Mailer\\Message`:" -msgstr "" +msgstr "要创建带有纯文本正文的简单消息,请使用 `Yiisoft\\Mailer\\Message`:" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -111,7 +111,7 @@ msgstr "" #: en/tutorial/mailing.md #, no-wrap msgid "Simple HTML Message" -msgstr "" +msgstr "简单 HTML 消息" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -129,12 +129,12 @@ msgstr "" #: en/tutorial/mailing.md #, no-wrap msgid "HTML Message from template" -msgstr "" +msgstr "从模板创建 HTML 消息" #. type: Plain text #: en/tutorial/mailing.md msgid "For this example, we will use package rendering package [view](https://github.com/yiisoft/view)." -msgstr "" +msgstr "本示例将使用渲染包 [view](https://github.com/yiisoft/view)。" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -161,12 +161,12 @@ msgstr "" #: en/tutorial/mailing.md #, no-wrap msgid "Using Layouts" -msgstr "" +msgstr "使用布局" #. type: Plain text #: en/tutorial/mailing.md msgid "You can also pass parameters to layouts from your template message:" -msgstr "" +msgstr "您也可以从模板消息向布局传递参数:" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -198,12 +198,12 @@ msgstr "" #: en/tutorial/mailing.md #, no-wrap msgid "Layout Example" -msgstr "" +msgstr "布局示例" #. type: Plain text #: en/tutorial/mailing.md msgid "You can wrap the view rendering result in a layout, similar to how layouts work in web applications. This is useful for setting up shared content like CSS styles:" -msgstr "" +msgstr "您可以将视图渲染结果包裹在布局中,与 Web 应用程序中布局的工作方式类似,这对于设置 CSS 样式等共享内容非常有用:" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -234,199 +234,199 @@ msgstr "" #: en/tutorial/mailing.md #, no-wrap msgid "Adding More Data" -msgstr "" +msgstr "添加更多数据" #. type: Plain text #: en/tutorial/mailing.md msgid "The `Yiisoft\\Mailer\\MessageInterface` provides several methods to customize your message:" -msgstr "" +msgstr "`Yiisoft\\Mailer\\MessageInterface` 提供了多个方法来自定义消息:" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withCharset()` - Returns a new instance with the specified charset." -msgstr "" +msgstr "`withCharset()` - 返回指定字符集的新实例。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withFrom()` - Returns a new instance with the specified sender email address." -msgstr "" +msgstr "`withFrom()` - 返回指定发件人邮箱地址的新实例。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withTo()` - Returns a new instance with the specified recipient(s) email address." -msgstr "" +msgstr "`withTo()` - 返回指定收件人邮箱地址的新实例。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withReplyTo()` - Returns a new instance with the specified reply-to address." -msgstr "" +msgstr "`withReplyTo()` - 返回指定回复地址的新实例。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withCc()` - Returns a new instance with the specified Cc (extra copy receiver) addresses." -msgstr "" +msgstr "`withCc()` - 返回指定抄送地址的新实例。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withBcc()` - Returns a new instance with the specified Bcc (hidden copy receiver) addresses." -msgstr "" +msgstr "`withBcc()` - 返回指定密送地址的新实例。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withSubject()` - Returns a new instance with the specified message subject." -msgstr "" +msgstr "`withSubject()` - 返回指定邮件主题的新实例。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withDate()` - Returns a new instance with the specified date when the message was sent." -msgstr "" +msgstr "`withDate()` - 返回指定发送日期的新实例。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withPriority()` - Returns a new instance with the specified priority of this message." -msgstr "" +msgstr "`withPriority()` - 返回指定优先级的新实例。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withReturnPath()` - Returns a new instance with the specified return-path (the bounce address) of this message." -msgstr "" +msgstr "`withReturnPath()` - 返回指定退信地址的新实例。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withSender()` - Returns a new instance with the specified actual sender email address." -msgstr "" +msgstr "`withSender()` - 返回指定实际发件人邮箱地址的新实例。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withHtmlBody()` - Returns a new instance with the specified message HTML content." -msgstr "" +msgstr "`withHtmlBody()` - 返回指定 HTML 正文内容的新实例。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withTextBody()` - Returns a new instance with the specified message plain text content." -msgstr "" +msgstr "`withTextBody()` - 返回指定纯文本正文内容的新实例。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withAddedHeader()` - Returns a new instance with the specified added custom header value." -msgstr "" +msgstr "`withAddedHeader()` - 返回添加了指定自定义请求头值的新实例。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withHeader()` - Returns a new instance with the specified custom header value." -msgstr "" +msgstr "`withHeader()` - 返回指定自定义请求头值的新实例。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`withHeaders()` - Returns a new instance with the specified custom header values." -msgstr "" +msgstr "`withHeaders()` - 返回指定多个自定义请求头值的新实例。" #. type: Plain text #: en/tutorial/mailing.md msgid "These methods are immutable, meaning they return a new instance of the message with the updated data." -msgstr "" +msgstr "这些方法均为不可变方法,即返回包含更新数据的新消息实例。" #. type: Plain text #: en/tutorial/mailing.md msgid "Note `with` prefix. It indicates that the method is immutable and returns a new instance of the class with the changed data." -msgstr "" +msgstr "注意 `with` 前缀,它表示该方法是不可变的,会返回包含变更数据的新类实例。" #. type: Title ### #: en/tutorial/mailing.md #, no-wrap msgid "Getters" -msgstr "" +msgstr "获取器" #. type: Plain text #: en/tutorial/mailing.md msgid "The following getters are available to retrieve message data:" -msgstr "" +msgstr "以下获取器可用于读取消息数据:" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getCharset()` - Returns the charset of this message." -msgstr "" +msgstr "`getCharset()` - 返回消息的字符集。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getFrom()` - Returns the message sender email address." -msgstr "" +msgstr "`getFrom()` - 返回发件人邮箱地址。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getTo()` - Returns the message recipient(s) email address." -msgstr "" +msgstr "`getTo()` - 返回收件人邮箱地址。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getReplyTo()` - Returns the reply-to address of this message." -msgstr "" +msgstr "`getReplyTo()` - 返回回复地址。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getCc()` - Returns the Cc (extra copy receiver) addresses of this message." -msgstr "" +msgstr "`getCc()` - 返回抄送地址。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getBcc()` - Returns the Bcc (hidden copy receiver) addresses of this message." -msgstr "" +msgstr "`getBcc()` - 返回密送地址。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getSubject()` - Returns the message subject." -msgstr "" +msgstr "`getSubject()` - 返回邮件主题。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getDate()` - Returns the date when the message was sent, or null if it wasn't set." -msgstr "" +msgstr "`getDate()` - 返回消息发送日期,若未设置则返回 null。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getPriority()` - Returns the priority of this message." -msgstr "" +msgstr "`getPriority()` - 返回消息优先级。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getReturnPath()` - Returns the return-path (the bounce address) of this message." -msgstr "" +msgstr "`getReturnPath()` - 返回退信地址。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getSender()` - Returns the message actual sender email address." -msgstr "" +msgstr "`getSender()` - 返回实际发件人邮箱地址。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getHtmlBody()` - Returns the message HTML body." -msgstr "" +msgstr "`getHtmlBody()` - 返回消息的 HTML 正文。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getTextBody()` - Returns the message text body." -msgstr "" +msgstr "`getTextBody()` - 返回消息的纯文本正文。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`getHeader()` - Returns all values for the specified header." -msgstr "" +msgstr "`getHeader()` - 返回指定请求头的所有值。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`__toString()` - Returns string representation of this message." -msgstr "" +msgstr "`__toString()` - 返回消息的字符串表示。" #. type: Title ## #: en/tutorial/mailing.md #, no-wrap msgid "Attaching Files" -msgstr "" +msgstr "附加文件" #. type: Plain text #: en/tutorial/mailing.md msgid "You can attach files to your message using the `withAttached()` method:" -msgstr "" +msgstr "可以使用 `withAttached()` 方法向消息附加文件:" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -449,12 +449,12 @@ msgstr "" #: en/tutorial/mailing.md #, no-wrap msgid "Embedding Images" -msgstr "" +msgstr "嵌入图片" #. type: Plain text #: en/tutorial/mailing.md msgid "You can embed images into the message content using the `withEmbedded()` method. This is particularly useful when composing messages with views:" -msgstr "" +msgstr "可以使用 `withEmbedded()` 方法将图片嵌入消息内容,在使用视图编写消息时尤为有用:" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -480,7 +480,7 @@ msgstr "" #. type: Plain text #: en/tutorial/mailing.md msgid "In your view or layout template, you can reference the embedded image using its CID:" -msgstr "" +msgstr "在视图或布局模板中,可以通过 CID 引用嵌入的图片:" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -492,12 +492,12 @@ msgstr "" #: en/tutorial/mailing.md #, no-wrap msgid "Sending a Message" -msgstr "" +msgstr "发送消息" #. type: Plain text #: en/tutorial/mailing.md msgid "To send an email message:" -msgstr "" +msgstr "发送电子邮件消息的方法:" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -526,12 +526,12 @@ msgstr "" #: en/tutorial/mailing.md #, no-wrap msgid "Sending Multiple Messages" -msgstr "" +msgstr "批量发送消息" #. type: Plain text #: en/tutorial/mailing.md msgid "You can send multiple messages at once:" -msgstr "" +msgstr "可以一次性发送多条消息:" #. type: Fenced code block (php) #: en/tutorial/mailing.md @@ -551,49 +551,49 @@ msgstr "" #. type: Plain text #: en/tutorial/mailing.md msgid "The `sendMultiple()` method returns a `Yiisoft\\Mailer\\SendResults` object containing arrays of successfully sent and failed messages." -msgstr "" +msgstr "`sendMultiple()` 方法返回一个 `Yiisoft\\Mailer\\SendResults` 对象,其中包含发送成功和发送失败的消息数组。" #. type: Title ## #: en/tutorial/mailing.md #, no-wrap msgid "Implementing your own mail driver" -msgstr "" +msgstr "实现自定义邮件驱动" #. type: Plain text #: en/tutorial/mailing.md msgid "To create a custom mail solution, implement the `Yiisoft\\Mailer\\MailerInterface` and `Yiisoft\\Mailer\\MessageInterface` interfaces." -msgstr "" +msgstr "要创建自定义邮件解决方案,请实现 `Yiisoft\\Mailer\\MailerInterface` 和 `Yiisoft\\Mailer\\MessageInterface` 接口。" #. type: Title ## #: en/tutorial/mailing.md #, no-wrap msgid "For Development" -msgstr "" +msgstr "开发环境" #. type: Plain text #: en/tutorial/mailing.md msgid "For local or test development, you can use simplified implementations of the mailer that does not send emails. The package provides these implementations:" -msgstr "" +msgstr "在本地或测试开发环境中,可以使用不实际发送邮件的简化邮件发送器实现。该包提供了以下实现:" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`Yiisoft\\Mailer\\StubMailer` - A simple mailer that stores messages in a local array." -msgstr "" +msgstr "`Yiisoft\\Mailer\\StubMailer` - 将消息存储在本地数组中的简单邮件发送器。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`Yiisoft\\Mailer\\FileMailer` - A mock mailer that saves email messages as files instead of sending them." -msgstr "" +msgstr "`Yiisoft\\Mailer\\FileMailer` - 将邮件消息保存为文件而非实际发送的模拟邮件发送器。" #. type: Bullet: '- ' #: en/tutorial/mailing.md msgid "`Yiisoft\\Mailer\\NullMailer` - A mailer that discards messages without sending or storing them." -msgstr "" +msgstr "`Yiisoft\\Mailer\\NullMailer` - 直接丢弃消息、不发送也不存储的空邮件发送器。" #. type: Plain text #: en/tutorial/mailing.md msgid "To use one of these mailers, configure it in your development environment file Example: `environments/local/di.php`" -msgstr "" +msgstr "要使用其中一种发送器,请在开发环境配置文件中进行配置,例如 `environments/local/di.php`:" #. type: Fenced code block (php) #: en/tutorial/mailing.md diff --git a/_translations/po/zh-CN/guide_tutorial_performance-tuning.md.po b/_translations/po/zh-CN/guide_tutorial_performance-tuning.md.po index 17402543..1fab3c5d 100644 --- a/_translations/po/zh-CN/guide_tutorial_performance-tuning.md.po +++ b/_translations/po/zh-CN/guide_tutorial_performance-tuning.md.po @@ -19,106 +19,106 @@ msgstr "" #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Performance tuning" -msgstr "" +msgstr "性能调优" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "There are many factors affecting the performance of your application. Some are environmental, some are related to your code, while some others are related to Yii itself. In this section, we will count most of these factors and explain how you can improve your application performance by adjusting these factors." -msgstr "" +msgstr "影响应用程序性能的因素有很多,有些与运行环境有关,有些与您的代码有关,还有一些与 Yii 框架本身有关。本节将列举这些主要因素,并说明如何通过调整它们来提升应用程序性能。" #. type: Title ## #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Optimizing your PHP Environment " -msgstr "" +msgstr "优化 PHP 环境 " #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "A well-configured PHP environment is important. To get maximum performance:" -msgstr "" +msgstr "合理配置 PHP 环境至关重要。为获得最佳性能,建议:" #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "Use the latest stable PHP version. Major releases of PHP may bring significant performance improvements." -msgstr "" +msgstr "使用最新稳定版 PHP。PHP 的主要版本通常会带来显著的性能提升。" #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "Enable bytecode caching with [Opcache](https://secure.php.net/opcache). Bytecode caching avoids the time spent on parsing and including PHP scripts for every incoming request." -msgstr "" +msgstr "通过 [Opcache](https://secure.php.net/opcache) 启用字节码缓存。字节码缓存可避免在每次请求时重复解析和加载 PHP 脚本的开销。" #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "[Tune `realpath()` cache](https://github.com/samdark/realpath_cache_tuner)." -msgstr "" +msgstr "[调优 `realpath()` 缓存](https://github.com/samdark/realpath_cache_tuner)。" #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "Make sure [XDebug](https://xdebug.org/) isn't installed in the production environment." -msgstr "" +msgstr "确保生产环境中未安装 [XDebug](https://xdebug.org/)。" #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "Try [PHP 7 preloading](https://wiki.php.net/rfc/preload)." -msgstr "" +msgstr "尝试 [PHP 7 预加载](https://wiki.php.net/rfc/preload)。" #. type: Title ## #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Optimizing your code " -msgstr "" +msgstr "优化代码 " #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "Beyond environment configuration, there are code-level optimizations that can improve your application's performance:" -msgstr "" +msgstr "除环境配置外,代码层面的优化同样能提升应用程序性能:" #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "Look out for [algorithm complexity](https://en.wikipedia.org/wiki/Time_complexity). Especially give attention to `foreach` within `foreach` loops but look out for using [heavy PHP functions](https://stackoverflow.com/questions/2473989/list-of-big-o-for-php-functions) in loops as well." -msgstr "" +msgstr "注意 [算法复杂度](https://en.wikipedia.org/wiki/Time_complexity)。尤其要留意 `foreach` 嵌套循环,同时也要避免在循环中使用[高开销的 PHP 函数](https://stackoverflow.com/questions/2473989/list-of-big-o-for-php-functions)。" #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "[Speeding up array_merge()](https://www.exakat.io/speeding-up-array_merge/)" -msgstr "" +msgstr "[加速 array_merge()](https://www.exakat.io/speeding-up-array_merge/)" #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "[Move that foreach() inside the method](https://www.exakat.io/move-that-foreach-inside-the-method/)" -msgstr "" +msgstr "[将 foreach() 移入方法内部](https://www.exakat.io/move-that-foreach-inside-the-method/)" #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "[Array, classes and anonymous classes memory usage](https://www.exakat.io/array-classes-and-anonymous-memory-usage/)" -msgstr "" +msgstr "[数组、类与匿名类的内存占用](https://www.exakat.io/array-classes-and-anonymous-memory-usage/)" #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "Use fully qualified function names with leading backslashes to optimize opcache performance. When calling [certain global functions](https://github.com/php/php-src/blob/944b6b6bbd6f05ad905f5f4ad07445792bee4027/Zend/zend_compile.c#L4291-L4353) from within a namespace, PHP first searches in the current namespace before falling back to the global namespace. Adding a leading backslash (e.g., `\\count()` instead of `count()`) tells PHP to directly use the global function, avoiding the namespace lookup and improving opcache efficiency. This optimization is best implemented automatically using tools like [PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) with the `native_function_invocation` rule." -msgstr "" +msgstr "使用带前导反斜杠的完全限定函数名以优化 opcache 性能。在命名空间内调用 [某些全局函数](https://github.com/php/php-src/blob/944b6b6bbd6f05ad905f5f4ad07445792bee4027/Zend/zend_compile.c#L4291-L4353) 时,PHP 会先在当前命名空间中查找,再回退到全局命名空间。添加前导反斜杠(例如用 `\\count()` 代替 `count()`)可告知 PHP 直接使用全局函数,避免命名空间查找,提升 opcache 效率。建议通过 [PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) 的 `native_function_invocation` 规则自动完成此优化。" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "The above optimizations would give you a significant performance boost only if the code in question is executed frequently. That is usually the case for big loops or batch processing." -msgstr "" +msgstr "上述代码层面的优化只有在相关代码被频繁执行时才能带来显著提升,通常适用于大型循环或批量处理场景。" #. type: Title ## #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Using caching techniques " -msgstr "" +msgstr "使用缓存技术 " #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "You can use various caching techniques to significantly improve the performance of your application. For example, if your application allows users to enter text in Markdown format, you may consider caching the parsed Markdown content to avoid parsing the same Markdown text repeatedly in every request. Please refer to the [Caching](../caching/overview.md) section to learn about the caching support provided by Yii." -msgstr "" +msgstr "您可以使用多种缓存技术来显著提升应用程序性能。例如,如果应用程序允许用户输入 Markdown 格式文本,可以考虑缓存解析后的 Markdown 内容,避免每次请求都重复解析相同的 Markdown 文本。请参阅[缓存](../caching/overview.md)章节了解 Yii 提供的缓存支持。" #. type: Title ## #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Optimizing session storage " -msgstr "" +msgstr "优化会话存储 " #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md @@ -130,11 +130,16 @@ msgid "" "initial request to release a session file. This is fine for development and probably small projects. But when it comes \n" "to handling massive concurrent requests, it's better to use more sophisticated storage, such as Redis.\n" msgstr "" +"默认情况下,会话数据存储在文件中。该实现会在会话打开时锁定文件,直到\n" +"通过 `$session->close()` 或请求结束时关闭会话为止。\n" +"在会话文件被锁定期间,所有尝试使用同一会话的其他请求都将被阻塞,等待\n" +"初始请求释放会话文件。这对于开发环境和小型项目来说没有问题,但当需要 \n" +"处理大量并发请求时,最好使用更完善的存储方案,例如 Redis。\n" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "It could be done either by [configuring PHP via php.ini](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-redis-server-as-a-session-handler-for-php-on-ubuntu-14-04) or [implementing SessionHandlerInterface](https://www.sitepoint.com/saving-php-sessions-in-redis/) and configuring session service as follows:" -msgstr "" +msgstr "可以通过 [在 php.ini 中配置 PHP](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-redis-server-as-a-session-handler-for-php-on-ubuntu-14-04),或 [实现 SessionHandlerInterface](https://www.sitepoint.com/saving-php-sessions-in-redis/) 并按如下方式配置会话服务来实现:" #. type: Fenced code block (php) #: ../src/guide/tutorial/performance-tuning.md @@ -150,38 +155,38 @@ msgstr "" #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Optimizing databases " -msgstr "" +msgstr "优化数据库 " #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "Executing DB queries and fetching data from databases are often the main performance bottleneck in a Web application. Although using [data caching](../caching/data.md) techniques may ease the performance hit, it doesn't fully solve the problem. When the database has enormous amounts of data and the cached data are invalid, fetching the latest data could be prohibitively expensive without a proper database and query design." -msgstr "" +msgstr "执行数据库查询和从数据库获取数据通常是 Web 应用程序的主要性能瓶颈。尽管使用[数据缓存](../caching/data.md)技术可以缓解性能压力,但并不能彻底解决问题。当数据库中的数据量极大且缓存数据失效时,如果没有合理的数据库和查询设计,获取最新数据的代价可能会非常高昂。" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "A general technique to improve the performance of DB queries is to create indices for table columns that need to be filtered by. For example, if you need to look for a user record by `username`, you should create an index on `username`. Note that while indexing can make SELECT queries much faster, it will slow down INSERT, UPDATE and DELETE queries." -msgstr "" +msgstr "提升数据库查询性能的通用方法是为需要过滤的表列创建索引。例如,如果需要通过 `username` 查找用户记录,应在 `username` 列上创建索引。请注意,索引虽然能大幅提升 SELECT 查询速度,但会降低 INSERT、UPDATE 和 DELETE 操作的速度。" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "For complex DB queries, it's recommended that you create database views to save the query parsing and preparation time." -msgstr "" +msgstr "对于复杂的数据库查询,建议创建数据库视图以节省查询解析和准备的时间。" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "Last but not least, use `LIMIT` in your `SELECT` queries. This avoids fetching an overwhelming amount of data from the database and exhausting the memory allocated to PHP." -msgstr "" +msgstr "最后同样重要的一点是,在 `SELECT` 查询中使用 `LIMIT`,以避免从数据库获取过量数据而耗尽 PHP 分配的内存。" #. type: Title ## #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Optimizing composer autoloader " -msgstr "" +msgstr "优化 Composer 自动加载器 " #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "Because Composer autoloader is used to include most third-party class files, you should consider optimizing it by executing the following command:" -msgstr "" +msgstr "由于 Composer 自动加载器用于加载大多数第三方类文件,建议通过执行以下命令对其进行优化:" #. type: Fenced code block #: ../src/guide/tutorial/performance-tuning.md @@ -192,70 +197,70 @@ msgstr "" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "Additionally, you may consider using [authoritative class maps](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-a-authoritative-class-maps) and [APCu cache](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-b-apcu-cache). Note that both optimizations may or may not be suitable for your particular case." -msgstr "" +msgstr "此外,您还可以考虑使用 [权威类映射](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-a-authoritative-class-maps) 和 [APCu 缓存](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-b-apcu-cache)。请注意,这两种优化不一定适用于所有情况。" #. type: Title ## #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Processing data offline " -msgstr "" +msgstr "离线处理数据 " #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "When a request involves some resource-intensive operations, you should think of ways to perform those operations in offline mode without having users wait for them to finish." -msgstr "" +msgstr "当某个请求涉及资源密集型操作时,应考虑以离线方式执行这些操作,避免让用户等待其完成。" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "There are two methods to process data offline: pull and push." -msgstr "" +msgstr "离线处理数据有两种方式:拉取(pull)和推送(push)。" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "In the pull method, whenever a request involves some complex operation, you create a task and save it in a persistent storage, such as a database. You then use a separate process (such as a cron job) to pull the tasks and process them. This method is straightforward to implement, but it has some drawbacks. For example, the task process needs to periodically pull from the task storage. If the pull frequency is too low, the tasks may be processed with great delay, but if the frequency is too high, it will introduce high overhead." -msgstr "" +msgstr "在拉取模式中,每当请求涉及复杂操作时,您创建一个任务并将其保存到持久化存储(如数据库)中,然后使用独立进程(如定时任务)来拉取并处理这些任务。这种方式实现简单,但有一些缺点:例如,任务进程需要周期性地从任务存储中拉取数据,拉取频率过低会导致任务处理延迟较大,而频率过高则会引入较大开销。" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "In the push method, you would use a message queue (e.g., RabbitMQ, ActiveMQ, Amazon SQS, etc.) to manage the tasks. Whenever a new task is put in the queue, it will initiate or notify the task handling process to trigger the task processing." -msgstr "" +msgstr "在推送模式中,您使用消息队列(例如 RabbitMQ、ActiveMQ、Amazon SQS 等)来管理任务。每当有新任务加入队列时,它会启动或通知任务处理进程以触发任务执行。" #. type: Title ## #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Using preloading" -msgstr "" +msgstr "使用预加载" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "As of PHP 7.4.0, PHP can be configured to preload scripts into the opcache when the engine starts. You can read more in the [documentation](https://www.php.net/manual/en/opcache.preloading.php) and the corresponding [RFC](https://wiki.php.net/rfc/preload)." -msgstr "" +msgstr "自 PHP 7.4.0 起,可以配置 PHP 在引擎启动时将脚本预加载到 opcache 中。详情请参阅 [官方文档](https://www.php.net/manual/en/opcache.preloading.php) 和对应的 [RFC](https://wiki.php.net/rfc/preload)。" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "Note that the optimal tradeoff between performance and memory may vary with the application. \"Preload everything\" may be the easiest strategy, but not necessarily the best strategy." -msgstr "" +msgstr "请注意,性能与内存之间的最优权衡因应用程序而异。“预加载所有内容”可能是最简单的策略,但未必是最佳策略。" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "For example, we conducted a simple [yiisoft/app](https://github.com/yiisoft/app) application template benchmark. Without preloading and with preloading of the entire composer class map." -msgstr "" +msgstr "例如,我们对 [yiisoft/app](https://github.com/yiisoft/app) 应用程序模板进行了简单基准测试,分别测试了未启用预加载和预加载整个 Composer 类映射两种情况。" #. type: Title ### #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Preloading benchmarks" -msgstr "" +msgstr "预加载基准测试" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "The application template benchmark includes configuring classes to injected dependencies in the bootstrap script." -msgstr "" +msgstr "该应用程序模板基准测试包含在引导脚本中配置依赖注入的相关类。" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "For both variants, [ApacheBench](https://httpd.apache.org/docs/2.4/programs/ab.html) was used with the following run parameters:" -msgstr "" +msgstr "两种情况均使用 [ApacheBench](https://httpd.apache.org/docs/2.4/programs/ab.html) 进行测试,运行参数如下:" #. type: Fenced code block (shell) #: ../src/guide/tutorial/performance-tuning.md @@ -266,7 +271,7 @@ msgstr "" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "Also, the debug mode was disabled. And an optimized autoloader of the [Composer](https://getcomposer.org) was used, and development dependencies weren't used:" -msgstr "" +msgstr "同时,调试模式已禁用,使用了 [Composer](https://getcomposer.org) 的优化自动加载器,且未安装开发依赖:" #. type: Fenced code block (shell) #: ../src/guide/tutorial/performance-tuning.md @@ -277,7 +282,7 @@ msgstr "" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "With preloading enabled, the entire composer class map (825 files) was used:" -msgstr "" +msgstr "启用预加载时,使用了完整的 Composer 类映射(825 个文件):" #. type: Fenced code block (php) #: ../src/guide/tutorial/performance-tuning.md @@ -294,7 +299,7 @@ msgstr "" #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Test results" -msgstr "" +msgstr "测试结果" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md @@ -305,22 +310,26 @@ msgid "" "| Without preloading | 0 | 12.32 mb | 1.71 mb | 27.63 ms | 36.55 rq/s |\n" "| With preloading | 825 | 17.86 mb | 1.82 mb | 26.21 ms | 38.42 rq/s |\n" msgstr "" +"| 基准测试 | 预加载文件数 | Opcache 内存用量 | 每请求内存用量 | 每请求耗时 | 每秒请求数 |\n" +"|--------------------|-----------------|---------------------|-------------------------|------------------|---------------------|\n" +"| 未预加载 | 0 | 12.32 mb | 1.71 mb | 27.63 ms | 36.55 rq/s |\n" +"| 已预加载 | 825 | 17.86 mb | 1.82 mb | 26.21 ms | 38.42 rq/s |\n" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "As you can see, the test results aren't much different, since this is just a clean application template that contains a few classes. More discussion of preloading, including benchmarks, can be found in the [composer's issue](https://github.com/composer/composer/issues/7777)." -msgstr "" +msgstr "如您所见,测试结果差异不大,因为这只是一个仅包含少量类的干净应用程序模板。关于预加载的更多讨论(包括基准测试)可参阅 [Composer 的相关 issue](https://github.com/composer/composer/issues/7777)。" #. type: Title ## #: ../src/guide/tutorial/performance-tuning.md #, no-wrap msgid "Performance profiling " -msgstr "" +msgstr "性能分析 " #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md msgid "You should profile your code to find out the performance bottlenecks and take appropriate measures accordingly. The following profiling tools may be useful:" -msgstr "" +msgstr "应对代码进行性能分析以找出瓶颈,并采取相应措施。以下分析工具可能对您有所帮助:" #. type: Plain text #: ../src/guide/tutorial/performance-tuning.md @@ -341,4 +350,4 @@ msgstr "" #. type: Bullet: '- ' #: ../src/guide/tutorial/performance-tuning.md msgid "[XDebug profiler](https://xdebug.org/docs/profiler)" -msgstr "" +msgstr "[XDebug 分析器](https://xdebug.org/docs/profiler)" diff --git a/_translations/po/zh-CN/guide_tutorial_using-with-event-loop.md.po b/_translations/po/zh-CN/guide_tutorial_using-with-event-loop.md.po index 415d70ac..22356599 100644 --- a/_translations/po/zh-CN/guide_tutorial_using-with-event-loop.md.po +++ b/_translations/po/zh-CN/guide_tutorial_using-with-event-loop.md.po @@ -19,7 +19,7 @@ msgstr "" #: ../../guide/en/tutorial/using-with-event-loop.md #, no-wrap msgid "Using Yii with event loop" -msgstr "" +msgstr "在事件循环中使用 Yii" #. type: Plain text #: ../../guide/en/tutorial/using-with-event-loop.md @@ -31,27 +31,32 @@ msgid "" "have to take much care about memory leaks or properly clean up context. On the other side, initializing everything for\n" "every request takes time and overall consumes up to 50% of processing resources.\n" msgstr "" +"普通 PHP Web 请求的执行周期包括设置环境、获取请求、处理请求以生成响应\n" +"以及发送结果。响应发送后,执行终止,其上下文也随之丢失。因此,对于后续\n" +"请求,整个流程会重复执行。这种方式的一大优点是开发简便,开发者无需\n" +"过多关注内存泄漏或上下文清理问题。但另一方面,为每个请求初始化所有内容\n" +"需要消耗时间,整体上会占用多达 50% 的处理资源。\n" #. type: Plain text #: ../../guide/en/tutorial/using-with-event-loop.md msgid "There is an alternative way of running an application. Event loop. The idea is to initialize everything possible at once and then process a number of requests using it. Such an approach is usually called event loop." -msgstr "" +msgstr "还有一种运行应用程序的方式——事件循环。其思路是一次性初始化所有可初始化的内容,然后利用它来处理多个请求。这种方式通常被称为事件循环。" #. type: Plain text #: ../../guide/en/tutorial/using-with-event-loop.md msgid "There are multiple tools that could be used to achieve it. Notably, [FrankenPHP](https://frankenphp.dev/), [RoadRunner](https://roadrunner.dev/) and [Swoole](https://www.swoole.co.uk/)." -msgstr "" +msgstr "可以使用多种工具来实现这一目标,其中较为知名的有 [FrankenPHP](https://frankenphp.dev/)、[RoadRunner](https://roadrunner.dev/) 和 [Swoole](https://www.swoole.co.uk/)。" #. type: Title ## #: ../../guide/en/tutorial/using-with-event-loop.md #, no-wrap msgid "Event loop implications" -msgstr "" +msgstr "事件循环的影响" #. type: Plain text #: ../../guide/en/tutorial/using-with-event-loop.md msgid "Event loop worker basically looks like the following:" -msgstr "" +msgstr "事件循环的 worker 基本结构如下:" #. type: Fenced code block (php) #: ../../guide/en/tutorial/using-with-event-loop.md @@ -67,39 +72,39 @@ msgstr "" #. type: Plain text #: ../../guide/en/tutorial/using-with-event-loop.md msgid "Usually, there are multiple workers processing requests at the same time as with traditional php-fpm." -msgstr "" +msgstr "通常会有多个 worker 同时处理请求,与传统的 php-fpm 方式类似。" #. type: Plain text #: ../../guide/en/tutorial/using-with-event-loop.md msgid "That means that there's more to consider when developing applications." -msgstr "" +msgstr "这意味着在开发应用程序时需要考虑更多因素。" #. type: Title ### #: ../../guide/en/tutorial/using-with-event-loop.md #, no-wrap msgid "Processing is blocking" -msgstr "" +msgstr "处理是阻塞的" #. type: Plain text #: ../../guide/en/tutorial/using-with-event-loop.md msgid "Worker process requests one by one that's current processing is blocking processing next request. That means that long-running processes, same as in general PHP applications, should be put into a background via using a queue." -msgstr "" +msgstr "Worker 逐一处理请求,当前请求的处理会阻塞下一个请求的处理。这意味着与普通 PHP 应用程序一样,耗时较长的任务应通过队列放到后台执行。" #. type: Title ### #: ../../guide/en/tutorial/using-with-event-loop.md #, no-wrap msgid "Services and state" -msgstr "" +msgstr "服务与状态" #. type: Plain text #: ../../guide/en/tutorial/using-with-event-loop.md msgid "Since the context in the event loop is shared between all request-responses processed by a single worker, all changes in the state of a service made by the previous request may affect the current request. Moreover, it can be a security problem if data from one user is available to another user." -msgstr "" +msgstr "由于事件循环中的上下文由同一 worker 处理的所有请求-响应共享,上一个请求对服务状态所做的任何修改都可能影响当前请求。此外,如果一个用户的数据可被另一个用户访问,还会带来安全问题。" #. type: Plain text #: ../../guide/en/tutorial/using-with-event-loop.md msgid "There are two ways of dealing with it. First, you can avoid having state by making services stateless. PHP's `readonly` keyword may be handy for it. Second, you can reset the services' state at the end of the request processing. In this case, a state resetter will help you:" -msgstr "" +msgstr "有两种应对方式。第一种是将服务设计为无状态,从而避免状态问题,PHP 的 `readonly` 关键字在此很有用。第二种是在每次请求处理结束后重置服务状态,此时可以使用状态重置器:" #. type: Fenced code block (php) #: ../../guide/en/tutorial/using-with-event-loop.md @@ -118,7 +123,7 @@ msgstr "" #: ../../guide/en/tutorial/using-with-event-loop.md #, no-wrap msgid "Integrations" -msgstr "" +msgstr "集成" #. type: Bullet: '- ' #: ../../guide/en/tutorial/using-with-event-loop.md diff --git a/_translations/po/zh-CN/guide_tutorial_using-yii-with-roadrunner.md.po b/_translations/po/zh-CN/guide_tutorial_using-yii-with-roadrunner.md.po index 6fff0326..767452ff 100644 --- a/_translations/po/zh-CN/guide_tutorial_using-yii-with-roadrunner.md.po +++ b/_translations/po/zh-CN/guide_tutorial_using-yii-with-roadrunner.md.po @@ -37,7 +37,7 @@ msgstr "配置" #: ../src/guide/tutorial/using-yii-with-roadrunner.md #, no-wrap msgid "Using Yii with RoadRunner" -msgstr "" +msgstr "在 Yii 中使用 RoadRunner" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md @@ -48,11 +48,15 @@ msgid "" "[event loop](using-with-event-loop.md) and allows not re-initializing a framework for each request that improves\n" "performance significantly.\n" msgstr "" +"[RoadRunner](https://roadrunner.dev/) 是一个由 Golang 驱动的应用服务器,可以与 PHP 良好集成。它将 PHP 作为 worker 运行,\n" +"每个 worker 可以处理多个请求。这种操作模式通常称为\n" +"[事件循环](using-with-event-loop.md),无需为每个请求重新初始化框架,\n" +"从而显著提升性能。\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "RoadRunner works on Linux, macOS and Windows. The best way to install it is to use a Composer:" -msgstr "" +msgstr "RoadRunner 支持 Linux、macOS 和 Windows。安装它的最佳方式是使用 Composer:" #. type: Fenced code block #: ../src/guide/tutorial/using-yii-with-roadrunner.md @@ -63,7 +67,7 @@ msgstr "" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "After installation is done, run" -msgstr "" +msgstr "安装完成后,运行:" #. type: Fenced code block #: ../src/guide/tutorial/using-yii-with-roadrunner.md @@ -74,12 +78,12 @@ msgstr "" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "That would download ready to use RoadRunner server `rr` binary." -msgstr "" +msgstr "这将下载可直接使用的 RoadRunner 服务器 `rr` 二进制文件。" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "First, we need to configure the server itself. Create `/.rr.yaml` and add the following config:" -msgstr "" +msgstr "首先,我们需要配置服务器本身。创建 `/.rr.yaml` 并添加以下配置:" #. type: Fenced code block (yaml) #: ../src/guide/tutorial/using-yii-with-roadrunner.md @@ -120,16 +124,18 @@ msgid "" "> [!INFO]\n" "> Read more about TLS, HTTP/2, HTTP/3 configuration and other middleware [on the RoadRunner docs](https://docs.roadrunner.dev/docs/http/http).\n" msgstr "" +"> [!INFO]\n" +"> 了解更多关于 TLS、HTTP/2、HTTP/3 配置和其他中间件的信息,请参阅 [RoadRunner 文档](https://docs.roadrunner.dev/docs/http/http)。\n" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "We're specifying that the entry script is `worker.php`, the server listens on port 8080, `public` directory files are served statically except `.php` and `.htaccess`. The `max_worker_memory` is a soft limit: if a worker exceeds 192 MB, it will restart after finishing its current request. Also, we're sending an additional header." -msgstr "" +msgstr "我们指定入口脚本为 `worker.php`,服务器监听 8080 端口,`public` 目录中的文件(除 `.php` 和 `.htaccess` 外)以静态方式提供服务。`max_worker_memory` 是一个软限制:如果 worker 超过 192 MB,它将在完成当前请求后重启。此外,我们还发送了一个额外的响应头。" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "Create `/worker.php`:" -msgstr "" +msgstr "创建 `/worker.php`:" #. type: Fenced code block (php) #: ../src/guide/tutorial/using-yii-with-roadrunner.md @@ -153,13 +159,13 @@ msgstr "" #: ../src/guide/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Starting a server" -msgstr "" +msgstr "启动服务器" #. type: Plain text #: ../src/guide/tutorial/using-yii-with-roadrunner.md #: ../src/guide/tutorial/using-yii-with-swoole.md msgid "To start a server, execute the following command:" -msgstr "" +msgstr "要启动服务器,请执行以下命令:" #. type: Fenced code block #: ../src/guide/tutorial/using-yii-with-roadrunner.md @@ -171,19 +177,19 @@ msgstr "" #: ../src/guide/tutorial/using-yii-with-roadrunner.md #, no-wrap msgid "On worker scope" -msgstr "" +msgstr "关于 Worker 作用域" #. type: Bullet: '- ' #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "Each worker's scope is isolated from other workers. Memory isn't shared." -msgstr "" +msgstr "每个 worker 的作用域与其他 worker 隔离,内存不共享。" #. type: Bullet: '- ' #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "A single worker serves multiple requests where the scope is shared." -msgstr "" +msgstr "单个 worker 服务多个请求,请求之间共享作用域。" #. type: Bullet: '- ' #: ../src/guide/tutorial/using-yii-with-roadrunner.md msgid "At each iteration of the event loop, every service that depends on state should be reset." -msgstr "" +msgstr "在事件循环的每次迭代中,所有依赖状态的服务都应进行重置。" diff --git a/_translations/po/zh-CN/guide_tutorial_using-yii-with-swoole.md.po b/_translations/po/zh-CN/guide_tutorial_using-yii-with-swoole.md.po index 97da407c..be03bcb8 100644 --- a/_translations/po/zh-CN/guide_tutorial_using-yii-with-swoole.md.po +++ b/_translations/po/zh-CN/guide_tutorial_using-yii-with-swoole.md.po @@ -27,19 +27,19 @@ msgstr "安装" #: ../../guide/en/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Starting a server" -msgstr "" +msgstr "启动服务器" #. type: Plain text #: ../../guide/en/tutorial/using-yii-with-roadrunner.md #: ../../guide/en/tutorial/using-yii-with-swoole.md msgid "To start a server, execute the following command:" -msgstr "" +msgstr "要启动服务器,请执行以下命令:" #. type: Title # #: ../../guide/en/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Using Yii with Swoole" -msgstr "" +msgstr "在 Swoole 中使用 Yii" #. type: Plain text #: ../../guide/en/tutorial/using-yii-with-swoole.md @@ -48,16 +48,18 @@ msgid "" "[Swoole](https://www.swoole.co.uk/) is a PHP network framework distributed as a PECL extension. It allows you built-in async,\n" "multiple threads I/O modules. Developers can use sync or async, coroutine API to write the applications.\n" msgstr "" +"[Swoole](https://www.swoole.co.uk/) 是一个以 PECL 扩展形式发布的 PHP 网络框架,内置了异步、\n" +"多线程 I/O 模块。开发者可以使用同步或异步、协程 API 来编写应用程序。\n" #. type: Plain text #: ../../guide/en/tutorial/using-yii-with-swoole.md msgid "In the context of Yii, it allows running request handlers as workers. Each worker may handle multiple requests. Such an operation mode is often called [event loop](using-with-event-loop.md) and allows not re-initializing a framework for each request that improves performance significantly." -msgstr "" +msgstr "在 Yii 的使用场景中,Swoole 允许将请求处理器作为 worker 运行,每个 worker 可处理多个请求。这种运行模式通常称为[事件循环](using-with-event-loop.md),无需为每个请求重新初始化框架,从而显著提升性能。" #. type: Plain text #: ../../guide/en/tutorial/using-yii-with-swoole.md msgid "Swoole works on Linux and macOS and can be installed via pecl:" -msgstr "" +msgstr "Swoole 支持 Linux 和 macOS,可通过 pecl 安装:" #. type: Fenced code block (bash) #: ../../guide/en/tutorial/using-yii-with-swoole.md @@ -69,12 +71,12 @@ msgstr "" #: ../../guide/en/tutorial/using-yii-with-swoole.md #, no-wrap msgid "Putting up a server" -msgstr "" +msgstr "搭建服务器" #. type: Plain text #: ../../guide/en/tutorial/using-yii-with-swoole.md msgid "Since Swoole doesn't have built-in PSR-7 support, you need a package fixing so:" -msgstr "" +msgstr "由于 Swoole 没有内置的 PSR-7 支持,需要安装一个补充包:" #. type: Fenced code block (php) #: ../../guide/en/tutorial/using-yii-with-swoole.md @@ -85,7 +87,7 @@ msgstr "" #. type: Plain text #: ../../guide/en/tutorial/using-yii-with-swoole.md msgid "Create an entry script, `server.php`:" -msgstr "" +msgstr "创建入口脚本 `server.php`:" #. type: Fenced code block (php) #: ../../guide/en/tutorial/using-yii-with-swoole.md @@ -188,9 +190,9 @@ msgstr "" #: ../../guide/en/tutorial/using-yii-with-swoole.md #, no-wrap msgid "On scope" -msgstr "" +msgstr "关于作用域" #. type: Plain text #: ../../guide/en/tutorial/using-yii-with-swoole.md msgid "A scope is shared, so at each iteration of the event loop every service that depends on state should be reset." -msgstr "" +msgstr "作用域是共享的,因此在事件循环的每次迭代中,所有依赖状态的服务都应进行重置。" diff --git a/_translations/po/zh-CN/guide_views_asset.md.po b/_translations/po/zh-CN/guide_views_asset.md.po index dd907980..98eb7bc1 100644 --- a/_translations/po/zh-CN/guide_views_asset.md.po +++ b/_translations/po/zh-CN/guide_views_asset.md.po @@ -37,17 +37,17 @@ msgstr "安装" #: ../src/guide/views/asset.md #, no-wrap msgid "Assets" -msgstr "" +msgstr "资源" #. type: Plain text #: ../src/guide/views/asset.md msgid "Asset management is crucial for modern web applications. Assets include CSS stylesheets, JavaScript files, images, fonts, and other static resources. Yii3 provides a comprehensive asset management system through the `yiisoft/assets` package that handles dependencies, optimization, and deployment of these resources." -msgstr "" +msgstr "资源管理对现代 Web 应用程序至关重要。资源包括 CSS 样式表、JavaScript 文件、图像、字体及其他静态资源。Yii3 通过 `yiisoft/assets` 包提供了一套完整的资源管理系统,用于处理这些资源的依赖、优化和部署。" #. type: Plain text #: ../src/guide/views/asset.md msgid "The asset management functionality is provided by the `yiisoft/assets` package:" -msgstr "" +msgstr "资源管理功能由 `yiisoft/assets` 包提供:" #. type: Fenced code block (bash) #: ../src/guide/views/asset.md @@ -58,53 +58,53 @@ msgstr "" #. type: Plain text #: ../src/guide/views/asset.md msgid "This package is included by default in the `yiisoft/app` application template." -msgstr "" +msgstr "该包默认包含在 `yiisoft/app` 应用程序模板中。" #. type: Title ## #: ../src/guide/views/asset.md ../src/guide/views/view.md #: ../src/guide/views/widget.md #, no-wrap msgid "Basic Concepts" -msgstr "" +msgstr "基本概念" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "Asset Bundles" -msgstr "" +msgstr "资源包" #. type: Plain text #: ../src/guide/views/asset.md msgid "An asset bundle is a collection of related asset files (CSS, JavaScript, images) that are logically grouped together. Asset bundles can depend on other bundles, allowing for proper dependency management." -msgstr "" +msgstr "资源包是一组相关资源文件(CSS、JavaScript、图像)的集合,它们在逻辑上被组合在一起。资源包可以依赖其他包,从而实现适当的依赖关系管理。" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "Asset Manager" -msgstr "" +msgstr "资源管理器" #. type: Plain text #: ../src/guide/views/asset.md msgid "The Asset Manager is responsible for: - Resolving asset bundle dependencies - Publishing assets from protected directories to web-accessible locations - Combining and minifying assets (when configured) - Generating proper URLs for assets" -msgstr "" +msgstr "资源管理器负责:- 解析资源包依赖 - 将资源从受保护目录发布到 Web 可访问的位置 - 合并和压缩资源(当配置时)- 生成资源的正确 URL" #. type: Title ## #: ../src/guide/views/asset.md #, no-wrap msgid "Creating Asset Bundles" -msgstr "" +msgstr "创建资源包" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "Basic Asset Bundle" -msgstr "" +msgstr "基本资源包" #. type: Plain text #: ../src/guide/views/asset.md msgid "Here's a simple asset bundle definition:" -msgstr "" +msgstr "下面是一个简单的资源包定义:" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -144,7 +144,7 @@ msgstr "" #: ../src/guide/views/asset.md #, no-wrap msgid "Asset Bundle Properties" -msgstr "" +msgstr "资源包属性" #. type: Plain text #: ../src/guide/views/asset.md @@ -155,6 +155,10 @@ msgid "" "- `$baseUrl` - Web-accessible URL path for assets\n" "- `$sourcePath` - Source directory for assets that need to be published\n" msgstr "" +"**路径配置:**\n" +"- `$basePath` - 资源文件的物理路径\n" +"- `$baseUrl` - 资源的 Web 可访问 URL 路径\n" +"- `$sourcePath` - 需要发布的资源的源目录\n" #. type: Plain text #: ../src/guide/views/asset.md @@ -164,6 +168,9 @@ msgid "" "- `$css` - Array of CSS files\n" "- `$js` - Array of JavaScript files \n" msgstr "" +"**资源文件:**\n" +"- `$css` - CSS 文件数组\n" +"- `$js` - JavaScript 文件数组 \n" #. type: Plain text #: ../src/guide/views/asset.md @@ -172,6 +179,8 @@ msgid "" "**Dependencies:**\n" "- `$depends` - Array of other asset bundles this bundle depends on\n" msgstr "" +"**依赖:**\n" +"- `$depends` - 此包所依赖的其他资源包数组\n" #. type: Plain text #: ../src/guide/views/asset.md @@ -181,12 +190,15 @@ msgid "" "- `$jsOptions` - HTML attributes for JavaScript tags\n" "- `$cssOptions` - HTML attributes for CSS link tags\n" msgstr "" +"**选项:**\n" +"- `$jsOptions` - JavaScript 标签的 HTML 属性\n" +"- `$cssOptions` - CSS link 标签的 HTML 属性\n" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "Advanced Asset Bundle" -msgstr "" +msgstr "高级资源包" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -240,18 +252,18 @@ msgstr "" #: ../src/guide/views/asset.md #, no-wrap msgid "Using Asset Bundles" -msgstr "" +msgstr "使用资源包" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "In Controllers" -msgstr "" +msgstr "在控制器中" #. type: Plain text #: ../src/guide/views/asset.md msgid "Register asset bundles in your controllers or views:" -msgstr "" +msgstr "在控制器或视图中注册资源包:" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -302,12 +314,12 @@ msgstr "" #: ../src/guide/views/asset.md #, no-wrap msgid "In Views" -msgstr "" +msgstr "在视图中" #. type: Plain text #: ../src/guide/views/asset.md msgid "You can also register assets directly in views:" -msgstr "" +msgstr "你也可以直接在视图中注册资源:" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -340,12 +352,12 @@ msgstr "" #: ../src/guide/views/asset.md #, no-wrap msgid "With WebView Integration" -msgstr "" +msgstr "与 WebView 集成" #. type: Plain text #: ../src/guide/views/asset.md msgid "The recommended approach is to integrate with WebView for automatic asset rendering:" -msgstr "" +msgstr "推荐的方式是与 WebView 集成,以自动渲染资源:" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -382,18 +394,18 @@ msgstr "" #: ../src/guide/views/asset.md #, no-wrap msgid "Asset Publishing" -msgstr "" +msgstr "资源发布" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "Source Path Publishing" -msgstr "" +msgstr "源路径发布" #. type: Plain text #: ../src/guide/views/asset.md msgid "When assets are located in non-web-accessible directories (like vendor packages), they need to be published:" -msgstr "" +msgstr "当资源位于不可通过 Web 访问的目录(如 vendor 包)时,需要发布它们:" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -430,12 +442,12 @@ msgstr "" #: ../src/guide/views/asset.md #, no-wrap msgid "Custom Publishing" -msgstr "" +msgstr "自定义发布" #. type: Plain text #: ../src/guide/views/asset.md msgid "You can also manually publish directories:" -msgstr "" +msgstr "你也可以手动发布目录:" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -456,13 +468,13 @@ msgstr "" #: ../src/guide/views/asset.md #, no-wrap msgid "Third-party Library Assets" -msgstr "" +msgstr "第三方库资源" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "jQuery Asset Bundle" -msgstr "" +msgstr "jQuery 资源包" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -497,7 +509,7 @@ msgstr "" #: ../src/guide/views/asset.md #, no-wrap msgid "Bootstrap Asset Bundle" -msgstr "" +msgstr "Bootstrap 资源包" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -534,12 +546,12 @@ msgstr "" #: ../src/guide/views/asset.md #, no-wrap msgid "CDN Assets" -msgstr "" +msgstr "CDN 资源" #. type: Plain text #: ../src/guide/views/asset.md msgid "For CDN-hosted assets, you can specify full URLs:" -msgstr "" +msgstr "对于托管在 CDN 上的资源,可以指定完整 URL:" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -574,24 +586,24 @@ msgstr "" #: ../src/guide/views/asset.md #, no-wrap msgid "Asset Configuration" -msgstr "" +msgstr "资源配置" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "Application Configuration" -msgstr "" +msgstr "应用程序配置" #. type: Plain text #: ../src/guide/views/asset.md msgid "Configure asset management in your application configuration:" -msgstr "" +msgstr "在应用程序配置中配置资源管理:" #. type: Plain text #: ../src/guide/views/asset.md #, no-wrap msgid "**config/web/params.php**\n" -msgstr "" +msgstr "**config/web/params.php**\n" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -620,12 +632,12 @@ msgstr "" #: ../src/guide/views/asset.md #, no-wrap msgid "Environment-specific Assets" -msgstr "" +msgstr "特定环境的资源" #. type: Plain text #: ../src/guide/views/asset.md msgid "Configure different assets for different environments:" -msgstr "" +msgstr "为不同环境配置不同的资源:" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -666,18 +678,18 @@ msgstr "" #: ../src/guide/views/asset.md #, no-wrap msgid "Asset Optimization" -msgstr "" +msgstr "资源优化" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "Asset Combination" -msgstr "" +msgstr "资源合并" #. type: Plain text #: ../src/guide/views/asset.md msgid "Combine multiple CSS or JavaScript files into single files:" -msgstr "" +msgstr "将多个 CSS 或 JavaScript 文件合并为单个文件:" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -701,12 +713,12 @@ msgstr "" #: ../src/guide/views/asset.md #, no-wrap msgid "Asset Compression" -msgstr "" +msgstr "资源压缩" #. type: Plain text #: ../src/guide/views/asset.md msgid "Configure asset compression for production:" -msgstr "" +msgstr "为生产环境配置资源压缩:" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -725,13 +737,13 @@ msgstr "" #: ../src/guide/views/asset.md #, no-wrap msgid "Working with Asset Converter" -msgstr "" +msgstr "使用资源转换器" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "SCSS/SASS Compilation" -msgstr "" +msgstr "SCSS/SASS 编译" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -762,7 +774,7 @@ msgstr "" #: ../src/guide/views/asset.md #, no-wrap msgid "TypeScript Compilation" -msgstr "" +msgstr "TypeScript 编译" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -793,13 +805,13 @@ msgstr "" #: ../src/guide/views/asset.md ../src/guide/views/script-style-meta.md #, no-wrap msgid "Practical Examples" -msgstr "" +msgstr "实践示例" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "Complete Application Asset Structure" -msgstr "" +msgstr "完整应用程序资源结构" #. type: Fenced code block #: ../src/guide/views/asset.md @@ -828,7 +840,7 @@ msgstr "" #: ../src/guide/views/asset.md #, no-wrap msgid "Complete Asset Bundle Setup" -msgstr "" +msgstr "完整资源包配置" #. type: Fenced code block (php) #: ../src/guide/views/asset.md @@ -902,53 +914,53 @@ msgstr "" #: ../src/guide/views/template-engines.md #, no-wrap msgid "Best Practices" -msgstr "" +msgstr "最佳实践" #. type: Bullet: '1. ' #: ../src/guide/views/asset.md msgid "**Organize by functionality**: Group related assets into logical bundles" -msgstr "" +msgstr "**按功能组织**:将相关资源归入逻辑包" #. type: Bullet: '2. ' #: ../src/guide/views/asset.md msgid "**Manage dependencies**: Properly declare dependencies between bundles" -msgstr "" +msgstr "**管理依赖**:正确声明包之间的依赖关系" #. type: Bullet: '3. ' #: ../src/guide/views/asset.md msgid "**Use meaningful names**: Name your asset bundles clearly" -msgstr "" +msgstr "**使用有意义的名称**:清晰地命名资源包" #. type: Bullet: '4. ' #: ../src/guide/views/asset.md msgid "**Environment optimization**: Use minified assets in production" -msgstr "" +msgstr "**环境优化**:在生产环境中使用压缩资源" #. type: Bullet: '5. ' #: ../src/guide/views/asset.md msgid "**CDN consideration**: Use CDN for popular libraries when appropriate" -msgstr "" +msgstr "**考虑 CDN**:在适当时对常用库使用 CDN" #. type: Bullet: '6. ' #: ../src/guide/views/asset.md msgid "**Version your assets**: Include version numbers in filenames for cache busting" -msgstr "" +msgstr "**版本化资源**:在文件名中包含版本号以清除缓存" #. type: Bullet: '7. ' #: ../src/guide/views/asset.md msgid "**Minimize HTTP requests**: Combine related assets when possible" -msgstr "" +msgstr "**减少 HTTP 请求**:尽可能合并相关资源" #. type: Bullet: '8. ' #: ../src/guide/views/asset.md msgid "**Optimize file sizes**: Compress and minify assets for production" -msgstr "" +msgstr "**优化文件大小**:为生产环境压缩和最小化资源" #. type: Title ### #: ../src/guide/views/asset.md #, no-wrap msgid "Common Issues" -msgstr "" +msgstr "常见问题" #. type: Plain text #: ../src/guide/views/asset.md @@ -959,6 +971,10 @@ msgid "" "- Verify `$basePath` and `$baseUrl` are configured correctly\n" "- Ensure assets are published if using `$sourcePath`\n" msgstr "" +"**资源未找到:**\n" +"- 检查资源文件是否存在于指定路径中\n" +"- 验证 `$basePath` 和 `$baseUrl` 是否配置正确\n" +"- 如果使用 `$sourcePath`,确保资源已发布\n" #. type: Plain text #: ../src/guide/views/asset.md @@ -969,6 +985,10 @@ msgid "" "- Check for circular dependencies\n" "- Ensure dependency bundles are correctly configured\n" msgstr "" +"**依赖未加载:**\n" +"- 验证依赖包是否已正确注册\n" +"- 检查是否存在循环依赖\n" +"- 确保依赖包已正确配置\n" #. type: Plain text #: ../src/guide/views/asset.md @@ -978,6 +998,9 @@ msgid "" "- Make sure you're calling `$this->addCssFiles()` and `$this->addJsFiles()` in your layout\n" "- Verify that `$this->head()`, `$this->beginBody()`, and `$this->endBody()` are called in the layout\n" msgstr "" +"**资源未出现在 HTML 中:**\n" +"- 确保在布局中调用了 `$this->addCssFiles()` 和 `$this->addJsFiles()`\n" +"- 验证布局中是否调用了 `$this->head()`、`$this->beginBody()` 和 `$this->endBody()`\n" #. type: Plain text #: ../src/guide/views/asset.md @@ -987,3 +1010,6 @@ msgid "" "- Check that the web server has write permissions to the assets directory\n" "- Verify the published assets directory is web-accessible\n" msgstr "" +"**权限问题:**\n" +"- 检查 Web 服务器是否具有资源目录的写入权限\n" +"- 验证已发布的资源目录是否可通过 Web 访问\n" diff --git a/_translations/po/zh-CN/guide_views_script-style-meta.md.po b/_translations/po/zh-CN/guide_views_script-style-meta.md.po index 8afa86d5..d1598567 100644 --- a/_translations/po/zh-CN/guide_views_script-style-meta.md.po +++ b/_translations/po/zh-CN/guide_views_script-style-meta.md.po @@ -19,78 +19,78 @@ msgstr "" #: ../src/guide/structure/overview.md ../src/guide/views/script-style-meta.md #, no-wrap msgid "Overview" -msgstr "" +msgstr "概述" #. type: Title ## #: ../src/guide/views/asset.md ../src/guide/views/script-style-meta.md #, no-wrap msgid "Practical Examples" -msgstr "" +msgstr "实践示例" #. type: Title ## #: ../src/guide/views/asset.md ../src/guide/views/script-style-meta.md #: ../src/guide/views/template-engines.md #, no-wrap msgid "Best Practices" -msgstr "" +msgstr "最佳实践" #. type: Title # #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Scripts, styles and meta tags" -msgstr "" +msgstr "脚本、样式与 meta 标签" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Modern web applications require careful management of CSS styles, JavaScript code, and HTML meta tags. Yii3 provides a comprehensive system for registering and organizing these resources through the `WebView` class, which is part of the `yiisoft/view` package." -msgstr "" +msgstr "现代 Web 应用程序需要对 CSS 样式、JavaScript 代码和 HTML meta 标签进行精细管理。Yii3 通过 `yiisoft/view` 包中的 `WebView` 类提供了一套完整的系统,用于注册和组织这些资源。" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "The `WebView` class extends the basic `View` class with web-specific functionality, allowing you to:" -msgstr "" +msgstr "`WebView` 类在基础 `View` 类的基础上扩展了 Web 特有的功能,使你可以:" #. type: Bullet: '- ' #: ../src/guide/views/script-style-meta.md msgid "Register CSS files and inline styles" -msgstr "" +msgstr "注册 CSS 文件和内联样式" #. type: Bullet: '- ' #: ../src/guide/views/script-style-meta.md msgid "Register JavaScript files and inline scripts" -msgstr "" +msgstr "注册 JavaScript 文件和内联脚本" #. type: Bullet: '- ' #: ../src/guide/views/script-style-meta.md msgid "Manage HTML meta tags and link tags" -msgstr "" +msgstr "管理 HTML meta 标签和 link 标签" #. type: Bullet: '- ' #: ../src/guide/views/script-style-meta.md msgid "Control the position where resources are rendered" -msgstr "" +msgstr "控制资源的渲染位置" #. type: Bullet: '- ' #: ../src/guide/views/script-style-meta.md msgid "Handle dependencies between resources" -msgstr "" +msgstr "处理资源之间的依赖关系" #. type: Title ## #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "CSS management" -msgstr "" +msgstr "CSS 管理" #. type: Title ### #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Registering CSS Files" -msgstr "" +msgstr "注册 CSS 文件" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "You can register CSS files to be included in your HTML pages:" -msgstr "" +msgstr "你可以注册需要包含在 HTML 页面中的 CSS 文件:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -122,12 +122,12 @@ msgstr "" #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Registering Inline CSS" -msgstr "" +msgstr "注册内联 CSS" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "For inline CSS styles, use the `registerCss()` method:" -msgstr "" +msgstr "对于内联 CSS 样式,使用 `registerCss()` 方法:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -157,12 +157,12 @@ msgstr "" #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "CSS from Files" -msgstr "" +msgstr "从文件注册 CSS" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "You can also register CSS content from external files:" -msgstr "" +msgstr "你也可以从外部文件读取 CSS 内容并注册为内联样式:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -178,12 +178,12 @@ msgstr "" #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Using Style Tags" -msgstr "" +msgstr "使用 Style 标签" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "For more control, you can use HTML style tags directly:" -msgstr "" +msgstr "如需更精细的控制,可以直接使用 HTML style 标签:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -207,18 +207,18 @@ msgstr "" #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "JavaScript management" -msgstr "" +msgstr "JavaScript 管理" #. type: Title ### #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Registering JavaScript Files" -msgstr "" +msgstr "注册 JavaScript 文件" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Include external JavaScript files using `registerJsFile()`:" -msgstr "" +msgstr "使用 `registerJsFile()` 引入外部 JavaScript 文件:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -246,12 +246,12 @@ msgstr "" #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Registering Inline JavaScript" -msgstr "" +msgstr "注册内联 JavaScript" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Add inline JavaScript code with `registerJs()`:" -msgstr "" +msgstr "使用 `registerJs()` 添加内联 JavaScript 代码:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -277,12 +277,12 @@ msgstr "" #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "JavaScript Variables" -msgstr "" +msgstr "JavaScript 变量" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Pass PHP data to JavaScript using `registerJsVar()`:" -msgstr "" +msgstr "使用 `registerJsVar()` 将 PHP 数据传递给 JavaScript:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -304,7 +304,7 @@ msgstr "" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "This generates JavaScript code like:" -msgstr "" +msgstr "这将生成如下 JavaScript 代码:" #. type: Fenced code block (html) #: ../src/guide/views/script-style-meta.md @@ -321,12 +321,12 @@ msgstr "" #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Using Script Tags" -msgstr "" +msgstr "使用 Script 标签" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "For more control over script tags:" -msgstr "" +msgstr "如需对 script 标签进行更精细的控制:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -349,12 +349,12 @@ msgstr "" #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Position Constants" -msgstr "" +msgstr "位置常量" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Resources can be positioned at different locations in the HTML document:" -msgstr "" +msgstr "资源可以定位到 HTML 文档的不同位置:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -381,7 +381,7 @@ msgstr "" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Example layout showing where each position is rendered:" -msgstr "" +msgstr "以下布局示例展示了各位置的渲染位置:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -421,18 +421,18 @@ msgstr "" #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Meta tags" -msgstr "" +msgstr "Meta 标签" #. type: Title ### #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Basic Meta Tags" -msgstr "" +msgstr "基本 Meta 标签" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Register meta tags for SEO and page information:" -msgstr "" +msgstr "为 SEO 和页面信息注册 meta 标签:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -457,12 +457,12 @@ msgstr "" #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Using Meta Tag Objects" -msgstr "" +msgstr "使用 Meta 标签对象" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "For more control, use the `Html::meta()` helper:" -msgstr "" +msgstr "如需更精细的控制,使用 `Html::meta()` 辅助方法:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -488,12 +488,12 @@ msgstr "" #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Preventing Duplicate Meta Tags" -msgstr "" +msgstr "防止重复 Meta 标签" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Use keys to prevent duplicate meta tags:" -msgstr "" +msgstr "使用键名防止 meta 标签重复注册:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -516,18 +516,18 @@ msgstr "" #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Link tags" -msgstr "" +msgstr "Link 标签" #. type: Title ### #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Basic Link Tags" -msgstr "" +msgstr "基本 Link 标签" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Register various types of link tags:" -msgstr "" +msgstr "注册各类 link 标签:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -568,7 +568,7 @@ msgstr "" #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Using Link Tag Objects" -msgstr "" +msgstr "使用 Link 标签对象" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -595,12 +595,12 @@ msgstr "" #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Complete Page Setup" -msgstr "" +msgstr "完整页面配置" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Here's how you might set up a complete page with all types of resources:" -msgstr "" +msgstr "以下示例展示如何为页面配置所有类型的资源:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -673,12 +673,12 @@ msgstr "" #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Conditional Resource Loading" -msgstr "" +msgstr "条件资源加载" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "Load resources based on conditions:" -msgstr "" +msgstr "根据条件加载资源:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md @@ -720,53 +720,53 @@ msgstr "" #. type: Bullet: '1. ' #: ../src/guide/views/script-style-meta.md msgid "**Use appropriate positions**: Place CSS in `POSITION_HEAD`, JavaScript at `POSITION_END`" -msgstr "" +msgstr "**使用合适的位置**:将 CSS 放在 `POSITION_HEAD`,JavaScript 放在 `POSITION_END`" #. type: Bullet: '2. ' #: ../src/guide/views/script-style-meta.md msgid "**Minimize inline resources**: Prefer external files for better caching" -msgstr "" +msgstr "**减少内联资源**:优先使用外部文件以获得更好的缓存效果" #. type: Bullet: '3. ' #: ../src/guide/views/script-style-meta.md msgid "**Use keys for duplicates**: Prevent duplicate resources with meaningful keys" -msgstr "" +msgstr "**使用键名去重**:通过有意义的键名防止资源重复注册" #. type: Bullet: '4. ' #: ../src/guide/views/script-style-meta.md msgid "**Optimize loading**: Use `async` and `defer` attributes for non-critical JavaScript" -msgstr "" +msgstr "**优化加载**:对非关键 JavaScript 使用 `async` 和 `defer` 属性" #. type: Bullet: '5. ' #: ../src/guide/views/script-style-meta.md msgid "**Group related resources**: Keep related CSS and JS files together" -msgstr "" +msgstr "**分组管理相关资源**:将相关的 CSS 和 JS 文件放在一起" #. type: Bullet: '6. ' #: ../src/guide/views/script-style-meta.md msgid "**Use CDNs wisely**: Balance performance with reliability" -msgstr "" +msgstr "**合理使用 CDN**:在性能与可靠性之间取得平衡" #. type: Bullet: '7. ' #: ../src/guide/views/script-style-meta.md msgid "**Validate meta tags**: Ensure proper SEO meta tags are set" -msgstr "" +msgstr "**验证 meta 标签**:确保正确设置 SEO 所需的 meta 标签" #. type: Bullet: '8. ' #: ../src/guide/views/script-style-meta.md msgid "**Consider security**: Be careful with inline scripts and CSP policies" -msgstr "" +msgstr "**注意安全性**:谨慎处理内联脚本与 CSP 策略" #. type: Title ## #: ../src/guide/views/script-style-meta.md #, no-wrap msgid "Working with Asset Bundles" -msgstr "" +msgstr "使用资源包" #. type: Plain text #: ../src/guide/views/script-style-meta.md msgid "For more complex asset management, consider using asset bundles:" -msgstr "" +msgstr "对于更复杂的资源管理需求,可以考虑使用资源包:" #. type: Fenced code block (php) #: ../src/guide/views/script-style-meta.md diff --git a/_translations/po/zh-CN/guide_views_template-engines.md.po b/_translations/po/zh-CN/guide_views_template-engines.md.po index 994aa4db..5ac86bae 100644 --- a/_translations/po/zh-CN/guide_views_template-engines.md.po +++ b/_translations/po/zh-CN/guide_views_template-engines.md.po @@ -20,34 +20,34 @@ msgstr "" #: ../src/guide/views/template-engines.md #, no-wrap msgid "Best Practices" -msgstr "" +msgstr "最佳实践" #. type: Title # #: ../src/guide/views/template-engines.md #, no-wrap msgid "Template engines" -msgstr "" +msgstr "模板引擎" #. type: Plain text #: ../src/guide/views/template-engines.md msgid "Yii3 supports multiple template engines through a flexible renderer system. By default, PHP is used as the template engine, but you can easily add support for other engines like Twig and [Blade](https://github.com/lee-to/yii-blade), or create your own custom renderers." -msgstr "" +msgstr "Yii3 通过灵活的渲染器系统支持多种模板引擎。默认情况下,PHP 用作模板引擎,但您可以轻松添加对其他引擎(如 Twig 和 [Blade](https://github.com/lee-to/yii-blade))的支持,或创建自己的自定义渲染器。" #. type: Plain text #: ../src/guide/views/template-engines.md msgid "PHP templates were described in the \"[View](view.md)\" guide section." -msgstr "" +msgstr "PHP 模板在“[视图](view.md)”指南部分中有描述。" #. type: Title ## #: ../src/guide/views/template-engines.md #, no-wrap msgid "Twig Template Engine" -msgstr "" +msgstr "Twig 模板引擎" #. type: Plain text #: ../src/guide/views/template-engines.md msgid "Twig is a modern template engine that provides a more designer-friendly syntax. To use Twig in your Yii3 application, you need to install the Twig extension." -msgstr "" +msgstr "Twig 是一种现代模板引擎,提供更适合设计师的语法。要在您的 Yii3 应用程序中使用 Twig,您需要安装 Twig 扩展。" #. type: Fenced code block (bash) #: ../src/guide/views/template-engines.md @@ -58,7 +58,7 @@ msgstr "" #. type: Plain text #: ../src/guide/views/template-engines.md msgid "Now you can use `.twig` templates. For example, `views/site/about.twig`:" -msgstr "" +msgstr "现在您可以使用 `.twig` 模板。例如,`views/site/about.twig`:" #. type: Fenced code block (twig) #: ../src/guide/views/template-engines.md @@ -93,13 +93,13 @@ msgstr "" #: ../src/guide/views/template-engines.md #, no-wrap msgid "Twig Features" -msgstr "" +msgstr "Twig 特性" #. type: Plain text #: ../src/guide/views/template-engines.md #, no-wrap msgid "**Automatic Escaping**: Twig automatically escapes variables for HTML context:\n" -msgstr "" +msgstr "**自动转义**:Twig 自动转义 HTML 上下文中的变量:\n" #. type: Fenced code block (twig) #: ../src/guide/views/template-engines.md @@ -116,7 +116,7 @@ msgstr "" #: ../src/guide/views/template-engines.md #, no-wrap msgid "**Filters and Functions**: Twig provides many built-in filters and functions:\n" -msgstr "" +msgstr "**过滤器和函数**:Twig 提供了许多内置过滤器和函数:\n" #. type: Fenced code block (twig) #: ../src/guide/views/template-engines.md @@ -136,7 +136,7 @@ msgstr "" #: ../src/guide/views/template-engines.md #, no-wrap msgid "**Template Inheritance**: Twig supports template inheritance:\n" -msgstr "" +msgstr "**模板继承**:Twig 支持模板继承:\n" #. type: Plain text #: ../src/guide/views/template-engines.md @@ -185,12 +185,12 @@ msgstr "" #: ../src/guide/views/template-engines.md #, no-wrap msgid "Rendering Twig Templates" -msgstr "" +msgstr "渲染 Twig 模板" #. type: Plain text #: ../src/guide/views/template-engines.md msgid "Use Twig templates the same way as PHP templates:" -msgstr "" +msgstr "以与 PHP 模板相同的方式使用 Twig 模板:" #. type: Fenced code block (php) #: ../src/guide/views/template-engines.md @@ -210,12 +210,12 @@ msgstr "" #: ../src/guide/views/template-engines.md #, no-wrap msgid "Custom Template Engines" -msgstr "" +msgstr "自定义模板引擎" #. type: Plain text #: ../src/guide/views/template-engines.md msgid "You can create custom template engines by implementing the `TemplateRendererInterface`:" -msgstr "" +msgstr "您可以通过实现 `TemplateRendererInterface` 来创建自定义模板引擎:" #. type: Fenced code block (php) #: ../src/guide/views/template-engines.md @@ -252,7 +252,7 @@ msgstr "" #. type: Plain text #: ../src/guide/views/template-engines.md msgid "Register your custom renderer:" -msgstr "" +msgstr "注册您的自定义渲染器:" #. type: Fenced code block (php) #: ../src/guide/views/template-engines.md @@ -271,7 +271,7 @@ msgstr "" #. type: Plain text #: ../src/guide/views/template-engines.md msgid "Now you can use `.md` template files:" -msgstr "" +msgstr "现在您可以使用 `.md` 模板文件:" #. type: Plain text #: ../src/guide/views/template-engines.md @@ -298,7 +298,7 @@ msgstr "" #: ../src/guide/views/template-engines.md #, no-wrap msgid "Choosing the Right Template Engine" -msgstr "" +msgstr "选择合适的模板引擎" #. type: Plain text #: ../src/guide/views/template-engines.md @@ -310,6 +310,11 @@ msgid "" "- You want to leverage existing PHP knowledge\n" "- You need complex logic in templates (though this should be minimized)\n" msgstr "" +"**在以下情况下使用 PHP 模板:**\n" +"- 您需要最大的灵活性和性能\n" +"- 您的团队熟悉 PHP\n" +"- 您希望利用现有的 PHP 知识\n" +"- 您需要在模板中使用复杂逻辑(尽管应尽量减少)\n" #. type: Plain text #: ../src/guide/views/template-engines.md @@ -321,6 +326,11 @@ msgid "" "- You need automatic escaping and security features\n" "- You want template inheritance and advanced features\n" msgstr "" +"**在以下情况下使用 Twig 模板:**\n" +"- 您希望逻辑与表示之间有更严格的分离\n" +"- 您与喜欢更简洁语法的设计师合作\n" +"- 您需要自动转义和安全功能\n" +"- 您需要模板继承和高级功能\n" #. type: Plain text #: ../src/guide/views/template-engines.md @@ -331,33 +341,37 @@ msgid "" "- You're working with specialized content formats\n" "- You need integration with external template systems\n" msgstr "" +"**在以下情况下使用自定义模板:**\n" +"- 您有 PHP 或 Twig 无法满足的特定要求\n" +"- 您正在处理专业的内容格式\n" +"- 您需要与外部模板系统集成\n" #. type: Bullet: '1. ' #: ../src/guide/views/template-engines.md msgid "**Keep templates simple**: Move complex logic to controllers or services" -msgstr "" +msgstr "**保持模板简单**:将复杂逻辑移至控制器或服务" #. type: Bullet: '2. ' #: ../src/guide/views/template-engines.md msgid "**Always escape output**: Prevent XSS attacks by properly escaping variables" -msgstr "" +msgstr "**始终转义输出**:通过正确转义变量来防止 XSS 攻击" #. type: Bullet: '3. ' #: ../src/guide/views/template-engines.md msgid "**Use meaningful names**: Name your templates and variables clearly" -msgstr "" +msgstr "**使用有意义的名称**:清晰地命名模板和变量" #. type: Bullet: '4. ' #: ../src/guide/views/template-engines.md msgid "**Organize templates**: Group related templates in subdirectories" -msgstr "" +msgstr "**组织模板**:将相关模板分组到子目录中" #. type: Bullet: '5. ' #: ../src/guide/views/template-engines.md msgid "**Document variables**: Always add type hints for better IDE support" -msgstr "" +msgstr "**记录变量**:始终添加类型提示以获得更好的 IDE 支持" #. type: Bullet: '6. ' #: ../src/guide/views/template-engines.md msgid "**Avoid business logic**: Keep business logic in models and services" -msgstr "" +msgstr "**避免业务逻辑**:将业务逻辑保留在模型和服务中" diff --git a/_translations/po/zh-CN/guide_views_view-injections.md.po b/_translations/po/zh-CN/guide_views_view-injections.md.po index feafc4fa..4b13c281 100644 --- a/_translations/po/zh-CN/guide_views_view-injections.md.po +++ b/_translations/po/zh-CN/guide_views_view-injections.md.po @@ -27,17 +27,17 @@ msgstr "配置" #: ../src/guide/views/view-injections.md #, no-wrap msgid "View injections" -msgstr "" +msgstr "视图注入" #. type: Plain text #: ../src/guide/views/view-injections.md msgid "The view injections are designed to provide a standardized way to pass parameters to the common layer of views in an application. It allows developers to manage the data that will be available across various views, ensuring flexibility and reusability of code." -msgstr "" +msgstr "视图注入旨在提供一种标准化的方式,将参数传递给应用程序的公共视图层。它允许开发者管理在各个视图中可用的数据,从而确保代码的灵活性和可复用性。" #. type: Plain text #: ../src/guide/views/view-injections.md msgid "The view injections could be used if you require `yiisoft/yii-view-renderer` package:" -msgstr "" +msgstr "使用视图注入需要引入 `yiisoft/yii-view-renderer` 包:" #. type: Fenced code block (sh) #: ../src/guide/views/view-injections.md ../src/guide/views/view.md @@ -48,7 +48,7 @@ msgstr "" #. type: Plain text #: ../src/guide/views/view-injections.md msgid "In config `params.php`:" -msgstr "" +msgstr "在配置文件 `params.php` 中:" #. type: Fenced code block (php) #: ../src/guide/views/view-injections.md @@ -68,12 +68,12 @@ msgstr "" #: ../src/guide/views/view-injections.md #, no-wrap msgid "New injections" -msgstr "" +msgstr "新建注入" #. type: Plain text #: ../src/guide/views/view-injections.md msgid "Start by defining a class that will implement the `Yiisoft\\Yii\\View\\Renderer\\CommonParametersInjectionInterface`. This class will be responsible for providing the parameters you want to inject into your view templates and layouts." -msgstr "" +msgstr "首先定义一个实现 `Yiisoft\\Yii\\View\\Renderer\\CommonParametersInjectionInterface` 接口的类。该类负责提供您希望注入到视图模板和布局中的参数。" #. type: Fenced code block (php) #: ../src/guide/views/view-injections.md @@ -102,7 +102,7 @@ msgstr "" #. type: Plain text #: ../src/guide/views/view-injections.md msgid "Add your new Injection to `params.php`:" -msgstr "" +msgstr "将新建的注入类添加到 `params.php`:" #. type: Fenced code block (php) #: ../src/guide/views/view-injections.md @@ -120,17 +120,17 @@ msgstr "" #: ../src/guide/views/view-injections.md #, no-wrap msgid "Using Separate Injections for Different Layouts" -msgstr "" +msgstr "为不同布局使用独立注入" #. type: Plain text #: ../src/guide/views/view-injections.md msgid "If your application has multiple layouts, you can create separate parameter injections for each layout. This approach allows you to tailor the parameters injected into each layout according to its specific needs, enhancing the flexibility and maintainability of your application." -msgstr "" +msgstr "如果您的应用程序有多个布局,可以为每个布局创建独立的参数注入类。这种方式允许您根据每个布局的具体需求定制注入的参数,从而提高应用程序的灵活性和可维护性。" #. type: Plain text #: ../src/guide/views/view-injections.md msgid "Create your custom ViewInjection for a specific layout:" -msgstr "" +msgstr "为特定布局创建自定义视图注入类:" #. type: Fenced code block (php) #: ../src/guide/views/view-injections.md @@ -154,7 +154,7 @@ msgstr "" #. type: Plain text #: ../src/guide/views/view-injections.md msgid "Add your new injection to `params.php` under specific layout name. In the following example, it's `@layout/cart`:" -msgstr "" +msgstr "在 `params.php` 中,将新建的注入类添加到指定布局名称下。以下示例中布局名称为 `@layout/cart`:" #. type: Fenced code block (php) #: ../src/guide/views/view-injections.md diff --git a/_translations/po/zh-CN/guide_views_view.md.po b/_translations/po/zh-CN/guide_views_view.md.po index d5951e07..879a6806 100644 --- a/_translations/po/zh-CN/guide_views_view.md.po +++ b/_translations/po/zh-CN/guide_views_view.md.po @@ -29,7 +29,7 @@ msgstr "安装" #: ../src/guide/index.md ../src/guide/views/view.md #, no-wrap msgid "Views" -msgstr "" +msgstr "视图" #. type: Fenced code block (php) #: ../src/guide/start/hello.md ../src/guide/views/view.md @@ -80,7 +80,7 @@ msgstr "" #: ../src/guide/views/widget.md #, no-wrap msgid "Basic Concepts" -msgstr "" +msgstr "基本概念" #. type: Fenced code block (sh) #: ../src/guide/views/view-injections.md ../src/guide/views/view.md @@ -91,7 +91,7 @@ msgstr "" #. type: Plain text #: ../src/guide/views/view.md msgid "View is responsible for presenting data to end users. You give it a template with some placeholders and presentation logic and some data. The view is passing data to the template executing template logic. The end result is ready to be passed to end user, be it a browser, a file to download, an email to send or something else." -msgstr "" +msgstr "视图负责向最终用户呈现数据。您为其提供一个包含一些占位符、表示逻辑和数据的模板。视图将数据传递给模板,执行模板逻辑。最终结果准备好传递给最终用户,无论是浏览器、要下载的文件、要发送的电子邮件还是其他内容。" #. type: Fenced code block (mermaid) #: ../src/guide/views/view.md @@ -107,12 +107,12 @@ msgstr "" #. type: Plain text #: ../src/guide/views/view.md msgid "In Yii3 views are typically PHP files that contain presentation logic and HTML markup. The view system provides a flexible way to organize your presentation layer and supports features like layouts and partial views. Instead of using plain PHP templates, you can leverage one of the template engines such as [Twig](template-engines.md) or [Blade](https://github.com/lee-to/yii-blade)." -msgstr "" +msgstr "在 Yii3 中,视图通常是包含表示逻辑和 HTML 标记的 PHP 文件。视图系统提供了一种灵活的方式来组织您的表示层,并支持布局和局部视图等功能。除了使用纯 PHP 模板,您还可以利用模板引擎,例如 [Twig](template-engines.md) 或 [Blade](https://github.com/lee-to/yii-blade)。" #. type: Plain text #: ../src/guide/views/view.md msgid "For basic view functionality, you need the `yiisoft/view` package:" -msgstr "" +msgstr "对于基本的视图功能,您需要 `yiisoft/view` 包:" #. type: Fenced code block (sh) #: ../src/guide/views/view.md @@ -123,38 +123,38 @@ msgstr "" #. type: Plain text #: ../src/guide/views/view.md msgid "For web applications, you should also install the `yiisoft/yii-view-renderer` package which provides [PSR-7](https://www.php-fig.org/psr/psr-7/) compatibility and web-specific features:" -msgstr "" +msgstr "对于 Web 应用程序,您还应该安装 `yiisoft/yii-view-renderer` 包,它提供 [PSR-7](https://www.php-fig.org/psr/psr-7/) 兼容性和 Web 特定功能:" #. type: Plain text #: ../src/guide/views/view.md ../src/guide/views/widget.md msgid "These packages are included by default in the `yiisoft/app` application template." -msgstr "" +msgstr "这些包默认包含在 `yiisoft/app` 应用程序模板中。" #. type: Plain text #: ../src/guide/views/view.md msgid "A view template file contains presentation logic. In the `yiisoft/app` template, view files are typically stored alongside their controllers (e.g., `src/Web/Echo/Action.php`). Here's a simple view file example, `src/Web/Echo/template.php`:" -msgstr "" +msgstr "视图模板文件包含表示逻辑。在 `yiisoft/app` 模板中,视图文件通常与它们的控制器存储在一起(例如,`src/Web/Echo/Action.php`)。这是一个简单的视图文件示例,`src/Web/Echo/template.php`:" #. type: Plain text #: ../src/guide/views/view.md msgid "Here `$message` is a view data that is passed when you render a template with the help of `WebViewRenderer`. For example, `src/Web/Echo/Action.php`:" -msgstr "" +msgstr "这里 `$message` 是通过 `WebViewRenderer` 渲染模板时传递的视图数据。例如,`src/Web/Echo/Action.php`:" #. type: Plain text #: ../src/guide/views/view.md msgid "First argument of the `render()` method is a path to the template file. In the `yiisoft/app`, template files are typically stored alongside their actions. The result is ready to be rendered to the browser so we return it immediately." -msgstr "" +msgstr "`render()` 方法的第一个参数是模板文件的路径。在 `yiisoft/app` 中,模板文件通常与其操作一起存储。结果已准备好渲染到浏览器,因此我们立即返回它。" #. type: Title ## #: ../src/guide/views/view.md #, no-wrap msgid "Working with layouts" -msgstr "" +msgstr "使用布局" #. type: Plain text #: ../src/guide/views/view.md msgid "Most web applications use a common layout for all pages. In the `yiisoft/app` template, layouts are stored in `src/Web/Shared/Layout/Main/` directory. You can set a default layout in `config/common/params.php`:" -msgstr "" +msgstr "大多数 Web 应用程序为所有页面使用通用布局。在 `yiisoft/app` 模板中,布局存储在 `src/Web/Shared/Layout/Main/` 目录中。您可以在 `config/common/params.php` 中设置默认布局:" #. type: Fenced code block (php) #: ../src/guide/views/view.md @@ -171,7 +171,7 @@ msgstr "" #. type: Plain text #: ../src/guide/views/view.md msgid "A typical layout file such as `src/Web/Shared/Layout/Main/layout.php` looks like this:" -msgstr "" +msgstr "典型的布局文件,例如 `src/Web/Shared/Layout/Main/layout.php`,如下所示:" #. type: Fenced code block (php) #: ../src/guide/views/view.md @@ -240,17 +240,17 @@ msgstr "" #. type: Plain text #: ../src/guide/views/view.md msgid "In the template above `$applicationParams` is an array of parameters from `config/common/application.php`." -msgstr "" +msgstr "在上面的模板中,`$applicationParams` 是来自 `config/common/application.php` 的参数数组。" #. type: Plain text #: ../src/guide/views/view.md msgid "`$aliases` refers to [aliases component](../concept/aliases.md) that is used to get the base URL of the application at the server for URLs." -msgstr "" +msgstr "`$aliases` 指的是[别名组件](../concept/aliases.md),用于获取服务器上应用程序的基础 URL。" #. type: Plain text #: ../src/guide/views/view.md msgid "`$this` is an instance of the view that we use to get page title and output assets. Both standard and custom." -msgstr "" +msgstr "`$this` 是视图的实例,我们用它来获取页面标题和输出资源,包括标准的和自定义的。" #. type: Plain text #: ../src/guide/views/view.md @@ -260,6 +260,9 @@ msgid "" "automatically copied to `public/assets` on first use. It is not very useful for a single CSS file but becomes handy as\n" "the number of assets grows.\n" msgstr "" +"使用 `$assetManager->register(MainAsset::class);` 我们注册一个资源,定义要包含在页面中的 `css`。它在\n" +"首次使用时会自动复制到 `public/assets`。对于单个 CSS 文件来说用处不大,但随着\n" +"资源数量的增加,它会变得很方便。\n" #. type: Plain text #: ../src/guide/views/view.md @@ -269,22 +272,25 @@ msgid "" "> No output in plain PHP templates is encoded you should not forget to use `Html::encode()` to prevent\n" "XSS security vulnerabilities.\n" msgstr "" +"> [!IMPORTANT]\n" +"> 纯 PHP 模板中的输出不会被编码,您不应忘记使用 `Html::encode()` 来防止\n" +"XSS 安全漏洞。\n" #. type: Plain text #: ../src/guide/views/view.md msgid "More about what's available in layout could be read in [yiisoft/view](https://github.com/yiisoft/view) documentation." -msgstr "" +msgstr "更多关于布局中可用内容的信息可以在 [yiisoft/view](https://github.com/yiisoft/view) 文档中阅读。" #. type: Title ### #: ../src/guide/views/view.md #, no-wrap msgid "Rendering without layout" -msgstr "" +msgstr "不使用布局渲染" #. type: Plain text #: ../src/guide/views/view.md msgid "Sometimes you need to render a view without a layout (for example, for AJAX responses):" -msgstr "" +msgstr "有时您需要渲染没有布局的视图(例如,对于 AJAX 响应):" #. type: Fenced code block (php) #: ../src/guide/views/view.md @@ -308,19 +314,19 @@ msgstr "" #: ../src/guide/views/view.md #, no-wrap msgid "Nested Views and Partials" -msgstr "" +msgstr "嵌套视图和局部视图" #. type: Title ### #: ../src/guide/views/view.md #, no-wrap msgid "Rendering Sub-views" -msgstr "" +msgstr "渲染子视图" #. type: Plain text #: ../src/guide/views/view.md #, no-wrap msgid "You can render other views from within a view using the `$this->render()` method:\n" -msgstr "" +msgstr "您可以使用 `$this->render()` 方法从视图中渲染其他视图:\n" #. type: Fenced code block (php) #: ../src/guide/views/view.md @@ -374,12 +380,12 @@ msgstr "" #: ../src/guide/views/view.md #, no-wrap msgid "Using Blocks" -msgstr "" +msgstr "使用块" #. type: Plain text #: ../src/guide/views/view.md msgid "Blocks allow you to define content in one view and display it in another, typically in layouts:" -msgstr "" +msgstr "块允许您在一个视图中定义内容,并在另一个视图(通常是布局)中显示它:" #. type: Fenced code block (php) #: ../src/guide/views/view.md @@ -398,12 +404,12 @@ msgstr "" #: ../src/guide/views/view.md #, no-wrap msgid "Rendering as String" -msgstr "" +msgstr "渲染为字符串" #. type: Plain text #: ../src/guide/views/view.md msgid "If you need the rendered content as a string instead of a PSR-7 response:" -msgstr "" +msgstr "如果您需要将渲染内容作为字符串而不是 PSR-7 响应:" #. type: Fenced code block (php) #: ../src/guide/views/view.md @@ -421,12 +427,12 @@ msgstr "" #: ../src/guide/views/view.md #, no-wrap msgid "View Events" -msgstr "" +msgstr "视图事件" #. type: Plain text #: ../src/guide/views/view.md msgid "The view system triggers events during the rendering process that you can listen to:" -msgstr "" +msgstr "视图系统在渲染过程中触发您可以监听的事件:" #. type: Fenced code block (php) #: ../src/guide/views/view.md diff --git a/_translations/po/zh-CN/guide_views_widget.md.po b/_translations/po/zh-CN/guide_views_widget.md.po index bd967c86..3217531b 100644 --- a/_translations/po/zh-CN/guide_views_widget.md.po +++ b/_translations/po/zh-CN/guide_views_widget.md.po @@ -30,28 +30,28 @@ msgstr "安装" #: ../src/guide/views/widget.md #, no-wrap msgid "Basic Concepts" -msgstr "" +msgstr "基本概念" #. type: Plain text #: ../src/guide/views/view.md ../src/guide/views/widget.md msgid "These packages are included by default in the `yiisoft/app` application template." -msgstr "" +msgstr "这些包默认包含在 `yiisoft/app` 应用程序模板中。" #. type: Title # #: ../src/guide/views/widget.md #, no-wrap msgid "Widgets" -msgstr "" +msgstr "小部件" #. type: Plain text #: ../src/guide/views/widget.md msgid "Widgets are reusable, self-contained components that encapsulate complex HTML generation logic. They provide a clean way to create configurable UI elements that can be used across different views and applications. Yii3 provides a flexible widget system through the `yiisoft/widget` package." -msgstr "" +msgstr "小部件是可重用的独立组件,封装了复杂的 HTML 生成逻辑。它们提供了一种简洁的方式来创建可配置的 UI 元素,可在不同的视图和应用程序中使用。Yii3 通过 `yiisoft/widget` 包提供了灵活的小部件系统。" #. type: Plain text #: ../src/guide/views/widget.md msgid "The widget functionality is provided by the `yiisoft/widget` package:" -msgstr "" +msgstr "小部件功能由 `yiisoft/widget` 包提供:" #. type: Fenced code block (bash) #: ../src/guide/views/widget.md @@ -62,7 +62,7 @@ msgstr "" #. type: Plain text #: ../src/guide/views/widget.md msgid "For ready-made widgets (like forms, navigation, etc.), you can also install:" -msgstr "" +msgstr "对于现成的小部件(如表单、导航等),您还可以安装:" #. type: Fenced code block (bash) #: ../src/guide/views/widget.md @@ -74,51 +74,51 @@ msgstr "" #: ../src/guide/views/widget.md #, no-wrap msgid "Widget Class" -msgstr "" +msgstr "小部件类" #. type: Plain text #: ../src/guide/views/widget.md msgid "A widget is a PHP class that extends the abstract `Widget` class and implements a `render()` method that returns HTML content as a string." -msgstr "" +msgstr "小部件是一个 PHP 类,继承自抽象的 `Widget` 类,并实现一个返回 HTML 内容字符串的 `render()` 方法。" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Widget Factory" -msgstr "" +msgstr "小部件工厂" #. type: Plain text #: ../src/guide/views/widget.md msgid "The `WidgetFactory` is responsible for creating widget instances and can inject dependencies through the DI container." -msgstr "" +msgstr "`WidgetFactory` 负责创建小部件实例,并可以通过 DI 容器注入依赖。" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Widget Configuration" -msgstr "" +msgstr "小部件配置" #. type: Plain text #: ../src/guide/views/widget.md msgid "Widgets can be configured with properties and methods, making them highly customizable and reusable across different contexts." -msgstr "" +msgstr "小部件可以通过属性和方法进行配置,使其在不同上下文中具有高度可定制性和可重用性。" #. type: Title ## #: ../src/guide/views/widget.md #, no-wrap msgid "Creating Custom Widgets" -msgstr "" +msgstr "创建自定义小部件" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Simple Widget" -msgstr "" +msgstr "简单小部件" #. type: Plain text #: ../src/guide/views/widget.md msgid "Here's a basic widget that displays an alert message:" -msgstr "" +msgstr "以下是一个显示警告消息的基础小部件:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -191,7 +191,7 @@ msgstr "" #: ../src/guide/views/widget.md #, no-wrap msgid "Using the Widget" -msgstr "" +msgstr "使用小部件" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -224,12 +224,12 @@ msgstr "" #: ../src/guide/views/widget.md #, no-wrap msgid "Widget with Dependencies" -msgstr "" +msgstr "带依赖的小部件" #. type: Plain text #: ../src/guide/views/widget.md msgid "Widgets can use dependency injection for services:" -msgstr "" +msgstr "小部件可以通过依赖注入使用服务:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -306,24 +306,24 @@ msgstr "" #: ../src/guide/views/widget.md #, no-wrap msgid "Widget Factory Setup" -msgstr "" +msgstr "小部件工厂设置" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Bootstrap Configuration" -msgstr "" +msgstr "启动配置" #. type: Plain text #: ../src/guide/views/widget.md msgid "Initialize the widget factory in your application bootstrap:" -msgstr "" +msgstr "在应用程序启动时初始化小部件工厂:" #. type: Plain text #: ../src/guide/views/widget.md #, no-wrap msgid "**config/bootstrap.php**\n" -msgstr "" +msgstr "**config/bootstrap.php**\n" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -357,13 +357,13 @@ msgstr "" #: ../src/guide/views/widget.md #, no-wrap msgid "DI Container Configuration" -msgstr "" +msgstr "DI 容器配置" #. type: Plain text #: ../src/guide/views/widget.md #, no-wrap msgid "**config/web/di.php**\n" -msgstr "" +msgstr "**config/web/di.php**\n" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -387,18 +387,18 @@ msgstr "" #: ../src/guide/views/widget.md #, no-wrap msgid "Advanced Widget Examples" -msgstr "" +msgstr "高级小部件示例" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Data List Widget" -msgstr "" +msgstr "数据列表小部件" #. type: Plain text #: ../src/guide/views/widget.md msgid "A widget that displays a list of items with pagination:" -msgstr "" +msgstr "一个带分页显示条目列表的小部件:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -486,7 +486,7 @@ msgstr "" #. type: Plain text #: ../src/guide/views/widget.md msgid "Usage:" -msgstr "" +msgstr "用法:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -514,12 +514,12 @@ msgstr "" #: ../src/guide/views/widget.md #, no-wrap msgid "Form Widget" -msgstr "" +msgstr "表单小部件" #. type: Plain text #: ../src/guide/views/widget.md msgid "A widget that simplifies form rendering:" -msgstr "" +msgstr "一个简化表单渲染的小部件:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -627,12 +627,12 @@ msgstr "" #: ../src/guide/views/widget.md #, no-wrap msgid "Breadcrumb Widget" -msgstr "" +msgstr "面包屑小部件" #. type: Plain text #: ../src/guide/views/widget.md msgid "A widget for navigation breadcrumbs:" -msgstr "" +msgstr "一个用于导航面包屑的小部件:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -721,18 +721,18 @@ msgstr "" #: ../src/guide/views/widget.md #, no-wrap msgid "Widget Best Practices" -msgstr "" +msgstr "小部件最佳实践" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Configuration Pattern" -msgstr "" +msgstr "配置模式" #. type: Plain text #: ../src/guide/views/widget.md msgid "Use immutable configuration methods:" -msgstr "" +msgstr "使用不可变的配置方法:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -750,12 +750,12 @@ msgstr "" #: ../src/guide/views/widget.md #, no-wrap msgid "Validation" -msgstr "" +msgstr "验证" #. type: Plain text #: ../src/guide/views/widget.md msgid "Validate widget configuration in the render method:" -msgstr "" +msgstr "在 render 方法中验证小部件配置:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -775,12 +775,12 @@ msgstr "" #: ../src/guide/views/widget.md #, no-wrap msgid "HTML Encoding" -msgstr "" +msgstr "HTML 编码" #. type: Plain text #: ../src/guide/views/widget.md msgid "Always encode user data:" -msgstr "" +msgstr "始终对用户数据进行编码:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -798,12 +798,12 @@ msgstr "" #: ../src/guide/views/widget.md #, no-wrap msgid "Asset Management" -msgstr "" +msgstr "资源管理" #. type: Plain text #: ../src/guide/views/widget.md msgid "Register widget-specific assets:" -msgstr "" +msgstr "注册小部件专用资源:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -840,12 +840,12 @@ msgstr "" #: ../src/guide/views/widget.md #, no-wrap msgid "Using Widgets in Layouts" -msgstr "" +msgstr "在布局中使用小部件" #. type: Plain text #: ../src/guide/views/widget.md msgid "Widgets are particularly useful in layouts for common UI elements:" -msgstr "" +msgstr "小部件在布局中对于常见 UI 元素特别有用:" #. type: Plain text #: ../src/guide/views/widget.md @@ -896,18 +896,18 @@ msgstr "" #: ../src/guide/views/widget.md #, no-wrap msgid "Testing Widgets" -msgstr "" +msgstr "测试小部件" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Unit Testing" -msgstr "" +msgstr "单元测试" #. type: Plain text #: ../src/guide/views/widget.md msgid "Test widget rendering logic:" -msgstr "" +msgstr "测试小部件的渲染逻辑:" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -950,13 +950,13 @@ msgstr "" #: ../src/guide/views/widget.md #, no-wrap msgid "Common Widget Patterns" -msgstr "" +msgstr "常见小部件模式" #. type: Title ### #: ../src/guide/views/widget.md #, no-wrap msgid "Conditional Rendering" -msgstr "" +msgstr "条件渲染" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -981,7 +981,7 @@ msgstr "" #: ../src/guide/views/widget.md #, no-wrap msgid "Template-based Rendering" -msgstr "" +msgstr "基于模板的渲染" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -1006,7 +1006,7 @@ msgstr "" #: ../src/guide/views/widget.md #, no-wrap msgid "Event Integration" -msgstr "" +msgstr "事件集成" #. type: Fenced code block (php) #: ../src/guide/views/widget.md @@ -1029,4 +1029,4 @@ msgstr "" #. type: Plain text #: ../src/guide/views/widget.md msgid "Widgets provide a powerful way to create reusable, configurable UI components in Yii3 applications. They help maintain clean separation of concerns and make your views more maintainable and testable." -msgstr "" +msgstr "小部件为在 Yii3 应用程序中创建可重用、可配置的 UI 组件提供了强大的方式。它们有助于保持清晰的关注点分离,使您的视图更易于维护和测试。" diff --git a/src/zh-CN/guide/caching/data.md b/src/zh-CN/guide/caching/data.md index 0b7d1a62..ef1f0590 100644 --- a/src/zh-CN/guide/caching/data.md +++ b/src/zh-CN/guide/caching/data.md @@ -1,18 +1,14 @@ -# Data caching +# 数据缓存 -Data caching is about storing some PHP variables in a cache and retrieving -them later from the cache. It's also the foundation for more advanced -caching features, such as [page caching](page.md). +数据缓存是将一些 PHP 变量存储在缓存中,然后稍后从缓存中检索它们。它也是更高级缓存功能(如 [页面缓存](page.md))的基础。 -To use cache, install [yiisoft/cache](https://github.com/yiisoft/cache) -package: +要使用缓存,请安装 [yiisoft/cache](https://github.com/yiisoft/cache) 包: ```shell composer require yiisoft/cache ``` -The following code is a typical usage pattern of data caching, where -`$cache` refers to a `Cache` instance from the package: +以下代码是数据缓存的典型使用模式,其中 `$cache` 引用包中的 `Cache` 实例: ```php public function getTopProducts(\Yiisoft\Cache\CacheInterface $cache): array @@ -29,92 +25,65 @@ public function getTopProducts(\Yiisoft\Cache\CacheInterface $cache): array } ``` -When cache has data associated with the `$key`, it returns the cached -value. Otherwise, it executes the passed anonymous function to calculate -the value to cache and return. - -If the anonymous function requires some data from the outer scope, you can -pass it with the `use` statement. - -## Cache handlers - -The cache service uses [PSR-16](https://www.php-fig.org/psr/psr-16/) -compatible cache handlers which represent various cache storages, such as -memory, files, and databases. - -Yii provides the following handlers: - -- `NullCache` — a cache placeholder which does no real caching. The purpose - of this handler is to simplify the code that needs to check the - availability of cache. For example, during development or if the server - doesn't have actual cache support, you may configure a cache service to - use this handler. When you enable actual cache support, you can switch to - using the corresponding cache handler. In both cases, you may use the - same code without extra checks. -- `ArrayCache` — provides caching for the current request only by storing - the values in an array. -- [APCu](https://github.com/yiisoft/cache-apcu) - uses a PHP - [APC](https://secure.php.net/manual/en/book.apc.php) extension. You can - consider this option as the fastest one when dealing with cache for a - centralized thick application (e.g., one server, no dedicated load - balancers, etc.). -- [Database](https://github.com/yiisoft/cache-db) — uses a database table to - store cached data. -- [File](https://github.com/yiisoft/cache-file) — uses standard files to - store cached data. This is particularly suitable to cache large chunks of - data, such as page content. -- [Memcached](https://github.com/yiisoft/cache-memcached) — uses a PHP +当缓存中有与 `$key` 关联的数据时,它返回缓存的值。否则,它执行传递的匿名函数来计算要缓存的值并返回。 + +如果匿名函数需要来自外部作用域的一些数据,您可以使用 `use` 语句传递它。 + +## 缓存处理器 + +缓存服务使用兼容 [PSR-16](https://www.php-fig.org/psr/psr-16/) +的缓存处理器,它们代表各种缓存存储,如内存、文件和数据库。 + +Yii 提供以下处理器: + +- `NullCache` — + 一个不进行实际缓存的缓存占位符。此处理器的目的是简化需要检查缓存可用性的代码。例如,在开发期间或服务器没有实际缓存支持时,您可以配置缓存服务使用此处理器。当您启用实际缓存支持时,可以切换到使用相应的缓存处理器。在这两种情况下,您都可以使用相同的代码而无需额外检查。 +- `ArrayCache` — 通过将值存储在数组中,仅为当前请求提供缓存。 +- [APCu](https://github.com/yiisoft/cache-apcu) - 使用 PHP + [APC](https://secure.php.net/manual/en/book.apc.php) + 扩展。在处理集中式厚应用程序(例如,单服务器,无专用负载均衡器等)的缓存时,您可以将此选项视为最快的选项。 +- [数据库](https://github.com/yiisoft/cache-db) — 使用数据库表存储缓存数据。 +- [文件](https://github.com/yiisoft/cache-file) — + 使用标准文件存储缓存数据。这特别适合缓存大块数据,如页面内容。 +- [Memcached](https://github.com/yiisoft/cache-memcached) — 使用 PHP [memcached](https://secure.php.net/manual/en/book.memcached.php) - extension. You can consider this option as the fastest one when dealing - with cache in a distributed application - (e.g., with several servers, load balancers, etc.) -- [Wincache](https://github.com/yiisoft/cache-wincache) — uses PHP [WinCache](https://iis.net/downloads/microsoft/wincache-extension) - ([see also](https://secure.php.net/manual/en/book.wincache.php)) extension. + 扩展。在分布式应用程序中处理缓存时,您可以将此选项视为最快的选项 + (例如,多个服务器、负载均衡器等) +- [Wincache](https://github.com/yiisoft/cache-wincache) — 使用 PHP [WinCache](https://iis.net/downloads/microsoft/wincache-extension) + ([另见](https://secure.php.net/manual/en/book.wincache.php))扩展。 -[You could find more handlers at -packagist.org](https://packagist.org/providers/psr/simple-cache-implementation). +[您可以在 packagist.org +找到更多处理器](https://packagist.org/providers/psr/simple-cache-implementation)。 > [!TIP] -> You may use different cache storage in the same application. A common strategy is: -> - To use memory-based cache storage to store small but constantly used data (e.g., statistics) -> - To use file-based or database-based cache storage to store big and less often used data (e.g., page content) +> 您可以在同一应用程序中使用不同的缓存存储。常见策略是: +> - 使用基于内存的缓存存储来存储小但经常使用的数据(例如,统计信息) +> - 使用基于文件或数据库的缓存存储来存储大且不常使用的数据(例如,页面内容) -Cache handlers are usually set up in a [dependency injection -container](../concept/di-container.md) so that they can be globally -configurable and accessible. +缓存处理器通常在[依赖注入容器](../concept/di-container.md)中设置,以便它们可以全局配置和访问。 -Because all cache handlers support the same set of APIs, you can swap the -underlying cache handler with a different one. You can do it by -reconfiguring the application without modifying the code that uses the -cache. +由于所有缓存处理器都支持相同的 API 集,您可以将底层缓存处理器替换为不同的处理器。您可以通过重新配置应用程序来实现,而无需修改使用缓存的代码。 -### Cache keys +### 缓存键 -A key uniquely identifies each data item stored in the cache. When you store -a data item, you have to specify a key for it. Later, when you retrieve the -data item, you should give the corresponding key. +键唯一标识存储在缓存中的每个数据项。当您存储数据项时,必须为其指定一个键。稍后,当您检索数据项时,应提供相应的键。 -You may use a string or an arbitrary value as a cache key. When a key isn't -a string, it will be automatically serialized into a string. +您可以使用字符串或任意值作为缓存键。当键不是字符串时,它将自动序列化为字符串。 -A common strategy of defining a cache key is to include all determining -factors in terms of an array. +定义缓存键的常见策略是将所有决定因素包含在数组中。 -When different applications use the same cache storage, you should specify a -unique cache key prefix for each application to avoid conflicts of cache -keys. You can do this by using `\Yiisoft\Cache\PrefixedCache` decorator: +当不同的应用程序使用相同的缓存存储时,您应该为每个应用程序指定唯一的缓存键前缀以避免缓存键冲突。您可以使用 +`\Yiisoft\Cache\PrefixedCache` 装饰器来实现: ```php $arrayCacheWithPrefix = new \Yiisoft\Cache\PrefixedCache(new \Yiisoft\Cache\ArrayCache(), 'myapp_'); $cache = new \Yiisoft\Cache\Cache($arrayCacheWithPrefix); ``` -### Cache expiration +### 缓存过期 -A data item stored in a cache will remain there forever unless it's removed -because of some caching policy enforcement. For example, caching space is -full and cache storage removes the oldest data. To change this behavior, -you can set a TTL parameter when calling a method to store a data item: +存储在缓存中的数据项将永久保留在那里,除非由于某些缓存策略强制执行而被删除。例如,缓存空间已满,缓存存储会删除最旧的数据。要更改此行为,您可以在调用方法存储数据项时设置 +TTL 参数: ```php $ttl = 3600; @@ -123,35 +92,27 @@ return getTopProductsFromDatabase($count); }, $ttl); ``` -The `$ttl` parameter indicates for how many seconds the data item can remain -valid in the cache. When you retrieve the data item, if it has passed the -expiration time, the method will execute the function and set the resulting -value into cache. +`$ttl` 参数指示数据项在缓存中可以保持有效的秒数。当您检索数据项时,如果已超过过期时间,该方法将执行函数并将结果值设置到缓存中。 -You may set the default TTL for the cache: +您可以为缓存设置默认 TTL: ```php $cache = new \Yiisoft\Cache\Cache($arrayCache, 60 * 60); // 1 hour ``` -Additionally, you can invalidate a cache key explicitly: +此外,您可以显式使缓存键失效: ```php $cache->remove($key); ``` -### Invalidation dependencies +### 失效依赖 -Besides the expiration setting, changes of the so-called **invalidation -dependencies** may also invalidate cached data item. For example, -`\Yiisoft\Cache\Dependency\FileDependency` represents the dependency of a -file's modification time. When this dependency changes, it means something -modifying the corresponding file. As a result, any outdated file content -found in the cache should invalidate. +除了过期设置外,所谓的**失效依赖**的更改也可能使缓存的数据项失效。例如,`\Yiisoft\Cache\Dependency\FileDependency` +表示文件修改时间的依赖关系。当此依赖关系发生变化时,意味着有东西修改了相应的文件。因此,在缓存中找到的任何过时的文件内容都应该失效。 -Cache dependencies are objects of `\Yiisoft\Cache\Dependency\Dependency` -descendant classes. When you store a data item in the cache, you can pass -along an associated cache dependency object. For example, +缓存依赖是 `\Yiisoft\Cache\Dependency\Dependency` +后代类的对象。当您在缓存中存储数据项时,可以传递关联的缓存依赖对象。例如, ```php /** @@ -169,38 +130,28 @@ $cache->getOrSet('item_42_total', $callable, 3600, new TagDependency('item_42')) TagDependency::invalidate($cache, 'item_42'); ``` -Below is a summary of the available cache dependencies: - -- `\Yiisoft\Cache\Dependency\ValueDependency`: invalidates the cache when - specified value changes. -- `\Yiisoft\Cache\Dependency\CallbackDependency`: invalidates the cache when - the result of the specified PHP callback is different. -- `\Yiisoft\Cache\Dependency\FileDependency`: invalidates the cache when the - file's last modification time is different. -- `\Yiisoft\Cache\Dependency\TagDependency`: associates a cached data item - with one or many tags. You may invalidate the cached data items with the - specified tag(s) by calling `TagDependency::invalidate()`. - -You may combine many dependencies using -`\Yiisoft\Cache\Dependency\AnyDependency` or -`\Yiisoft\Cache\Dependency\AllDependencies`. - -To implement your own dependency, extend from -`\Yiisoft\Cache\Dependency\Dependency`. - -### Cache stampede prevention - -[A cache stampede](https://en.wikipedia.org/wiki/Cache_stampede) is a type -of cascading failure that can occur when massively parallel computing -systems with caching mechanisms come under a high load. This behavior is -sometimes also called dog-piling. - -The `\Yiisoft\Cache\Cache` uses a built-in "Probably early expiration" -algorithm that prevents cache stampede. This algorithm randomly fakes a -cache miss for one user while others are still served the cached value. You -can control its behavior with the fifth optional parameter of `getOrSet()`, -which is a float value called `$beta`. By default, beta is `1.0`, which is -usually enough. The higher the value, the earlier cache will be re-created. +以下是可用缓存依赖的摘要: + +- `\Yiisoft\Cache\Dependency\ValueDependency`:当指定值更改时使缓存失效。 +- `\Yiisoft\Cache\Dependency\CallbackDependency`:当指定 PHP 回调的结果不同时使缓存失效。 +- `\Yiisoft\Cache\Dependency\FileDependency`:当文件的最后修改时间不同时使缓存失效。 +- `\Yiisoft\Cache\Dependency\TagDependency`:将缓存的数据项与一个或多个标签关联。您可以通过调用 + `TagDependency::invalidate()` 使具有指定标签的缓存数据项失效。 + +您可以使用 `\Yiisoft\Cache\Dependency\AnyDependency` 或 +`\Yiisoft\Cache\Dependency\AllDependencies` 组合多个依赖项。 + +要实现您自己的依赖项,请从 `\Yiisoft\Cache\Dependency\Dependency` 扩展。 + +### 缓存雪崩预防 + +[缓存雪崩](https://en.wikipedia.org/wiki/Cache_stampede)是一种级联故障,当具有缓存机制的大规模并行计算系统处于高负载时可能发生。这种行为有时也称为 +dog-piling。 + +`\Yiisoft\Cache\Cache` +使用内置的“可能提前过期”算法来防止缓存雪崩。该算法随机为一个用户伪造缓存未命中,而其他用户仍然获得缓存值。您可以使用 `getOrSet()` +的第五个可选参数来控制其行为,该参数是一个名为 `$beta` 的浮点值。默认情况下,beta 为 +`1.0`,这通常就足够了。值越高,缓存重新创建得越早。 ```php /** diff --git a/src/zh-CN/guide/caching/overview.md b/src/zh-CN/guide/caching/overview.md index 2e2d4845..a4273809 100644 --- a/src/zh-CN/guide/caching/overview.md +++ b/src/zh-CN/guide/caching/overview.md @@ -1,21 +1,13 @@ -# Caching +# 缓存 -Caching is an inexpensive and effective way to improve the performance of an -application. By storing relatively static data in cache and serving it from -cache when requested, the application saves the time that it otherwise would -require to generate the data from scratch every time. +缓存是提高应用程序性能的一种廉价而有效的方法。通过将相对静态的数据存储在缓存中,并在请求时从缓存中提供数据,应用程序节省了每次从头生成数据所需的时间。 -Caching can occur at different levels and places in an application. On the -server-side, at the lower level, cache may be used to store basic data, such -as a list of most recent article information fetched from the database; and -at the higher level, cache may be used to store fragments or whole of Web -pages, such as the rendering result of the most recent articles. On the -client-side, you may use HTTP caching to keep most recently visited page -content in the browser cache. +缓存可以在应用程序的不同级别和位置发生。在服务器端,在较低级别,缓存可用于存储基本数据,例如从数据库获取的最新文章信息列表;在较高级别,缓存可用于存储 +Web 页面的片段或整体,例如最新文章的渲染结果。在客户端,您可以使用 HTTP 缓存将最近访问的页面内容保存在浏览器缓存中。 -Yii supports all these caching mechanisms: +Yii 支持所有这些缓存机制: -* [Data caching](data.md) -* [Fragment caching](fragment.md) -* [Page caching](page.md) -* [HTTP caching](http.md) +* [数据缓存](data.md) +* [片段缓存](fragment.md) +* [页面缓存](page.md) +* [HTTP 缓存](http.md) diff --git a/src/zh-CN/guide/concept/aliases.md b/src/zh-CN/guide/concept/aliases.md index f683f630..2581818f 100644 --- a/src/zh-CN/guide/concept/aliases.md +++ b/src/zh-CN/guide/concept/aliases.md @@ -1,18 +1,14 @@ -# Aliases +# 别名 -You can use aliases to represent file paths or URLs so that you don't have -to hard-code absolute paths or URLs in your project. An alias must start -with the `@` character to be differentiated from normal file paths and -URLs. Alias defined without leading `@` will be prefixed with `@` character. +您可以使用别名来表示文件路径或 URL,这样您就不必在项目中硬编码绝对路径或 URL。别名必须以 `@` 字符开头,以便与普通文件路径和 URL +区分开来。定义时没有前导 `@` 的别名将自动添加 `@` 字符前缀。 -Default Yii application has some aliases pre-defined in -`config/params.php`. For example, the alias `@public` represents the web -root path; `@baseUrl` represents the base URL for the currently running Web -application. +默认的 Yii 应用程序在 `config/params.php` 中预定义了一些别名。例如,别名 `@public` 表示 Web +根路径;`@baseUrl` 表示当前运行的 Web 应用程序的基础 URL。 -## Defining aliases +## 定义别名 -You can define an alias via application's `config/params.php`: +您可以通过应用程序的 `config/params.php` 定义别名: ```php return [ @@ -36,21 +32,20 @@ return [ ``` > [!NOTE] -> The file path or URL being aliased may *not* necessarily refer to an existing file or resource. +> 被别名化的文件路径或 URL *不一定*指向现有的文件或资源。 -Given a defined alias, you may derive a new alias by appending a slash `/` -followed with one or more path segments. For example, `@foo` is a root -alias, while `@foo/bar/file.php` is a derived alias. +给定一个已定义的别名,您可以通过附加斜杠 `/` 后跟一个或多个路径段来派生新别名。例如,`@foo` 是根别名,而 +`@foo/bar/file.php` 是派生别名。 -You can define an alias using another alias (either root or derived): +您可以使用另一个别名(根别名或派生别名)来定义别名: ```php '@foobar' => '@foo/bar', ``` -The `yiisoft/aliases` parameter initializes `Aliases` service from -[`yiisoft/aliases`](https://github.com/yiisoft/aliases) package. You can -set extra aliases in runtime by using the service: +`yiisoft/aliases` 参数从 +[`yiisoft/aliases`](https://github.com/yiisoft/aliases) 包初始化 `Aliases` +服务。您可以在运行时使用该服务设置额外的别名: ```php use \Yiisoft\Aliases\Aliases; @@ -61,10 +56,9 @@ public function actionIndex(Aliases $aliases) } ``` -## Using aliases in configuration +## 在配置中使用别名 -It's preferred to resolve aliases at the configuration level, so services -get URLs and paths as ready to use strings: +最好在配置级别解析别名,这样服务就可以获得可直接使用的 URL 和路径字符串: ```php +## 解析别名 -You can use `Aliases` service to resolve an alias or derived alias into the -file path or URL it represents: +您可以使用 `Aliases` 服务将别名或派生别名解析为它所代表的文件路径或 URL: ```php use \Yiisoft\Aliases\Aliases; @@ -99,16 +92,13 @@ public function actionIndex(Aliases $aliases) } ``` -The path/URL represented by a derived alias is determined by replacing the -root alias part with its corresponding path/URL in the derived alias. +派生别名所代表的 path/URL 是通过将派生别名中的根别名部分替换为其对应的 path/URL 来确定的。 > [!NOTE] -> The `get()` method doesn't check whether the resulting path/URL refers to an existing file or resource. +> `get()` 方法不检查结果 path/URL 是否指向现有的文件或资源。 -A root alias may also contain slash `/` characters. The `get()` method is -intelligent enough to tell, which part of an alias is a root alias and thus -correctly determines the corresponding file path or URL: +根别名也可以包含斜杠 `/` 字符。`get()` 方法足够智能,可以判断别名的哪一部分是根别名,从而正确确定相应的文件路径或 URL: ```php use \Yiisoft\Aliases\Aliases; @@ -123,27 +113,22 @@ public function actionIndex(Aliases $aliases) } ``` -If `@foo/bar` isn't defined as a root alias, the last statement would -display `/path/to/foo/bar/file.php`. - - -## Predefined aliases - -[Yii application](https://github.com/yiisoft/app) predefines a set of -aliases to reference commonly used file paths and URLs: - -- `@root` - the base directory of the currently running application. -- `@assets` - application's public directory where it publishes assets. -- `@assetsUrl` - URL of base directory with published assets. -- `@baseUrl` - the base URL of the currently running Web - application. Defaults to `/`. -- `@npm` - node packages directory. -- `@bower` - bower packages directory. -- `@vendor` - Composer's `vendor` directory. -- `@public` - application's publicly accessible directory that with - `index.php`. -- `@runtime` - the runtime path of the currently running - application. Defaults to `@root/runtime`. -- `@layout` - the directory with layouts. -- `@resources` - directory with views, asset sources and other resources. -- `@views` - application view templates base directory. +如果 `@foo/bar` 未定义为根别名,最后一条语句将显示 `/path/to/foo/bar/file.php`。 + + +## 预定义别名 + +[Yii 应用程序](https://github.com/yiisoft/app) 预定义了一组别名来引用常用的文件路径和 URL: + +- `@root` - 当前运行应用程序的基础目录。 +- `@assets` - 应用程序发布资源的公共目录。 +- `@assetsUrl` - 已发布资源的基础目录的 URL。 +- `@baseUrl` - 当前运行的 Web 应用程序的基础 URL。默认为 `/`。 +- `@npm` - node 包目录。 +- `@bower` - bower 包目录。 +- `@vendor` - Composer 的 `vendor` 目录。 +- `@public` - 应用程序的公共可访问目录,包含 `index.php`。 +- `@runtime` - 当前运行应用程序的运行时路径。默认为 `@root/runtime`。 +- `@layout` - 布局目录。 +- `@resources` - 包含视图、资源源文件和其他资源的目录。 +- `@views` - 应用程序视图模板基础目录。 diff --git a/src/zh-CN/guide/concept/autoloading.md b/src/zh-CN/guide/concept/autoloading.md index 2d1a232c..2c7d052d 100644 --- a/src/zh-CN/guide/concept/autoloading.md +++ b/src/zh-CN/guide/concept/autoloading.md @@ -1,15 +1,12 @@ -# Class autoloading +# 类自动加载 -Since Yii uses [Composer](https://getcomposer.org) to manage packages, it -automatically loads classes from these packages without the need to -`require` their file explicitly. When it installs packages, it generates a -[PSR-4 compatible autoloader](https://www.php-fig.org/psr/psr-4/). To use -it, `require_once` autoloader `/vendor/autoload.php` in your `index.php` -entry point file. +由于 Yii 使用 [Composer](https://getcomposer.org) 来管理包,它会自动从这些包中加载类,而无需显式 +`require` 它们的文件。当它安装包时,会生成一个 [兼容 PSR-4 +的自动加载器](https://www.php-fig.org/psr/psr-4/)。要使用它,请在您的 `index.php` 入口文件中 +`require_once` 自动加载器 `/vendor/autoload.php`。 -You can use autoloader not only for the packages installed, but for your -application as well since it's also a package. To load classes of a certain -namespace, add the following to `composer.json`: +您不仅可以为已安装的包使用自动加载器,还可以为您的应用程序使用,因为它也是一个包。要加载特定命名空间的类,请将以下内容添加到 +`composer.json`: ```json { @@ -21,17 +18,14 @@ namespace, add the following to `composer.json`: } ``` -Where `App\\` is a root namespace and `src/` is a directory where you have -your classes. You can add more source roots if needed. When done, execute -`composer dump-autoload` or simply `composer du` and classes from the -corresponding namespaces will start loading automatically. +其中 `App\\` 是根命名空间,`src/` 是您放置类的目录。如果需要,您可以添加更多源根目录。完成后,执行 `composer +dump-autoload` 或简单地执行 `composer du`,相应命名空间的类将开始自动加载。 -If you need development-environment-specific autoloading that isn't used -when executing Composer with `--no-dev` flag, add it to `autoload-dev` -section instead of `autoload`. +如果您需要开发环境特定的自动加载,在使用 `--no-dev` 标志执行 Composer 时不使用,请将其添加到 `autoload-dev` +部分而不是 `autoload`。 ## 参考资料 -- [PSR-4: Autoloader](https://www.php-fig.org/psr/psr-4/). -- [Composer guide on - autoloading](https://getcomposer.org/doc/01-basic-usage.md#autoloading). +- [PSR-4: 自动加载器](https://www.php-fig.org/psr/psr-4/)。 +- [Composer + 自动加载指南](https://getcomposer.org/doc/01-basic-usage.md#autoloading)。 diff --git a/src/zh-CN/guide/concept/configuration.md b/src/zh-CN/guide/concept/configuration.md index 1332715e..81293867 100644 --- a/src/zh-CN/guide/concept/configuration.md +++ b/src/zh-CN/guide/concept/configuration.md @@ -1,28 +1,21 @@ # 配置 -There are many ways to configure your application. We will focus on concepts -used in the [default project template](https://github.com/yiisoft/app). +有很多方法可以配置您的应用程序。我们将重点关注 [默认项目模板](https://github.com/yiisoft/app) 中使用的概念。 -Yii3 configs are part of the application. You can change many aspects of how -the application works by editing configuration under `config/`. +Yii3 配置是应用程序的一部分。您可以通过编辑 `config/` 下的配置来更改应用程序工作方式的许多方面。 -## Config plugin +## 配置插件 -In the application template -[yiisoft/config](https://github.com/yiisoft/config) is used. Since writing -all application configurations from scratch is a tedious process, many -packages offer default configs, and the plugin helps with copying these into -the application. +在应用程序模板中使用了 +[yiisoft/config](https://github.com/yiisoft/config)。由于从头开始编写所有应用程序配置是一个繁琐的过程,许多包提供默认配置,插件帮助将这些配置复制到应用程序中。 -To offer default configs, `composer.json` of the package has to have -`config-plugin` section. When installing or updating packages with -Composer, the plugin reads `config-plugin` sections for each dependency, -copies files themselves to application `config/packages/` if they don't yet -exist and writes a merge plan to `config/packages/merge_plan.php`. The merge -plan defines how to merge the configs into a single big array ready to be -passed to [DI container](di-container.md). +要提供默认配置,包的 `composer.json` 必须有 `config-plugin` 部分。在使用 Composer +安装或更新包时,插件会读取每个依赖项的 `config-plugin` 部分,如果文件尚不存在,则将文件本身复制到应用程序 +`config/packages/`,并将合并计划写入 +`config/packages/merge_plan.php`。合并计划定义了如何将配置合并到一个准备传递给 [DI +容器](di-container.md) 的大数组中。 -Take a look at what's in the "yiisoft/app" `composer.json` by default: +看看默认情况下 "yiisoft/app" `composer.json` 中有什么: ```json "config-plugin-options": { @@ -64,32 +57,25 @@ Take a look at what's in the "yiisoft/app" `composer.json` by default: }, ``` -There are many named configs defined. For each name, there is a -configuration. +定义了许多命名配置。对于每个名称,都有一个配置。 -A string means that the plugin takes config as is and merges it with -same-named configs from packages you require. That happens if these -packages have `config-plugin` in their `composer.json`. +字符串意味着插件按原样获取配置并将其与您需要的包中的同名配置合并。如果这些包的 `composer.json` 中有 +`config-plugin`,就会发生这种情况。 -The array means that the plugin will merge many files in the order they're -specified. +数组意味着插件将按指定的顺序合并多个文件。 -`?` at the beginning of the file path indicated that the file may be -absent. In this case, it's skipped. +文件路径开头的 `?` 表示文件可能不存在。在这种情况下,它会被跳过。 -`$` at the beginning of the name means a reference to another named config. +名称开头的 `$` 表示对另一个命名配置的引用。 -`params` is a bit special because it's reserved for application -parameters. These are automatically available as `$params` in all other -configuration files. +`params` 有点特殊,因为它是为应用程序参数保留的。这些参数在所有其他配置文件中自动作为 `$params` 可用。 -You can learn more about config plugin features [from its -documentation](https://github.com/yiisoft/config/blob/master/README.md). +您可以 [从其文档](https://github.com/yiisoft/config/blob/master/README.md) +中了解有关配置插件功能的更多信息。 -## Config files +## 配置文件 -Now, as you know how the plugin assembles configs, look at `config` -directory: +现在,当您知道插件如何组装配置时,请查看 `config` 目录: ``` common/ @@ -116,12 +102,9 @@ routes.php ### 容器配置 -The application consists of a set of services registered in a [dependency -container](di-container.md). The config files that responsible for direct -dependency container configuration are under `common/`, `console/` and -`web/` directories. We use `web/` for config specific to web application -and `console/` for config specific to console commands. Both web and console -are sharing configuration under `common/`. +应用程序由在 [依赖容器](di-container.md) 中注册的一组服务组成。负责直接依赖容器配置的配置文件位于 +`common/`、`console/` 和 `web/` 目录下。我们使用 `web/` 用于特定于 Web 应用程序的配置,使用 +`console/` 用于特定于控制台命令的配置。Web 和控制台都共享 `common/` 下的配置。 ```php [!TIP] -> Don't use parameters, constants or environment variables directly in your application, configure -> services instead. +> 不要在应用程序中直接使用参数、常量或环境变量,而是配置 +> 服务。 -Default application `params.php` looks like the following: +默认应用程序 `params.php` 如下所示: ```php +## 依赖注入 -There are two ways of re-using things in OOP: inheritance and composition. +在面向对象编程中,有两种重用代码的方式:继承和组合。 -Inheritance is simple: +继承很简单: ```php class Cache @@ -28,10 +28,9 @@ final readonly class CachedWidget extends Cache } ``` -The issue here is that these two are becoming unnecessarily coupled or -inter-dependent, making them more fragile. +这里的问题是这两者变得不必要地耦合或相互依赖,使它们更加脆弱。 -Another way to handle this is composition: +另一种处理方式是组合: ```php interface CacheInterface @@ -66,86 +65,60 @@ final readonly class CachedWidget } ``` -We've avoided unnecessary inheritance and used `CacheInterface` in the -`CacheWidget` to reduce coupling. You can replace cache implementation -without changing `CachedWidget` so it's becoming more stable. The less edits -are made to the code, the less chance of breaking it. +我们避免了不必要的继承,并在 `CacheWidget` 中使用 `CacheInterface` 来减少耦合。您可以在不更改 +`CachedWidget` 的情况下替换缓存实现,因此它变得更加稳定。对代码的编辑越少,破坏它的机会就越小。 -The `CacheInterface` here is a dependency: a contract our object needs to -function. In other words, our object depends on the contract. +这里的 `CacheInterface` 是一个依赖:我们的对象需要运行的契约。换句话说,我们的对象依赖于这个契约。 -The process of putting an instance of a contract into an object -(`CachedWidget`) is called dependency injection. There are many ways to -perform it: +将契约的实例放入对象(`CachedWidget`)的过程称为依赖注入。有多种方式可以执行它: -- Constructor injection. Best for mandatory dependencies. -- Method injection. Best for optional dependencies. -- Property injection. Better to be avoided in PHP except maybe data transfer - objects. +- 构造函数注入。最适合强制性依赖。 +- 方法注入。最适合可选依赖。 +- 属性注入。在 PHP 中最好避免使用,除非可能是数据传输对象。 -### Why use private properties +### 为什么使用私有属性 -In the composition example above, note that the `$cache` property is -declared as `private`. +在上面的组合示例中,请注意 `$cache` 属性被声明为 `private`。 -This approach embraces composition by ensuring objects have well-defined -interfaces for interaction rather than direct property access, making the -code more maintainable and less prone to certain types of mistakes. +这种方法通过确保对象具有明确定义的交互接口而不是直接属性访问来拥抱组合,使代码更易于维护,并且不太容易出现某些类型的错误。 -This design choice provides several benefits: +这种设计选择提供了几个好处: -- **Encapsulation**: Private properties with getters/setters allow you to - control access and make future changes without breaking existing code. -- **Data integrity**: Setters can validate, normalize, or format values - before storing them, ensuring properties contain valid data. -- **Immutability**: Private properties enable immutable object patterns - where setter `with*()` methods return new instances rather than modifying - the current one. -- **Flexibility**: You can create read-only or write-only properties or add - additional logic to property access later. +- **封装**:带有 getter/setter 的私有属性允许您控制访问并在不破坏现有代码的情况下进行未来更改。 +- **数据完整性**:Setter 可以在存储值之前验证、规范化或格式化值,确保属性包含有效数据。 +- **不可变性**:私有属性启用不可变对象模式,其中 setter `with*()` 方法返回新实例而不是修改当前实例。 +- **灵活性**:您可以创建只读或只写属性,或稍后向属性访问添加额外的逻辑。 -## DI container +## DI 容器 -Injecting basic dependencies is straightforward. You're choosing a place -where you don't care about dependencies, which is usually an action handler, -which you aren't going to unit-test ever, create instances of dependencies -needed and pass these to dependent classes. +注入基本依赖很简单。您选择一个不关心依赖的地方,通常是一个操作处理器,您永远不会对其进行单元测试,创建所需依赖的实例并将这些传递给依赖类。 -It works well when there are few dependencies overall and when there are no -nested dependencies. When there are many and each dependency has -dependencies itself, instantiating the whole hierarchy becomes a tedious -process, which requires lots of code and may lead to hardly debuggable -mistakes. +当总体依赖很少且没有嵌套依赖时,它运行良好。当有很多依赖并且每个依赖本身都有依赖时,实例化整个层次结构变成一个繁琐的过程,需要大量代码,并可能导致难以调试的错误。 -Additionally, lots of dependencies, such as certain third-party API -wrappers, are the same for any class using it. So it makes sense to: +此外,许多依赖(例如某些第三方 API 包装器)对于使用它的任何类都是相同的。因此,有必要: -- Define how to instantiate such common dependencies. -- Instantiate them when required and only once per request. +- 定义如何实例化这些常见依赖。 +- 在需要时实例化它们,并且每个请求只实例化一次。 -That's what dependency containers are for. +这就是依赖容器的用途。 -A dependency injection (DI) container is an object that knows how to -instantiate and configure objects and all objects they depend on. +依赖注入(DI)容器是一个知道如何实例化和配置对象以及它们所依赖的所有对象的对象。 -Yii provides the DI container feature through the -[yiisoft/di](https://github.com/yiisoft/di) package and -[yiisoft/injector](https://github.com/yiisoft/injector) package. +Yii 通过 [yiisoft/di](https://github.com/yiisoft/di) 包和 +[yiisoft/injector](https://github.com/yiisoft/injector) 包提供 DI 容器功能。 > [!NOTE] -> The container contains only shared instances. If you need a factory, use the dedicated -> [yiisoft/factory](https://github.com/yiisoft/factory) package. +> 容器仅包含共享实例。如果您需要工厂,请使用专用的 +> [yiisoft/factory](https://github.com/yiisoft/factory) 包。 > [!TIP] -> [Martin Fowler's article](https://martinfowler.com/articles/injection.html) has well -> explained why DI container is useful. Here we will mainly explain the usage of the DI container provided by Yii. +> [Martin Fowler 的文章](https://martinfowler.com/articles/injection.html) 很好地 +> 解释了为什么 DI 容器有用。这里我们将主要解释 Yii 提供的 DI 容器的使用。 -### Configuring container +### 配置容器 -Because to create a new object you need its dependencies, you should -register them as early as possible. You can do it in the application -configuration, `config/web.php`. For the following service: +因为要创建新对象需要其依赖,所以您应该尽早注册它们。您可以在应用程序配置 `config/web.php` 中执行此操作。对于以下服务: ```php final class MyService implements MyServiceInterface @@ -161,7 +134,7 @@ final class MyService implements MyServiceInterface } ``` -configuration could be: +配置可以是: ```php return [ @@ -173,14 +146,14 @@ return [ ]; ``` -That's equal to the following: +这等同于以下内容: ```php $myService = new MyService(42); $myService->setDiscount(10); ``` -You can provide arguments with names as well: +您也可以提供带名称的参数: ```php return [ @@ -192,10 +165,7 @@ return [ ]; ``` -That's basically it. You define a map of interfaces to classes and define -how to configure them. When an interface is requested in constructor or -elsewhere, container creates an instance of a class and configures it as per -the configuration: +基本上就是这样。您定义接口到类的映射并定义如何配置它们。当在构造函数或其他地方请求接口时,容器会创建类的实例并根据配置对其进行配置: ```php final class MyAction @@ -212,11 +182,9 @@ final class MyAction } ``` -There are extra methods of declaring dependency configuration. +还有其他声明依赖配置的方法。 -For simplest cases where there are no custom values needed and all the -constructor dependencies could be obtained from a container, you can use a -class name as a value. +对于不需要自定义值且所有构造函数依赖都可以从容器获取的最简单情况,您可以使用类名作为值。 ```php interface EngineInterface @@ -231,8 +199,7 @@ final class EngineMarkOne implements EngineInterface } ``` -In the above example, if we already have cache defined in the container, -nothing besides the class name is needed: +在上面的示例中,如果我们已经在容器中定义了缓存,则除了类名之外不需要任何东西: ```php return [ @@ -241,8 +208,7 @@ return [ ]; ``` -If you have a dependency that has public properties, you can configure it as -well. +如果您有一个具有公共属性的依赖,您也可以配置它。 ```php @@ -252,7 +218,7 @@ final class NameProvider } ``` -Here's how to do it for the example above: +以下是上面示例的操作方法: ```php NameProvider::class => [ @@ -261,11 +227,9 @@ NameProvider::class => [ ], ``` -In this example, you may notice `NameProvider` specified twice. The key is -what you may request as dependency and the value is how to create it. +在此示例中,您可能会注意到 `NameProvider` 被指定了两次。键是您可以请求作为依赖的内容,值是如何创建它。 -If the configuration is tricky and requires some logic, a closure can be -used: +如果配置很复杂并需要一些逻辑,可以使用闭包: ```php MyServiceInterface::class => static function(ContainerInterface $container) { @@ -273,9 +237,7 @@ MyServiceInterface::class => static function(ContainerInterface $container) { }, ``` -Additionally, to `ContainerInterface`, you can request any registered -service directly as a closure parameter. The injector will automatically -resolve and inject these: +此外,除了 `ContainerInterface`,您还可以直接将任何已注册的服务作为闭包参数请求。注入器将自动解析并注入这些: ```php MyServiceInterface::class => static function(ConnectionInterface $db) { @@ -283,27 +245,24 @@ MyServiceInterface::class => static function(ConnectionInterface $db) { }, ``` -It's possible to use a static method call: +可以使用静态方法调用: ```php MyServiceInterface::class => [MyFactory::class, 'create'], ``` -Or an instance of an object: +或对象的实例: ```php MyServiceInterface::class => new MyService(), ``` -### Injecting dependencies properly +### 正确注入依赖 -Directly referencing a container in a class is a bad idea since the code -becomes non-generic, coupled to the container interface and, what's worse, -dependencies are becoming hidden. Because of that, Yii inverts the control -by automatically injecting objects from a container in some constructors and -methods based on method argument types. +在类中直接引用容器是一个坏主意,因为代码变得不通用,耦合到容器接口,更糟糕的是,依赖变得隐藏。因此,Yii +通过根据方法参数类型在某些构造函数和方法中自动从容器注入对象来反转控制。 -This is primarily done in constructor and handing method of action handlers: +这主要在操作处理器的构造函数和处理方法中完成: ```php use \Yiisoft\Cache\CacheInterface; @@ -330,17 +289,11 @@ final readonly class MyController } ``` -Since it's [yiisoft/injector](https://github.com/yiisoft/injector) that -instantiates and calls action handler, it checks the constructor and method -argument types, gets dependencies of these types from a container and passes -them as arguments. That's usually called auto-wiring. It happens for -sub-dependencies as well, that's if you don't give dependency explicitly, -the container would check if it has such a dependency first. It's enough to -declare a dependency you need, and it would be got from a container -automatically. +由于是 [yiisoft/injector](https://github.com/yiisoft/injector) +实例化并调用操作处理器,它会检查构造函数和方法参数类型,从容器中获取这些类型的依赖并将它们作为参数传递。这通常称为自动装配。它也适用于子依赖,也就是说,如果您没有显式提供依赖,容器会首先检查它是否有这样的依赖。只需声明您需要的依赖,它就会自动从容器中获取。 -## References +## 参考资料 -- [Inversion of Control Containers and the Dependency Injection pattern by - Martin Fowler](https://martinfowler.com/articles/injection.html) +- [Martin Fowler + 的控制反转容器和依赖注入模式](https://martinfowler.com/articles/injection.html) diff --git a/src/zh-CN/guide/concept/events.md b/src/zh-CN/guide/concept/events.md index a9a487bd..0cb7c628 100644 --- a/src/zh-CN/guide/concept/events.md +++ b/src/zh-CN/guide/concept/events.md @@ -1,33 +1,24 @@ # 事件 -Events allow you to make custom code executed at certain execution points -without modifying existing code. You can attach a custom code called -"handler" to an event so that when the event is triggered, the handler gets -executed automatically. - -For example, when a user is signed up, you need to send a welcome email. You -can do it right in the `SignupService` but then, when you additionally need -to resize user's avatar image, you'll have to change `SignupService` code -again. In other words, `SignupService` will be coupled to both code sending -welcome email and code resizing avatar image. +事件允许您在特定执行点执行自定义代码,而无需修改现有代码。您可以将称为“处理器”的自定义代码附加到事件,以便在触发事件时,处理器会自动执行。 + +例如,当用户注册时,您需要发送欢迎邮件。您可以直接在 `SignupService` 中执行此操作,但如果您还需要调整用户头像图片的大小,则必须再次更改 +`SignupService` 代码。换句话说,`SignupService` 将与发送欢迎邮件的代码和调整头像图片大小的代码耦合。 -To avoid it, instead of telling what do after signup explicitly you can, instead, raise `UserSignedUp` event -and then finish a signup process. The code sending an email and the code resizing avatar image will attach to the event - and, therefore, will be executed. If you'll ever need to do more on signup, you'll be able to attach extra event -handlers without modifying `SignupService`. +为避免这种情况,您可以触发 `UserSignedUp` 事件, +然后完成注册流程,而不是明确告知注册后要做什么。发送邮件的代码和调整头像图片大小的代码将附加到该事件, +因此,它们将被执行。如果您以后需要在注册时执行更多操作,您可以附加额外的事件 +处理器,而无需修改 `SignupService`。 -For raising events and attaching handlers to these events, Yii has a special -service called event dispatcher. It's available from -[yiisoft/event-dispatcher -package](https://github.com/yiisoft/event-dispatcher). +要触发事件并将处理器附加到这些事件,Yii 有一个称为事件调度器的特殊服务。它可以从 [yiisoft/event-dispatcher +包](https://github.com/yiisoft/event-dispatcher) 获取。 -## Event Handlers +## 事件处理器 -An event handler is [PHP -callable](https://www.php.net/manual/en/language.types.callable.php) that -gets executed when the event it's attached to is triggered. +事件处理器是 [PHP +callable](https://www.php.net/manual/en/language.types.callable.php),当它附加的事件被触发时执行。 -The signature of an event handler is: +事件处理器的签名是: ```php function (EventClass $event) { @@ -35,9 +26,9 @@ function (EventClass $event) { } ``` -## Attaching event handlers +## 附加事件处理器 -You can attach a handler to an event like the following: +您可以按如下方式将处理器附加到事件: ```php use Yiisoft\EventDispatcher\Provider\Provider; @@ -56,23 +47,19 @@ final readonly class WelcomeEmailSender } ``` -The `attach()` method is accepting a callback. Based on the type of this -callback argument, the event type is determined. +`attach()` 方法接受一个回调。根据此回调参数的类型,确定事件类型。 -## Event handlers order +## 事件处理器顺序 -You may attach one or more handlers to a single event. When an event is -triggered, the attached handlers will be called in the order that they were -attached to the event. In case an event implements -`Psr\EventDispatcher\StoppableEventInterface`, event handler can stop -executing the rest of the handlers that follow it if -`isPropagationStopped()` returns `true`. +您可以将一个或多个处理器附加到单个事件。当事件被触发时,附加的处理器将按照它们附加到事件的顺序被调用。如果事件实现了 +`Psr\EventDispatcher\StoppableEventInterface`,当 `isPropagationStopped()` 返回 +`true` 时,事件处理器可以停止执行其后的其余处理器。 -In general, it's better not to rely on the order of event handlers. +一般来说,最好不要依赖事件处理器的顺序。 -## Raising events +## 触发事件 -Events are raised like the following: +事件按如下方式触发: ```php use Psr\EventDispatcher\EventDispatcherInterface; @@ -95,10 +82,9 @@ final readonly class SignupService } ``` -First, you create an event supplying it with data that may be useful for -handlers. Then you dispatch the event. +首先,您创建一个事件,并为其提供可能对处理器有用的数据。然后您调度该事件。 -The event class itself may look like the following: +事件类本身可能如下所示: ```php final readonly class UserSignedUp @@ -111,11 +97,9 @@ final readonly class UserSignedUp } ``` -## Events hierarchy +## 事件层次结构 -Events don't have any name or wildcard matching on purpose. Event class -names and class/interface hierarchy and composition could be used to achieve -great flexibility: +事件故意没有任何名称或通配符匹配。事件类名称以及类/接口层次结构和组合可用于实现极大的灵活性: ```php interface DocumentEvent @@ -131,7 +115,7 @@ final readonly class AfterDocumentProcessed implements DocumentEvent } ``` -With the interface, you can listen to all document-related events: +使用接口,您可以监听所有与文档相关的事件: ```php @@ -140,16 +124,15 @@ $provider->attach(function (DocumentEvent $event) { }); ``` -## Detaching event handlers +## 分离事件处理器 -To detach a handler from an event you can call `detach()` method: +要从事件中分离处理器,您可以调用 `detach()` 方法: ```php $provider->detach(DocmentEvent::class); ``` -## Configuring application events +## 配置应用程序事件 -You usually assign event handlers via application config. See -["Configuration"](configuration.md) for details. +您通常通过应用程序配置来分配事件处理器。有关详细信息,请参阅 ["配置"](configuration.md)。 diff --git a/src/zh-CN/guide/concept/immutability.md b/src/zh-CN/guide/concept/immutability.md index 851b7e79..5e3e2102 100644 --- a/src/zh-CN/guide/concept/immutability.md +++ b/src/zh-CN/guide/concept/immutability.md @@ -1,13 +1,9 @@ # 不可变性 -Immutability means an object's state cannot change after it has been -created. Instead of modifying an instance, you create a new instance with -the desired changes. This approach is common for value objects such as -Money, IDs, and DTOs. It helps to avoid accidental side effects: methods -cannot silently change shared state, which makes code easier to reason -about. +不可变性是指对象在创建后其状态不能被改变。您不能修改一个已有实例,而是创建一个包含所需更改的新实例。这种方式常用于值对象,如 Money、ID 和 +DTO。它有助于避免意外的副作用:方法不能静默修改共享状态,从而使代码更易于理解。 -## Mutable pitfalls (what we avoid) +## 可变对象的陷阱(我们要避免的) ```php // A shared base query built once and reused: @@ -21,11 +17,9 @@ $list = $base->orderBy(['created_at' => SORT_DESC])->all(); // Oops: still limited to 1 because the previous limit(1) modified $base. ``` -## Creating an immutable object in PHP +## 在 PHP 中创建不可变对象 -There is no direct way to modify an instance, but you can use clone to -create a new instance with the desired changes. That is what `with*` -methods do. +PHP 中没有直接修改实例的方式,但可以使用 clone 创建一个包含所需更改的新实例。这正是 `with*` 方法的作用。 ```php final class Money @@ -102,24 +96,19 @@ $discounted = $price->withAmount(800); // $price is still 1000 USD, $discounted is 800 USD ``` -- We mark the class `final` to prevent subclass mutations; alternatively, - design for extension carefully. -- Validate in the constructor and `with*` methods so every instance is - always valid. +- 将类标记为 `final` 以防止子类修改状态;也可以谨慎地设计以支持扩展。 +- 在构造函数和 `with*` 方法中进行验证,确保每个实例始终处于有效状态。 > [!TIP] -> If you define a simple DTO, you can use modern PHP `readonly` and leave properties `public`. The `readonly` keyword -> would ensure that the properties cannot be modified after the object is created. +> 如果您定义的是简单的 DTO,可以使用现代 PHP 的 `readonly` 关键字并将属性设为 `public`。`readonly` 关键字 +> 可确保属性在对象创建后无法被修改。 -## Using clone (and why it is inexpensive) +## 使用 clone(以及为何开销低) -PHP's clone performs a shallow copy of the object. For immutable value -objects that contain only scalars or other immutable objects, shallow -cloning is enough and fast. In modern PHP, cloning small value objects is -inexpensive in both time and memory. +PHP 的 clone 对对象执行浅拷贝。对于只包含标量或其他不可变对象的不可变值对象,浅拷贝已经足够且速度很快。在现代 PHP +中,克隆小型值对象在时间和内存方面的开销都很低。 -If your object holds mutable sub-objects that must also be copied, implement -`__clone` to deep-clone them: +如果对象持有也需要复制的可变子对象,请实现 `__clone` 来对其进行深拷贝: ```php final class Order @@ -148,13 +137,9 @@ final class Order } ``` -## Usage style +## 使用风格 -- Build a value object once and pass it around. If you need a change, use a - `with*` method that returns a new instance. -- Prefer scalar/immutable fields inside immutable objects; if a field can - mutate, isolate it and deep-clone in `__clone` when needed. +- 一次性构建值对象并传递使用。如需更改,使用返回新实例的 `with*` 方法。 +- 不可变对象内部优先使用标量或不可变字段;如果某个字段可能发生变化,请将其隔离,并在需要时在 `__clone` 中对其进行深拷贝。 -Immutability aligns well with Yii's preference for predictable, -side-effect-free code and makes services, caching, and configuration more -robust. +不可变性与 Yii 对可预测、无副作用代码的偏好高度契合,能使服务、缓存和配置更加健壮。 diff --git a/src/zh-CN/guide/databases/db-migrations.md b/src/zh-CN/guide/databases/db-migrations.md index e4e67f51..0dd66451 100644 --- a/src/zh-CN/guide/databases/db-migrations.md +++ b/src/zh-CN/guide/databases/db-migrations.md @@ -1,75 +1,54 @@ -# Migrations - -During the course of developing and maintaining a database-driven -application, the structure of the database being used evolves just like the -source code does. For example, during the development of an application, a -new table may be found necessary; after the application is deployed to -production, it may be discovered that an index should be created to improve -the query performance; and so on. Because a database structure change often -requires some source code changes, Yii supports the so-called *database -migration* feature that allows you to keep track of database changes in -terms of *database migrations* which are version-controlled together with -the source code. - -The following steps show how database migration can be used by a team during -development: - -1. Tim creates a new migration (e.g. creates a new table, changes a column - definition, etc.). -2. Tim commits the new migration into the source control system (e.g. Git, - Mercurial). -3. Doug updates his repository from the source control system and receives - the new migration. -4. Doug applies the migration to his local development database, thereby - synchronizing his database to reflect the changes that Tim has made. - -And the following steps show how to deploy a new release with database -migrations to production: - -1. Scott creates a release tag for the project repository that contains some - new database migrations. -2. Scott updates the source code on the production server to the release - tag. -3. Scott applies any accumulated database migrations to the production - database. - -Yii provides a set of migration command line tools that allow you to: - -* create new migrations; -* apply migrations; -* revert migrations; -* re-apply migrations; -* show migration history and status. - -All these tools are accessible through the command `yii migrate`. In this -section we will describe in detail how to accomplish various tasks using -these tools. +# 数据库迁移 + +在开发和维护数据库驱动的应用程序过程中,所使用的数据库结构会像源代码一样不断演变。例如,在应用程序开发过程中,可能发现需要一张新表;在应用程序部署到生产环境后,可能发现应该创建一个索引来提高查询性能;等等。由于数据库结构变更通常需要相应的源代码变更,Yii +支持所谓的*数据库迁移*功能,允许您以*数据库迁移*的形式追踪数据库变更,这些迁移与源代码一起进行版本控制。 + +以下步骤展示了团队在开发过程中如何使用数据库迁移: + +1. Tim 创建一个新的迁移(例如创建一张新表、修改列定义等)。 +2. Tim 将新的迁移提交到源代码控制系统(例如 Git、Mercurial)。 +3. Doug 从源代码控制系统更新他的仓库,获取新的迁移。 +4. Doug 将迁移应用到他的本地开发数据库,从而将数据库同步以反映 Tim 所做的更改。 + +以下步骤展示了如何将带有数据库迁移的新版本部署到生产环境: + +1. Scott 为包含一些新数据库迁移的项目仓库创建一个发布标签。 +2. Scott 将生产服务器上的源代码更新到该发布标签。 +3. Scott 将所有累积的数据库迁移应用到生产数据库。 + +Yii 提供了一套迁移命令行工具,允许您: + +* 创建新迁移; +* 应用迁移; +* 回滚迁移; +* 重新应用迁移; +* 显示迁移历史和状态。 + +所有这些工具都可以通过命令 `yii migrate` 访问。在本节中,我们将详细描述如何使用这些工具完成各种任务。 > [!TIP] -> Migrations could affect not only database schema but adjust existing data to fit new schema, create RBAC -hierarchy or clean up cache. +> 迁移不仅可以影响数据库模式,还可以调整现有数据以适应新模式、创建 RBAC +层次结构或清理缓存。 > [!NOTE] -> When manipulating data using a migration you may find that using your Active Record or entity classes -> for this might be useful because some of the logic is already implemented there. Keep in mind however, that in contrast -> to code written in the migrations, whose nature is to stay constant forever, application logic is subject to change. -> So when using Active Record or entity classes in migration code, changes to the logic in the source code -> may accidentally break the existing migrations. For this reason migration code should be kept independent of other -> application logic such. +> 在使用迁移操作数据时,您可能会发现使用 Active Record 或实体类会很有用, +> 因为其中已经实现了一些逻辑。但请记住,与迁移中编写的代码(其本质是永久不变的)不同, +> 应用程序逻辑是会发生变化的。因此,在迁移代码中使用 Active Record 或实体类时, +> 源代码中逻辑的变更可能会意外破坏现有的迁移。出于这个原因,迁移代码应保持与 +> 其他应用程序逻辑相互独立。 -## Initial configuration +## 初始配置 -To use migrations, install -[yiisoft/db-migration](https://github.com/yiisoft/db-migration/) package: +要使用迁移,请安装 [yiisoft/db-migration](https://github.com/yiisoft/db-migration/) +包: ```shell make composer require yiisoft/db-migration ``` -Create a directory to store migrations `src/Migration` right in the project -root. +在项目根目录中创建一个用于存储迁移的目录 `src/Migration`。 -Add the following configuration to `config/common/params.php`: +将以下配置添加到 `config/common/params.php`: ```php 'yiisoft/db-migration' => [ @@ -78,28 +57,22 @@ Add the following configuration to `config/common/params.php`: ], ``` -If you want to place migrations elsewhere, you can define the path in -`newMigrationPath`. If your migrations to be applied are from multiple -sources, such as external modules, `sourcePaths` could be used to define -these. +如果您想将迁移放置在其他位置,可以在 `newMigrationPath` 中定义路径。如果您要应用的迁移来自多个来源(例如外部模块),可以使用 +`sourcePaths` 来定义这些来源。 -You need a database connection configured as well. See [Working with -databases](../start/databases.md) for an example of configuring it for -PostgreSQL. +您还需要配置数据库连接。有关为 PostgreSQL 配置的示例,请参阅 [使用数据库](../start/databases.md)。 -## Creating a migration +## 创建迁移 -To create a new empty migration, run the following command: +要创建一个新的空迁移,请运行以下命令: ```sh make shell ./yii migrate:create ``` -The required `name` argument gives a brief description about the new -migration. For example, if the migration is about creating a new table named -*news*, you may use the name `create_news_table` and run the following -command: +必填的 `name` 参数对新迁移进行简短描述。例如,如果迁移是关于创建一张名为 *news* 的新表,您可以使用名称 +`create_news_table` 并运行以下命令: ``` make shell @@ -108,13 +81,11 @@ make shell > [!NOTE] -> Because the `name` argument will be used as part of the generated migration class name, -> it should only contain letters, digits, and/or underscore characters. +> 由于 `name` 参数将用作生成的迁移类名的一部分, +> 因此它应该只包含字母、数字和/或下划线字符。 -The above command will create a new PHP class file named -`src/Migration/M251225221906CreateNewsTable.php`. The file contains the -following code which mainly declares a migration class with the skeleton -code: +上述命令将创建一个名为 `src/Migration/M251225221906CreateNewsTable.php` 的新 PHP +类文件。该文件包含以下代码,主要声明了一个带有骨架代码的迁移类: ```php Note: Not all DBMS support transactions. And some DB queries cannot be put into a transaction. For some examples, -please refer to [implicit commit](https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html). +> 注意:并非所有数据库管理系统都支持事务。而且某些数据库查询无法放入事务中。有关一些示例, +请参阅 [隐式提交](https://dev.mysql.com/doc/refman/5.7/en/implicit-commit.html)。 -## Generating a migration +## 生成迁移 -Instead of writing migrations by hand, the command provides a convenient way -generate some of the code. +该命令提供了一种方便的方式来生成部分代码,而不必手动编写迁移。 ```shell make shell ./yii migrate:create -- my_first_table --command=table --fields=name,example --table-comment=my_first_table ``` -That would generate the following: +这将生成以下内容: ```php +## 回滚迁移 -To revert (undo) one or multiple migrations that have been applied before, -you can run the following command: +要回滚(撤销)之前已应用的一个或多个迁移,可以运行以下命令: ``` ./yii migrate:down # revert the most recently applied migration @@ -385,14 +326,13 @@ you can run the following command: ./yii migrate:down --all # revert all migrations ``` -> Note: Not all migrations are reversible. Trying to revert such migrations will cause an error and stop the -entire reverting process. +> 注意:并非所有迁移都是可逆的。尝试回滚此类迁移将导致错误并停止 +整个回滚过程。 -## Redoing Migrations +## 重做迁移 -Redoing migrations means first reverting the specified migrations and then -applying again. This can be done as follows: +重做迁移是指先回滚指定的迁移,然后再重新应用。可以按如下方式操作: ``` ./yii migrate:redo # redo the last applied migration @@ -400,12 +340,11 @@ applying again. This can be done as follows: ./yii migrate:redo --all # redo all migrations ``` -> Note: If a migration is not reversible, you will not be able to redo it. +> 注意:如果迁移不可逆,您将无法重做它。 -## Listing Migrations +## 列出迁移 -To list which migrations have been applied and which are not, you may use -the following commands: +要列出哪些迁移已应用、哪些未应用,可以使用以下命令: ``` ./yii migrate/history # showing the last 10 applied migrations @@ -417,14 +356,11 @@ the following commands: ./yii migrate:new --all # showing all new migrations ``` -### Upgrading from Yii 2.0 +### 从 Yii 2.0 升级 -Migrations in Yii 2.0 and the -[yiisoft/db-migration](https://github.com/yiisoft/db-migration/) package are -not compatible, and the `migration` table is also not compatible. +Yii 2.0 中的迁移与 +[yiisoft/db-migration](https://github.com/yiisoft/db-migration/) +包不兼容,`migration` 表也不兼容。 -A probable solution is to use structure dumps and rename the old `migration` -table. Upon the initial execution of migrations, a new `migration` table -with new fields will be created. All further changes in the database schema -are applied using the new `migration` component and recorded in the new -migration table. +一个可行的解决方案是使用结构转储并重命名旧的 `migration` 表。在初次执行迁移时,将创建一个具有新字段的新 `migration` +表。此后数据库模式的所有变更都使用新的 `migration` 组件应用,并记录在新的迁移表中。 diff --git a/src/zh-CN/guide/glossary.md b/src/zh-CN/guide/glossary.md index cb8f973c..d0ca57b1 100644 --- a/src/zh-CN/guide/glossary.md +++ b/src/zh-CN/guide/glossary.md @@ -2,91 +2,71 @@ ## alias -Alias is a string used by Yii to refer to the class or directory such as -`@app/vendor`. Read more in ["Aliases"](concept/aliases.md). +别名是 Yii 用于引用类或目录的字符串,例如 `@app/vendor`。详见[“别名”](concept/aliases.md)。 ## asset -Asset refers to a resource file. Typically, it contains JavaScript or CSS -code but can be any static content accessed via HTTP. Read more in -["Assets"](views/asset.md). +资源是指资源文件。通常包含 JavaScript 或 CSS 代码,但也可以是任何通过 HTTP +访问的静态内容。详见[“资源”](views/asset.md)。 # C ## configuration -The Configuration may refer either to the process of setting properties of -an object or to a configuration file that stores settings for an object, or -a class of objects. Read more in -["Configuration"](concept/configuration.md). +配置既可以指设置对象属性的过程,也可以指存储对象或一类对象设置的配置文件。详见[“配置”](concept/configuration.md)。 # D ## DI -Dependency Injection is a programming technique where an object injects a -dependent object. Read more in ["Dependency injection and -container"](concept/di-container.md). +依赖注入是一种编程技术,通过该技术将依赖对象注入到另一个对象中。详见[“依赖注入与容器”](concept/di-container.md)。 # I ## installation -Installation is a process of preparing something to work either by following -a readme file or by executing a specially prepared script. In the case of -Yii, it's setting permissions and fulfilling software requirements. +安装是按照 readme 文件或执行专门准备的脚本来使软件正常运行的过程。对于 Yii 而言,主要是设置权限和满足软件依赖要求。 # M ## middleware -Middleware is a processor in the request processing stack. Given a request, -it may either produce a response or do some action and pass processing to -the next middleware. Read more in ["Middleware"](structure/middleware.md). +中间件是请求处理栈中的一个处理器。对于给定的请求,它既可以直接生成响应,也可以执行某些操作后将处理传递给下一个中间件。详见[“中间件”](structure/middleware.md)。 ## module -The module is a namespace that groups some code based on a use-case. It's -typically used within the main application and may contain any source code, -define additional URL handlers or console commands. +模块是根据使用场景对代码进行分组的命名空间。它通常在主应用程序中使用,可以包含任意源代码、定义额外的 URL 处理器或控制台命令。 # N ## namespace -Namespace refers to a [PHP language -feature](https://www.php.net/manual/en/language.namespaces.php) to group -multiple classes under a certain name. +命名空间是指一种 [PHP +语言特性](https://www.php.net/manual/en/language.namespaces.php),用于将多个类归组到某个特定名称下。 # P ## package -A package usually refers to [Composer -package](https://getcomposer.org/doc/). It's code ready for reuse and -redistribution installable automatically via package manager. +包通常指 [Composer 包](https://getcomposer.org/doc/),是可通过包管理器自动安装的、已准备好复用和再分发的代码。 # R ## rule -The rule usually refers to a validation rule of the -[yiisoft/validator](https://github.com/yiisoft/validator) package. It holds -a set of parameters for checking if a data set is valid. "Rule handler" -does the actual processing. +规则通常指 [yiisoft/validator](https://github.com/yiisoft/validator) +包的验证规则。它持有一组用于检查数据集是否有效的参数。“规则处理器”负责实际执行处理。 # Q ## queue -A queue is similar to a stack. Queue follows First-In-First-Out -methodology. Yii has a [yiisoft/queue](https://github.com/yiisoft/queue) -package. +队列类似于栈,遵循先进先出(FIFO)原则。Yii 提供了 +[yiisoft/queue](https://github.com/yiisoft/queue) 包。 # V ## vendor -A Vendor is an organization or individual developer providing code in the -form of packages. It also may refer to [Composer's `vendor` -directory](https://getcomposer.org/doc/). +Vendor 是指以包的形式提供代码的组织或个人开发者。也可以指 [Composer 的 `vendor` +目录](https://getcomposer.org/doc/)。 diff --git a/src/zh-CN/guide/index.md b/src/zh-CN/guide/index.md index 2a1ddeae..ec842f38 100644 --- a/src/zh-CN/guide/index.md +++ b/src/zh-CN/guide/index.md @@ -1,155 +1,153 @@ -# The definitive guide to Yii3 +# Yii3 权威指南 -We release this guide under the [Terms of Yii -Documentation](https://www.yiiframework.com/license#docs). +本指南遵循 [Yii 文档条款](https://www.yiiframework.com/license#docs) 发布。 -## Introduction +## 介绍 -- [About Yii](intro/what-is-yii.md) -- [Upgrading from version 2.0](intro/upgrade-from-v2.md) +- [关于 Yii](intro/what-is-yii.md) +- [从 2.0 版本升级](intro/upgrade-from-v2.md) -## Getting started +## 入门 -- [What do you need to know?](start/prerequisites.md) -- [Creating a project](start/creating-project.md) -- [Running applications](start/workflow.md) -- [Saying hello](start/hello.md) -- [Working with forms](start/forms.md) -- [Working with databases](start/databases.md) -- [Generating code with Gii](start/gii.md) TODO -- [Looking ahead](start/looking-ahead.md) +- [你需要了解什么?](start/prerequisites.md) +- [创建项目](start/creating-project.md) +- [运行应用](start/workflow.md) +- [说 Hello](start/hello.md) +- [使用表单](start/forms.md) +- [使用数据库](start/databases.md) +- [使用 Gii 生成代码](start/gii.md) TODO +- [展望未来](start/looking-ahead.md) -## Application structure +## 应用结构 -- [Application structure overview](structure/overview.md) -- [Entry scripts](structure/entry-script.md) -- [Application](structure/application.md) -- [Service components](structure/service.md) -- [Actions](structure/action.md) -- [Domain](structure/domain.md) -- [Middleware](structure/middleware.md) -- [Packages](structure/package.md) +- [应用结构概述](structure/overview.md) +- [入口脚本](structure/entry-script.md) +- [应用](structure/application.md) +- [服务组件](structure/service.md) +- [动作](structure/action.md) +- [领域](structure/domain.md) +- [中间件](structure/middleware.md) +- [包](structure/package.md) -## Key concepts +## 核心概念 -- [Class autoloading](concept/autoloading.md) -- [Dependency injection container](concept/di-container.md) -- [Configuration](concept/configuration.md) -- [Aliases](concept/aliases.md) -- [Events](concept/events.md) -- [Immutability](concept/immutability.md) +- [类自动加载](concept/autoloading.md) +- [依赖注入容器](concept/di-container.md) +- [配置](concept/configuration.md) +- [别名](concept/aliases.md) +- [事件](concept/events.md) +- [不可变性](concept/immutability.md) -## Handling requests +## 处理请求 -- [Routing and URL generation](runtime/routing.md) -- [Request](runtime/request.md) -- [Response](runtime/response.md) -- [Sessions](runtime/sessions.md) +- [路由和 URL 生成](runtime/routing.md) +- [请求](runtime/request.md) +- [响应](runtime/response.md) +- [会话](runtime/sessions.md) - [Cookies](runtime/cookies.md) -- [Handling errors](runtime/handling-errors.md) -- [Logging](runtime/logging.md) +- [错误处理](runtime/handling-errors.md) +- [日志](runtime/logging.md) -## Views +## 视图 -- [View](views/view.md) -- [Template engines](views/template-engines.md) TODO: verify! -- [View injections](views/view-injections.md) -- [Scripts, styles and metatags](views/script-style-meta.md) TODO: verify! -- [Assets](views/asset.md) TODO: verify! -- [Widgets](views/widget.md) TODO: verify! +- [视图](views/view.md) +- [模板引擎](views/template-engines.md) TODO: verify! +- [视图注入](views/view-injections.md) +- [脚本、样式和元标签](views/script-style-meta.md) TODO: verify! +- [资源](views/asset.md) TODO: verify! +- [小部件](views/widget.md) TODO: verify! -## Working with databases +## 使用数据库 - [Yii DB](https://github.com/yiisoft/db/blob/master/docs/guide/en/README.md) - [Active Record](https://github.com/yiisoft/active-record/blob/master/README.md) -- [Migrations](databases/db-migrations.md) TODO: verify/update! +- [迁移](databases/db-migrations.md) TODO: verify/update! -## Getting data from users +## 从用户获取数据 -- [Creating forms](input/forms.md) TODO -- [Validating - input](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md) -- [Uploading files](input/file-upload.md) TODO -- [Collecting tabular input](input/tabular-input.md) TODO +- [创建表单](input/forms.md) TODO +- [验证输入](https://github.com/yiisoft/validator/blob/master/docs/guide/en/README.md) +- [上传文件](input/file-upload.md) TODO +- [收集表格输入](input/tabular-input.md) TODO -## Displaying data +## 显示数据 -- [Data formatting](output/formatting.md) TODO -- [Pagination](output/pagination.md) TODO -- [Sorting](output/sorting.md) TODO -- [Data providers](output/data-providers.md) TODO -- [Data widgets](output/data-widgets.md) TODO +- [数据格式化](output/formatting.md) TODO +- [分页](output/pagination.md) TODO +- [排序](output/sorting.md) TODO +- [数据提供者](output/data-providers.md) TODO +- [数据小部件](output/data-widgets.md) TODO -## Security +## 安全 -- [Security overview](security/overview.md) -- [Authentication](security/authentication.md) -- [Authorization](security/authorization.md) TODO: verify and complete! -- [Working with passwords](security/passwords.md) -- [Cryptography](security/cryptography.md) -- [Best practices](security/best-practices.md) +- [安全概述](security/overview.md) +- [认证](security/authentication.md) +- [授权](security/authorization.md) TODO: verify and complete! +- [使用 passwords](security/passwords.md) +- [加密](security/cryptography.md) +- [最佳实践](security/best-practices.md) -## Caching +## 缓存 -- [Caching overview](caching/overview.md) -- [Data caching](caching/data.md) -- [Fragment caching](caching/fragment.md) TODO -- [Page caching](caching/page.md) TODO -- [HTTP caching](caching/http.md) TODO +- [缓存概述](caching/overview.md) +- [数据缓存](caching/data.md) +- [片段缓存](caching/fragment.md) TODO +- [页面缓存](caching/page.md) TODO +- [HTTP 缓存](caching/http.md) TODO ## REST APIs -- [Quick start](rest/quick-start.md) TODO -- [Resources](rest/resources.md) TODO -- [Controllers](rest/controllers.md) TODO -- [Routing](rest/routing.md) TODO -- [Authentication](rest/authentication.md) TODO -- [Rate limiting](rest/rate-limiting.md) TODO -- [Versioning](rest/versioning.md) TODO -- [Error handling](rest/error-handling.md) TODO +- [快速开始](rest/quick-start.md) TODO +- [资源](rest/resources.md) TODO +- [控制器](rest/controllers.md) TODO +- [路由](rest/routing.md) TODO +- [认证](rest/authentication.md) TODO +- [速率限制](rest/rate-limiting.md) TODO +- [版本控制](rest/versioning.md) TODO +- [错误处理](rest/error-handling.md) TODO -## Development tools +## 开发工具 -- Debug toolbar and debugger -- Generating code using Gii -- Generating API documentation +- 调试工具栏和调试器 +- 使用 Gii 生成代码 +- 生成 API 文档 -## Testing +## 测试 -- [Testing overview](testing/overview.md) TODO -- [Testing environment setup](testing/environment-setup.md) TODO -- [Unit tests](testing/unit.md) TODO -- [Functional tests](testing/functional.md) TODO -- [Acceptance tests](testing/acceptance.md) TODO -- [Fixtures](testing/fixtures.md) TODO +- [测试概述](testing/overview.md) TODO +- [测试环境设置](testing/environment-setup.md) TODO +- [单元测试](testing/unit.md) TODO +- [功能测试](testing/functional.md) TODO +- [验收测试](testing/acceptance.md) TODO +- [固件](testing/fixtures.md) TODO -## Special topics +## 特殊主题 -- [Console applications](tutorial/console-applications.md) -- [Internationalization](tutorial/i18n.md) TODO -- [Mailing](tutorial/mailing.md) -- [Performance tuning](tutorial/performance-tuning.md) -- [Using Yii with event loop](tutorial/using-with-event-loop.md) -- [Using Yii with RoadRunner](tutorial/using-yii-with-roadrunner.md) -- [Using Yii with Swoole](tutorial/using-yii-with-swoole.md) +- [控制台应用](tutorial/console-applications.md) +- [国际化](tutorial/i18n.md) TODO +- [邮件](tutorial/mailing.md) +- [性能调优](tutorial/performance-tuning.md) +- [在事件循环中使用 Yii](tutorial/using-with-event-loop.md) +- [在 RoadRunner 中使用 Yii](tutorial/using-yii-with-roadrunner.md) +- [在 Swoole 中使用 Yii](tutorial/using-yii-with-swoole.md) -## Helpers +## 助手类 -- [Arrays](https://github.com/yiisoft/arrays/) -- [Files](https://github.com/yiisoft/files/) +- [数组](https://github.com/yiisoft/arrays/) +- [文件](https://github.com/yiisoft/files/) - [Html](https://github.com/yiisoft/html/) - [Json](https://github.com/yiisoft/json) -- [Network utilities](https://github.com/yiisoft/network-utilities/) +- [网络工具](https://github.com/yiisoft/network-utilities/) - [VarDumper](https://github.com/yiisoft/var-dumper) -- [Strings](https://github.com/yiisoft/strings) +- [字符串](https://github.com/yiisoft/strings) -## Extras +## 额外内容 -- [Cookbook](../cookbook/index.md) -- [Glossary](glossary.md) +- [实用手册](../cookbook/index.md) +- [术语表](glossary.md) diff --git a/src/zh-CN/guide/intro/upgrade-from-v2.md b/src/zh-CN/guide/intro/upgrade-from-v2.md index 4f7e1347..4bdfa198 100644 --- a/src/zh-CN/guide/intro/upgrade-from-v2.md +++ b/src/zh-CN/guide/intro/upgrade-from-v2.md @@ -1,63 +1,47 @@ -# Upgrading from Version 2.0 - -> If you haven't used Yii 2.0, you can skip this section and get directly to "[getting started](../start/prerequisites.md)" -> section. - -While sharing some common ideas and values, Yii3 is conceptually different -from Yii 2.0. There is no easy upgrade path, so first [check maintenance -policy and end-of-life dates for Yii -2.0](https://www.yiiframework.com/release-cycle) and consider starting new -projects on Yii3 while keeping existing ones on Yii 2.0. - -## PHP requirements - -Yii3 requires PHP 8.2 or above. As a result, there are language features -used that weren't used in Yii 2.0: - -- [Type - declarations](https://www.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration) -- [Return type - declarations](https://www.php.net/manual/en/functions.returning-values.php#functions.returning-values.type-declaration) -- [Class constant - visibility](https://www.php.net/manual/en/language.oop5.constants.php) -- [Named - arguments](https://www.php.net/manual/en/functions.arguments.php#functions.named-arguments) -- [Anonymous - classes](https://www.php.net/manual/en/language.oop5.anonymous.php) +# 从 2.0 版本升级 + +> 如果您未曾使用过 Yii 2.0,可以跳过本节,直接阅读“[入门](../start/prerequisites.md)” +> 章节。 + +尽管 Yii3 与 Yii 2.0 有一些共同的理念和价值观,但两者在概念上存在显著差异。升级并无捷径,建议先[查看 Yii 2.0 +的维护策略和生命周期终止日期](https://www.yiiframework.com/release-cycle),并考虑将新项目迁移到 +Yii3,同时保持现有项目继续使用 Yii 2.0。 + +## PHP 要求 + +Yii3 要求 PHP 8.2 或更高版本。因此,它使用了 Yii 2.0 中未使用的语言特性: + +- [类型声明](https://www.php.net/manual/en/functions.arguments.php#functions.arguments.type-declaration) +- [返回类型声明](https://www.php.net/manual/en/functions.returning-values.php#functions.returning-values.type-declaration) +- [类常量可见性](https://www.php.net/manual/en/language.oop5.constants.php) +- [命名参数](https://www.php.net/manual/en/functions.arguments.php#functions.named-arguments) +- [匿名类](https://www.php.net/manual/en/language.oop5.anonymous.php) - [::class](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.class) -- [Generators](https://www.php.net/manual/en/language.generators.php) -- [Variadic - functions](https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list) -- [Readonly - properties](https://www.php.net/manual/en/language.oop5.properties.php#language.oop5.properties.readonly-properties) -- [Readonly - classes](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.readonly) -- [Constructor property - promotion](https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.constructor.promotion) -- [Attributes](https://www.php.net/manual/en/language.attributes.php) +- [生成器](https://www.php.net/manual/en/language.generators.php) +- [可变参数函数](https://www.php.net/manual/en/functions.arguments.php#functions.variable-arg-list) +- [只读属性](https://www.php.net/manual/en/language.oop5.properties.php#language.oop5.properties.readonly-properties) +- [只读类](https://www.php.net/manual/en/language.oop5.basic.php#language.oop5.basic.class.readonly) +- [构造函数属性提升](https://www.php.net/manual/en/language.oop5.decon.php#language.oop5.decon.constructor.promotion) +- [注解](https://www.php.net/manual/en/language.attributes.php) -## Preliminary refactoring +## 预备重构 -It's a good idea to refactor your Yii 2.0 project before porting it to -Yii3. That would both make porting easier and benefit the project in -question while it's not moved to Yii3 yet. +在将 Yii 2.0 项目迁移到 Yii3 之前,先进行重构是个好主意。这既能简化迁移过程,也能在项目尚未切换到 Yii3 时直接受益。 -### Use DI instead of the service locator +### 使用 DI 替代服务定位器 -Since Yii3 is forcing you to inject dependencies, it's a good idea to prepare and switch from using -service locator (`Yii::$app->`) to [DI container](https://www.yiiframework.com/doc/guide/2.0/en/concept-di-container). +由于 Yii3 强制要求注入依赖,建议提前做好准备,将 +服务定位器(`Yii::$app->`)切换为 [DI 容器](https://www.yiiframework.com/doc/guide/2.0/en/concept-di-container)。 -If usage of DI container is problematic for whatever reason, consider moving all calls to `Yii::$app->` to controller -actions and widgets and passing dependencies manually from a controller to what needs them. +如果因某种原因使用 DI 容器存在困难,可以考虑将所有 `Yii::$app->` 调用迁移到控制器 +动作和小部件中,并从控制器手动将依赖传递给需要它的对象。 -See [Dependency injection and container](../concept/di-container.md) for an -explanation of the idea. +有关该理念的说明,请参阅[依赖注入与容器](../concept/di-container.md)。 -### Introduce repositories for getting data +### 引入仓储层获取数据 -Since Active Record isn't the only way to work with a database in Yii3, -consider introducing repositories that would hide details of getting data -and gather them in a single place. You can later redo it: +由于 Active Record 并非 Yii3 +中操作数据库的唯一方式,建议引入仓储层来隐藏数据获取的实现细节,并将其集中管理。后续可以随时对其进行重构: ```php final readonly class PostRepository @@ -75,48 +59,38 @@ final readonly class PostRepository } ``` -### Separate domain layer from infrastructure +### 将领域层与基础设施层分离 -In case you have a rich complicated domain, it's a good idea to separate it -from infrastructure provided by a framework that's all the business logic -has to go to framework-independent classes. +如果您的应用拥有复杂的领域逻辑,建议将其与框架提供的基础设施层分离,即所有业务逻辑应放入与框架无关的类中。 -### Move more into components +### 将更多逻辑移入组件 -Yii3 services are conceptually similar to Yii 2.0 components, so it's a good -idea to move reusable parts of your application into components. +Yii3 的服务在概念上与 Yii 2.0 的组件类似,因此建议将应用程序中可复用的部分移入组件。 -## Things to learn +## 需要学习的内容 ### Docker -Default application templates are using -[Docker](https://www.docker.com/get-started/) to run application. It's a -good idea to learn how to use it and use it for your own projects since it -provides a lot of benefits: +默认应用程序模板使用 [Docker](https://www.docker.com/get-started/) +来运行应用程序。建议学习并在自己的项目中使用 Docker,因为它提供了许多好处: -1. Exactly the same environment as in production. -2. No need to install anything except Docker itself. -3. Environment is per application, not per server. +1. 与生产环境完全相同的运行环境。 +2. 除 Docker 本身外,无需安装任何其他软件。 +3. 环境按应用程序隔离,而非按服务器共享。 -### Environment variables +### 环境变量 -Yii3 application templates are using [environment -variables](https://en.wikipedia.org/wiki/Environment_variable) to configure -parts of the application. The concept is [very handy for Dockerized -applications](https://12factor.net/) but might be alien to users of Yii 1.1 -and Yii 2.0. +Yii3 应用程序模板使用 [环境变量](https://en.wikipedia.org/wiki/Environment_variable) +来配置应用程序的各个部分。这一概念对于[容器化应用程序非常实用](https://12factor.net/),但对于 Yii 1.1 和 Yii +2.0 的用户来说可能较为陌生。 -### Actions +### 动作 -Unlike Yii 2.0, Yii3 does not require controllers. Instead, it uses -[actions](../structure/action.md), which are any callables. You can organize -these into controllers similar to Yii 2, but it's not required. +与 Yii 2.0 不同,Yii3 不要求使用控制器。它改为使用 +[动作](../structure/action.md),动作可以是任意可调用对象。您可以像 Yii 2 那样将动作组织到控制器中,但这并非必须。 -### Application structure +### 应用结构 -Suggested Yii3 application structure is different from Yii 2.0. It's -described in [application structure](../structure/overview.md). +Yii3 建议的应用程序结构与 Yii 2.0 有所不同,详见 [应用程序结构](../structure/overview.md)。 -Despite that, Yii3 is flexible, so it's still possible to use a structure -similar to Yii 2.0 with Yii3. +尽管如此,Yii3 具有良好的灵活性,仍然可以在 Yii3 中使用类似 Yii 2.0 的结构。 diff --git a/src/zh-CN/guide/intro/what-is-yii.md b/src/zh-CN/guide/intro/what-is-yii.md index aa3478dd..0a38fee6 100644 --- a/src/zh-CN/guide/intro/what-is-yii.md +++ b/src/zh-CN/guide/intro/what-is-yii.md @@ -1,65 +1,52 @@ -# What is Yii +# 什么是 Yii Yii 是一个高性能、基于包的 PHP 框架,用于开发现代应用程序。Yii(发音为 `Yee` 或 `[ji:]`)在中文中意为“简单且不断演进”。你也可以把它看作是 **Yes It Is**(是的,就是它)的首字母缩写! -## What's Yii best for +## Yii 最擅长什么 Yii 是一个通用的 Web 编程框架。你可以使用它来开发各种类型的 PHP Web 应用程序。由于其架构和完善的缓存支持,它特别适合开发大型应用程序,如门户网站、内容管理系统、电子商务、REST API 等。 -## How does Yii compare with other frameworks? +## Yii 与其他框架相比如何? -If you're already familiar with another framework, you may appreciate -knowing how Yii compares: +如果您已经熟悉其他框架,您可能会想了解 Yii 与它们的比较: -- Yii takes the [philosophy of being practical and - helpful](../../internals/001-yii-values.md) achieving: - - Performance in both development and execution. - - Convenient customizable defaults. - - Practice-orientation. - - Simplicity. - - Explicitness. - - Consistency. +- Yii 秉持 [务实和有益的理念](../../internals/001-yii-values.md),致力于实现: + - 开发和执行两方面的高性能。 + - 方便可定制的默认配置。 + - 实践导向。 + - 简洁性。 + - 明确性。 + - 一致性。 - Yii will never try to over-design things mainly to follow some design patterns. -- Yii extensively uses PSR interfaces with the ability to reuse what PHP community created and even - replace core implementations if needed. -- Yii is both a set of libraries and a full-stack framework providing many proven and ready-to-use features: - caching, logging, template engine, data abstraction, development tools, code generation, and more. -- Yii is extensible. You can customize or replace every piece of the core's code. You can also - take advantage of Yii's solid architecture to use or develop redistributable packages. -- High performance is always a primary goal of Yii. - -Yii is backed up by a [strong core developer -team](https://www.yiiframework.com/team/) financially backed from an -[OpenCollective foundation](https://opencollective.com/yiisoft), as well as -a large community of professionals constantly contributing to Yii's -development. The Yii developer team keeps a close eye on the latest Web -development trends and on the best practices and features found in other -frameworks and projects. The most relevant best practices and features found -elsewhere are incorporated into the core framework and exposed via simple -and elegant interfaces. - - -## Yii versions - -Yii currently has three major versions available: 1.1, 2.0, and 3.0. - -- Version 1.1 is the old generation and is now in the feature freeze bugfix - mode. -- Version 2.0 is a current stable version in the feature freeze bugfix mode. -- Version 3.0 is the current version in development. This guide is mainly - about version 3. - - -## Requirements and prerequisites - -Yii3 requires PHP 8.2 or above, but some packages work with older PHP, such -as PHP 7.4. - -Using Yii requires basic knowledge of object-oriented programming (OOP), as -Yii is a pure OOP-based framework. Yii3 also makes use of the latest PHP -features, such as type declarations and generators. Understanding these -concepts will help you pick up Yii3 faster. + Yii 不会为了追随某些设计模式而过度设计。 +- Yii 广泛使用 PSR 接口,能够复用 PHP 社区的成果,甚至在需要时替换核心实现。 +- Yii 既是一套类库,也是一个全栈框架,提供了许多经过验证的即用功能: + 缓存、日志、模板引擎、数据抽象、开发工具、代码生成等。 +- Yii 具有高度可扩展性。您可以自定义或替换核心代码的任何部分,也可以 + 利用 Yii 的稳固架构来使用或开发可再发布的包。 +- 高性能始终是 Yii 的首要目标。 + +Yii 由一支 [强大的核心开发团队](https://www.yiiframework.com/team/) 支撑,并获得 +[OpenCollective 基金会](https://opencollective.com/yiisoft) 的资金支持,同时拥有一个持续为 Yii +发展做出贡献的庞大专业社区。Yii 开发团队密切关注最新的 Web +开发趋势,以及其他框架和项目中发现的最佳实践和功能。在其他地方发现的最相关的最佳实践和功能都被融入核心框架,并通过简洁优雅的接口对外暴露。 + + +## Yii 版本 + +Yii 目前有三个主要版本:1.1、2.0 和 3.0。 + +- 1.1 版本是旧一代,目前处于功能冻结的错误修复模式。 +- 2.0 版本是当前稳定版本,处于功能冻结的错误修复模式。 +- 3.0 版本是目前正在开发的版本。本指南主要介绍第 3 个版本。 + + +## 要求和先决条件 + +Yii3 需要 PHP 8.2 或更高版本,但某些包也可以与较旧的 PHP 一起使用,例如 PHP 7.4。 + +使用 Yii 需要具备面向对象编程(OOP)的基础知识,因为 Yii 是一个纯 OOP 框架。Yii3 还利用了最新的 PHP +特性,例如类型声明和生成器。理解这些概念将帮助您更快地上手 Yii3。 diff --git a/src/zh-CN/guide/runtime/cookies.md b/src/zh-CN/guide/runtime/cookies.md index 9a8ff8a1..91e9669e 100644 --- a/src/zh-CN/guide/runtime/cookies.md +++ b/src/zh-CN/guide/runtime/cookies.md @@ -1,14 +1,11 @@ -# Cookies +# Cookie -Cookies are for persisting data between requests by sending it to the client -browser using HTTP headers. The client sends data back to the server in -request headers. Thus, cookies are handy to store small amounts of data, -such as tokens or flags. +Cookie 用于通过 HTTP 头将数据发送到客户端浏览器,以在请求之间持久化数据。客户端在请求头中将数据发回服务器。因此,Cookie +非常适合存储少量数据,例如令牌或标志位。 -## Reading cookies +## 读取 Cookie -You could obtain Cookie values from server request that's available as route -handler (such as controller action) argument: +您可以从作为路由处理器(例如控制器操作)参数提供的服务器请求中获取 Cookie 值: ```php private function actionProfile(\Psr\Http\Message\ServerRequestInterface $request) @@ -19,15 +16,12 @@ private function actionProfile(\Psr\Http\Message\ServerRequestInterface $request } ``` -In addition to getting cookie values directly from the server request, you -can also use the +除了直接从服务器请求获取 Cookie 值外,您还可以使用 [yiisoft/request-provider](https://github.com/yiisoft/request-provider) -package, which provides a more structured way to handle cookies through the -`\Yiisoft\RequestProvider\RequestCookieProvider`. This approach can -simplify your code and improve readability. +包,该包通过 `\Yiisoft\RequestProvider\RequestCookieProvider` 提供了一种更结构化的 Cookie +处理方式,能简化代码并提高可读性。 -Here’s an example of how to work with cookies using the -`\Yiisoft\RequestProvider\RequestCookieProvider`: +以下是使用 `\Yiisoft\RequestProvider\RequestCookieProvider` 处理 Cookie 的示例: ```php final readonly class MyService @@ -68,20 +62,17 @@ $cookie = (new \Yiisoft\Cookies\Cookie('cookieName', 'value')) return $cookie->addToResponse($response); ``` -After forming a cookie call `addToResponse()` passing an instance of -`\Psr\Http\Message\ResponseInterface` to add corresponding HTTP headers to -it. +构造好 Cookie 后,调用 `addToResponse()` 并传入 `\Psr\Http\Message\ResponseInterface` +实例,以将相应的 HTTP 头添加到响应中。 -## Signing and encrypting cookies +## 签名与加密 Cookie -To prevent the substitution of the cookie value, the package provides two -implementations: +为防止 Cookie 值被篡改,该包提供了两种实现: -`Yiisoft\Cookies\CookieSigner` - signs each cookie with a unique prefix hash -based on the value of the cookie and a secret key. -`Yiisoft\Cookies\CookieEncryptor` - encrypts each cookie with a secret key. +`Yiisoft\Cookies\CookieSigner` — 使用基于 Cookie 值和密钥的唯一前缀哈希对每个 Cookie +进行签名。`Yiisoft\Cookies\CookieEncryptor` — 使用密钥对每个 Cookie 进行加密。 -Encryption is more secure than signing but has lower performance. +加密比签名更安全,但性能较低。 ```php $cookie = new \Yiisoft\Cookies\Cookie('identity', 'identityValue'); @@ -96,18 +87,15 @@ $signedCookie = $signer->sign($cookie); $encryptedCookie = $encryptor->encrypt($cookie); ``` -To validate and get back the pure value, use the `validate()` and -`decrypt()` method. +要验证并还原纯净值,请使用 `validate()` 和 `decrypt()` 方法。 ```php $cookie = $signer->validate($signedCookie); $cookie = $encryptor->decrypt($encryptedCookie); ``` -If the cookie value is tampered with or hasn't been signed/encrypted before, -a `\RuntimeException` will be thrown. Therefore, if you aren't sure that -the cookie value was signed/encrypted earlier, first use the `isSigned()` -and `isEncrypted()` methods, respectively. +如果 Cookie 值被篡改,或之前未经过签名/加密,则会抛出 `\RuntimeException`。因此,如果不确定 Cookie +值之前是否已签名/加密,请先分别使用 `isSigned()` 和 `isEncrypted()` 方法进行检查。 ```php if ($signer->isSigned($cookie)) { @@ -119,27 +107,21 @@ if ($encryptor->isEncrypted($cookie)) { } ``` -It makes sense to sign or encrypt the value of a cookie if you store -important data that a user shouldn't change. +如果 Cookie 中存储了用户不应修改的重要数据,对其值进行签名或加密是有必要的。 -### Automating encryption and signing +### 自动化加密与签名 -To automate the encryption/signing and decryption/validation of cookie -values, use an instance of `Yiisoft\Cookies\CookieMiddleware`, which is -[PSR-15](https://www.php-fig.org/psr/psr-15/) middleware. +要自动化 Cookie 值的加密/签名和解密/验证,请使用 `Yiisoft\Cookies\CookieMiddleware` 实例,它是符合 +[PSR-15](https://www.php-fig.org/psr/psr-15/) 规范的中间件。 -This middleware provides the following features: +该中间件提供以下功能: -- Validates and decrypts the cookie parameter values from the request. -- Excludes the cookie parameter from the request if it was tampered with and - logs information about it. -- Encrypts/signs cookie values and replaces their clean values in the - `Set-Cookie` headers in the response. +- 验证并解密请求中的 Cookie 参数值。 +- 如果 Cookie 参数被篡改,则将其从请求中排除并记录相关信息。 +- 对 Cookie 值进行加密/签名,并在响应的 `Set-Cookie` 头中替换原始值。 -In order for the middleware to know which values of which cookies need to be -encrypted/signed, an array of settings must be passed to its -constructor. The array keys are cookie name patterns and values are constant -values of `CookieMiddleware::ENCRYPT` or `CookieMiddleware::SIGN`. +为了让中间件知道哪些 Cookie 的值需要加密/签名,必须向其构造函数传入一个配置数组。数组的键是 Cookie 名称匹配模式,值为 +`CookieMiddleware::ENCRYPT` 或 `CookieMiddleware::SIGN` 常量。 ```php use Yiisoft\Cookies\CookieMiddleware; @@ -155,11 +137,11 @@ $cookiesSettings = [ ]; ``` -For more information on using the wildcard pattern, see the +有关通配符模式用法的更多信息,请参阅 [yiisoft/strings](https://github.com/yiisoft/strings#wildcardpattern-usage) -package. +包。 -Creating and using middleware: +创建并使用中间件: ```php /** @@ -190,22 +172,15 @@ $middleware = new \Yiisoft\Cookies\CookieMiddleware( $response = $middleware->process($request, $handler); ``` -If the `$cookiesSettings` array is empty, no cookies will be encrypted and -signed. - -## Cookies security - -You should configure each cookie to be secure. Important security settings -are: - -- `httpOnly`. Setting it to `true` would prevent JavaScript to access cookie - value. -- `secure`. Setting it to `true` would prevent sending cookie via `HTTP`. It - will be sent via `HTTPS` only. -- `sameSite`, if set to either `SAME_SITE_LAX` or `SAME_SITE_STRICT` would - prevent sending a cookie in cross-site browsing context. `SAME_SITE_LAX` - would prevent cookie sending during CSRF-prone request methods (e.g., - POST, PUT, PATCH, etc.). `SAME_SITE_STRICT` would prevent cookies sending - for all methods. -- Sign or encrypt the value of the cookie to prevent spoofing of values if - the data in the value shouldn't be tampered with. +如果 `$cookiesSettings` 数组为空,则不会对任何 Cookie 进行加密或签名。 + +## Cookie 安全 + +应将每个 Cookie 配置为安全的。重要的安全设置包括: + +- `httpOnly`。设为 `true` 可防止 JavaScript 访问 Cookie 值。 +- `secure`。设为 `true` 可防止通过 `HTTP` 发送 Cookie,仅允许通过 `HTTPS` 发送。 +- `sameSite`,设为 `SAME_SITE_LAX` 或 `SAME_SITE_STRICT` 可防止在跨站浏览上下文中发送 + Cookie。`SAME_SITE_LAX` 会阻止在易受 CSRF 攻击的请求方法(如 POST、PUT、PATCH 等)中发送 + Cookie;`SAME_SITE_STRICT` 会阻止所有方法发送 Cookie。 +- 如果 Cookie 值中的数据不应被篡改,请对其进行签名或加密,以防止值被伪造。 diff --git a/src/zh-CN/guide/runtime/handling-errors.md b/src/zh-CN/guide/runtime/handling-errors.md index e009564b..4d94fccc 100644 --- a/src/zh-CN/guide/runtime/handling-errors.md +++ b/src/zh-CN/guide/runtime/handling-errors.md @@ -1,44 +1,30 @@ -# Handling errors - -Yii has a [yiisoft/error-handler](https://github.com/yiisoft/error-handler) -package that makes error handling a much more pleasant experience than -before. In particular, the Yii error handler provides the following: - -- [PSR-15](https://www.php-fig.org/psr/psr-15/) middleware for catching - unhandled errors. -- PSR-15 middleware for mapping certain exceptions to custom responses. -- Production and debug modes. -- Debug mode displays details, stacktrace, has dark and light themes and - handy buttons to search for error without typing. -- Takes PHP settings into account. -- Handles out of memory errors, fatal errors, warnings, notices, and - exceptions. -- Can use any [PSR-3](https://www.php-fig.org/psr/psr-3/) compatible logger - for error logging. -- Detects a response format based on a mime type of the request. -- Supports responding with HTML, plain text, JSON, XML, and headers out of - the box. -- You can implement your own error rendering for extra types. - -This guide describes how to use the error handler in the [Yii -framework](https://www.yiiframework.com/), for information about using it -separate from Yii, see the [package -description](https://github.com/yiisoft/error-handler). - -## Using error handler - -The error handler consists of two parts. One part is -`Yiisoft\ErrorHandler\Middleware\ErrorCatcher` middleware that, when -registered, catches exceptions that may appear during middleware stack -execution and passes them to the handler. Another part is the error handler -itself, `Yiisoft\ErrorHandler\ErrorHandler`, that's catching exceptions -occurring outside the middleware stack and fatal errors. The handler also -converts warnings and notices to exceptions and does more handy things. - -Error handler is registered in the application itself. Usually it happens in -`ApplicationRunner`. By default, the handler configuration comes from the -container. You may configure it in the application configuration, -`config/web.php` like the following: +# 错误处理 + +Yii 提供了 [yiisoft/error-handler](https://github.com/yiisoft/error-handler) +包,使错误处理体验大为改善。Yii 错误处理器具体提供了以下功能: + +- 用于捕获未处理错误的 [PSR-15](https://www.php-fig.org/psr/psr-15/) 中间件。 +- 用于将特定异常映射到自定义响应的 PSR-15 中间件。 +- 生产模式和调试模式。 +- 调试模式显示详细信息和堆栈跟踪,提供深色和浅色主题,以及无需输入即可搜索错误的快捷按钮。 +- 考虑 PHP 配置设置。 +- 处理内存溢出错误、致命错误、警告、通知和异常。 +- 可使用任何兼容 [PSR-3](https://www.php-fig.org/psr/psr-3/) 的日志记录器记录错误。 +- 根据请求的 MIME 类型自动检测响应格式。 +- 开箱即支持 HTML、纯文本、JSON、XML 和响应头格式的响应。 +- 您可以为其他类型实现自定义错误渲染。 + +本指南介绍如何在 [Yii 框架](https://www.yiiframework.com/)中使用错误处理器。若要了解独立于 Yii +使用的信息,请参阅[包说明](https://github.com/yiisoft/error-handler)。 + +## 使用错误处理器 + +错误处理器由两部分组成。第一部分是 `Yiisoft\ErrorHandler\Middleware\ErrorCatcher` +中间件,注册后可捕获中间件栈执行过程中出现的异常并将其传递给处理器。另一部分是错误处理器本身 +`Yiisoft\ErrorHandler\ErrorHandler`,用于捕获中间件栈之外的异常和致命错误。处理器还会将警告和通知转换为异常,并执行更多便捷操作。 + +错误处理器在应用程序本身中注册,通常在 `ApplicationRunner` 中完成。默认情况下,处理器的配置来自容器。您可以在应用配置 +`config/web.php` 中按如下方式配置: ```php use Psr\Log\LoggerInterface; @@ -71,9 +57,9 @@ return [ ]; ``` -As aforementioned, the error handler turns all non-fatal PHP errors into -catchable exceptions (`Yiisoft\ErrorHandler\Exception\ErrorException`). This -means you can use the following code to deal with PHP errors: +如前所述,错误处理器会将所有非致命 PHP +错误转换为可捕获的异常(`Yiisoft\ErrorHandler\Exception\ErrorException`)。这意味着您可以使用以下代码处理 +PHP 错误: ```php try { @@ -84,10 +70,8 @@ try { // execution continues... ``` -The package has another middleware, -`Yiisoft\ErrorHandler\Middleware\ExceptionResponder`. This middleware maps -certain exceptions to custom responses. Configure it in the application -configuration as follows: +该包还有另一个中间件 +`Yiisoft\ErrorHandler\Middleware\ExceptionResponder`,用于将特定异常映射到自定义响应。在应用配置中按如下方式配置: ```php use Psr\Http\Message\ResponseFactoryInterface; @@ -110,27 +94,23 @@ return [ ]; ``` -Note that when configuring application middleware stack, you must place -`Yiisoft\ErrorHandler\Middleware\ExceptionResponder` before -`Yiisoft\ErrorHandler\Middleware\ErrorCatcher`. +请注意,在配置应用中间件栈时,必须将 `Yiisoft\ErrorHandler\Middleware\ExceptionResponder` 放在 +`Yiisoft\ErrorHandler\Middleware\ErrorCatcher` 之前。 -## Rendering error data +## 渲染错误数据 -One of the renderers could render error data into a certain format. The -following renderers are available out of the box: +渲染器可将错误数据渲染为特定格式。以下渲染器开箱即用: -- `Yiisoft\ErrorHandler\Renderer\HeaderRenderer` - Renders error into HTTP - headers. It's used for `HEAD` request. -- `Yiisoft\ErrorHandler\Renderer\HtmlRenderer` - Renders error into HTML. -- `Yiisoft\ErrorHandler\Renderer\JsonRenderer` - Renders error into JSON. -- `Yiisoft\ErrorHandler\Renderer\PlainTextRenderer` - Renders error into - plain text. -- `Yiisoft\ErrorHandler\Renderer\XmlRenderer` - Renders error into XML. +- `Yiisoft\ErrorHandler\Renderer\HeaderRenderer` - 将错误渲染为 HTTP 响应头,用于 `HEAD` + 请求。 +- `Yiisoft\ErrorHandler\Renderer\HtmlRenderer` - 将错误渲染为 HTML。 +- `Yiisoft\ErrorHandler\Renderer\JsonRenderer` - 将错误渲染为 JSON。 +- `Yiisoft\ErrorHandler\Renderer\PlainTextRenderer` - 将错误渲染为纯文本。 +- `Yiisoft\ErrorHandler\Renderer\XmlRenderer` - 将错误渲染为 XML。 -The renderer produces detailed error data depending on whether debug mode is -enabled or disabled. +渲染器根据是否启用调试模式生成详细程度不同的错误数据。 -An Example of header rendering with a debugging mode turned off: +调试模式关闭时,响应头渲染示例: ``` ... @@ -138,7 +118,7 @@ X-Error-Message: An internal server error occurred. ... ``` -An Example of header rendering with a debugging mode turned on: +调试模式开启时,响应头渲染示例: ``` ... @@ -150,13 +130,13 @@ X-Error-Line: 21 ... ``` -Example of JSON rendering output with a debugging mode turned off: +调试模式关闭时,JSON 渲染输出示例: ```json {"message":"An internal server error occurred."} ``` -An Example of JSON rendering output with debugging mode turned on: +调试模式开启时,JSON 渲染输出示例: ```json { @@ -183,31 +163,25 @@ An Example of JSON rendering output with debugging mode turned on: } ``` -Example of HTML rendering with debugging mode turned off: +调试模式关闭时,HTML 渲染示例: -![View production](/images/guide/runtime/view-production.png) +![生产模式视图](/images/guide/runtime/view-production.png) -Example of HTML rendering with debugging mode on and a light theme: +调试模式开启且使用浅色主题时,HTML 渲染示例: -![View development with light -theme](/images/guide/runtime/view-development-light.png) +![开发模式视图(浅色主题)](/images/guide/runtime/view-development-light.png) -Example of HTML rendering with debugging mode on and a dark theme: +调试模式开启且使用深色主题时,HTML 渲染示例: -![View development with dark -theme](/images/guide/runtime/view-development-dark.png) +![开发模式视图(深色主题)](/images/guide/runtime/view-development-dark.png) -The error catcher chooses how to render an exception based on `accept` HTTP -header. If it's `text/html` or any unknown content type, it will use the -error or exception HTML template to display errors. For other mime types, -the error handler will choose different renderers that you register within -the error catcher. By default, it supports JSON, XML, and plain text. +错误捕获器根据 `accept` HTTP 请求头决定如何渲染异常。若为 `text/html` 或未知内容类型,将使用错误或异常 HTML +模板显示错误。对于其他 MIME 类型,错误处理器会选择您在错误捕获器中注册的不同渲染器。默认支持 JSON、XML 和纯文本。 -### Implementing your own renderer +### 实现自定义渲染器 -You may customize the error response format by providing your own instance -of `Yiisoft\ErrorHandler\ThrowableRendererInterface` when registering error -catcher middleware. +在注册错误捕获器中间件时,可以通过提供自己的 `Yiisoft\ErrorHandler\ThrowableRendererInterface` +实例来自定义错误响应格式。 ```php use Psr\Http\Message\ServerRequestInterface; @@ -231,7 +205,7 @@ final readonly class MyRenderer implements ThrowableRendererInterface }; ``` -You may configure it in the application configuration `config/web.php`: +可以在应用配置 `config/web.php` 中进行配置: ```php use Psr\Container\ContainerInterface; @@ -256,12 +230,10 @@ return [ ]; ``` -## Friendly exceptions +## 友好异常 -Yii error renderer supports [friendly -exceptions](https://github.com/yiisoft/friendly-exception) that make error -handling an even more pleasant experience for your team. The idea is to -offer a readable name and possible solutions to the problem: +Yii +错误渲染器支持[友好异常](https://github.com/yiisoft/friendly-exception),让团队的错误处理体验更佳。其理念是为问题提供可读的名称和可能的解决方案: ```php use Yiisoft\FriendlyException\FriendlyExceptionInterface; @@ -282,5 +254,4 @@ SOLUTION; } ``` -When the application throws such an exception, the error renderer would -display the name and the solution if the debug mode is on. +当应用程序抛出此类异常时,若调试模式已开启,错误渲染器将显示名称和解决方案。 diff --git a/src/zh-CN/guide/runtime/logging.md b/src/zh-CN/guide/runtime/logging.md index 2becad6b..8c582602 100644 --- a/src/zh-CN/guide/runtime/logging.md +++ b/src/zh-CN/guide/runtime/logging.md @@ -1,27 +1,22 @@ -# Logging +# 日志 -Yii relies on [PSR-3 interfaces](https://www.php-fig.org/psr/psr-3/) for -logging, so you could configure any PSR-3 compatible logging library to do -the actual job. +Yii 依赖 [PSR-3 接口](https://www.php-fig.org/psr/psr-3/) 进行日志记录,因此您可以配置任何兼容 +PSR-3 的日志库来完成实际工作。 -Yii provides its own logger that's highly customizable and extensible. -Using it, you can log various types of messages, filter them, and gather -them at different targets, such as files or emails. +Yii +提供了自己的日志记录器,具有高度的可定制性和可扩展性。使用它,您可以记录各种类型的消息,对其进行过滤,并将其收集到不同的目标中,例如文件或电子邮件。 -Using the Yii logging framework involves the following steps: +使用 Yii 日志框架涉及以下步骤: -* Record [log messages](#log-messages) at various places in your code; -* Configure [log targets](#log-targets) in the application configuration to - filter and export log messages; -* Examine the filtered logged messages exported by different targets - (e.g. the Yii debugger). +* 在代码的各个位置记录 [日志消息](#log-messages); +* 在应用配置中配置 [日志目标](#log-targets),以过滤和导出日志消息; +* 检查由不同目标导出的已过滤日志消息(例如 Yii 调试器)。 -In this section, the focus in on the first two steps. +本节重点介绍前两个步骤。 -## Log Messages +## 日志消息 -To record log messages, you need an instance of PSR-3 logger. A class that -writes log messages should receive it as a dependency: +要记录日志消息,您需要一个 PSR-3 日志记录器实例。需要写入日志消息的类应通过依赖注入的方式接收它: ```php class MyService @@ -35,30 +30,19 @@ class MyService } ``` -Recording a log message is as simple as calling one of the following logging -methods that correspond to log levels: - -- `emergency` - System is unusable. -- `alert` - Action must be taken immediately. Example: Entire website down, - database unavailable, etc. This should trigger the SMS alerts and wake - you up. -- `critical` - Critical conditions. Example: Application component - unavailable, unexpected exception. -- `error` - Runtime errors that don't require immediate action but should - typically be logged and monitored. -- `warning` - Exceptional occurrences that aren't errors. Example: Use of - deprecated APIs, poor use of an API, undesirable things that aren't - necessarily wrong. -- `notice` - Normal but significant events. -- `info` - Interesting events. Example: User logs in, SQL logs. -- `debug` - Detailed debug information. - -Each method has two arguments. The first is a message. The Second is a -context array that typically has structured data that doesn't fit a message -well but still does offer important information. In case you provide an -exception as context, you should pass the "exception" key. Another special -key is "category." Categories are handy to better organize and filter log -messages. +记录日志消息非常简单,只需调用以下对应不同日志级别的方法之一: + +- `emergency` — 系统不可用。 +- `alert` — 必须立即采取行动。示例:整个网站宕机、数据库不可用等。这类事件应触发短信告警并将您唤醒。 +- `critical` — 严重状态。示例:应用程序组件不可用、意外异常。 +- `error` — 不需要立即处理但通常应记录和监控的运行时错误。 +- `warning` — 非错误的异常情况。示例:使用已废弃的 API、不当使用 API、不理想但不一定错误的情况。 +- `notice` — 正常但值得关注的事件。 +- `info` — 值得关注的事件。示例:用户登录、SQL 日志。 +- `debug` — 详细的调试信息。 + +每个方法有两个参数。第一个是消息内容。第二个是上下文数组,通常包含不适合放入消息中但仍然重要的结构化数据。如果以异常作为上下文,应传入 +"exception" 键。另一个特殊键是 "category"(分类),分类有助于更好地组织和过滤日志消息。 ```php use \Psr\Log\LoggerInterface; @@ -78,37 +62,26 @@ final readonly class MyService } ``` -When deciding on a category for a message, you may choose a hierarchical -naming scheme, which will make it easier for [log targets](#log-targets) to -filter messages based on their categories. A simple yet effective naming -scheme is to use the PHP magic constant `__METHOD__` for the category -names. This is also the approach used in the core Yii framework code. +在为消息选择分类时,可以采用层级命名方案,这将便于 [日志目标](#log-targets) 按分类过滤消息。一种简单而有效的命名方案是使用 PHP +魔术常量 `__METHOD__` 作为分类名称,Yii 框架核心代码也采用了这种方式。 -The `__METHOD__` constant evaluates as the name of the method (prefixed with -the fully qualified class name) where the constant appears. For example, -it's equal to the string `'App\\Service\\MyService::serve'` if the above -line of code is called within this method. +`__METHOD__` 常量的值为其所在方法的名称(前缀为完整类名)。例如,如果上述代码在该方法中调用,其值等于字符串 +`'App\\Service\\MyService::serve'`。 > [!IMPORTANT] -> The logging methods described above are actually shortcuts to the [[\Psr\Log\LoggerInterface::log()]]. +> 上述日志方法实际上是 [[\Psr\Log\LoggerInterface::log()]] 的快捷方式。 -Note that PSR-3 package provides `\Psr\Log\NullLogger` class that provides -the same set of methods but doesn't log anything. That means that you don't -have to check if logger is configured with `if ($logger !== null)` and, -instead, can assume that logger is always present. +请注意,PSR-3 包提供了 `\Psr\Log\NullLogger` 类,该类提供相同的方法集但不记录任何内容。这意味着您无需通过 `if +($logger !== null)` 检查日志记录器是否已配置,而可以始终假定日志记录器存在。 -## Log targets +## 日志目标 -A log target is an instance of a class that extends the -[[\Yiisoft\Log\Target]]. It filters the log messages by their severity -levels and categories and then exports them to some medium. For example, a -[[\Yiisoft\Log\Target\File\FileTarget|file target]]exports the filtered log -messages to a file, while a [[Yiisoft\Log\Target\Email\EmailTarget|email -target]] exports the log messages to specified email addresses. +日志目标是继承自 [[\Yiisoft\Log\Target]] +的类的实例。它按严重级别和分类过滤日志消息,然后将其导出到某种介质。例如,[[\Yiisoft\Log\Target\File\FileTarget|文件目标]]将过滤后的日志消息导出到文件,而 +[[Yiisoft\Log\Target\Email\EmailTarget|邮件目标]]则将日志消息发送到指定的电子邮件地址。 -You can register many log targets in an application by configuring them -through the `\Yiisoft\Log\Logger` constructor: +您可以通过 `\Yiisoft\Log\Logger` 构造函数配置多个日志目标并在应用中注册它们: ```php use \Psr\Log\LogLevel; @@ -126,60 +99,45 @@ $logger = new \Yiisoft\Log\Logger([ ]); ``` -In the above code, two log targets are registered: +在上述代码中,注册了两个日志目标: -* the first target selects error and warning messages and writes them to - `/path/to/app.log` file; -* the second target selects emergency, alert, and critical messages under the categories whose names start with -`Yiisoft\Cache\`, and sends them in an email to both `admin@example.com` and `developer@example.com`. +* 第一个目标选择 error 和 warning 消息并将其写入 `/path/to/app.log` 文件; +* 第二个目标选择分类名称以 `Yiisoft\Cache\` 开头的 emergency、alert 和 critical 消息, +并通过电子邮件发送给 `admin@example.com` 和 `developer@example.com`。 -Yii comes with the following built-in log targets. Please refer to the API -documentation about these classes to learn how to configure and use them. +Yii 内置了以下日志目标。请参阅这些类的 API 文档了解如何配置和使用它们。 -* [[\Yiisoft\Log\PsrTarget]]: passes log messages to another PSR-3 - compatible logger. -* [[\Yiisoft\Log\StreamTarget]]: writes log messages into a specified output - stream. -* [[\Yiisoft\Log\Target\Db\DbTarget]]: saves log messages in database. -* [[\Yiisoft\Log\Target\Email\EmailTarget]]: sends log messages to - pre-specified email addresses. -* [[\Yiisoft\Log\Target\File\FileTarget]]: saves log messages in files. -* [[\Yiisoft\Log\Target\Syslog\SyslogTarget]]: saves log messages to syslog - by calling the PHP function `syslog()`. +* [[\Yiisoft\Log\PsrTarget]]:将日志消息传递给另一个兼容 PSR-3 的日志记录器。 +* [[\Yiisoft\Log\StreamTarget]]:将日志消息写入指定的输出流。 +* [[\Yiisoft\Log\Target\Db\DbTarget]]:将日志消息保存到数据库。 +* [[\Yiisoft\Log\Target\Email\EmailTarget]]:将日志消息发送到预先指定的电子邮件地址。 +* [[\Yiisoft\Log\Target\File\FileTarget]]:将日志消息保存到文件。 +* [[\Yiisoft\Log\Target\Syslog\SyslogTarget]]:通过调用 PHP 函数 `syslog()` + 将日志消息保存到系统日志。 -In the following, we will describe the features common to all log targets. +下面将介绍所有日志目标共有的功能。 -### Message Filtering +### 消息过滤 -For each log target, you can configure its levels and categories to specify -which severity levels and categories of the messages the target should -process. +对于每个日志目标,您可以配置其级别和分类,以指定该目标应处理哪些严重级别和分类的消息。 -The target `setLevels()` method takes an array consisting of one or several -of `\Psr\Log\LogLevel` constants. +目标的 `setLevels()` 方法接受一个由一个或多个 `\Psr\Log\LogLevel` 常量组成的数组。 -By default, the target will process messages of *any* severity level. +默认情况下,目标将处理*任意*严重级别的消息。 -The target `setCategories()` method takes an array consisting of message -category names or patterns. A target will only process messages whose -category can be found or match one of the patterns in this array. A -category pattern is a category name prefix with an asterisk `*` at its -end. A category name matches a category pattern if it starts with the same -prefix of the pattern. For example, `Yiisoft\Cache\Cache::set` and -`Yiisoft\Cache\Cache::get` both match the pattern `Yiisoft\Cache\*`. +目标的 `setCategories()` +方法接受一个由消息分类名称或模式组成的数组。目标只处理分类能在该数组中找到或匹配其中某个模式的消息。分类模式是以星号 `*` +结尾的分类名称前缀。如果分类名称以模式的相同前缀开头,则该名称与该模式匹配。例如,`Yiisoft\Cache\Cache::set` 和 +`Yiisoft\Cache\Cache::get` 都匹配模式 `Yiisoft\Cache\*`。 -By default, the target will process messages of *any* category. +默认情况下,目标将处理*任意*分类的消息。 -Besides allowing the categories by the `setCategories()` method, you may -also deny certain categories by the `setExcept()` method. If the category -of a message is found or matches one of the patterns in this property, the -target will NOT process it. +除了通过 `setCategories()` 方法允许某些分类外,您还可以通过 `setExcept()` +方法排除某些分类。如果消息的分类在该属性中被找到或匹配其中某个模式,目标将不处理该消息。 -The following target configuration specifies that the target should only -process error and warning messages under the categories whose names match -either `Yiisoft\Cache\*` or `App\Exceptions\HttpException:*`, but not -`App\Exceptions\HttpException:404`. +以下目标配置指定该目标只处理分类名称匹配 `Yiisoft\Cache\*` 或 `App\Exceptions\HttpException:*` +但不匹配 `App\Exceptions\HttpException:404` 的 error 和 warning 消息。 ```php $fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); @@ -188,12 +146,10 @@ $fileTarget->setCategories(['Yiisoft\Cache\*', 'App\Exceptions\HttpException:*'] $fileTarget->setExcept(['App\Exceptions\HttpException:404']); ``` -### Message Formatting +### 消息格式化 -Log targets export the filtered log messages in a certain format. For -example, if you install a log target of the class -[[\Yiisoft\Log\Target\File\FileTarget]], you may find a log message similar -to the following in the log file: +日志目标以特定格式导出过滤后的日志消息。例如,如果安装了 [[\Yiisoft\Log\Target\File\FileTarget]] +类的日志目标,可以在日志文件中找到类似如下的日志消息: ``` 2020-12-05 09:27:52.223800 [info][application] Some message @@ -205,15 +161,14 @@ memory: 4398536 category: 'application' ``` -By default, log messages have the following format: +默认情况下,日志消息的格式如下: ``` Timestamp Prefix[Level][Category] Message Context ``` -You may customize this format by calling -[[\Yiisoft\Log\Target::setFormat()|setFormat()]] method, which takes a PHP -callable returning a custom-formatted message. +您可以通过调用 [[\Yiisoft\Log\Target::setFormat()|setFormat()]] +方法来自定义此格式,该方法接受一个返回自定义格式消息的 PHP 可调用对象。 ```php $fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); @@ -230,13 +185,10 @@ $logger->info('Text message', ['category' => 'app']); // (APP) [info] Text message ``` -In addition, if you're comfortable with the default message format but need -to change the timestamp format or add custom data to the message, you can -call the [[\Yiisoft\Log\Target::setTimestampFormat()|setTimestampFormat()]] -and [[\Yiisoft\Log\Target::setPrefix()|setPrefix()]] methods. For example, -the following code changes the timestamp format and configures a log target -to prefix each log message with the current user ID (IP address and Session -ID are removed for privacy reasons). +此外,如果您对默认消息格式满意,但需要更改时间戳格式或向消息添加自定义数据,可以调用 +[[\Yiisoft\Log\Target::setTimestampFormat()|setTimestampFormat()]] 和 +[[\Yiisoft\Log\Target::setPrefix()|setPrefix()]] +方法。例如,以下代码更改了时间戳格式,并配置日志目标为每条日志消息添加当前用户 ID 前缀(出于隐私原因,IP 地址和 Session ID 已移除)。 ```php $fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); @@ -256,20 +208,17 @@ $logger->info('Text', ['category' => 'user']); // Common context: ... ``` -The PHP callable that's passed to the -[[\Yiisoft\Log\Target::setFormat()|setFormat()]] and -[[\Yiisoft\Log\Target::setPrefix()|setPrefix()]] methods has the following -signature: +传递给 [[\Yiisoft\Log\Target::setFormat()|setFormat()]] 和 +[[\Yiisoft\Log\Target::setPrefix()|setPrefix()]] 方法的 PHP 可调用对象具有以下签名: ```php function (\Yiisoft\Log\Message $message, array $commonContext): string; ``` -Besides message prefixes, log targets also append some common context information to each of the log messages. -You may adjust this behavior by calling target [[\Yiisoft\Log\Target::setCommonContext()|setCommonContext()]] -method, passing an array of data in the `key => value` format that you want to include. -For example, the following log target configuration specifies that only the -value of the `$_SERVER` variable will be appended to the log messages. +除消息前缀外,日志目标还会向每条日志消息追加一些公共上下文信息。 +您可以通过调用目标的 [[\Yiisoft\Log\Target::setCommonContext()|setCommonContext()]] +方法来调整此行为,传入希望包含的 `key => value` 格式的数据数组。 +例如,以下日志目标配置指定只将 `$_SERVER` 变量的值追加到日志消息中。 ```php $fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); @@ -277,24 +226,19 @@ $fileTarget->setCommonContext(['server' => $_SERVER]); ``` -### Message Trace Level +### 消息追踪级别 -During development, it's often desirable to see where each log message is -coming from. You can achieve this by calling the -[[\Yiisoft\Log\Logger::setTraceLevel()|setTraceLevel()]] method like the -following: +在开发过程中,了解每条日志消息的来源通常很有必要。您可以通过如下方式调用 +[[\Yiisoft\Log\Logger::setTraceLevel()|setTraceLevel()]] 方法来实现: ```php $logger = new \Yiisoft\Log\Logger($targets); $logger->setTraceLevel(3); ``` -This application configuration sets the trace level to be 3, so each log -message will be appended with at most three levels of the call stack at -which the log message is recorded. You can also set a list of paths to -exclude from the trace by calling the +此应用配置将追踪级别设置为 3,因此每条日志消息最多会附加记录该消息时的三层调用栈。您还可以通过调用 [[\Yiisoft\Log\Logger::setExcludedTracePaths()|setExcludedTracePaths()]] -method. +方法设置要从追踪中排除的路径列表。 ```php $logger = new \Yiisoft\Log\Logger($targets); @@ -302,18 +246,15 @@ $logger->setExcludedTracePaths(['/path/to/file', '/path/to/folder']); ``` > [!IMPORTANT] -> Getting call stack information isn't trivial. Therefore, you should only use this feature during development -or when debugging an application. +> 获取调用栈信息并非轻量操作。因此,您应仅在开发阶段 +或调试应用程序时使用此功能。 -### Message flushing and exporting +### 消息刷新与导出 -As aforementioned, log messages are maintained in an array by -[[\Yiisoft\Log\Logger|logger object]]. To limit the memory consumption by -this array, the logger will flush the recorded messages to the [log -targets](#log-targets) each time the array accumulates a certain number of -log messages. You can customize this number by calling the -[[\Yiisoft\Log\Logger::setFlushInterval()]] method: +如前所述,日志消息由 [[\Yiisoft\Log\Logger|日志对象]] +维护在一个数组中。为限制该数组的内存占用,每当数组累积到一定数量的日志消息时,日志记录器会将已记录的消息刷新到[日志目标](#log-targets)。您可以通过调用 +[[\Yiisoft\Log\Logger::setFlushInterval()]] 方法自定义此数量: ```php @@ -322,26 +263,22 @@ $logger->setFlushInterval(100); // default is 1000 ``` > [!IMPORTANT] -> Message flushing also occurs when the application ends, -which ensures log targets can receive complete log messages. +> 消息刷新也会在应用程序结束时发生, +这确保日志目标能接收到完整的日志消息。 -When the [[\Yiisoft\Log\Logger|logger object]] flushes log messages to [log targets](#log-targets), -they don't get exported immediately. Instead, the message exporting only occurs when a log target - accumulates a certain number of the filtered messages. You can customize this number by calling the -[[\Yiisoft\Log\Target::setExportInterval()|setExportInterval()]] method of individual -[log targets](#log-targets), like the following: +当 [[\Yiisoft\Log\Logger|日志对象]] 将日志消息刷新到 [日志目标](#log-targets) 时, +消息并不会立即被导出。消息导出只在日志目标 +累积了一定数量的已过滤消息后才会发生。您可以通过调用各个 +[日志目标](#log-targets) 的 [[\Yiisoft\Log\Target::setExportInterval()|setExportInterval()]] 方法 +来自定义此数量,如下所示: ```php $fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); $fileTarget->setExportInterval(100); // default is 1000 ``` -Because of the flushing and exporting level setting, by default when you -call any logging method, you will NOT see the log message immediately in the -log targets. This could be a problem for some long-running console -applications. To make each log message appear immediately in the log -targets, you should set both flush interval and export interval to be 1, as -shown below: +由于刷新和导出间隔的设置,默认情况下调用任何日志方法时,您不会立即在日志目标中看到该日志消息。这对某些长期运行的控制台应用程序可能是个问题。要使每条日志消息立即出现在日志目标中,应将刷新间隔和导出间隔都设置为 +1,如下所示: ```php $fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); @@ -352,15 +289,14 @@ $logger->setFlushInterval(1); ``` > [!NOTE] -> Frequent message flushing and exporting will degrade the performance of your application. +> 频繁的消息刷新和导出会降低应用程序的性能。 -### Toggling log targets +### 启用/禁用日志目标 -You can enable or disable a log target by calling its -[[\Yiisoft\Log\Target::enable()|enable()] ] and -[[\Yiisoft\Log\Target::disable()|disable()]] methods. You may do so via the -log target configuration or by the following PHP statement in your code: +您可以通过调用日志目标的 [[\Yiisoft\Log\Target::enable()|enable()]] 和 +[[\Yiisoft\Log\Target::disable()|disable()]] 方法来启用或禁用它。您可以通过日志目标配置或在代码中使用以下 +PHP 语句来实现: ```php $fileTarget = new \Yiisoft\Log\Target\File\FileTarget('/path/to/app.log'); @@ -373,33 +309,27 @@ foreach ($logger->getTargets() as $target) { } ``` -To check whether the log target is enabled, call the `isEnabled()` method. -You also may pass callable to -[[\Yiisoft\Log\Target::setEnabled()|setEnabled()]] to define a dynamic -condition for whether the log target should be enabled or not. +要检查日志目标是否已启用,可调用 `isEnabled()` 方法。您还可以向 +[[\Yiisoft\Log\Target::setEnabled()|setEnabled()]] 传入可调用对象,以动态定义日志目标的启用条件。 -### Creating new targets +### 创建新目标 -Creating a new log target class is straightforward. You mainly need to -implement the [[\Yii\Log\Target::export()]] abstract method that sends all -accumulated log messages to a designated medium. +创建新的日志目标类非常简单。您主要需要实现 [[\Yii\Log\Target::export()]] +抽象方法,该方法负责将所有累积的日志消息发送到指定的介质。 -The following protected methods will also be available for child targets: +以下受保护的方法也可在子目标中使用: -- `getMessages` - Get a list of log messages ([[\Yii\Log\Message]] - instances). -- `getFormattedMessages` - Get a list of log messages formatted as strings. -- `formatMessages` - Get all log messages formatted as a string. -- `getCommonContext` - Get an array with common context data in the `key => - value` format. +- `getMessages` — 获取日志消息列表([[\Yii\Log\Message]] 实例)。 +- `getFormattedMessages` — 获取格式化为字符串的日志消息列表。 +- `formatMessages` — 获取所有日志消息格式化后的单个字符串。 +- `getCommonContext` — 获取包含公共上下文数据的 `key => value` 格式数组。 -For more details, you may refer to any of the log target classes included in -the package. +更多详情,请参阅包中包含的任意日志目标类。 > [!TIP] -> Instead of creating your own loggers, you may try any PSR-3 compatible logger such -as [Monolog](https://github.com/Seldaek/monolog) by using [[\Yii\Log\PsrTarget]]. +> 无需自己创建日志记录器,您可以通过 [[\Yii\Log\PsrTarget]] 使用任何兼容 PSR-3 的日志库, +例如 [Monolog](https://github.com/Seldaek/monolog)。 ```php /** diff --git a/src/zh-CN/guide/runtime/request.md b/src/zh-CN/guide/runtime/request.md index 812d2804..dee85771 100644 --- a/src/zh-CN/guide/runtime/request.md +++ b/src/zh-CN/guide/runtime/request.md @@ -1,6 +1,6 @@ -# Request +# 请求 -HTTP request has a method, URI, a set of headers and a body: +HTTP 请求包含方法、URI、一组请求头以及正文: ``` POST /contact HTTP/1.1 @@ -14,13 +14,10 @@ Accept-Encoding: gzip, deflate } ``` -The method is `POST`, URI is `/contact`. Extra headers are specifying host, -preferred language and encoding. The body could be anything. In this case, -it's a JSON payload. +方法为 `POST`,URI 为 `/contact`。额外的请求头指定了主机、首选语言和编码。正文可以是任何内容,此处为 JSON 数据。 -Yii uses [PSR-7 `ServerRequest`](https://www.php-fig.org/psr/psr-7/) as -request representation. The object is available in controller actions and -other types of middleware: +Yii 使用 [PSR-7 `ServerRequest`](https://www.php-fig.org/psr/psr-7/) +作为请求的表示。该对象可在控制器操作和其他类型的中间件中使用: ```php public function view(ServerRequestInterface $request): ResponseInterface @@ -29,15 +26,15 @@ public function view(ServerRequestInterface $request): ResponseInterface } ``` -## Method +## 方法 -The method could be obtained from a request object: +可以从请求对象中获取方法: ```php $method = $request->getMethod(); ``` -Usually it's one of the: +通常是以下之一: - GET - POST @@ -47,8 +44,7 @@ Usually it's one of the: - PATCH - OPTIONS -In case you want to make sure the request method is of a certain type, there -is a special class with method names: +如果需要判断请求方法是否为某种类型,可以使用包含方法名称的专用类: ```php use Yiisoft\Http\Method; @@ -60,22 +56,22 @@ if ($request->getMethod() === Method::POST) { ## URI -A URI has: +URI 包含以下部分: -- Scheme (`http`, `https`) -- Host (`yiiframework.com`) -- Port (`80`, `443`) -- Path (`/posts/1`) -- Query string (`page=1&sort=+id`) -- Fragment (`#anchor`) +- 协议(`http`、`https`) +- 主机(`yiiframework.com`) +- 端口(`80`、`443`) +- 路径(`/posts/1`) +- 查询字符串(`page=1&sort=+id`) +- 片段(`#anchor`) -You can obtain `UriInterface` from request like the following: +您可以按如下方式从请求中获取 `UriInterface`: ```php $uri = $request->getUri(); ``` -Then you can get various details from its methods: +然后您可以通过其方法获取各类详细信息: - `getScheme()` - `getAuthority()` @@ -86,10 +82,9 @@ Then you can get various details from its methods: - `getQuery()` - `getFragment()` -## Headers +## 头部 -There are various methods to inspect request headers. To get all headers as -an array: +有多种方法可以查看请求头。获取所有请求头的数组: ```php $headers = $request->getHeaders(); @@ -98,15 +93,14 @@ foreach ($headers as $name => $values) { } ``` -To get a single header: +获取单个请求头: ```php $values = $request->getHeader('Accept-Encoding'); ``` -Also, you could get value as a comma-separated string instead of an array. -That's especially handy if a header has a single value: +也可以获取逗号分隔的字符串形式而非数组,当请求头只有单个值时尤为方便: ```php if ($request->getHeaderLine('X-Requested-With') === 'XMLHttpRequest') { @@ -115,7 +109,7 @@ if ($request->getHeaderLine('X-Requested-With') === 'XMLHttpRequest') { } ``` -To check if a header is present in the request: +检查请求中是否存在某个请求头: ```php if ($request->hasHeader('Accept-Encoding')) { @@ -125,23 +119,21 @@ if ($request->hasHeader('Accept-Encoding')) { ## 正文 -There are two methods to get body contents. The first is getting the body as -it is without parsing: +有两种方式获取正文内容。第一种是直接获取未解析的原始正文: ```php $body = $request->getBody(); ``` -The `$body` would be an instance of `Psr\Http\Message\StreamInterface`. +`$body` 是 `Psr\Http\Message\StreamInterface` 的实例。 -Also, you could get a parsed body: +也可以获取已解析的正文: ```php $bodyParameters = $request->getParsedBody(); ``` -Parsing depends on PSR-7 implementation and may require middleware for -custom body formats. +解析取决于 PSR-7 的具体实现,对于自定义正文格式可能需要中间件支持。 ```php getUploadedFiles(); @@ -182,8 +173,6 @@ foreach ($files as $file) { } ``` -## Attributes +## 属性 -Application middleware may set custom request attributes using -`withAttribute()` method. You can get these attributes with -`getAttribute()`. +应用中间件可以使用 `withAttribute()` 方法设置自定义请求属性,并通过 `getAttribute()` 获取这些属性。 diff --git a/src/zh-CN/guide/runtime/response.md b/src/zh-CN/guide/runtime/response.md index 59f99663..2cac325c 100644 --- a/src/zh-CN/guide/runtime/response.md +++ b/src/zh-CN/guide/runtime/response.md @@ -1,6 +1,6 @@ -# Response +# 响应 -HTTP response has status code and message, a set of headers and a body: +HTTP 响应包含状态码和消息、一组响应头以及正文: ``` HTTP/1.1 200 OK @@ -14,12 +14,10 @@ Connection: Closed Hello! ``` -Yii uses [PSR-7 `Response`](https://www.php-fig.org/psr/psr-7/) in the web -application to represent response. +Yii 在 Web 应用程序中使用 [PSR-7 `Response`](https://www.php-fig.org/psr/psr-7/) +来表示响应。 -The object should be constructed and returned as a result of the execution -of controller actions or other middleware. Usually, the middleware has a -response factory injected into its constructor. +该对象应在控制器操作或其他中间件执行后构建并返回。通常,中间件会通过构造函数注入一个响应工厂。 ```php use Psr\Http\Message\ResponseFactoryInterface; @@ -43,9 +41,9 @@ final readonly class PostAction } ``` -## Status code +## 状态码 -You can set a status code like the following: +您可以按如下方式设置状态码: ```php use Yiisoft\Http\Status; @@ -53,24 +51,23 @@ use Yiisoft\Http\Status; $response = $response->withStatus(Status::NOT_FOUND); ``` -Majority of status codes are available from `Status` class for convenience -and readability. +大多数状态码可通过 `Status` 类获取,以便于使用和提高可读性。 -## Headers +## 头部 -You can set headers like this: +您可以按如下方式设置响应头: ```php $response = $response->withHeader('Content-type', 'application/json'); ``` -If there is a need to append a header value to the existing header: +如果需要向已有响应头追加值: ```php $response = $response->withAddedHeader('Set-Cookie', 'qwerty=219ffwef9w0f; Domain=somecompany.co.uk; Path=/; Expires=Wed, 30 Aug 2019 00:00:00 GMT'); ``` -And, if needed, headers could be removed: +如果需要,也可以移除响应头: ```php $response = $response->withoutHeader('Set-Cookie'); @@ -78,9 +75,9 @@ $response = $response->withoutHeader('Set-Cookie'); ## 正文 -Response body is an object implementing `Psr\Http\Message\StreamInterface`. +响应正文是一个实现 `Psr\Http\Message\StreamInterface` 的对象。 -You can write to it via the interface itself: +您可以通过该接口直接写入内容: ```php $body = $response->getBody(); @@ -88,9 +85,9 @@ $body->write('Hello'); ``` -## Examples +## 示例 -### Redirecting +### 重定向 ```php use Yiisoft\Http\Status; @@ -100,17 +97,17 @@ return $response ->withHeader('Location', 'https://www.example.com'); ``` -Note that there are different statuses used for redirection: +请注意,重定向使用不同的状态码: -| Code | Usage | What is it for | +| 代码 | 用法 | 用途 | |------|------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| 301 | `Status::MOVED_PERMANENTLY` | Permanently changed a URL structure. Search engines update their indexes, and browsers cache it. | -| 308 | `Status::PERMANENT_REDIRECT` | Like 301, but guarantees the HTTP method won't change. | -| 302 | `Status::FOUND` | Temporary changes like maintenance pages. Original URL should still be used for future requests. Search engines typically don't update their indexes. | -| 307 | `Status::TEMPORARY_REDIRECT` | Like 302, but guarantees the HTTP method won't change. | -| 303 | `Status::SEE_OTHER` | After form submissions to prevent duplicate submissions if the user refreshes. Explicitly tells to use `GET` for the redirect, even if the original request was `POST`. | +| 301 | `Status::MOVED_PERMANENTLY` | URL 结构已永久更改。搜索引擎更新索引,浏览器缓存结果。 | +| 308 | `Status::PERMANENT_REDIRECT` | 类似 301,但保证 HTTP 方法不会改变。 | +| 302 | `Status::FOUND` | 临时更改,例如维护页面。原始 URL 应继续用于未来请求,搜索引擎通常不更新索引。 | +| 307 | `Status::TEMPORARY_REDIRECT` | 类似 302,但保证 HTTP 方法不会改变。 | +| 303 | `Status::SEE_OTHER` | 表单提交后防止用户刷新时重复提交。明确指定重定向使用 `GET`,即使原始请求是 `POST`。 | -### Responding with JSON +### 返回 JSON 响应 ```php use Yiisoft\Http\Status; diff --git a/src/zh-CN/guide/runtime/routing.md b/src/zh-CN/guide/runtime/routing.md index 6bf620d2..3e92e3bb 100644 --- a/src/zh-CN/guide/runtime/routing.md +++ b/src/zh-CN/guide/runtime/routing.md @@ -1,23 +1,17 @@ -# Routing and URL generation +# 路由与 URL 生成 -Usually, a Yii application processes certain requests with certain -handlers. It selects a handler based on the request URL. The part of the -application that does the job is a router, and the process of selecting a -handler, instantiating it and running a handler method is *routing*. +通常,Yii 应用程序使用特定的处理器处理特定的请求。它根据请求 URL +选择处理器。应用程序中负责此工作的部分是路由器,而选择处理器、实例化并调用处理器方法的过程就是*路由*。 -The reverse process of routing is *URL generation*, which creates a URL from -a given named route and the associated query parameters. When you later -request the created URL, the routing process can resolve it back into the -original route and query parameters. +路由的逆过程是 *URL 生成*,它根据给定的命名路由和相关查询参数创建 URL。当您之后请求所生成的 URL +时,路由过程可以将其解析回原始路由和查询参数。 -Routing and URL generation are separate services, but they use a common set -of routes for both URL matching and URL generation. +路由和 URL 生成是独立的服务,但它们共用同一套路由配置来进行 URL 匹配和 URL 生成。 -## Configuring routes +## 配置路由 -By configuring routes, you can let your application recognize arbitrary URL -formats without modifying your existing application code. You can configure -routes in `/config/routes.php`. The structure of the file is the following: +通过配置路由,您可以让应用程序识别任意 URL 格式,而无需修改现有应用代码。您可以在 `/config/routes.php` +中配置路由,文件结构如下: ```php +## 路由 -Yii routing is flexible, and internally it may use different routing -implementations. The actual matching algorithm may vary, but the basic idea -stays the same. +Yii 路由非常灵活,内部可以使用不同的路由实现。实际的匹配算法可能有所不同,但基本思路是一致的。 -Router matches routes defined in config from top to bottom. If there is a -match, further matching isn't performed and the router executes the route -handler to get the response. If there is no match at all, router passes -handling to the next middleware in the [application middleware -set](../structure/middleware.md). +路由器从上到下匹配配置中定义的路由。一旦匹配成功,就不再继续匹配,路由器会执行路由处理器以获取响应。如果完全没有匹配,路由器会将处理传递给[应用中间件集合](../structure/middleware.md)中的下一个中间件。 -## Generating URLs +## 生成 URL -To generate URL based on a route, a route should have a name: +要根据路由生成 URL,路由必须有名称: ```php +## 路由模式 -Route patterns used depend on the underlying implementation used. The -default implementation is -[nikic/FastRoute](https://github.com/nikic/FastRoute). +所使用的路由模式取决于底层实现。默认实现为 [nikic/FastRoute](https://github.com/nikic/FastRoute)。 -Basic patterns are static like `/test`. That means they must match exactly -in order for a route match. +基本模式是静态的,如 `/test`,这意味着必须完全匹配才能成功路由。 -### Named Parameters +### 命名参数 -A pattern can include one or more named parameters which are specified in -the pattern in the format of `{ParamName:RegExp}`, where `ParamName` -specifies the parameter name and `RegExp` is an optional regular expression -used to match parameter values. If `RegExp` isn't specified, it means the -parameter value should be a string without any slash. +模式中可以包含一个或多个命名参数,格式为 `{ParamName:RegExp}`,其中 `ParamName` 指定参数名称,`RegExp` +是用于匹配参数值的可选正则表达式。如果未指定 `RegExp`,则表示参数值应为不含斜杠的字符串。 > [!NOTE] -> You can only use regular expressions inside parameters. The rest of the pattern is considered plain text. +> 您只能在参数内部使用正则表达式,模式的其余部分被视为纯文本。 -You can't use capturing groups. For example `{lang:(en|de)}` isn't a valid -placeholder, because `()` is a capturing group. Instead, you can use either -`{lang:en|de}` or `{lang:(?:en|de)}`. +不能使用捕获组。例如 `{lang:(en|de)}` 不是有效的占位符,因为 `()` 是捕获组。应改用 `{lang:en|de}` 或 +`{lang:(?:en|de)}`。 -On a route match router fills the associated request attributes with values -matching the corresponding parts of the URL. When you use the rule to -create a URL, it will take the values of the provided parameters and insert -them at the places where the parameters are declared. +路由匹配时,路由器会用 URL 中对应部分的值填充相关请求属性。当使用规则生成 URL 时,它会取所提供参数的值并将其插入参数声明的位置。 -Let's use some examples to illustrate how named parameters work. Assume -you've declared the following three patterns: +让我们通过示例来说明命名参数的工作方式。假设您声明了以下三个模式: 1. `'posts/{year:\d{4}}/{category}` 2. `'posts'` 3. `'post/{id:\d+}'` -- `/posts` match the second pattern; -- `/posts/2014/php` match a first pattern. Parameters are the `year` whose - value is 2014 and the `category` whose value is `php`; -- `/post/100` match a third pattern. The `id` parameter value is 100; -- `/posts/php` doesn't match. +- `/posts` 匹配第二个模式; +- `/posts/2014/php` 匹配第一个模式,参数 `year` 的值为 2014,`category` 的值为 `php`; +- `/post/100` 匹配第三个模式,`id` 参数值为 100; +- `/posts/php` 不匹配任何模式。 -When generating URLs, you should use the following parameters: +生成 URL 时,应使用以下参数: ```php echo $url->generate('first', ['year' => '2020', 'category' => 'Virology']); @@ -308,13 +268,11 @@ echo $url->generate('second'); echo $url->generate('third', ['id' => '42']); ``` -### Optional parts +### 可选部分 -You should wrap optional pattern parts with `[` and `]`. For example, -`/posts[/{id}]` pattern would match both `http://example.com/posts` and -`http://example.com/posts/42`. Router would fill `id` argument of -`CurrentRoute` service in the second case only. In this case, you could -specify the default value: +可选模式部分应用 `[` 和 `]` 包裹。例如,`/posts[/{id}]` 模式可以同时匹配 `http://example.com/posts` +和 `http://example.com/posts/42`。路由器只在第二种情况下填充 `CurrentRoute` 服务的 `id` +参数。此时可以指定默认值: ```php use \Yiisoft\Router\Route; @@ -322,5 +280,4 @@ use \Yiisoft\Router\Route; Route::get('/posts[/{id}]')->defaults(['id' => '1']); ``` -Optional parts are only supported in a trailing position, not in the middle -of a route. +可选部分只支持在路由末尾,不支持在路由中间。 diff --git a/src/zh-CN/guide/runtime/sessions.md b/src/zh-CN/guide/runtime/sessions.md index e2df2a50..9a7ffa54 100644 --- a/src/zh-CN/guide/runtime/sessions.md +++ b/src/zh-CN/guide/runtime/sessions.md @@ -1,25 +1,20 @@ -# Sessions +# 会话 -Sessions persist data between requests without passing them to the client -and back. Yii has [a session package](https://github.com/yiisoft/session) -to work with session data. +会话在请求之间持久化数据,无需将数据传递给客户端再传回。Yii 提供了 +[会话包](https://github.com/yiisoft/session) 来处理会话数据。 -To add it to your application, use composer: +要将其添加到应用程序,请使用 composer: ```shell composer require yiisoft/session ``` -## Configuring middleware +## 配置中间件 -To keep a session between requests, you need to add `SessionMiddleware` to -your route group or application middlewares. You should prefer a route -group when you have both API with token-based authentication and regular web -routes in the same application. Having it this way avoids starting the -session for API endpoints. +要在请求之间保持会话,需要将 `SessionMiddleware` 添加到路由组或应用程序中间件中。当应用程序同时包含基于令牌认证的 API 和常规 +Web 路由时,优先选择路由组。这样可以避免为 API 端点启动会话。 -To add a session for a certain group of routes, edit `config/routes.php` -like the following: +要为特定路由组添加会话,请按如下方式编辑 `config/routes.php`: ```php [!NOTE] -> Closing session as early as possible is a good practice since many session implementations are blocking other -> requests while the session is open. +> 尽早关闭会话是一个良好实践,因为许多会话实现在会话开启期间 +> 会阻塞其他请求。 -There are two more ways to close a session: +关闭会话还有两种方式: ```php public function actionProfile(\Yiisoft\Session\SessionInterface $session) @@ -93,9 +87,9 @@ public function actionProfile(\Yiisoft\Session\SessionInterface $session) } ``` -## Working with session data +## 处理会话数据 -Usually you will use the following methods to work with session data: +通常您将使用以下方法处理会话数据: ```php public function actionProfile(\Yiisoft\Session\SessionInterface $session) @@ -125,15 +119,11 @@ public function actionProfile(\Yiisoft\Session\SessionInterface $session) } ``` -## Flash messages +## 闪存消息 -In case you need some data to remain in session until read, such as in case -of displaying a message on the next page, "flash" messages are what you -need. A flash message is a special type of data that's available only in -the current request and the next request. After that, it will be deleted -automatically. +如果您需要某些数据在会话中保留直到被读取(例如在下一页显示消息),那么“闪存”消息正是您所需要的。闪存消息是一种特殊类型的数据,仅在当前请求和下一个请求中可用,之后将被自动删除。 -`FlashInteface` usage is the following: +`FlashInterface` 的用法如下: ```php /** @var Yiisoft\Session\Flash\FlashInterface $flash */ @@ -148,14 +138,13 @@ if ($warning !== null) { } ``` -## Custom session storage +## 自定义会话存储 -When using `Yiisoft\Session\Session`, you can use your own storage -implementation: +使用 `Yiisoft\Session\Session` 时,您可以使用自定义存储实现: ```php $handler = new MySessionHandler(); $session = new \Yiisoft\Session\Session([], $handler); ``` -Custom storage must implement `\SessionHandlerInterface`. +自定义存储必须实现 `\SessionHandlerInterface`。 diff --git a/src/zh-CN/guide/security/authentication.md b/src/zh-CN/guide/security/authentication.md index 1e658d47..cc6b0f44 100644 --- a/src/zh-CN/guide/security/authentication.md +++ b/src/zh-CN/guide/security/authentication.md @@ -1,34 +1,26 @@ -# Authentication +# 认证 -Authentication is the process of verifying the identity of a user. It -usually uses an identifier (for example, a username or an email address) and -a secret token (such as a password or an access token) to judge if the user -is the one whom he claims as. Authentication is the basis of the login -feature. +认证是验证用户身份的过程。它通常使用标识符(例如用户名或电子邮件地址)和 secret 令牌(例如 password +或访问令牌)来判断用户是否是其声称的人。认证是登录功能的基础。 -Yii provides an authentication framework which wires up various components -to support login. To use this framework, you mainly need to do the following -work: +Yii 提供了一个认证框架,它连接各种组件以支持登录。要使用此框架,您主要需要执行以下工作: -* Configure the `Yiisoft\User\CurrentUser` service; -* Create a class implementing the `\Yiisoft\Auth\IdentityInterface` - interface; -* Create a class implementing the - `\Yiisoft\Auth\IdentityRepositoryInterface` interface; +* 配置 `Yiisoft\User\CurrentUser` 服务; +* 创建一个实现 `\Yiisoft\Auth\IdentityInterface` 接口的类; +* 创建一个实现 `\Yiisoft\Auth\IdentityRepositoryInterface` 接口的类; -To use the `Yiisoft\User\CurrentUser` service, install -[yiisoft/user](https://github.com/yiisoft/user) package: +要使用 `Yiisoft\User\CurrentUser` 服务,请安装 +[yiisoft/user](https://github.com/yiisoft/user) 包: ```shell composer require yiisoft/user ``` -## Configuring `Yiisoft\User\CurrentUser` +## 配置 `Yiisoft\User\CurrentUser` -The `Yiisoft\User\CurrentUser` application service manages the user -authentication status. It depends on -`Yiisoft\Auth\IdentityRepositoryInterface` that should return an instance of -`\Yiisoft\Auth\IdentityInterface` which has the actual authentication logic. +`Yiisoft\User\CurrentUser` 应用服务管理用户认证状态。它依赖于 +`Yiisoft\Auth\IdentityRepositoryInterface`,该接口应返回一个包含实际认证逻辑的 +`\Yiisoft\Auth\IdentityInterface` 实例。 ```php use Yiisoft\Session\Session; @@ -53,16 +45,13 @@ return [ ]; ``` -## Implementing`\Yiisoft\Auth\IdentityInterface` +## 实现 `\Yiisoft\Auth\IdentityInterface` -The identity class must implement the `\Yiisoft\Auth\IdentityInterface` -which has a single method: +身份类必须实现 `\Yiisoft\Auth\IdentityInterface` 接口,该接口只有一个方法: -* [[yii\web\IdentityInterface::getId()|getId()]]: it returns the ID of the - user represented by this identity instance. +* [[yii\web\IdentityInterface::getId()|getId()]]:它返回此身份实例所代表的用户的 ID。 -In the following example, an identity class is implemented as a pure PHP -object. +在以下示例中,身份类被实现为一个纯 PHP 对象。 ```php +## 实现 `\Yiisoft\Auth\IdentityRepositoryInterface` -The identity repository class must implement the -`\Yiisoft\Auth\IdentityRepositoryInterface` which has the following methods: +身份仓库类必须实现 `\Yiisoft\Auth\IdentityRepositoryInterface` 接口,该接口具有以下方法: -* `findIdentity(string $id): ?IdentityInterface`: it looks for an instance - of the identity class using the specified ID. This method is used when you - need to keep the login status via session. -* `findIdentityByToken(string $token, string $type): ?IdentityInterface`: it - looks for an instance of the identity class using the specified access - token. This method is used when you need to authenticate a user by a - single secret token (for example, in a stateless REST API). +* `findIdentity(string $id): ?IdentityInterface`:它使用指定的 ID + 查找身份类的实例。当您需要通过会话保持登录状态时使用此方法。 +* `findIdentityByToken(string $token, string $type): + ?IdentityInterface`:它使用指定的访问令牌查找身份类的实例。当您需要通过单个 secret 令牌(例如,在无状态 REST API + 中)对用户进行认证时使用此方法。 -A dummy implementation may look like the following: +一个示例实现可能如下所示: ```php namespace App\User; @@ -144,11 +130,9 @@ final readonly class IdentityRepository implements IdentityRepositoryInterface } ``` -## Using `Yiisoft\User\CurrentUser` +## 使用 `Yiisoft\User\CurrentUser` -You can use `Yiisoft\User\CurrentUser` service to get current user -identity. As any service, it could be auto-wired in either action handler -constructor or method: +您可以使用 `Yiisoft\User\CurrentUser` 服务来获取当前用户身份。与任何服务一样,它可以在操作处理器的构造函数或方法中自动装配: ```php use Psr\Http\Message\ServerRequestInterface; @@ -170,10 +154,9 @@ final readonly class SiteController } ``` -`isGuest()` determines if user is logged in or not. `getIdentity()` returns -an instance of identity. +`isGuest()` 判断用户是否已登录。`getIdentity()` 返回一个身份实例。 -To log in a user, you may use the following code: +要登录用户,您可以使用以下代码: ```php $identity = $identityRepository->findByEmail($email); @@ -182,22 +165,20 @@ $identity = $identityRepository->findByEmail($email); $user->login($identity); ``` -The `login()` method sets the identity to the User service. It stores -identity into session so user authentication status is maintained. +`login()` 方法将身份设置到用户服务。它将身份存储到会话中,以便维护用户认证状态。 -To log out a user, call +要注销用户,请调用 ```php /* @var $user \Yiisoft\User\CurrentUser */ $user->logout(); ``` -## Protecting Routes +## 保护路由 -The `Yiisoft\Auth\Middleware\Authentication` middleware can be used to -restrict access to a given route to authenticated users only. +`Yiisoft\Auth\Middleware\Authentication` 中间件可用于将对给定路由的访问限制为仅限已认证用户。 -First, configure the `Yiisoft\Auth\AuthenticationMethodInterface`: +首先,配置 `Yiisoft\Auth\AuthenticationMethodInterface`: ```php use Yiisoft\Auth\AuthenticationMethodInterface; @@ -209,8 +190,7 @@ return [ ]; ``` -Then, apply the `Yiisoft\Auth\Middleware\Authentication` middleware to a -route: +然后,将 `Yiisoft\Auth\Middleware\Authentication` 中间件应用到路由: ```php use Yiisoft\Auth\Middleware\Authentication; @@ -221,7 +201,7 @@ Route::post('/create') ->name('site/create') ``` - Or to a group of routes: + 或应用到一组路由: ```php use Yiisoft\Auth\Middleware\Authentication; @@ -238,21 +218,17 @@ Group::create() ) ``` -## Authentication Events +## 认证事件 -The user service raises a few events during the login and logout processes. +用户服务在登录和注销过程中会触发一些事件。 -* `\Yiisoft\User\Event\BeforeLogin`: raised at the beginning of `login()`. - If the event handler calls `invalidate()` on an event object, the login - process will be cancelled. -* `\Yiisoft\User\Event\AfterLogin`: raised after a successful login. -* `\Yiisoft\User\Event\BeforeLogout`: raised at the beginning of - `logout()`. If the event handler calls `invalidate()` on an event object, - the logout process will be cancelled. -* `\Yiisoft\User\Event\AfterLogout`: raised after a successful logout. +* `\Yiisoft\User\Event\BeforeLogin`:在 `login()` 开始时触发。如果事件处理器在事件对象上调用 + `invalidate()`,登录过程将被取消。 +* `\Yiisoft\User\Event\AfterLogin`:在成功登录后触发。 +* `\Yiisoft\User\Event\BeforeLogout`:在 `logout()` 开始时触发。如果事件处理器在事件对象上调用 + `invalidate()`,注销过程将被取消。 +* `\Yiisoft\User\Event\AfterLogout`:在成功注销后触发。 -You may respond to these events to implement features such as login audit, -online user statistics. For example, in the handler for -`\Yiisoft\User\Event\AfterLogin`, you may record the login time and IP -address in the `user` database table. +您可以响应这些事件来实现登录审计、在线用户统计等功能。例如,在 `\Yiisoft\User\Event\AfterLogin` 的处理器中,您可以在 +`user` 数据库表中记录登录时间和 IP 地址。 diff --git a/src/zh-CN/guide/security/authorization.md b/src/zh-CN/guide/security/authorization.md index f8fd2792..0c9244de 100644 --- a/src/zh-CN/guide/security/authorization.md +++ b/src/zh-CN/guide/security/authorization.md @@ -1,12 +1,10 @@ -# Authorization +# 授权 -Authorization is the process of verifying that a user has enough permission -to do something. +授权是验证用户是否有足够权限执行某项操作的过程。 -## Checking for permission +## 检查权限 -You can check if a user has certain permissions by using -`\Yiisoft\User\CurrentUser` service: +您可以使用 `\Yiisoft\User\CurrentUser` 服务来检查用户是否具有特定权限: ```php namespace App\Blog\Post; @@ -46,75 +44,54 @@ final readonly class PostController } ``` -Behind the scenes, `Yiisoft\User\CurrentUser::can()` method calls -`Yiisoft\Access\AccessCheckerInterface::userHasPermission()` so you should -provide an implementation in dependency container in order for it to work. +在幕后,`Yiisoft\User\CurrentUser::can()` 方法调用 +`Yiisoft\Access\AccessCheckerInterface::userHasPermission()`,因此您应该在依赖容器中提供一个实现才能使其工作。 -## Role-based access control (RBAC) +## 基于角色的访问控制 (RBAC) -Role-Based Access Control (RBAC) provides a simple yet powerful centralized -access control. Please refer to the -[Wikipedia](https://en.wikipedia.org/wiki/Role-based_access_control) for -details about comparing RBAC with other more traditional access control -schemes. +基于角色的访问控制 (RBAC) 提供了一种简单而强大的集中式访问控制。有关 RBAC 与其他更传统的访问控制方案的比较详情,请参阅 +[Wikipedia](https://en.wikipedia.org/wiki/Role-based_access_control)。 -Yii implements a General Hierarchical RBAC, following the [NIST RBAC -model](https://csrc.nist.gov/CSRC/media/Publications/conference-paper/2000/07/26/the-nist-model-for-role-based-access-control-towards-a-unified-/documents/sandhu-ferraiolo-kuhn-00.pdf). +Yii 实现了通用分层 RBAC,遵循 [NIST RBAC +模型](https://csrc.nist.gov/CSRC/media/Publications/conference-paper/2000/07/26/the-nist-model-for-role-based-access-control-towards-a-unified-/documents/sandhu-ferraiolo-kuhn-00.pdf)。 -Using RBAC involves two parts of work. The first part is to build up the -RBAC authorization data, and the second part is to use the authorization -data to perform access check in places where it's necessary. Since RBAC -implements `\Yiisoft\Access\AccessCheckerInterface`, using it's similar to -using any other implementation of an access checker. +使用 RBAC 涉及两部分工作。第一部分是构建 RBAC 授权数据,第二部分是在必要的地方使用授权数据执行访问检查。由于 RBAC 实现了 +`\Yiisoft\Access\AccessCheckerInterface`,使用它类似于使用任何其他访问检查器的实现。 -To ease description next, there are some basic RBAC concepts first. +为了便于接下来的描述,首先介绍一些基本的 RBAC 概念。 -### Basic concepts +### 基本概念 -A role represents a collection of *permissions* (for example, creating -posts, updating posts). You may assign a role to one or many users. To -check if a user has a specified permission, you may check if the user has a -role with that permission. +角色代表一组*权限*(例如,创建文章、更新文章)。您可以将角色分配给一个或多个用户。要检查用户是否具有指定的权限,您可以检查用户是否具有包含该权限的角色。 -Associated with each role or permission, there may be a *rule*. A rule -represents a piece of code that an access checker will execute to decide if -the corresponding role or permission applies to the current user. For -example, the "update post" permission may have a rule that checks if the -current user is the post creator. During access checking, if the user is -NOT the post creator, there's no "update post" permission. +每个角色或权限可能关联一个*规则*。规则代表访问检查器将执行的一段代码,用于决定相应的角色或权限是否适用于当前用户。例如,“更新文章”权限可能有一个规则来检查当前用户是否是文章创建者。在访问检查期间,如果用户不是文章创建者,则没有“更新文章”权限。 -Both roles and permissions are in a hierarchy. In particular, a role may -consist of other roles or permissions. And a permission may consist of -other permissions. Yii implements a *partial order* hierarchy which -includes the more special *tree* hierarchy. While a role can contain a -permission, it isn't `true` vice versa. +角色和权限都处于层次结构中。特别是,一个角色可以由其他角色或权限组成。一个权限可以由其他权限组成。Yii +实现了*偏序*层次结构,其中包括更特殊的*树*层次结构。虽然角色可以包含权限,但反之则不成立。 -### Configuring RBAC +### 配置 RBAC -Yii RBAC requires storage to be provided. +Yii RBAC 需要提供存储。 -One of the following storages could be installed: +可以安装以下存储之一: -- [PHP storage](https://github.com/yiisoft/rbac-php) - PHP file storage; -- [DB storage](https://github.com/yiisoft/rbac-db) - database storage based - on [Yii DB](https://github.com/yiisoft/db); -- [Cycle DB storage](https://github.com/yiisoft/rbac-cycle-db) - database - storage based on [Cycle DBAL](https://github.com/cycle/database). +- [PHP storage](https://github.com/yiisoft/rbac-php) — PHP 文件存储; +- [DB storage](https://github.com/yiisoft/rbac-db) — 基于 [Yii + DB](https://github.com/yiisoft/db) 的数据库存储; +- [Cycle DB storage](https://github.com/yiisoft/rbac-cycle-db) — 基于 [Cycle + DBAL](https://github.com/cycle/database) 的数据库存储。 -You can also provide your own storage using the -[yiisoft/rbac](https://github.com/yiisoft/rbac) package. +您还可以使用 [yiisoft/rbac](https://github.com/yiisoft/rbac) 包提供自己的存储。 -#### Configuring RBAC with the [PHP storage](https://github.com/yiisoft/rbac-php) +#### 使用 [PHP storage](https://github.com/yiisoft/rbac-php) 配置 RBAC -Install [yiisoft/rbac-php](https://github.com/yiisoft/rbac-php) package: +安装 [yiisoft/rbac-php](https://github.com/yiisoft/rbac-php) 包: ``` composer require yiisoft/rbac-php ``` -Before we set off to define authorization data and perform access checking, -you need to configure the `Yiisoft\Access\AccessCheckerInterface` in -dependency container: +在开始定义授权数据和执行访问检查之前,您需要在依赖容器中配置 `Yiisoft\Access\AccessCheckerInterface`: ```php use Yiisoft\Rbac\ItemsStorageInterface; @@ -147,31 +124,27 @@ return [ ]; ``` -`Yiisoft\Rbac\Manager` uses PHP script files to store authorization data. -Make sure the directory and all the files in it are writable by the Web -server process if you want to change permission hierarchy online. +`Yiisoft\Rbac\Manager` 使用 PHP 脚本文件来存储授权数据。如果您想在线更改权限层次结构,请确保该目录及其中的所有文件都可由 +Web 服务器进程写入。 -#### Configuring RBAC with the [DB storage](https://github.com/yiisoft/rbac-db) +#### 使用 [DB storage](https://github.com/yiisoft/rbac-db) 配置 RBAC -Install [yiisoft/rbac-db](https://github.com/yiisoft/rbac-db) package: +安装 [yiisoft/rbac-db](https://github.com/yiisoft/rbac-db) 包: ``` composer require yiisoft/rbac-db ``` -Install one of the following drivers: - - [SQLite](https://github.com/yiisoft/db-sqlite) (minimal required version is 3.8.3) +安装以下驱动程序之一: + - [SQLite](https://github.com/yiisoft/db-sqlite)(最低要求版本为 3.8.3) - [MySQL](https://github.com/yiisoft/db-mysql) - [PostgreSQL](https://github.com/yiisoft/db-pgsql) - [Microsoft SQL Server](https://github.com/yiisoft/db-mssql) - [Oracle](https://github.com/yiisoft/db-oracle) -[Configure -connection](https://yiisoft.github.io/docs/guide/start/databases.html#configuring-connection). +[配置连接](https://yiisoft.github.io/docs/guide/start/databases.html#configuring-connection)。 -Before we set off to define authorization data and perform access checking, -you need to configure the `Yiisoft\Access\AccessCheckerInterface` in -dependency container: +在开始定义授权数据和执行访问检查之前,您需要在依赖容器中配置 `Yiisoft\Access\AccessCheckerInterface`: ```php use Yiisoft\Rbac\ItemsStorageInterface; @@ -189,8 +162,7 @@ return [ ]; ``` -Add the RBAC [DB storage](https://github.com/yiisoft/rbac-db) migration -paths to params.php: +将 RBAC [DB storage](https://github.com/yiisoft/rbac-db) 迁移路径添加到 params.php: ```php return [ @@ -204,45 +176,35 @@ return [ ]; ``` -Apply migrations: +应用迁移: ``` APP_ENV=dev ./yii migrate:up ``` -### Building authorization data +### 构建授权数据 -Building authorization data is all about the following tasks: +构建授权数据涉及以下任务: -- defining roles and permissions; -- establishing relations between roles and permissions; -- defining rules; -- associating rules with roles and permissions; -- assigning roles to users. +- 定义角色和权限; +- 建立角色和权限之间的关系; +- 定义规则; +- 将规则与角色和权限关联; +- 将角色分配给用户。 -Depending on authorization flexibility requirements, you can do the tasks in -different ways. If only developers change your permission hierarchy, you -can use either migrations or a console command. Migration advantage is that -you could execute it along with other migrations. The Console command -advantage is that you have a good overview of the hierarchy in the code -without a need to read many migrations. +根据授权灵活性要求,您可以以不同的方式完成这些任务。如果只有开发人员更改您的权限层次结构,您可以使用迁移或控制台命令。迁移的优点是您可以与其他迁移一起执行它。控制台命令的优点是您可以在代码中很好地概览层次结构,而无需阅读许多迁移。 -Either way, in the end, you'll get the following RBAC hierarchy: +无论哪种方式,最终您都会得到以下 RBAC 层次结构: -![Simple RBAC hierarchy](/images/guide/security/rbac-hierarchy-1.svg "Simple -RBAC hierarchy") +![简单的 RBAC 层次结构](/images/guide/security/rbac-hierarchy-1.svg "简单的 RBAC +层次结构") -In case you want to build permission hierarchy dynamically, you need a UI or -a console command. The API used to build the hierarchy itself won't be -different. +如果您想动态构建权限层次结构,则需要 UI 或控制台命令。用于构建层次结构本身的 API 不会有所不同。 -### Using console command +### 使用控制台命令 -If your permission hierarchy doesn't change at all, and you have a fixed -number of users, you can create a [console -command](../tutorial/console-applications.md) that will initialize -authorization data once via APIs offered by -`\Yiisoft\Rbac\ManagerInterface`: +如果您的权限层次结构根本不会改变,并且您有固定数量的用户,则可以创建一个[控制台命令](../tutorial/console-applications.md),通过 +`\Yiisoft\Rbac\ManagerInterface` 提供的 API 一次性初始化授权数据: ```php If you don't want to hardcode what users have certain roles, don't put `->assign()` calls into the command. Instead, - create either UI or console command to manage assignments. +> 如果您不想硬编码哪些用户具有某些角色,请不要在命令中放入 `->assign()` 调用。相反, + 创建 UI 或控制台命令来管理分配。 -#### Using migrations +#### 使用迁移 -**TODO**: finish it when migrations are implemented. +**TODO**:在实现迁移时完成它。 -You can use [migrations](../databases/db-migrations.md) to initialize and -change hierarchy via APIs offered by `\Yiisoft\Rbac\ManagerInterface`. +您可以使用 [迁移](../databases/db-migrations.md) 通过 +`\Yiisoft\Rbac\ManagerInterface` 提供的 API 初始化和更改层次结构。 -Create new migration using `APP_ENV=dev ./yii migrate:create init_rbac` then -implement creating a hierarchy: +使用 `APP_ENV=dev ./yii migrate:create init_rbac` 创建新迁移,然后实现创建层次结构: ```php If you don't want to hardcode which users have certain roles, don't put `->assign()` calls in migrations. Instead, - create either UI or console command to manage assignments. +> 如果您不想硬编码哪些用户具有某些角色,请不要在迁移中放入 `->assign()` 调用。相反, + 创建 UI 或控制台命令来管理分配。 -You could apply migration by using `APP_ENV=dev ./yii migrate:up`. +您可以使用 `APP_ENV=dev ./yii migrate:up` 应用迁移。 -## Assigning roles to users +## 将角色分配给用户 -TODO: update when signup implemented in demo / template. +TODO:在演示/模板中实现注册时更新。 -The author can create a post, admin can update the post and do everything -the author can. +作者可以创建文章,管理员可以更新文章并执行作者可以执行的所有操作。 -If your application allows user signup, you need to assign roles to these -new users at once. For example, in order for all signed-up users to become -authors in your advanced project template, you need to change -`frontend\models\SignupForm::signup()` as follows: +如果您的应用程序允许用户注册,您需要立即将角色分配给这些新用户。例如,为了让所有注册用户在您的高级项目模板中成为作者,您需要按如下方式更改 +`frontend\models\SignupForm::signup()`: ```php public function signup() @@ -437,19 +395,14 @@ public function signup() } ``` -For applications that require complex access control with dynamically -updated authorization data (such as an admin panel), you many need to -develop special user interfaces using APIs offered by -`Yiisoft\Rbac\Manager`. +对于需要复杂访问控制和动态更新授权数据的应用程序(例如管理面板),您可能需要使用 `Yiisoft\Rbac\Manager` 提供的 API +开发特殊的用户界面。 -### Using rules +### 使用规则 -As aforementioned, rules add extra constraint to roles and permissions. A -rule is a class extending from `\Yiisoft\Rbac\Rule`. It must implement the -`execute()` method. In the hierarchy you've created before, the author -can't edit his own post. Let's fix it. First, you need a rule to verify -that the user is the post author: +如前所述,规则为角色和权限添加了额外的约束。规则是从 `\Yiisoft\Rbac\Rule` 扩展的类。它必须实现 `execute()` +方法。在您之前创建的层次结构中,作者无法编辑自己的文章。让我们修复它。首先,您需要一个规则来验证用户是文章作者: ```php namespace App\User\Rbac; @@ -471,8 +424,7 @@ final readonly class AuthorRule implements RuleInterface } ``` -The rule checks if user created the `post`. Create a special permission -`updateOwnPost` in the command you've used before: +该规则检查用户是否创建了 `post`。在您之前使用的命令中创建一个特殊权限 `updateOwnPost`: ```php use Yiisoft\Rbac\Permission; @@ -494,16 +446,15 @@ $this->manager->addChild($authorRole->getName(), $updateOwnPost->getName()); $this->manager->addChild('admin', 'author'); ``` -Now you've got the following hierarchy: +现在您得到了以下层次结构: -![RBAC hierarchy with a rule](/images/guide/security/rbac-hierarchy-2.svg -"RBAC hierarchy with a rule") +![带有规则的 RBAC 层次结构](/images/guide/security/rbac-hierarchy-2.svg "带有规则的 RBAC +层次结构") -### Access check +### 访问检查 -The check is done similarly to how it was done in the first section of this -guide: +检查的方式与本指南第一部分中的方式类似: ```php namespace App\Blog\Post; @@ -542,17 +493,13 @@ final readonly class PostController } ``` -The difference is that now checking for a user's own post is part of the -RBAC. +不同之处在于,现在检查用户自己的文章是 RBAC 的一部分。 -If the current user is Jane with `ID=1` you are starting at `createPost` and -trying to get to `Jane`: +如果当前用户是 Jane,`ID=1`,您从 `createPost` 开始并尝试到达 `Jane`: -![Access check](/images/guide/security/rbac-access-check-1.svg "Access -check") +![访问检查](/images/guide/security/rbac-access-check-1.svg "访问检查") -To check if a user can update a post, you need to pass an extra parameter -that's required by `AuthorRule` described before: +要检查用户是否可以更新文章,您需要传递之前描述的 `AuthorRule` 所需的额外参数: ```php if ($user->can('updatePost', ['post' => $post])) { @@ -560,26 +507,23 @@ if ($user->can('updatePost', ['post' => $post])) { } ``` -Here is what happens if the current user is John: +如果当前用户是 John,会发生以下情况: -![Access check](/images/guide/security/rbac-access-check-2.svg "Access -check") +![访问检查](/images/guide/security/rbac-access-check-2.svg "访问检查") -You're starting with the `updatePost` and going through `updateOwnPost`. To pass the access check, `AuthorRule` -should return `true` from its `execute()` method. The method receives its `$params` from the `can()` method call, so the value is -`['post' => $post]`. -If everything is fine, you will get to `author` assigned to John. +您从 `updatePost` 开始并通过 `updateOwnPost`。要通过访问检查,`AuthorRule` +应该从其 `execute()` 方法返回 `true`。该方法从 `can()` 方法调用接收其 `$params`,因此值为 +`['post' => $post]`。 +如果一切正常,您将到达分配给 John 的 `author`。 -In the case of Jane, it's a bit simpler since she is an admin: +在 Jane 的情况下,这更简单,因为她是管理员: -![Access check](/images/guide/security/rbac-access-check-3.svg "Access -check") +![访问检查](/images/guide/security/rbac-access-check-3.svg "访问检查") -## Implementing your own access checker +## 实现您自己的访问检查器 -If RBAC doesn't suit your needs, you can implement your own access checker -without changing the application code: +如果 RBAC 不适合您的需求,您可以在不更改应用程序代码的情况下实现自己的访问检查器: ```php diff --git a/src/zh-CN/guide/security/best-practices.md b/src/zh-CN/guide/security/best-practices.md index 953bf864..5acc7c88 100644 --- a/src/zh-CN/guide/security/best-practices.md +++ b/src/zh-CN/guide/security/best-practices.md @@ -1,29 +1,22 @@ -# Security best practices +# 安全最佳实践 -Below, we'll review common security principles and describe how to avoid -threats when developing applications using Yii. Most of these principles -aren't unique to Yii alone but apply to website or software development in -general, so you will also find links for further reading on the general -ideas behind these. +下面,我们将回顾常见的安全原则,并描述在使用 Yii 开发应用程序时如何避免威胁。这些原则中的大多数并非 Yii +独有,而是适用于一般的网站或软件开发,因此您还会找到有关这些背后一般思想的进一步阅读链接。 -## Basic principles +## 基本原则 -There are two main principles when it comes to security no matter which -application is being developed: +无论开发哪种应用程序,在安全方面都有两个主要原则: -1. Filter input. -2. Escape output. +1. 过滤输入。 +2. 转义输出。 -### Filter input +### 过滤输入 -Filter input means that you should never consider input safe, and you should -always check if the value you've got is actually among allowed ones. For -example, if you know that you sort by three fields `title`, `created_at` and -`status` and the field came from user input, it's better to check the value -you've got right where you're receiving it. In terms of basic PHP, that -would look like the following: +过滤输入意味着您永远不应该认为输入是安全的,您应该始终检查您获得的值是否确实在允许的值之中。例如,如果您知道您按三个字段 +`title`、`created_at` 和 `status` 排序,并且该字段来自用户输入,最好在接收它的地方检查您获得的值。就基本 PHP +而言,看起来如下: ```php $sortBy = $_GET['sort']; @@ -32,57 +25,49 @@ if (!in_array($sortBy, ['title', 'created_at', 'status'])) { } ``` -In Yii, most probably you'll use form validation to do similar checks. +在 Yii 中,您很可能会使用表单验证来进行类似的检查。 -Further reading on the topic: +有关该主题的进一步阅读: - - -### Escape output +### 转义输出 -Escape output means that, depending on the context where you're using data, -you should prepend it with special characters to negate its special meaning. -In context of HTML you should escape `<`, `>` and alike special characters. -In the context of JavaScript or SQL, it will be a different set of characters. -Since it's error-prone to escape manually, Yii provides various tools to perform escaping in different contexts. +转义输出意味着,根据您使用数据的上下文, +您应该在其前面加上特殊字符以消除其特殊含义。 +在 HTML 上下文中,您应该转义 `<`、`>` 和类似的特殊字符。 +在 JavaScript 或 SQL 的上下文中,它将是一组不同的字符。 +由于手动转义容易出错,Yii 提供了各种工具来在不同上下文中执行转义。 -Further reading on the topic: +有关该主题的进一步阅读: - - - -## Avoiding SQL injections +## 避免 SQL 注入 -SQL injection happens when you form a query text by concatenating unescaped -strings such as the following: +SQL 注入发生在您通过连接未转义的字符串来形成查询文本时,如下所示: ```php $username = $_GET['username']; $sql = "SELECT * FROM user WHERE username = '$username'"; ``` -Instead of supplying correct username attacker could give your applications -something like `'; DROP TABLE user; --`. The Resulting SQL will be the -following: +攻击者可以给您的应用程序提供类似 `'; DROP TABLE user; --` 的内容,而不是提供正确的用户名。结果 SQL 将如下所示: ```sql SELECT * FROM user WHERE username = ''; DROP TABLE user; --' ``` -This is a valid query that will search for users with empty username and -then will drop `user` table most probably resulting in a broken website and -data loss (you've set up regular backups, right?). +这是一个有效的查询,它将搜索用户名为空的用户,然后删除 `user` 表,很可能导致网站损坏和数据丢失(您已经设置了定期备份,对吧?)。 -Make sure to either use PDO prepared statements directly or ensure that the -library you prefer is doing it. In the case of prepared statements, it's -impossible to manipulate the query as was demonstrated above. +确保直接使用 PDO 预处理语句,或确保您喜欢的库正在这样做。在预处理语句的情况下,不可能像上面演示的那样操纵查询。 -If you use data to specify column names or table names, the best thing to do -is to allow only a predefined set of values: +如果您使用数据来指定列名或表名,最好的做法是只允许预定义的值集: ```php function actionList($orderBy = null) @@ -95,175 +80,149 @@ function actionList($orderBy = null) } ``` -Further reading on the topic: +有关该主题的进一步阅读: - -## Avoiding XSS +## 避免 XSS -XSS or cross-site scripting happens when output isn't escaped properly when outputting HTML to the browser. For example, -if user can enter his name and instead of `Alexander` he enters ``, every page that -outputs username without escaping it will execute JavaScript `alert('Hello!');` resulting in alert box popping up -in a browser. Depending on the website instead of innocent alert, such a script could send messages using your name or even -perform bank transactions. +XSS 或跨站脚本攻击发生在向浏览器输出 HTML 时输出未正确转义的情况下。例如, +如果用户可以输入他的名字,而不是 `Alexander`,他输入 ``,每个 +输出用户名而不转义它的页面都将执行 JavaScript `alert('Hello!');`,导致警告框在 +浏览器中弹出。根据网站的不同,这样的脚本可以使用您的名字发送消息,甚至 +执行银行交易,而不是无害的警告。 -Avoiding XSS is quite easy in Yii. There are two cases: +在 Yii 中避免 XSS 非常容易。有两种情况: -1. You want to output data as plain text. -2. You want to output data as HTML. +1. 您想将数据输出为纯文本。 +2. 您想将数据输出为 HTML。 -If all you need is plain text, then escaping is as easy as the following: +如果您只需要纯文本,那么转义就像下面这样简单: ```php ``` -If it should be HTML, you could get some help from -[HtmlPurifier](http://htmlpurifier.org/). Note that HtmlPurifier processing -is quite heavy, so consider adding caching. +如果它应该是 HTML,您可以从 [HtmlPurifier](http://htmlpurifier.org/) +获得一些帮助。请注意,HtmlPurifier 处理相当繁重,因此请考虑添加缓存。 -Further reading on the topic: +有关该主题的进一步阅读: - -## Avoiding CSRF +## 避免 CSRF -CSRF is an abbreviation for cross-site request forgery. The idea is that -many applications assume that requests coming from a user browser are made -by the user themselves. This assumption could be false. +CSRF 是跨站请求伪造的缩写。其思想是许多应用程序假设来自用户浏览器的请求是由用户自己发出的。这个假设可能是错误的。 -For example, the website `an.example.com` has a `/logout` URL that, when accessed using a simple GET request, logs the user out. As long -as it's requested by the user themselves everything is OK, but one day bad guys are somehow posting -`` on a forum the user often visits. The browser doesn't make any difference between -requesting an image or requesting a page so when the user opens a page with such a manipulated `` tag, -the browser will send the GET request to that URL and the user will be logged out from `an.example.com`. +例如,网站 `an.example.com` 有一个 `/logout` URL,当使用简单的 GET 请求访问时,会将用户注销。只要 +它是由用户自己请求的,一切都很好,但有一天坏人以某种方式在用户经常访问的论坛上发布 +``。浏览器在 +请求图像或请求页面之间没有任何区别,因此当用户打开带有这样一个被操纵的 `` 标签的页面时, +浏览器将向该 URL 发送 GET 请求,用户将从 `an.example.com` 注销。 -That's the basic idea of how a CSRF attack works. One can say that logging out a user isn't a serious thing. -However, this was just an example. -There are many more things one could do using this approach. -For example, triggering payments or changing data. Imagine that some website has a URL -`http://an.example.com/purse/transfer?to=anotherUser&amount=2000`. Accessing it using GET request, causes transfer of $2000 -from an authorized user account to user `anotherUser`. -You know that the browser will always send a GET request to load an image, -so you can change the code to accept only POST requests on that URL. -Unfortunately, this won't save you, because an attacker -can put some JavaScript code instead of `` tag, which allows sending POST requests to that URL as well. +这就是 CSRF 攻击工作原理的基本思想。有人可能会说注销用户不是什么严重的事情。 +然而,这只是一个例子。 +使用这种方法可以做更多的事情。 +例如,触发付款或更改数据。想象一下某个网站有一个 URL +`http://an.example.com/purse/transfer?to=anotherUser&amount=2000`。使用 GET 请求访问它,会导致 +从授权用户帐户向用户 `anotherUser` 转账 $2000。 +您知道浏览器总是会发送 GET 请求来加载图像, +因此您可以更改代码以仅接受该 URL 上的 POST 请求。 +不幸的是,这不会拯救您,因为攻击者 +可以放置一些 JavaScript 代码而不是 `` 标签,这也允许向该 URL 发送 POST 请求。 -For this reason, Yii applies extra mechanisms to protect against CSRF -attacks. +因此,Yii 应用额外的机制来防止 CSRF 攻击。 -To avoid CSRF, you should always: +为了避免 CSRF,您应该始终: -1. Follow HTTP specification. GET shouldn't change the application state. - See [RFC2616](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html) for - more details. -2. Keep Yii CSRF protection enabled. +1. 遵循 HTTP 规范。GET 不应该改变应用程序状态。有关更多详细信息,请参阅 + [RFC2616](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html)。 +2. 保持 Yii CSRF 保护启用。 -Yii has CSRF protection as `Yiisoft\Yii\Web\Middleware\Csrf` middleware. -Make sure it's in your application middleware stack. +Yii 将 CSRF 保护作为 `Yiisoft\Yii\Web\Middleware\Csrf` 中间件。确保它在您的应用程序中间件堆栈中。 -Further reading on the topic: +有关该主题的进一步阅读: - - -## Avoiding file exposure +## 避免文件暴露 -By default, server webroot is meant to be pointed to `public` directory where `index.php` is. In the case of shared hosting - environments, it could be impossible to achieve, so you'll end up with all the code, configs and logs in server webroot. +默认情况下,服务器 webroot 应该指向 `index.php` 所在的 `public` 目录。在共享托管 +环境的情况下,这可能无法实现,因此您最终会将所有代码、配置和日志放在服务器 webroot 中。 -If so, remember to deny access to everything except `web`. If it's -impossible, consider hosting your application elsewhere. +如果是这样,请记住拒绝访问除 `web` 之外的所有内容。如果不可能,请考虑在其他地方托管您的应用程序。 -## Avoiding debug info and tools in production +## 避免在生产环境中使用调试信息和工具 -In debug mode, Yii shows quite verbose errors which are certainly helpful -for development. The thing is that these verbose errors are handy for -attacker as well since these could reveal database structure, configuration -values and parts of your code. +在调试模式下,Yii 显示相当详细的错误,这对开发肯定有帮助。问题是这些详细的错误对攻击者也很方便,因为它们可能会泄露数据库结构、配置值和部分代码。 -Never run production applications with debugger or Gii accessible to -everyone. One could use it to get information about database structure, -code and to simply rewrite code with what's generated by Gii. +永远不要在调试器或 Gii 可供所有人访问的情况下运行生产应用程序。有人可以使用它来获取有关数据库结构、代码的信息,并简单地用 Gii +生成的内容重写代码。 -You should avoid the debug toolbar in production unless necessary. It -exposes all the application and config details possible. If you absolutely -need it, check twice you restrict access to your IP only. +除非必要,否则应避免在生产环境中使用调试工具栏。它会暴露所有可能的应用程序和配置详细信息。如果您绝对需要它,请仔细检查您是否仅限制对您的 IP 的访问。 -Further reading on the topic: +有关该主题的进一步阅读: - - -## Using secure connection over TLS +## 通过 TLS 使用安全连接 -Yii provides features that rely on cookies and/or PHP sessions. These can be -vulnerable in case your connection is compromised. The risk is reduced if -the app uses secure connection via TLS (often referred to as -[SSL](https://en.wikipedia.org/wiki/Transport_Layer_Security)). +Yii 提供依赖于 cookie 和/或 PHP 会话的功能。如果您的连接受到威胁,这些可能会受到攻击。如果应用程序通过 TLS 使用安全连接(通常称为 +[SSL](https://en.wikipedia.org/wiki/Transport_Layer_Security)),则风险会降低。 -Nowadays, anyone can get a certificate for free and automatically update it -thanks to [Let's Encrypt](https://letsencrypt.org/). +如今,任何人都可以免费获得证书并自动更新它,这要归功于 [Let's Encrypt](https://letsencrypt.org/)。 -## Secure server configuration +## 安全的服务器配置 -The purpose of this section is to highlight risks that need to be considered -when creating a server configuration for serving a Yii-based -website. Besides the points covered here, there may be other -security-related configuration options to be considered, so don't consider -this section to be complete. +本节的目的是强调在为基于 Yii +的网站创建服务器配置时需要考虑的风险。除了这里涵盖的要点之外,可能还有其他与安全相关的配置选项需要考虑,因此不要认为本节是完整的。 -### Avoiding `Host`-header attacks +### 避免 `Host` 头攻击 -If the webserver is configured to serve the same site independent of the -value of the `Host` header, this information mayn't be reliable and [may be -faked by the user sending the HTTP -request](https://www.acunetix.com/vulnerabilities/web/host-header-attack). -In such situations, you should fix your webserver configuration to serve the -site only for specified host names. +如果 Web 服务器配置为独立于 `Host` 头的值提供相同的站点,则此信息可能不可靠,并且[可能被发送 HTTP +请求的用户伪造](https://www.acunetix.com/vulnerabilities/web/host-header-attack)。在这种情况下,您应该修复您的 +Web 服务器配置,以仅为指定的主机名提供站点。 -For more information about the server configuration, please refer to the -documentation of your webserver: +有关服务器配置的更多信息,请参阅您的 Web 服务器的文档: - Apache 2: - Nginx: -### Configuring SSL peer validation +### 配置 SSL 对等验证 -There is a typical misconception about how to solve SSL certificate -validation issues such as: +关于如何解决 SSL 证书验证问题存在一个典型的误解,例如: ``` cURL error 60: SSL certificate problem: unable to get local issuer certificate ``` -or +或 ``` stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error messages: error:1416F086:SSL routines:tls_process_server_certificate:certificate verify failed ``` -Many sources wrongly suggest disabling SSL peer verification. That -shouldn't be ever done since it enables man-in-the middle type of attacks. -Instead, PHP should be configured properly: +许多来源错误地建议禁用 SSL 对等验证。这永远不应该这样做,因为它会启用中间人类型的攻击。相反,应该正确配置 PHP: -1. Download - [https://curl.haxx.se/ca/cacert.pem](https://curl.haxx.se/ca/cacert.pem). -2. Add the following to your php.ini: +1. 下载 + [https://curl.haxx.se/ca/cacert.pem](https://curl.haxx.se/ca/cacert.pem)。 +2. 将以下内容添加到您的 php.ini: ``` openssl.cafile="/path/to/cacert.pem" curl.cainfo="/path/to/cacert.pem". ``` -Note that you should keep the file up to date. +请注意,您应该保持文件最新。 ## 参考资料 diff --git a/src/zh-CN/guide/security/cryptography.md b/src/zh-CN/guide/security/cryptography.md index 4b596bab..ad8893f4 100644 --- a/src/zh-CN/guide/security/cryptography.md +++ b/src/zh-CN/guide/security/cryptography.md @@ -1,25 +1,20 @@ -# Cryptography +# 加密 -In this section, we'll review the following security aspects: +在本节中,我们将回顾以下安全方面: -- Generating random data -- Encryption and Decryption -- Confirming Data Integrity +- 生成随机数据 +- 加密和解密 +- 确认数据完整性 -To use these features, you need to install `yiisoft/security` package: +要使用这些功能,您需要安装 `yiisoft/security` 包: ``` composer install yiisoft/security ``` -## Generating pseudorandom data +## 生成伪随机数据 -Pseudorandom data are useful in many situations. For example, when resetting -a password via email, you need to generate a token, save it to the database, -and send it via email to the end user, which in turn will allow them to -prove ownership of that account. It's important that this token be unique -and hard to guess, else there is a possibility that an attacker can predict -the token's value and reset the user's password. +伪随机数据在许多情况下都很有用。例如,当通过电子邮件重置密码时,您需要生成一个令牌,将其保存到数据库,并通过电子邮件发送给最终用户,这反过来将允许他们证明对该帐户的所有权。重要的是,此令牌必须是唯一的且难以猜测,否则攻击者有可能预测令牌的值并重置用户的密码。 `\Yiisoft\Security\Random` makes generating pseudorandom data simple: @@ -27,21 +22,17 @@ the token's value and reset the user's password. $key = \Yiisoft\Security\Random::string(42); ``` -The code above would give you a random string consisting of 42 characters. +上面的代码将为您提供一个由 42 个字符组成的随机字符串。 -If you need bytes or integers, use PHP functions directly: +如果您需要字节或整数,请直接使用 PHP 函数: -- `random_bytes()` for bytes. Note that the output may not be ASCII. -- `random_int()` for integers. +- 使用 `random_bytes()` 生成字节。请注意,输出可能不是 ASCII。 +- `random_int()` 用于整数。 -## Encryption and decryption +## 加密和解密 -Yii provides convenient helper functions to encrypt/decrypt data using a -secret key. The data is passed through the encryption function so that only -the person who has the secret key will be able to decrypt it. For example, -you need to store some information in your database, but you need to make -sure only the user who has the secret key can view it (even if one -compromises the application database): +Yii +提供了方便的辅助函数,使用密钥加密/解密数据。数据通过加密函数传递,以便只有拥有密钥的人才能解密它。例如,您需要在数据库中存储一些信息,但您需要确保只有拥有密钥的用户才能查看它(即使有人破坏了应用程序数据库): ```php $encryptedData = (new \Yiisoft\Security\Crypt())->encryptByPassword($data, $password); @@ -50,7 +41,7 @@ $encryptedData = (new \Yiisoft\Security\Crypt())->encryptByPassword($data, $pass saveData($encryptedData); ``` -Decrypting it: +解密它: ```php // collect encrypted data from a database or another storage @@ -59,7 +50,7 @@ $encryptedData = getEncryptedData(); $data = (new \Yiisoft\Security\Crypt())->decryptByPassword($encryptedData, $password); ``` -You could use a key instead of a password: +您可以使用密钥而不是密码: ```php $encryptedData = (new \Yiisoft\Security\Crypt())->encryptByKey($data, $key); @@ -68,7 +59,7 @@ $encryptedData = (new \Yiisoft\Security\Crypt())->encryptByKey($data, $key); saveData($encryptedData); ``` -Decrypting it: +解密它: ```php // collect encrypted data from a database or another storage @@ -77,14 +68,11 @@ $encryptedData = getEncryptedData(); $data = (new \Yiisoft\Security\Crypt())->decryptByKey($encryptedData, $key); ``` -## Confirming data integrity +## 确认数据完整性 -There are situations in which you need to verify that your data hasn't been -tampered with by a third party or even corrupted in some way. Yii provides a -way to confirm data integrity by MAC signing. +在某些情况下,您需要验证您的数据没有被第三方篡改,甚至以某种方式损坏。Yii 提供了一种通过 MAC 签名确认数据完整性的方法。 -The `$key` should be present at both sending and receiving sides. On the -sending side: +`$key` 应该在发送端和接收端都存在。在发送端: ```php $signedMessage = (new \Yiisoft\Security\Mac())->sign($message, $key); @@ -92,7 +80,7 @@ $signedMessage = (new \Yiisoft\Security\Mac())->sign($message, $key); sendMessage($signedMessage); ``` -On the receiving side: +在接收端: ```php $signedMessage = receiveMessage($signedMessage); @@ -104,19 +92,17 @@ try { } ``` -## Masking token length +## 掩码令牌长度 -Masking a token helps to mitigate a BREACH attack by randomizing how the -token outputted on each request. A random mask is applied to the token, -making the string always unique. +掩码令牌有助于通过随机化每个请求上令牌的输出方式来缓解 BREACH 攻击。对令牌应用随机掩码,使字符串始终唯一。 -To mask a token: +要掩码令牌: ```php $maskedToken = \Yiisoft\Security\TokenMask::apply($token); ``` -To get the original value from the masked one: +要从掩码中获取原始值: ```php $token = \Yiisoft\Security\TokenMask::remove($maskedToken); diff --git a/src/zh-CN/guide/security/overview.md b/src/zh-CN/guide/security/overview.md index fef074a7..5011faa8 100644 --- a/src/zh-CN/guide/security/overview.md +++ b/src/zh-CN/guide/security/overview.md @@ -1,19 +1,15 @@ -# Security +# 安全 -Good security is vital to the health and success of any -application. Unfortunately, many developers cut corners when it comes to -security, either due to a lack of understanding or because implementation is -too much of a hurdle. To make your Yii-powered application as secure as -possible, Yii has included several excellent and easy-to-use security -features. +良好的安全性对于任何应用程序的健康和成功至关重要。不幸的是,许多开发人员在安全方面偷工减料,要么是由于缺乏理解,要么是因为实施起来太困难。为了使您的 +Yii 驱动的应用程序尽可能安全,Yii 包含了几个出色且易于使用的安全功能。 -* [Authentication](authentication.md) -* [Authorization](authorization.md) -* [Working with Passwords](passwords.md) -* [Cryptography](cryptography.md) -* [Best Practices](best-practices.md) -* [Trusted request](trusted-request.md) +* [认证](authentication.md) +* [授权](authorization.md) +* [使用 Passwords](passwords.md) +* [加密](cryptography.md) +* [最佳实践](best-practices.md) +* [可信请求](trusted-request.md) -See also: +另请参阅: -* [Views security](../views/view.md#security) +* [视图安全](../views/view.md#security) diff --git a/src/zh-CN/guide/security/passwords.md b/src/zh-CN/guide/security/passwords.md index 2e112d77..69f529c3 100644 --- a/src/zh-CN/guide/security/passwords.md +++ b/src/zh-CN/guide/security/passwords.md @@ -1,25 +1,18 @@ -# Working with passwords +# 使用密码 -Most developers know that passwords can't be stored in plain text, but many -developers believe it's still safe to hash passwords using `md5`, `sha1` or -`sha256` etc. There was a time when using the aforementioned hashing -algorithms was enough, but modern hardware makes it possible to reverse such -hashes and even stronger ones using brute force attacks. +大多数开发人员知道密码不能以纯文本形式存储,但许多开发人员认为使用 `md5`、`sha1` 或 `sha256` +等对密码进行哈希处理仍然是安全的。曾经有一段时间,使用上述哈希算法就足够了,但现代硬件使得可以使用暴力攻击来逆向这些哈希甚至更强的哈希。 -To offer increased security for user passwords, even in the worst case -scenario (when one breaches your application), you need to use a hashing -algorithm that's resilient against brute force attacks. The best current -choice is `argon2`. Yii `yiisoft/security` package make securely generate -and verify hashes easier and ensure the best possible hashing solution used. +为了为用户密码提供更高的安全性,即使在最坏的情况下(当有人破坏您的应用程序时),您需要使用能够抵御暴力攻击的哈希算法。目前最好的选择是 +`argon2`。Yii `yiisoft/security` 包使安全生成和验证哈希变得更容易,并确保使用最佳的哈希解决方案。 -To use it, you need to require the package first: +要使用它,您需要首先安装该包: ``` composer require yiisoft/security ``` -When a user provides a password for the first time (e.g., upon -registration), the password needs to be hashed and stored: +当用户第一次提供密码时(例如,注册时),需要对密码进行哈希处理并存储: ```php @@ -29,8 +22,7 @@ $hash = (new PasswordHasher())->hash($password); saveHash($hash); ``` -When a user attempts to log in, the submitted password must be verified -against the previously hashed and stored password: +当用户尝试登录时,提交的密码必须与之前哈希和存储的密码进行验证: ```php diff --git a/src/zh-CN/guide/security/trusted-request.md b/src/zh-CN/guide/security/trusted-request.md index 29ff339a..914516c9 100644 --- a/src/zh-CN/guide/security/trusted-request.md +++ b/src/zh-CN/guide/security/trusted-request.md @@ -1,30 +1,23 @@ -# Trusted request +# 可信请求 -Getting user information, like a host and IP address, will work out of the -box in a normal setup where a single webserver is used to serve the -website. If your Yii application, however, runs behind a reverse proxy, you -need to add configuration to retrieve this information as the direct client -is now the proxy, and the user IP address is passed to the Yii application -by a header set by the proxy. +在使用单个 Web 服务器为网站提供服务的正常设置中,获取用户信息(如主机和 IP 地址)将开箱即用。但是,如果您的 Yii +应用程序在反向代理后面运行,则需要添加配置来检索此信息,因为直接客户端现在是代理,用户 IP 地址由代理设置的标头传递给 Yii 应用程序。 -You shouldn't blindly trust headers provided by proxies unless you -explicitly trust the proxy. Yii supports configuring trusted proxies via -the `Yiisoft\Yii\Web\Middleware\TrustedHostsNetworkResolver`. You should -add it to [middleware stack](../structure/middleware.md). +除非您明确信任代理,否则不应盲目信任代理提供的标头。Yii 支持通过 +`Yiisoft\Yii\Web\Middleware\TrustedHostsNetworkResolver` +配置可信代理。您应该将其添加到[中间件堆栈](../structure/middleware.md)。 -The following is a request config for an application that runs behind an -array of reverse proxies, which are located in the `10.0.2.0/24` IP network: +以下是在一组反向代理后面运行的应用程序的请求配置,这些代理位于 `10.0.2.0/24` IP 网络中: ```php /** @var \Yiisoft\Yii\Web\Middleware\TrustedHostsNetworkResolver $trustedHostsNetworkResolver */ $trustedHostsNetworkResolver = $trustedHostsNetworkResolver->withAddedTrustedHosts(['1.0.2.0/24']); ``` -The proxy sends the IP in the `X-Forwarded-For` header by default, and the -protocol (`http` or `https`) is in `X-Forwarded-Proto`. +代理默认在 `X-Forwarded-For` 标头中发送 IP,协议(`http` 或 `https`)在 `X-Forwarded-Proto` +中。 -In case your proxies are using different headers, you can use the request -configuration to adjust these, e.g.: +如果您的代理使用不同的标头,您可以使用请求配置来调整这些,例如: ```php /** @var \Yiisoft\Yii\Web\Middleware\TrustedHostsNetworkResolver $trustedHostsNetworkResolver */ @@ -39,5 +32,4 @@ $trustedHostsNetworkResolver = $trustedHostsNetworkResolver ); ``` -With the above configuration, `X-ProxyUser-Ip` and `Front-End-Https` headers -are used to get user IP and protocol. +使用上述配置,`X-ProxyUser-Ip` 和 `Front-End-Https` 标头用于获取用户 IP 和协议。 diff --git a/src/zh-CN/guide/start/creating-project.md b/src/zh-CN/guide/start/creating-project.md index 9a9aba55..510aac5b 100644 --- a/src/zh-CN/guide/start/creating-project.md +++ b/src/zh-CN/guide/start/creating-project.md @@ -1,25 +1,21 @@ -# Creating a project +# 创建项目 -In this guide we'll provide commands for both -[Docker](https://docs.docker.com/get-started/get-docker/) and the built-in -dev server with everything installed locally. +在本指南中,我们将提供 [Docker](https://docs.docker.com/get-started/get-docker/) +和本地安装所有内容的内置开发服务器的命令。 > [!NOTE] -> If you want to use another web server, -> see ["Configuring web servers"](../../cookbook/configuring-webservers/general.md). +> 如果你想使用其他 Web 服务器, +> 请参阅 ["配置 Web 服务器"](../../cookbook/configuring-webservers/general.md)。 -We recommend starting with a project template that's a minimal working Yii -project implementing some basic features. It can serve as a good starting -point for your projects. +我们建议从项目模板开始,这是一个实现了一些基本功能的最小可工作的 Yii 项目。它可以作为你项目的良好起点。 -You can create a new project from a template using the -[Composer](https://getcomposer.org) package manager: +你可以使用 [Composer](https://getcomposer.org) 包管理器从模板创建一个新项目: ```sh composer create-project yiisoft/app your_project ``` -Docker users can run the following commands: +Docker 用户可以运行以下命令: ```sh docker run --rm -it -v "$(pwd):/app" --user $(id -u):$(id -g) composer/composer create-project yiisoft/app your_project @@ -28,7 +24,7 @@ cd your_project make composer update ``` -If you want development version instead of release one: +如果你想要开发版本而不是发布版本: ```sh git clone https://github.com/yiisoft/app.git --depth 1 your_project && \ @@ -37,44 +33,42 @@ rm -rf .git && \ make composer update ``` -This installs the latest stable version of the Yii project template in a -directory named `your_project`. You can choose a different directory name -if you want. +这将在名为 `your_project` 的目录中安装最新稳定版本的 Yii 项目模板。如果你愿意,可以选择不同的目录名称。 > [!TIP] -> If you want to install the latest development version of Yii, you may add `--stability=dev` to the command. -> Don't use the development version of Yii for production because it may break your running code. +> 如果你想安装最新的 Yii 开发版本,可以在命令中添加 `--stability=dev`。 +> 不要在生产环境中使用 Yii 的开发版本,因为它可能会破坏你正在运行的代码。 -Go into the newly created directory and run: +进入新创建的目录并运行: ```sh APP_ENV=dev ./yii serve --port=80 ``` -For Windows Command Prompt users, run: +对于 Windows 命令提示符用户,运行: ```cmd set APP_ENV=dev yii serve --port=80 ``` -For Windows PowerShell users, run: +对于 Windows PowerShell 用户,运行: ```powershell $env:APP_ENV = "dev" .\yii serve --port=80 ``` -For Docker users, run: +对于 Docker 用户,运行: ```sh make up ``` -Open your browser to the URL `http://localhost/`. +在浏览器中打开 URL `http://localhost/`。 > [!NOTE] -> The HTTP server listens on port 80. If that port is already in use, specify the port via `--port` or, in case of Docker, -> `DEV_PORT` in the `docker/.env` file. +> HTTP 服务器监听 80 端口。如果该端口已被占用,请通过 `--port` 指定端口,或者在 Docker 的情况下, +> 在 `docker/.env` 文件中设置 `DEV_PORT`。 -![Successful Installation of Yii](/images/guide/start/app-installed.png) +![成功安装 Yii](/images/guide/start/app-installed.png) diff --git a/src/zh-CN/guide/start/databases.md b/src/zh-CN/guide/start/databases.md index 581796cb..0b32d238 100644 --- a/src/zh-CN/guide/start/databases.md +++ b/src/zh-CN/guide/start/databases.md @@ -1,7 +1,6 @@ -# Working with databases +# 使用数据库 -Yii doesn't dictate using a particular database or storage for your -application. There are many ways you can work with relational databases: +Yii 不强制您的应用程序使用特定的数据库或存储。有许多方式可以使用关系型数据库: - [Yii DB](https://github.com/yiisoft/db) - [Yii Active Record](https://github.com/yiisoft/active-record) @@ -11,23 +10,20 @@ application. There are many ways you can work with relational databases: package](https://github.com/stargazer-team/yii-doctrine) - [PDO](https://www.php.net/manual/en/book.pdo.php) -For non-relational ones, there are usually official libraries available: +对于非关系型数据库,通常也有官方库可用: - [ElasticSearch](https://github.com/elastic/elasticsearch-php) - [Redis](https://redis.io/docs/latest/develop/clients/php/) - ... -In this guide, we will focus on working with relational databases using Yii -DB. We'll use PostgreSQL to implement a simple CRUD (create read update -delete). +在本指南中,我们将重点介绍使用 Yii DB 处理关系型数据库。我们将使用 PostgreSQL 实现一个简单的 CRUD(创建、读取、更新、删除)。 -## Installing PostgreSQL +## 安装 PostgreSQL -You need to install PostgreSQL. If you prefer not to use Docker, [get the -installer from official website](https://www.postgresql.org/download/), -install it and create a database. +您需要安装 PostgreSQL。如果您不想使用 +Docker,请[从官方网站获取安装程序](https://www.postgresql.org/download/),安装它并创建数据库。 -If you use Docker, it is a bit simpler. Modify `docker/dev/compose.yml`: +如果您使用 Docker,则稍微简单一些。修改 `docker/dev/compose.yml`: ```yaml services: @@ -72,13 +68,13 @@ services: retries: 5 ``` -Note that we add `depends_on` so application waits for database to be up. +请注意,我们添加了 `depends_on`,使应用程序等待数据库启动。 > [!IMPORTANT] -> Also, we'll need a `pdo_pgsql` extension to communicate with PostgreSQL. You can enable it locally in `php.ini`. +> 此外,我们还需要 `pdo_pgsql` 扩展来与 PostgreSQL 通信。您可以在本地的 `php.ini` 中启用它。 -If you use Docker, check `docker/Dockerfile` and add `pdo_pgsql` in -`install-php-extensions` list: +如果您使用 Docker,请检查 `docker/Dockerfile` 并在 `install-php-extensions` 列表中添加 +`pdo_pgsql`: ```dockerfile RUN install-php-extensions \ @@ -97,23 +93,23 @@ RUN install-php-extensions \ pdo_pgsql ``` -Then rebuild PHP image with +然后使用以下命令重新构建 PHP 镜像: ```sh make build && make down && make up ``` -## Configuring connection +## 配置连接 -Now that we have the database, it's time to define the connection. +现在我们有了数据库,是时候定义连接了。 -First we need a package to be installed: +首先,我们需要安装一个包: ```sh make composer require yiisoft/db-pgsql:2.* ``` -Now create `config/common/di/db-pgsql.php`: +现在创建 `config/common/di/db-pgsql.php`: ```php [ @@ -183,8 +172,7 @@ root. Add the following configuration to `config/common/params.php`: ], ``` -Now you can use `make yii migrate:create page` to create a new -migration. For our example we need a `page` table with some columns: +现在您可以使用 `make yii migrate:create page` 创建新迁移。在我们的示例中,需要一个带有若干列的 `page` 表: ```php generate('page/edit', ['slug' => 'new'])) ?> ``` -### View a page +### 查看页面 -Create `src/Web/Page/ViewAction.php`: +创建 `src/Web/Page/ViewAction.php`: ```php close() ?> ``` -In this view we have a form that submits a request for page -deletion. Handing it with `GET` is common as well, but it is very -wrong. Since deletion changes data, it needs to be handled by one of the -non-idempotent HTTP methods. We use POST and a form in our example, but it -could be `DELETE` and async request made with JavaScript. The button could -be later styled properly to look similar to the "Edit". +在此视图中,我们有一个提交页面删除请求的表单。用 `GET` 处理也很常见,但这是非常错误的做法。由于删除会更改数据,它需要由非幂等的 HTTP +方法之一来处理。我们的示例中使用了 POST 和表单,但也可以使用 `DELETE` 和 JavaScript +发起的异步请求。该按钮后续可以适当设置样式,使其看起来类似于“编辑”按钮。 -### Delete a page +### 删除页面 -Create `src/Web/Page/DeleteAction.php`: +创建 `src/Web/Page/DeleteAction.php`: ```php toString()` won't work for MySQL and you'll need bytes instead, `Uuid::uuid7()->getBytes()`. +请注意,`Uuid::uuid7()->toString()` 在 MySQL 中不适用,您需要改用字节形式,即 `Uuid::uuid7()->getBytes()`。 -In the above we use a special slug in the URL for new pages so the URL looks -like `http://localhost/pages/new`. If the page isn't new, we pre-fill the -form with the data from the database. Similar to how we did in [Working with -forms](forms.md), we handle the form submission. After successful save we -redirect to the page view. +在上面,我们在 URL 中为新页面使用了特殊的 slug,因此 URL 看起来像 +`http://localhost/pages/new`。如果页面不是新的,我们会从数据库中预填充表单数据。与[使用表单](forms.md)中的操作类似,我们处理表单提交。保存成功后,我们重定向到页面视图。 -Now, a template in `src/Web/Page/edit.php`: +现在,在 `src/Web/Page/edit.php` 中创建模板: ```php close() ?> ``` -### Routing +### 路由 -Adjust `config/common/routes.php`: +调整 `config/common/routes.php`: ```php +## 创建表单 -The data to be requested from the user will be represented by a `Form` class -as shown below and saved in the file `/src/Web/Echo/Form.php`: +将从用户处请求的数据将由如下所示的 `Form` 类表示,并保存在文件 `/src/Web/Echo/Form.php` 中: ```php +## 使用表单 -Now that you have a form, use it in your action from "[Saying -Hello](hello.md)". +现在您有了一个表单,在“[打招呼](hello.md)”中的操作中使用它。 -Here's what you end up with in `/src/Web/Echo/Action.php`: +以下是 `/src/Web/Echo/Action.php` 中的最终结果: ```php ``` -If the form is valid, you display a message. The rest initializes and -renders the form. +如果表单有效,则显示消息。其余部分初始化并渲染表单。 -First, you initialize `$htmlForm` with the POST type and the action URL -generated with the help from the URL generator. You can access it as -`$urlGenerator` in all views. You also need to pass the CSRF token to the -form, which is also available in every view as `$csrf` thanks to the view -injections listed in `config/common/params.php`: +首先,您使用 POST 类型和借助 URL 生成器生成的操作 URL 初始化 `$htmlForm`。您可以在所有视图中以 +`$urlGenerator` 访问它。您还需要将 CSRF 令牌传递给表单,由于 `config/common/params.php` +中列出的视图注入,它也可以在每个视图中以 `$csrf` 的形式访问: ```php 'yiisoft/yii-view-renderer' => [ @@ -173,47 +161,33 @@ injections listed in `config/common/params.php`: ], ``` -The template renders the CSRF token value as a hidden input to ensure that -the request originates from the form page and not from another website. It -will be submitted along with POST form data. Omitting it would result in -[HTTP response code 422](https://tools.ietf.org/html/rfc4918#section-11.2). +模板将 CSRF 令牌值渲染为隐藏输入,以确保请求来自表单页面而非其他网站。它将与 POST 表单数据一起提交。省略它将导致 [HTTP 响应码 +422](https://tools.ietf.org/html/rfc4918#section-11.2)。 -You use `Field::text()` to output "message" field, so it takes care about -filling the value, escaping it, rendering field label and validation errors. +您使用 `Field::text()` 输出“message”字段,它会负责填充值、转义、渲染字段标签和验证错误。 -Now, in case you submit an empty message, you will get a validation error: -"The message to be echoed must contain at least 2 characters." +现在,如果您提交空消息,将会收到验证错误:“要回显的消息必须至少包含 2 个字符。” -## Trying it Out +## 试试看 -To see how it works, use your browser to access the following URL: +要查看其工作原理,请使用浏览器访问以下 URL: ``` http://localhost:8080/say ``` -You will see a page with a form input field and a label that indicates what -data to enter. Also, the form has a "submit" button labeled "Say". If you -click the "submit" button without entering anything, you will see that the -field is required. If you enter a single character, the form displays an -error message next to the problematic input field. +您将看到一个包含表单输入字段和标签的页面,标签指示要输入什么数据。此外,表单有一个标有“Say”的“提交”按钮。如果您不输入任何内容就点击“提交”按钮,将看到该字段是必填的。如果您输入单个字符,表单会在有问题的输入字段旁边显示错误消息。 -![Form with a validation error](/images/guide/start/form-error.png) +![表单验证错误](/images/guide/start/form-error.png) -After you enter a valid message and click the "submit" button, the page -echoes the data that you entered. +在您输入有效消息并点击“提交”按钮后,页面将回显您输入的数据。 -![Form with a success message](/images/guide/start/form-success.png) +![表单成功消息](/images/guide/start/form-success.png) -## Summary +## 总结 -In this section of the guide, you've learned how to create a form model -class to represent the user data and validate said data. +在本指南的这一节中,您已学习了如何创建表单模型类来表示用户数据并验证该数据。 -You've also learned how to get data from users and how to display data back -in the browser. This is a task that could take you a lot of time when -developing an application, but Yii provides powerful widgets to make this -task easy. +您还学习了如何从用户获取数据以及如何在浏览器中显示数据。这是开发应用程序时可能花费大量时间的任务,但 Yii 提供了强大的小部件来使这项任务变得容易。 -In the next section, you will learn how to work with databases, which are -needed in nearly every application. +在下一节中,您将学习如何使用数据库,这在几乎每个应用程序中都是必需的。 diff --git a/src/zh-CN/guide/start/gii.md b/src/zh-CN/guide/start/gii.md index 3963dac6..615edf77 100644 --- a/src/zh-CN/guide/start/gii.md +++ b/src/zh-CN/guide/start/gii.md @@ -1,4 +1,4 @@ -# Generating code with Gii +# 使用 Gii 生成代码 > [!NOTE] -> Gii is under development and will be available later. +> Gii 正在开发中,稍后将可使用。 diff --git a/src/zh-CN/guide/start/hello.md b/src/zh-CN/guide/start/hello.md index 7e5e20fc..52789ba4 100644 --- a/src/zh-CN/guide/start/hello.md +++ b/src/zh-CN/guide/start/hello.md @@ -1,28 +1,22 @@ -# Saying hello +# 说声 Hello -This section describes how to create a new "Hello" page in your -application. It's a simple page that will echo back whatever you pass to it -or, if nothing passed, will just say "Hello!". +本节描述如何在应用程序中创建一个新的“Hello”页面。这是一个简单的页面,它会回显您传递给它的任何内容,或者如果没有传递任何内容,则显示“Hello!”。 -To achieve this goal, you will define a route and create [a -handler](../structure/handler.md) that does the job and forms the response. -Then you will improve it to use [view](../views/view.md) for building the -response. +为实现这个目标,您将定义一个路由并创建一个 [处理器](../structure/handler.md) +来完成工作并形成响应。然后您将改进它,使用[视图](../views/view.md)来构建响应。 -Through this tutorial, you will learn three things: +通过本教程,您将学习三件事: -1. How to create a handler to respond to a request. -2. How to map URL to the handler. -3. How to use [view](../views/view.md) to compose the response's content. +1. 如何创建处理器来响应请求。 +2. 如何将 URL 映射到处理器。 +3. 如何使用 [视图](../views/view.md) 来组成响应的内容。 -## Creating a handler +## 创建处理器 -For the "Hello" task, you will create a handler class that reads a `message` -parameter from the request and displays that message back to the user. If -the request doesn't provide a `message` parameter, the action will display -the default "Hello" message. +对于“Hello”任务,您将创建一个处理器类,从请求中读取 `message` 参数并将该消息显示给用户。如果请求没有提供 `message` +参数,操作将显示默认的“Hello”消息。 -Create `src/Web/Echo/Action.php`: +创建 `src/Web/Echo/Action.php`: ```php +## 试试看 -After creating the action and the view open -`http://localhost/say/Hello+World` in your browser. +创建操作和视图后,在浏览器中打开 `http://localhost/say/Hello+World`。 -This URL displays a page with "The message is: Hello World". +此 URL 显示一个包含“The message is: Hello World”的页面。 -If you omit the `message` parameter in the URL, the page displays "The -message is: Hello!". +如果您在 URL 中省略 `message` 参数,页面将显示“The message is: Hello!”。 -## Creating a View Template +## 创建视图模板 -Usually, the task is more complicated than printing out "hello world" and -involves rendering some complex HTML. For this task, it's handy to use view -templates. They're scripts you write to generate a response's body. +通常,任务比打印“hello world”更复杂,涉及渲染一些复杂的 HTML。对于这项任务,使用视图模板很方便。它们是您编写的用于生成响应主体的脚本。 -For the "Hello" task, create a `src/Web/Echo/template.php` template that -prints the `message` parameter received from the action method: +对于“Hello”任务,创建一个 `src/Web/Echo/template.php` 模板,打印从操作方法接收的 `message` 参数: ```php The message is:

``` -In the above code, the `message` parameter uses HTML encoding before you -print it. You need that because the parameter comes from an end user and is -vulnerable to [cross-site scripting (XSS) -attacks](https://en.wikipedia.org/wiki/Cross-site_scripting) by embedding -malicious JavaScript in the parameter. +在上面的代码中,`message` 参数在打印之前使用 HTML 编码。这是必要的,因为该参数来自最终用户,通过在参数中嵌入恶意 JavaScript +容易受到 [跨站脚本(XSS)攻击](https://en.wikipedia.org/wiki/Cross-site_scripting)。 -Naturally, you may put more content in the `say` view. The content can -consist of HTML tags, plain text, and even PHP statements. In fact, the view -service executes the `say` view as a PHP script. +当然,您可以在 `say` 视图中放置更多内容。内容可以由 HTML 标签、纯文本甚至 PHP 语句组成。实际上,视图服务将 `say` 视图作为 +PHP 脚本执行。 -To use the view, you need to change `src/Web/Echo/Action.php`: +要使用视图,您需要修改 `src/Web/Echo/Action.php`: ```php +## 总结 -In this section, you've touched the handler and template parts of the -typical web application. You created a handler as part of a class to handle -a specific request. You also created a view to compose the response's -content. In this simple example, no data source was involved as the only -data used was the `message` parameter. +在本节中,您接触了典型 Web +应用程序的处理器和模板部分。您创建了一个处理器类来处理特定请求。您还创建了一个视图来组成响应的内容。在这个简单的示例中,没有涉及数据源,因为使用的唯一数据是 +`message` 参数。 -You've also learned about routing in Yii, which acts as the bridge between -user requests and handlers. +您还了解了 Yii 中的路由,它充当用户请求和处理器之间的桥梁。 -In the next section, you will learn how to fetch data and add a new page -containing an HTML form. +在下一节中,您将学习如何获取数据并添加一个包含 HTML 表单的新页面。 diff --git a/src/zh-CN/guide/start/looking-ahead.md b/src/zh-CN/guide/start/looking-ahead.md index 47d7d2fe..e64c2e46 100644 --- a/src/zh-CN/guide/start/looking-ahead.md +++ b/src/zh-CN/guide/start/looking-ahead.md @@ -1,9 +1,5 @@ -# Looking ahead +# 展望未来 -If you've read through the entire "Getting Started" chapter, you have now -created a complete Yii application. In the process, you've learned how to -implement some commonly necessary features, such as getting data from users -via an HTML form, fetching data from a database, and displaying data in a -paginated fashion. You've also learned how to use [Gii](gii.md) to generate -code automatically. Using Gii for code generation turns the bulk of your Web -development process into a task as simple as just filling out some forms. +如果您已经通读了整个“入门”章节,那么您现在已经创建了一个完整的 Yii 应用程序。在此过程中,您学会了如何实现一些常见的必要功能,例如通过 HTML +表单从用户处获取数据、从数据库中获取数据以及以分页方式显示数据。您还学会了如何使用 [Gii](gii.md) 自动生成代码。使用 Gii +生成代码,可以将大部分 Web 开发工作简化为仅需填写几个表单的简单任务。 diff --git a/src/zh-CN/guide/start/prerequisites.md b/src/zh-CN/guide/start/prerequisites.md index adc99e39..532f0de3 100644 --- a/src/zh-CN/guide/start/prerequisites.md +++ b/src/zh-CN/guide/start/prerequisites.md @@ -1,44 +1,34 @@ -# What do you need to know? +# 你需要了解什么? -The Yii learning curve isn't as steep as other PHP frameworks, but still, -there are some things you should learn before starting with Yii. +Yii 的学习曲线不像其他 PHP 框架那样陡峭,但在开始使用 Yii 之前,仍然有一些东西你应该学习。 ## PHP -Yii is a PHP framework, so make sure you [read and understand language -reference](https://www.php.net/manual/en/langref.php). +Yii 是一个 PHP 框架,所以请确保你[阅读并理解语言参考](https://www.php.net/manual/en/langref.php)。 -## Object-oriented programming +## 面向对象编程 -You need a basic understanding of object-oriented programming. If you're not -familiar with it, check one of the many tutorials available such as [the one -from -tuts+](https://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762). +你需要对面向对象编程有基本的了解。如果你不熟悉它,可以查看许多可用的教程,例如 [tuts+ +的教程](https://code.tutsplus.com/tutorials/object-oriented-php-for-beginners--net-12762)。 -When you develop with Yii, you write code in an object-oriented fashion, so -make sure you're familiar with [PHP OOP -support](https://www.php.net/manual/en/language.oop5.php). +当你使用 Yii 开发时,你会以面向对象的方式编写代码,所以请确保你熟悉 [PHP OOP +支持](https://www.php.net/manual/en/language.oop5.php)。 -Note that the more complicated your application is, the more advanced OOP -concepts you should learn to successfully manage that complexity. +请注意,你的应用程序越复杂,你就应该学习更高级的 OOP 概念来成功管理这种复杂性。 -## Command line and Composer +## 命令行和 Composer -Yii extensively uses the de-facto standard PHP package manager, -[Composer](https://getcomposer.org) so make sure you read and understand its -[guide](https://getcomposer.org/doc/01-basic-usage.md). If you aren't -familiar with using the command line, it's time to start trying. Once you -learn the basics, you'll never want to work without it. +Yii 广泛使用事实上的标准 PHP 包管理器 +[Composer](https://getcomposer.org),所以请确保你阅读并理解它的[指南](https://getcomposer.org/doc/01-basic-usage.md)。如果你不熟悉使用命令行,现在是时候开始尝试了。一旦你学会了基础知识,你就再也不想没有它了。 ## HTTP -Since Yii is a web framework and the web largely uses HTTP, it's a good idea -to [learn more about it](https://developer.mozilla.org/en-US/docs/Web/HTTP). +由于 Yii 是一个 Web 框架,而 Web 主要使用 +HTTP,所以[了解更多关于它的信息](https://developer.mozilla.org/en-US/docs/Web/HTTP)是个好主意。 ## Docker -The default application template leverages Docker, so we recommend that you -[read and understand the concepts](https://docs.docker.com/get-started/). +默认的应用程序模板利用了 +Docker,所以我们建议你[阅读并理解这些概念](https://docs.docker.com/get-started/)。 -Also, you will benefit from familiarizing yourself with [twelve-factor -app](https://12factor.net/) principles. +此外,熟悉 [twelve-factor app](https://12factor.net/) 原则也会让你受益。 diff --git a/src/zh-CN/guide/start/workflow.md b/src/zh-CN/guide/start/workflow.md index 8d8c2643..9a239f95 100644 --- a/src/zh-CN/guide/start/workflow.md +++ b/src/zh-CN/guide/start/workflow.md @@ -1,122 +1,95 @@ -# Running applications +# 运行应用 -After installing Yii, you have a working Yii application. This section -introduces the application's built-in functionality, how the code is -organized, and how the application handles requests in general. +安装 Yii 后,你就有了一个可工作的 Yii 应用程序。本节介绍应用程序的内置功能、代码的组织方式以及应用程序如何处理请求。 -Note that unlike the framework itself, after you install a project template, -it's all yours. You're free to add or delete code and overall change it as -you need. +请注意,与框架本身不同,安装项目模板后,它就完全属于你了。你可以自由地添加或删除代码,并根据需要进行整体更改。 -## Functionality +## 功能 -The installed application contains only one page, accessible at -`http://localhost/`. It shares a common layout that you can reuse on -further pages. +安装的应用程序只包含一个页面,可通过 `http://localhost/` 访问。它共享一个通用布局,你可以在其他页面上重用。 -In addition to the web application, you can access a console script via -`APP_ENV=dev ./yii` or, in case of Docker, `make yii`. Use this script to -run background and maintenance tasks for the application, which the [Console -Application Section](../tutorial/console-applications.md) describes. +除了 Web 应用程序外,你还可以通过 `APP_ENV=dev ./yii` 或在 Docker 的情况下通过 `make yii` +访问控制台脚本。使用此脚本运行应用程序的后台和维护任务,[控制台应用程序部分](../tutorial/console-applications.md)对此进行了描述。 -## Application structure +## 应用结构 -The most important directories and files in your application are (assuming -the application's root directory is `app`): +应用程序中最重要的目录和文件是(假设应用程序的根目录是 `app`): ``` -assets/ Asset bundle source files. -config/ Configuration files. - common/ Common configuration and DI definitions. - console/ Console-specific configuration. - environments/ Environment-specific configuration (dev/test/prod). - web/ Web-specific configuration. -docker/ Docker-specific files. -public/ Files publically accessible from the Internet. - assets/ Published/compiled assets. - index.php Entry script. -runtime/ Files generated during runtime. -src/ Application source code. - Console/ Console commands. - Shared/ Code shared between web and console applications. - Web/ Web-specific code (actions, handlers, layout). - Shared/ Shared web components. - Layout/ Layout components and templates. - Environment.php Environment configuration class. -tests/ A set of Codeception tests for the application. - Console/ Console command tests. - Functional/ Functional tests. - Unit/ Unit tests. - Web/ Web actions tests. -vendor/ Installed Composer packages. -Makefile Config for make command. -yii Console application entry point. +assets/ 资源包源文件。 +config/ 配置文件。 + common/ 通用配置和 DI 定义。 + console/ 控制台特定配置。 + environments/ 环境特定配置(dev/test/prod)。 + web/ Web 特定配置。 +docker/ Docker 特定文件。 +public/ 可从互联网公开访问的文件。 + assets/ 已发布/编译的资源。 + index.php 入口脚本。 +runtime/ 运行时生成的文件。 +src/ 应用程序源代码。 + Console/ 控制台命令。 + Shared/ Web 和控制台应用程序之间共享的代码。 + Web/ Web 特定代码(动作、处理器、布局)。 + Shared/ 共享的 Web 组件。 + Layout/ 布局组件和模板。 + Environment.php 环境配置类。 +tests/ 应用程序的 Codeception 测试集。 + Console/ 控制台命令测试。 + Functional/ 功能测试。 + Unit/ 单元测试。 + Web/ Web 动作测试。 +vendor/ 已安装的 Composer 包。 +Makefile make 命令的配置。 +yii 控制台应用程序入口点。 ``` -In general, the files in the application fall into two groups: those under -`app/public` and those under other directories. You can access the former -directly via HTTP (i.e., in a browser), while you shouldn't expose the -latter. +一般来说,应用程序中的文件分为两组:`app/public` 下的文件和其他目录下的文件。你可以通过 +HTTP(即在浏览器中)直接访问前者,而不应该暴露后者。 -Each application has an entry script `public/index.php`, the only -web-accessible PHP script in the application. The entry script uses an -[application runner](https://github.com/yiisoft/yii-runner) to create an -instance of an incoming request with the help of one of PSR-7 packages and -passes it to an [application](../structure/application.md) instance. The -application executes a set of middleware sequentially to process the -request. It then passes the result to the emitter, which sends the response -to the browser. +每个应用程序都有一个入口脚本 `public/index.php`,这是应用程序中唯一可通过 Web 访问的 PHP +脚本。入口脚本使用[应用程序运行器](https://github.com/yiisoft/yii-runner)在 PSR-7 +包之一的帮助下创建传入请求的实例,并将其传递给[应用程序](../structure/application.md)实例。应用程序按顺序执行一组中间件来处理请求。然后将结果传递给发射器,发射器将响应发送到浏览器。 -Depending on the middleware you use, the application may behave -differently. By default, a router uses the requested URL and configuration -to choose a handler and execute it to produce a response. +根据你使用的中间件,应用程序的行为可能会有所不同。默认情况下,路由器使用请求的 URL 和配置来选择处理器并执行它以生成响应。 -You can learn more about the application template from the [yiisoft/app -package -documentation](https://github.com/yiisoft/app/blob/master/README.md). +你可以从 [yiisoft/app +包文档](https://github.com/yiisoft/app/blob/master/README.md)中了解更多关于应用程序模板的信息。 -## Request Lifecycle +## 请求生命周期 -The following diagram shows how an application handles a request. +下图显示了应用程序如何处理请求。 ```mermaid flowchart LR - user[User's client] --> index - index[index.php] --> DI[Initialize Dependency Container] - config[configs] -.-> DI - DI --> RequestFactory[RequestFactory] - RequestFactory -->|Request| app[Application] - app -->|Request| middleware[Middleware] - middleware -->|Request| router[Router] - router -->|Request| action[Action Handler] - action -->|Response| emitter[SapiEmitter] - router -->|Response| emitter - middleware -->|Response| emitter - app -->|Response| emitter + user[用户客户端] --> index + index[index.php] --> DI[初始化依赖容器] + config[配置] -.-> DI + DI --> RequestFactory[请求工厂] + RequestFactory -->|请求| app[应用程序] + app -->|请求| middleware[中间件] + middleware -->|请求| router[路由器] + router -->|请求| action[动作处理器] + action -->|响应| emitter[SapiEmitter] + router -->|响应| emitter + middleware -->|响应| emitter + app -->|响应| emitter emitter --> user ``` -1. A user makes a request to the [entry - script](../structure/entry-script.md) `public/index.php`. -2. The entry script with the help of the application runner loads the - container [configuration](../concept/configuration.md) and creates an - [application](../structure/application.md) instance and services - necessary to handle the request. -3. Request factory creates a request object based on a raw request that came - from a user. -4. Application passes a request object through a middleware array - configured. One of these is typically a router. -5. The Router finds out what handler to execute based on request and - configuration. -6. The handler may load some data, possibly from a database. -7. The handler forms a response by using data. Either directly or with the - help of the view package. -8. Emitter receives the response and takes care of sending the response to - the user's browser. +1. 用户向 [入口脚本](../structure/entry-script.md) `public/index.php` 发出请求。 +2. 入口脚本在应用程序运行器的帮助下加载容器 [配置](../concept/configuration.md),并创建处理请求所需的 + [应用程序](../structure/application.md) 实例和服务。 +3. 请求工厂根据来自用户的原始请求创建请求对象。 +4. 应用程序将请求对象传递给配置的中间件数组。其中之一通常是路由器。 +5. 路由器根据请求和配置确定要执行的处理器。 +6. 处理器可能会加载一些数据,可能来自数据库。 +7. 处理器使用数据形成响应。可以直接形成,也可以借助视图包。 +8. 发射器接收响应并负责将响应发送到用户的浏览器。 diff --git a/src/zh-CN/guide/structure/action.md b/src/zh-CN/guide/structure/action.md index cc4278ec..32c341a0 100644 --- a/src/zh-CN/guide/structure/action.md +++ b/src/zh-CN/guide/structure/action.md @@ -1,13 +1,9 @@ -# Actions +# 动作 -In a web application, the request URL determines what's executed. Matching -is made by a router configured with multiple routes. Each route can be -attached to a middleware that, given request, produces a response. Since -middleware overall could be chained and can pass actual handling to the next -middleware, we call the middleware actually doing the job an action. +在 Web 应用程序中,请求 URL +决定了要执行的内容。匹配由配置了多条路由的路由器完成。每条路由可以绑定一个中间件,该中间件接收请求并产生响应。由于中间件可以链式调用并将实际处理传递给下一个中间件,我们将真正执行任务的中间件称为动作。 -There are multiple ways to describe an action. The simplest one is using a -closure: +描述动作有多种方式,最简单的是使用闭包: ```php use \Psr\Http\Message\ServerRequestInterface; @@ -21,9 +17,7 @@ Route::get('/')->action(function (ServerRequestInterface $request) use ($respons }); ``` -It's fine for simple handling since any more complicated one would require -getting dependencies, so a good idea would be moving the handling to a class -method. Callback middleware could be used for the purpose: +对于简单的处理,这种方式完全可以,但更复杂的处理通常需要获取依赖,因此将处理逻辑移至类方法是一个好主意。为此可以使用回调中间件: ```php use Yiisoft\Router\Route; @@ -31,7 +25,7 @@ use Yiisoft\Router\Route; Route::get('/')->action(FrontPageAction::class), ``` -The class itself would be like: +该类的结构如下: ```php use \Psr\Http\Message\ServerRequestInterface; @@ -46,8 +40,7 @@ final readonly class FrontPageAction } ``` -For many cases, it makes sense to group handling for many routes into a -single class: +在许多情况下,将多条路由的处理逻辑归入一个类是合理的: ```php @@ -57,7 +50,7 @@ Route::get('/post/index')->action([PostController::class, 'actionIndex']), Route::get('/post/view/{id:\d+}')->action([PostController::class, 'actionView']), ``` -The class itself would look like the following: +该类的结构如下所示: ```php use \Psr\Http\Message\ServerRequestInterface; @@ -78,12 +71,12 @@ final readonly class PostController } ``` -We usually call such a class "controller." +我们通常将这样的类称为“控制器”。 -## Autowiring +## 自动注入 -Both constructors of action-classes and action-methods are automatically getting services from - the dependency injection container: +动作类的构造函数和动作方法都可以自动从 + 依赖注入容器中获取服务: ```php use \Psr\Http\Message\ServerRequestInterface; @@ -112,7 +105,5 @@ final readonly class PostController } ``` -In the above example `PostRepository` is injected automatically via -constructor. That means it is available in every action. Logger is injected -into `index` action only. +在上面的示例中,`PostRepository` 通过构造函数自动注入,因此在每个动作中都可用。而 Logger 仅注入到 `index` 动作中。 diff --git a/src/zh-CN/guide/structure/application.md b/src/zh-CN/guide/structure/application.md index 3fff6311..88dc555b 100644 --- a/src/zh-CN/guide/structure/application.md +++ b/src/zh-CN/guide/structure/application.md @@ -1,18 +1,12 @@ -# Application +# 应用 -The primary purpose of the web application and its runner in Yii3 is to -process requests to get responses. +Yii3 中 Web 应用程序及其运行器的主要目的是处理请求以获取响应。 -Typically, the runtime consists of: +通常,运行时由以下部分组成: -1. Startup. Get config, create an instance of container and do additional - environment initialization such as registering error handler, so it can - handle errors occurring. Fire `ApplicationStartup` event. -2. Handle requests via passing request objects to middleware dispatcher to - execute [middleware stack](middleware.md) and get a response object. In - usual PHP applications, it's done once. In [environments such as - RoadRunner](../tutorial/using-with-event-loop.md), it could be done - multiple times with the same application instance. Response object is - converted into an actual HTTP response by using emitter. Fire - `AfterEmit` event. -3. Shutdown. Fire `ApplicationShutdown` event. +1. 启动。获取配置,创建容器实例,并进行额外的环境初始化,例如注册错误处理器以处理发生的错误。触发 `ApplicationStartup` 事件。 +2. 通过将请求对象传递给中间件调度器来处理请求,以执行[中间件栈](middleware.md)并获取响应对象。在普通的 PHP + 应用程序中,这只执行一次。在 [RoadRunner + 等环境](../tutorial/using-with-event-loop.md)中,可以使用同一应用程序实例执行多次。响应对象通过发射器转换为实际的 + HTTP 响应。触发 `AfterEmit` 事件。 +3. 关闭。触发 `ApplicationShutdown` 事件。 diff --git a/src/zh-CN/guide/structure/domain.md b/src/zh-CN/guide/structure/domain.md index dc12aeb3..0bef6a71 100644 --- a/src/zh-CN/guide/structure/domain.md +++ b/src/zh-CN/guide/structure/domain.md @@ -1,91 +1,64 @@ -# Domain +# 领域 -The Domain or domain model is what makes the project unique. With requirements and terminology of the problem being solved -in mind (the problem context), you build an abstraction that consists of entities, their relationships, and logic that -operates these entities. To focus on the complex part of the problem, domain is, ideally, separated from - the infrastructure part of the system (that's how to save data into a database, how to form HTTP response, etc.). +领域或领域模型是使项目独特的东西。考虑到正在解决的问题的需求和术语 +(问题上下文),您构建一个由实体、它们的关系以及操作这些实体的逻辑组成的 +抽象。为了专注于问题的复杂部分,领域理想情况下应与 +系统的基础设施部分分离(即如何将数据保存到数据库、如何形成 HTTP 响应等)。 > [!NOTE] -> Such isolation is suitable for complex systems. If your project domain is basically create/read/update/delete -> for a set of records with not much complex logic, it makes no sense to apply a complex solution to a simple problem. -> The individual concepts of domain design below could be applied separately, so make sure to check these even if your -> project isn't that complicated. +> 这种隔离适用于复杂系统。如果您的项目领域基本上是对一组记录的创建/读取/更新/删除, +> 没有太多复杂逻辑,那么将复杂解决方案应用于简单问题是没有意义的。 +> 下面的领域设计的各个概念可以单独应用,因此即使您的 +> 项目没有那么复杂,也请确保查看这些内容。 -## Bounded context +## 限界上下文 -It's nearly impossible to build a model that solves multiple problems that -aren't too complicated by itself. Therefore, it's a good practice to divide -the domain into several use-cases and have a separate model for each -use-case. Such separated models are called "bounded contexts." +几乎不可能构建一个能解决多个问题且本身不太复杂的模型。因此,将领域划分为几个用例并为每个用例建立单独的模型是一种良好实践。这种分离的模型被称为“限界上下文”。 -## Building blocks +## 构建块 -There are various building blocks that are typically used when describing -domain models. It isn't mandatory to use them all. +在描述领域模型时,通常使用各种构建块。并非必须使用所有构建块。 -### Entity +### 实体 -Entity is a uniquely identifiable object such as user, product, payment, -etc. When comparing them, you're checking ID, not the attribute values. If -there are two objects with different attributes but the same ID, they're -considered being the same thing. +实体是可唯一标识的对象,例如用户、产品、付款等。比较它们时,您检查的是 ID,而不是属性值。如果有两个属性不同但 ID +相同的对象,则认为它们是同一个事物。 -### Value object +### 值对象 -Value object describes an object by its characteristics. For example, a -price that consists of value and currency. When comparing such objects, -you're checking actual values. If they match, an object is considered to be -the same. +值对象通过其特征来描述对象。例如,由数值和货币组成的价格。比较此类对象时,您检查的是实际值。如果它们匹配,则认为对象相同。 -### Aggregate +### 聚合 -Aggregate is a set of domain objects such as entities and value objects and -additional data that could be treated as a single unit. It usually -represents a compound object from a domain model such as shop order or HR -person dossier. +聚合是一组可视为单一单元的领域对象(如实体、值对象)和附加数据。它通常代表领域模型中的复合对象,例如商店订单或人力资源人员档案。 -One of the components of an aggregate is called a root. The root identifies -an aggregate as a whole and should be used to access it. +聚合的一个组件称为根。根将聚合标识为一个整体,应通过根来访问聚合。 -### Domain event +### 领域事件 -An aggregate, while processed, may raise events. For example, when order is -confirmed, `OrderConfirmed` event would be risen so other parts of the -system may react on these. +聚合在处理过程中可能会引发事件。例如,当订单确认时,会触发 `OrderConfirmed` 事件,以便系统的其他部分可以响应这些事件。 -### Data transfer object +### 数据传输对象 -Data transfer object or DTO is an object whose only purpose is to hold data -as it is. It's commonly used to pass data between different services. +数据传输对象(DTO)是一种仅用于保存数据的对象。它通常用于在不同服务之间传递数据。 -### Service +### 服务 -Service is a class that contains a standalone operation within the context -of your domain model. See "[service components](service.md)". +服务是一个包含领域模型上下文中独立操作的类。请参阅“[服务组件](service.md)”。 -### Repository +### 仓库 -The repository task is to abstract away how domain objects are -obtained. These are usually separated into two parts: an interface that -stays in the domain layer and an implementation that's situated in the -infrastructure layer. In such a way, domain doesn't care how data is -obtained and saved and may be focused around the complicated business logic -instead. +仓库的任务是抽象化获取领域对象的方式。这些通常分为两部分:保留在领域层的接口和位于基础设施层的实现。这样,领域不关心如何获取和保存数据,可以专注于复杂的业务逻辑。 -Repository is usually implemented as a service. +仓库通常作为服务实现。 -### Instantiating building blocks +### 实例化构建块 -Entity, value object, aggregate, and domain events aren't services and -shouldn't be instantiated through DI container. Using `new` is the way to -go with these. +实体、值对象、聚合和领域事件不是服务,不应通过 DI 容器实例化。使用 `new` 是实例化这些对象的正确方式。 ## 参考资料 -- [BoundedContext by Martin - Fowler](https://martinfowler.com/bliki/BoundedContext.html) -- [ValueObject by Martin - Fowler](https://martinfowler.com/bliki/ValueObject.html) -- [Aggregate by Marting - Fowler](https://martinfowler.com/bliki/DDD_Aggregate.html) +- [Martin Fowler 的限界上下文](https://martinfowler.com/bliki/BoundedContext.html) +- [Martin Fowler 的值对象](https://martinfowler.com/bliki/ValueObject.html) +- [Martin Fowler 的聚合](https://martinfowler.com/bliki/DDD_Aggregate.html) diff --git a/src/zh-CN/guide/structure/entry-script.md b/src/zh-CN/guide/structure/entry-script.md index 29f63c0f..4462cadc 100644 --- a/src/zh-CN/guide/structure/entry-script.md +++ b/src/zh-CN/guide/structure/entry-script.md @@ -1,32 +1,26 @@ -# Entry scripts +# 入口脚本 -Entry scripts are the first step in the application bootstrapping -process. An application (either Web application or console application) has -a single entry script. End users make requests to entry scripts which -instantiate application instances and forward the requests to them. +入口脚本是应用程序引导过程的第一步。每个应用程序(无论是 Web +应用程序还是控制台应用程序)都只有一个入口脚本。最终用户向入口脚本发起请求,入口脚本负责实例化应用程序并将请求转发给它。 -Entry scripts for Web applications must be stored under Web-accessible -directories so that they can be accessed by end users. They're often named -as `index.php`, but can also use any other names, provided Web servers can -locate them. +Web 应用程序的入口脚本必须存储在 Web 可访问目录下,以便最终用户能够访问。文件名通常为 `index.php`,但也可以使用其他名称,只要 +Web 服务器能够找到即可。 -Entry script for console application is `./yii`. +控制台应用程序的入口脚本为 `./yii`。 -Entry scripts mainly perform the following work with the help of -`ApplicationRunner`: +入口脚本借助 `ApplicationRunner` 主要完成以下工作: -* Register [Composer - autoloader](https://getcomposer.org/doc/01-basic-usage.md#autoloading); -* Obtain configuration; -* Use configuration to initialize a dependency injection container; -* Get an instance of the request. -* Pass it to `Application` to handle and get a response from it. -* With the help of an emitter that transforms a response object into an - actual HTTP response that's sent to the client browser. +* 注册 [Composer + 自动加载器](https://getcomposer.org/doc/01-basic-usage.md#autoloading); +* 获取配置; +* 使用配置初始化依赖注入容器; +* 获取请求实例。 +* 将请求传递给 `Application` 处理并获取响应。 +* 借助发射器将响应对象转换为实际的 HTTP 响应并发送给客户端浏览器。 -## Web Applications +## Web 应用程序 -The following is the code in the entry script for the application template: +以下是应用程序模板中入口脚本的代码: ```php run(); ``` -## Console Applications +## 控制台应用程序 -Similarly, the following is the code for the entry script of a console -application: +类似地,以下是控制台应用程序入口脚本的代码: ```php #!/usr/bin/env php @@ -105,10 +98,9 @@ try { } ``` -## Alternative runtimes +## 其他运行时 -For alternative runtimes such as RoadRunner or Swoole, special entry scripts -should be used. See: +对于 RoadRunner 或 Swoole 等其他运行时,需要使用专用的入口脚本。请参阅: -- [Using Yii with RoadRunner](../tutorial/using-yii-with-roadrunner.md) -- [Using Yii with Swoole](../tutorial/using-yii-with-swoole.md) +- [在 RoadRunner 中使用 Yii](../tutorial/using-yii-with-roadrunner.md) +- [在 Swoole 中使用 Yii](../tutorial/using-yii-with-swoole.md) diff --git a/src/zh-CN/guide/structure/middleware.md b/src/zh-CN/guide/structure/middleware.md index 2b450c2c..a1835c84 100644 --- a/src/zh-CN/guide/structure/middleware.md +++ b/src/zh-CN/guide/structure/middleware.md @@ -1,39 +1,31 @@ -# Middleware +# 中间件 -Yii works with HTTP using the abstraction layer built around [PSR-7 HTTP -message interfaces](https://www.php-fig.org/psr/psr-7/) and [PSR-15 request -handler/middleware interfaces](https://www.php-fig.org/psr/psr-15/). +Yii 通过基于 [PSR-7 HTTP 消息接口](https://www.php-fig.org/psr/psr-7/) 和 [PSR-15 +请求处理器/中间件接口](https://www.php-fig.org/psr/psr-15/) 构建的抽象层来处理 HTTP。 -The application is composed of one or several middleware. Middleware runs -between request and response. When the URL is requested, the request object -is passed to the middleware dispatcher that starts executing middleware one -after another. Each middleware, given the request, can: +应用程序由一个或多个中间件组成。中间件在请求和响应之间运行。当 URL +被请求时,请求对象被传递给中间件调度器,后者开始逐个执行中间件。每个中间件在给定请求的情况下可以: -- Pass the request to the next middleware performing some work before / - after it. -- Form the response and return it. +- 将请求传递给下一个中间件,并在其之前/之后执行一些工作。 +- 形成响应并返回它。 -Depending on middleware used, application behavior may vary significantly. +根据所使用的中间件,应用程序的行为可能会有很大差异。 -![Middleware](/images/guide/middleware.svg) +![中间件](/images/guide/middleware.svg) -In the above each next middleware wraps the previous -middleware. Alternatively, it could be presented as follows: +在上图中,每个后续中间件都包裹着前一个中间件。或者,它也可以如下所示: -![Middleware](/images/guide/middleware_alternative.svg) +![中间件](/images/guide/middleware_alternative.svg) -## Using middleware +## 使用中间件 -Any [PSR-15](https://www.php-fig.org/psr/psr-15/) compatible middleware -could be used with Yii, and there are many. Say, you need to add basic -authentication to one of the application URLs. URL-dependent middleware is -configured using router, so you need to change the router factory. +任何与 [PSR-15](https://www.php-fig.org/psr/psr-15/) 兼容的中间件都可以与 Yii +一起使用,而且有很多。比如,您需要为应用程序的某个 URL 添加基本身份验证。依赖 URL 的中间件使用路由器配置,因此您需要修改路由器工厂。 -Authentication middleware is implemented by -`middlewares/http-authentication` package so execute `composer require -middlewares/http-authentication` in the application root directory. +身份验证中间件由 `middlewares/http-authentication` 包实现,因此在应用程序根目录中执行 `composer +require middlewares/http-authentication`。 -Now register the middleware in DI container configuration `config/web.php`: +现在在 DI 容器配置 `config/web.php` 中注册中间件: ```php withAttribute('answer', 42); return $handler->handle($request); ``` -To get it in the next middleware: +要在下一个中间件中获取它: ```php $answer = $request->getAttribute('answer'); ``` -### Capturing response to manipulate it +### 捕获响应以操作它 -You may want to capture the response to manipulate it. It could be useful -for adding CORS headers, gzipping content, etc. +您可能希望捕获响应以对其进行操作。这对于添加 CORS 标头、gzip 压缩内容等非常有用。 ```php $response = $handler->handle($request); diff --git a/src/zh-CN/guide/structure/overview.md b/src/zh-CN/guide/structure/overview.md index 3d8f5d9d..08893e15 100644 --- a/src/zh-CN/guide/structure/overview.md +++ b/src/zh-CN/guide/structure/overview.md @@ -1,65 +1,55 @@ -# Overview - -Yii applications code is typically grouped into modules by context. In each -module there could be grouping by type. - -For example, if the application is an online store, the context could be: - -- Customer - - Profile - - Products list - - Checkout -- Logistics -- Delivery - - Addresses -- Helpdesk - - Support - - Claims - - Returns -- Accounting - - Returns - - Transactions - - Taxes - -For a "Customer" context, residing under `App\Customer` namespace, structure -would be: +# 概述 + +Yii 应用程序代码通常按上下文分组到模块中。在每个模块中,可以按类型进行进一步分组。 + +例如,如果应用程序是一个在线商店,上下文可以是: + +- 客户 + - 个人资料 + - 产品列表 + - 结账 +- 物流 +- 配送 + - 地址 +- 帮助台 + - 支持 + - 索赔 + - 退货 +- 财务 + - 退货 + - 交易 + - 税务 + +对于位于 `App\Customer` 命名空间下的“Customer”上下文,结构将是: ``` App/ - Customer/ <-- module namespace + Customer/ <-- 模块命名空间 Entity/ - Customer.php <-- entity shared by "Profile" and "Checkout" + Customer.php <-- "Profile" 和 "Checkout" 共用的实体 Profile/ Widget/ Gravatar.php - ProfileRepository.php <-- repository is usually specific to context - ProfileController.php <-- "Customer\Profile" entry point - ProductList/ <-- module namespace - Entity/ <-- entities specific to "Customer\ProductList" + ProfileRepository.php <-- 仓库通常特定于上下文 + ProfileController.php <-- "Customer\Profile" 入口点 + ProductList/ <-- 模块命名空间 + Entity/ <-- "Customer\ProductList" 特有的实体 Category.php Product.php - ProductsListController.php <-- "Customer\ProductList" entry point - Checkout/ <-- module namespace + ProductsListController.php <-- "Customer\ProductList" 入口点 + Checkout/ <-- 模块命名空间 CheckoutController.php ``` -A context may include sub-contexts. If a class is shared by multiple -contexts, it's moved to the ancestor of both contexts. +一个上下文可以包含子上下文。如果一个类被多个上下文共享,它将被移动到两个上下文的共同祖先中。 -A context may have [an entry point known as "action" or -"controller"](action.md). Its job is to take [a request -instance](../runtime/request.md), pass it to [domain layer](domain.md) in a -suitable format, and create [a response](../runtime/response.md) based on -domain layer return. +一个上下文可以有 +[一个称为“动作”或“控制器”的入口点](action.md)。它的工作是获取[请求实例](../runtime/request.md),以适当的格式将其传递给 +[领域层](domain.md),并根据领域层的返回创建 [响应](../runtime/response.md)。 -Besides, Yii applications also have the following: +此外,Yii 应用程序还具有以下内容: -* [entry scripts](entry-script.md): they're PHP scripts that are directly - accessible by end users. They're responsible for starting a request - handling cycle. Typically, a single entry script is handling the whole - application. -* [services](service.md): they're typically stateless objects registered - within dependency container and provide various action methods. -* [middleware](middleware.md): they represent a code that needs to be - invoked before and after the actual handling of each request by action - handlers. +* [入口脚本](entry-script.md):它们是最终用户可以直接访问的 PHP + 脚本。它们负责启动请求处理周期。通常,单个入口脚本处理整个应用程序。 +* [服务](service.md):它们通常是在依赖容器中注册的无状态对象,并提供各种操作方法。 +* [中间件](middleware.md):它们表示需要在操作处理器实际处理每个请求之前和之后调用的代码。 diff --git a/src/zh-CN/guide/structure/package.md b/src/zh-CN/guide/structure/package.md index a0bb1716..bc6b9ac0 100644 --- a/src/zh-CN/guide/structure/package.md +++ b/src/zh-CN/guide/structure/package.md @@ -1,68 +1,51 @@ -# Packages +# 包 -Reusable code could be released as [a Composer -package](https://getcomposer.org/doc/05-repositories.md#package). It could -be an infrastructure library, a module representing one of the application -contexts or, basically, any reusable code. +可复用的代码可以作为 [Composer +包](https://getcomposer.org/doc/05-repositories.md#package)发布。它可以是一个基础设施库、代表某个应用上下文的模块,或者基本上任何可复用的代码。 -## Using packages +## 使用包 -By default, Composer installs packages registered on -[Packagist](https://packagist.org/) — the biggest repository for open source -PHP packages. You can look for packages on Packagist. You may also [create -your own -repository](https://getcomposer.org/doc/05-repositories.md#repository) and -configure Composer to use it. This is useful if you're developing private -packages that you want to share within your projects only. +默认情况下,Composer 会安装在 [Packagist](https://packagist.org/) 上注册的包——这是最大的开源 PHP +包仓库。您可以在 Packagist +上搜索包。您也可以[创建自己的仓库](https://getcomposer.org/doc/05-repositories.md#repository)并配置 +Composer 使用它,这在开发只在项目内部共享的私有包时非常有用。 -Packages installed by Composer are stored in the `vendor` directory of your -project. Because the Composer is a dependency manager, when it installs a -package, it will also install all its dependent packages. +Composer 安装的包存储在项目的 `vendor` 目录中。由于 Composer +是一个依赖管理器,在安装某个包时,它也会同时安装该包所依赖的所有包。 > [!WARNING] -> `vendor` directory of your application should never be modified. +> 永远不要手动修改应用程序的 `vendor` 目录。 -A package could be installed with the following command: +可以使用以下命令安装包: ``` composer install vendor-name/package-name ``` -After it's done, Composer modifies `composer.json` and `composer.lock`. The -former defines what packages to install, and their version constraints the -latter stores a snapshot of exact versions actually installed. +完成后,Composer 会修改 `composer.json` 和 +`composer.lock`。前者定义要安装的包及其版本约束,后者存储实际安装的精确版本快照。 -Classes from the package will be available immediately via -[autoloading](../concept/autoloading.md). +包中的类可以通过[自动加载](../concept/autoloading.md)立即使用。 -## Creating packages +## 创建包 -You may consider creating a package when you feel the need to share with -other people your great code. A package can contain any code you like, such -as a helper class, a widget, a service, middleware, the whole module, etc. +当您希望与他人共享优质代码时,可以考虑创建一个包。包可以包含任何代码,例如辅助类、小部件、服务、中间件、完整模块等。 -Below are the basic steps you may follow. +以下是基本步骤。 -1. Create a project for your package and host it on a VCS repository, such - as [GitHub.com](https://github.com). The development and maintenance - work for the package should be done on this repository. -2. Under the root directory of the project, create a file named - `composer.json` as required by Composer. Please refer to the next - subsection for more details. -3. Register your package with a Composer repository, such as - [Packagist](https://packagist.org/), so that other users can find and - install your package using Composer. +1. 为您的包创建一个项目,并将其托管在 VCS 仓库(例如 + [GitHub.com](https://github.com))上。包的开发和维护工作应在该仓库中进行。 +2. 在项目根目录下,按照 Composer 的要求创建 `composer.json` 文件。详情请参阅下一小节。 +3. 将您的包注册到 Composer 仓库(例如 [Packagist](https://packagist.org/)),以便其他用户能够通过 + Composer 找到并安装您的包。 ### `composer.json` -Each Composer package must have a `composer.json` file in its root -directory. The file contains the metadata about the package. You may find -the complete specification about this file in the [Composer -Manual](https://getcomposer.org/doc/01-basic-usage.md#composer-json-project-setup). -The following example shows the `composer.json` file for the -`yiisoft/yii-widgets` package: +每个 Composer 包的根目录下必须有一个 `composer.json` 文件,该文件包含包的元数据。您可以在 [Composer +手册](https://getcomposer.org/doc/01-basic-usage.md#composer-json-project-setup)中找到该文件的完整规范。以下示例展示了 +`yiisoft/yii-widgets` 包的 `composer.json` 文件: ```json { @@ -139,33 +122,26 @@ The following example shows the `composer.json` file for the ``` -#### Package Name +#### 包名 -Each Composer package should have a package name which uniquely identifies -the package among all others. The format of package names is -`vendorName/projectName`. For example, in the package name `yiisoft/queue`, -the vendor name, and the project name are `yiisoft` and `queue`, -respectively. +每个 Composer 包都应有一个唯一标识该包的包名。包名的格式为 `vendorName/projectName`。例如,在包名 +`yiisoft/queue` 中,供应商名称为 `yiisoft`,项目名称为 `queue`。 > [!WARNING] -> Don't use `yiisoft` as your vendor name as it's reserved for use by the Yii itself. +> 不要使用 `yiisoft` 作为您的供应商名称,该名称为 Yii 框架自身保留。 -We recommend you prefix `yii-` to the project name for packages that aren't -able to work as general PHP packages and require Yii application. This will -allow users to more easily tell whether a package is Yii specific. +对于无法作为通用 PHP 包使用、必须依赖 Yii 应用程序的包,我们建议在项目名称前加上 `yii-` 前缀,以便用户更容易判断某个包是否为 Yii +专属包。 -#### Dependencies +#### 依赖 -If your extension depends on other packages, you should list them in -`require` section of `composer.json`. Make sure you also list appropriate -version constraints (e.g. `^1.0`, `@stable`) for each dependent package. -Use stable dependencies when your extension is released in a stable version. +如果您的扩展依赖其他包,应在 `composer.json` 的 `require` 部分列出它们,并为每个依赖包指定适当的版本约束(例如 +`^1.0`、`@stable`)。当扩展发布稳定版本时,应使用稳定版本的依赖。 -#### Class Autoloading +#### 类自动加载 -In order for your classes to be autoloaded, you should specify the -`autoload` entry in the `composer.json` file, like shown below: +要使您的类能够被自动加载,需要在 `composer.json` 文件中指定 `autoload` 条目,如下所示: ```json { @@ -179,64 +155,39 @@ In order for your classes to be autoloaded, you should specify the } ``` -You may list one or multiple root namespaces and their corresponding file -paths. +您可以列出一个或多个根命名空间及其对应的文件路径。 -### Recommended Practices +### 推荐实践 -Because packages are meant to be used by other people, you often need to -make an extra effort during development. Below, we introduce some common -and recommended practices in creating high-quality extensions. +由于包是供他人使用的,在开发过程中往往需要付出额外的努力。以下介绍一些创建高质量扩展的常见推荐实践。 -#### Testing +#### 测试 -You want your package to run flawlessly without bringing problems to other -people. To reach this goal, you should test your extension before releasing -it to the public. +您希望自己的包能够无缺陷运行,不给他人带来问题。为此,应在公开发布前对扩展进行充分测试。 -It's recommended that you create various test cases to cover your extension -code rather than relying on manual tests. Each time before you release a -new version of your package, you may run these test cases to make sure -everything is in good shape. For more details, please refer to the -[Testing](../testing/overview.md) section. +建议编写各种测试用例来覆盖扩展代码,而不是依赖手动测试。每次发布新版本前,运行这些测试用例以确保一切正常。更多详情请参阅[测试](../testing/overview.md)章节。 -#### Versioning +#### 版本管理 -You should give each release of your extension a version number -(e.g. `1.0.1`). We recommend you follow the [semantic -versioning](https://semver.org) practice when determining what version -numbers should be used. +应为扩展的每个发布版本指定版本号(例如 `1.0.1`)。在确定版本号时,我们建议遵循[语义化版本](https://semver.org)规范。 -#### Releasing +#### 发布 -To let other people know about your package, you need to release it to the -public. +要让他人了解您的包,需要将其公开发布。 -If it's the first time you're releasing a package, you should register it in -a Composer repository, such as [Packagist](https://packagist.org/). After -that, all you need to do is create a release tag (for example, `v1.0.1`) on -the VCS repository of your extension and notify the Composer repository -about the new release. People will then be able to find the new release and -install or update the package through the Composer repository. +如果是首次发布包,应将其注册到 Composer 仓库(例如 +[Packagist](https://packagist.org/))。之后,只需在扩展的 VCS 仓库上创建发布标签(例如 `v1.0.1`)并通知 +Composer 仓库有新版本即可。其他人就能通过 Composer 仓库找到新版本并安装或更新该包。 -In the release of your package, in addition to code files, you should also -consider including the following to help other people learn about and use -your extension: +在发布包时,除代码文件外,还应考虑包含以下内容,以帮助他人了解和使用您的扩展: -* A readme file in the package root directory: it describes what your - extension does and how to install and use it. We recommend you write it - in [Markdown](https://daringfireball.net/projects/markdown/) format and - name the file as `README.md`. -* A changelog file in the package root directory: it lists what changes are - made in each release. The file may be written in Markdown format and named - as `CHANGELOG.md`. -* An upgrade file in the package root directory: it gives the instructions - on how to upgrade from older releases of the extension. The file may be - written in Markdown format and named as `UPGRADE.md`. -* Tutorials, demos, screenshots, etc.: these are needed if your extension - provides many features that can't be fully covered in the readme file. -* API documentation: your code should be well-documented to allow other - people to more easily read and understand it. +* 包根目录下的 readme 文件:描述扩展的功能及安装和使用方法。建议使用 + [Markdown](https://daringfireball.net/projects/markdown/) 格式编写,并命名为 + `README.md`。 +* 包根目录下的 changelog 文件:列出每个版本的变更内容。文件可使用 Markdown 格式编写,命名为 `CHANGELOG.md`。 +* 包根目录下的 upgrade 文件:提供从旧版本升级的说明。文件可使用 Markdown 格式编写,命名为 `UPGRADE.md`。 +* 教程、演示、截图等:如果扩展提供的功能较多,无法在 readme 文件中完整说明,则需要这些补充材料。 +* API 文档:代码应有完善的文档注释,以便他人更容易阅读和理解。 diff --git a/src/zh-CN/guide/structure/service.md b/src/zh-CN/guide/structure/service.md index 0baee5d5..680c86e4 100644 --- a/src/zh-CN/guide/structure/service.md +++ b/src/zh-CN/guide/structure/service.md @@ -1,9 +1,6 @@ -# Service components +# 服务组件 -Application may get complicated, so it makes sense to extract focused parts -of business logic or infrastructure into service components. They're -typically injected into other components or action handlers. It's usually -done via autowiring: +应用程序可能会变得复杂,因此将业务逻辑或基础设施的专注部分提取到服务组件中是有意义的。它们通常被注入到其他组件或操作处理器中。这通常通过自动装配来完成: ```php public function actionIndex(CurrentRoute $route, MyService $myService): ResponseInterface @@ -17,9 +14,7 @@ public function actionIndex(CurrentRoute $route, MyService $myService): Response } ``` -Yii3 doesn't technically imply any limitations on how you build services. In -general, there's no need to extend from a base class or implement a certain -interface: +Yii3 在技术上对如何构建服务没有任何限制。通常,无需从基类继承或实现特定接口: ```php final readonly class MyService @@ -37,29 +32,21 @@ final readonly class MyService } ``` -Services either perform a task or return data. They're created once, put -into a DI container and then could be used multiple times. Because of that, -it's a good idea to keep your services stateless that's both service itself -and any of its dependencies shouldn't hold state. You can ensure it by using -`readonly` PHP keyword at class level. +服务要么执行任务,要么返回数据。它们被创建一次,放入 DI +容器,然后可以多次使用。因此,保持服务无状态是个好主意,即服务本身及其任何依赖都不应保持状态。您可以通过在类级别使用 PHP 的 `readonly` +关键字来确保这一点。 -## Service dependencies and configuration +## 服务依赖和配置 -Services should always define all their dependencies on other services via -`__construct()`. It both allows you to use a service right away after it's -created and serves as an indicator of a service doing too much if there are -too many dependencies. +服务应始终通过 `__construct()` +定义对其他服务的所有依赖。这既允许您在服务创建后立即使用它,也可以在依赖太多时作为服务承担过多职责的提示。 -- After the service is created, it shouldn't be re-configured in runtime. -- DI container instance usually **shouldn't** be injected as a - dependency. Prefer concrete interfaces. -- In case of complicated or "heavy" initialization, try to postpone it until - the service method is called. +- 服务创建后,不应在运行时重新配置。 +- DI 容器实例通常**不应该**作为依赖注入。优先使用具体接口。 +- 如果初始化复杂或“繁重”,请尝试推迟到服务方法被调用时再进行。 -The same is valid for configuration values. They should be provided as a -constructor argument. Related values could be grouped together into value -objects. For example, database connection usually requires DSN string, -username and password. These three could be combined into Dsn class: +配置值也同样适用。它们应作为构造函数参数提供。相关值可以组合到值对象中。例如,数据库连接通常需要 DSN 字符串、用户名和密码。这三个可以合并到 Dsn +类中: ```php final readonly class Dsn @@ -82,10 +69,9 @@ final readonly class Dsn } ``` -## Service methods +## 服务方法 -Service method usually does something. It could be a simple thing repeated -exactly, but usually it depends on the context. For example: +服务方法通常执行某些操作。它可能是完全重复的简单事情,但通常取决于上下文。例如: ```php final readonly class PostPersister @@ -103,17 +89,13 @@ final readonly class PostPersister } ``` -There's a service that is saving posts into permanent storage such as a -database. An object allowing communication with a concrete storage is always -the same, so it's injected using constructor while the post saved could -vary, so it's passed as a method argument. +有一个将帖子保存到数据库等永久存储的服务。允许与具体存储通信的对象始终相同,因此使用构造函数注入;而要保存的帖子可能不同,因此作为方法参数传递。 -## Is everything a service? +## 一切都是服务吗? -Often it makes sense to choose another class type to place your code -into. Check: +通常选择另一种类类型来放置您的代码更合适。请检查: -- Repository -- Widget -- [Middleware](middleware.md) -- Entity +- 仓库 +- 小部件 +- [中间件](middleware.md) +- 实体 diff --git a/src/zh-CN/guide/tutorial/console-applications.md b/src/zh-CN/guide/tutorial/console-applications.md index 6263cca0..70a57388 100644 --- a/src/zh-CN/guide/tutorial/console-applications.md +++ b/src/zh-CN/guide/tutorial/console-applications.md @@ -1,27 +1,23 @@ -# Console applications +# 控制台应用程序 -Console applications are mainly used to create utility, background -processing and maintenance tasks. +控制台应用程序主要用于创建实用工具、后台处理和维护任务。 -To get support for console application in your project, get -`yiisoft/yii-console` via composer: +要在项目中获得控制台应用程序支持,请通过 composer 获取 `yiisoft/yii-console`: ``` composer require yiisoft/yii-console ``` -After it's installed, you can access the entry point as +安装后,您可以通过以下方式访问入口点: ``` ./yii ``` -Out of the box only `serve` command is available. It's starting PHP built-in -web server to serve the application locally. +开箱即用只有 `serve` 命令可用。它启动 PHP 内置 Web 服务器在本地提供应用程序服务。 -Commands are executed with `symfony/console`. To create your own console -command, you need to define a command: +命令使用 `symfony/console` 执行。要创建自己的控制台命令,您需要定义一个命令: ```php ``` -## Adding More Data - -The `Yiisoft\Mailer\MessageInterface` provides several methods to customize -your message: - -- `withCharset()` - Returns a new instance with the specified charset. -- `withFrom()` - Returns a new instance with the specified sender email - address. -- `withTo()` - Returns a new instance with the specified recipient(s) email - address. -- `withReplyTo()` - Returns a new instance with the specified reply-to - address. -- `withCc()` - Returns a new instance with the specified Cc (extra copy - receiver) addresses. -- `withBcc()` - Returns a new instance with the specified Bcc (hidden copy - receiver) addresses. -- `withSubject()` - Returns a new instance with the specified message - subject. -- `withDate()` - Returns a new instance with the specified date when the - message was sent. -- `withPriority()` - Returns a new instance with the specified priority of - this message. -- `withReturnPath()` - Returns a new instance with the specified return-path - (the bounce address) of this message. -- `withSender()` - Returns a new instance with the specified actual sender - email address. -- `withHtmlBody()` - Returns a new instance with the specified message HTML - content. -- `withTextBody()` - Returns a new instance with the specified message plain - text content. -- `withAddedHeader()` - Returns a new instance with the specified added - custom header value. -- `withHeader()` - Returns a new instance with the specified custom header - value. -- `withHeaders()` - Returns a new instance with the specified custom header - values. - -These methods are immutable, meaning they return a new instance of the -message with the updated data. - -Note `with` prefix. It indicates that the method is immutable and returns a -new instance of the class with the changed data. - -### Getters - -The following getters are available to retrieve message data: - -- `getCharset()` - Returns the charset of this message. -- `getFrom()` - Returns the message sender email address. -- `getTo()` - Returns the message recipient(s) email address. -- `getReplyTo()` - Returns the reply-to address of this message. -- `getCc()` - Returns the Cc (extra copy receiver) addresses of this - message. -- `getBcc()` - Returns the Bcc (hidden copy receiver) addresses of this - message. -- `getSubject()` - Returns the message subject. -- `getDate()` - Returns the date when the message was sent, or null if it - wasn't set. -- `getPriority()` - Returns the priority of this message. -- `getReturnPath()` - Returns the return-path (the bounce address) of this - message. -- `getSender()` - Returns the message actual sender email address. -- `getHtmlBody()` - Returns the message HTML body. -- `getTextBody()` - Returns the message text body. -- `getHeader()` - Returns all values for the specified header. -- `__toString()` - Returns string representation of this message. - -## Attaching Files - -You can attach files to your message using the `withAttached()` method: +## 添加更多数据 + +`Yiisoft\Mailer\MessageInterface` 提供了多个方法来自定义消息: + +- `withCharset()` - 返回指定字符集的新实例。 +- `withFrom()` - 返回指定发件人邮箱地址的新实例。 +- `withTo()` - 返回指定收件人邮箱地址的新实例。 +- `withReplyTo()` - 返回指定回复地址的新实例。 +- `withCc()` - 返回指定抄送地址的新实例。 +- `withBcc()` - 返回指定密送地址的新实例。 +- `withSubject()` - 返回指定邮件主题的新实例。 +- `withDate()` - 返回指定发送日期的新实例。 +- `withPriority()` - 返回指定优先级的新实例。 +- `withReturnPath()` - 返回指定退信地址的新实例。 +- `withSender()` - 返回指定实际发件人邮箱地址的新实例。 +- `withHtmlBody()` - 返回指定 HTML 正文内容的新实例。 +- `withTextBody()` - 返回指定纯文本正文内容的新实例。 +- `withAddedHeader()` - 返回添加了指定自定义请求头值的新实例。 +- `withHeader()` - 返回指定自定义请求头值的新实例。 +- `withHeaders()` - 返回指定多个自定义请求头值的新实例。 + +这些方法均为不可变方法,即返回包含更新数据的新消息实例。 + +注意 `with` 前缀,它表示该方法是不可变的,会返回包含变更数据的新类实例。 + +### 获取器 + +以下获取器可用于读取消息数据: + +- `getCharset()` - 返回消息的字符集。 +- `getFrom()` - 返回发件人邮箱地址。 +- `getTo()` - 返回收件人邮箱地址。 +- `getReplyTo()` - 返回回复地址。 +- `getCc()` - 返回抄送地址。 +- `getBcc()` - 返回密送地址。 +- `getSubject()` - 返回邮件主题。 +- `getDate()` - 返回消息发送日期,若未设置则返回 null。 +- `getPriority()` - 返回消息优先级。 +- `getReturnPath()` - 返回退信地址。 +- `getSender()` - 返回实际发件人邮箱地址。 +- `getHtmlBody()` - 返回消息的 HTML 正文。 +- `getTextBody()` - 返回消息的纯文本正文。 +- `getHeader()` - 返回指定请求头的所有值。 +- `__toString()` - 返回消息的字符串表示。 + +## 附加文件 + +可以使用 `withAttached()` 方法向消息附加文件: ```php use Yiisoft\Mailer\File; @@ -226,10 +195,9 @@ $message = $message->withAttached( ); ``` -## Embedding Images +## 嵌入图片 -You can embed images into the message content using the `withEmbedded()` -method. This is particularly useful when composing messages with views: +可以使用 `withEmbedded()` 方法将图片嵌入消息内容,在使用视图编写消息时尤为有用: ```php $logo = 'path/to/logo'; @@ -249,16 +217,15 @@ return new \Yiisoft\Mailer\Message( ); ``` -In your view or layout template, you can reference the embedded image using -its CID: +在视图或布局模板中,可以通过 CID 引用嵌入的图片: ```php ``` -## Sending a Message +## 发送消息 -To send an email message: +发送电子邮件消息的方法: ```php /** @@ -280,9 +247,9 @@ $message = new \Yiisoft\Mailer\Message( $mailer->send($message); ``` -## Sending Multiple Messages +## 批量发送消息 -You can send multiple messages at once: +可以一次性发送多条消息: ```php $messages = []; @@ -296,30 +263,22 @@ foreach ($users as $user) { $result = $mailer->sendMultiple($messages); ``` -The `sendMultiple()` method returns a `Yiisoft\Mailer\SendResults` object -containing arrays of successfully sent and failed messages. +`sendMultiple()` 方法返回一个 `Yiisoft\Mailer\SendResults` 对象,其中包含发送成功和发送失败的消息数组。 -## Implementing your own mail driver +## 实现自定义邮件驱动 -To create a custom mail solution, implement the -`Yiisoft\Mailer\MailerInterface` and `Yiisoft\Mailer\MessageInterface` -interfaces. +要创建自定义邮件解决方案,请实现 `Yiisoft\Mailer\MailerInterface` 和 +`Yiisoft\Mailer\MessageInterface` 接口。 -## For Development +## 开发环境 -For local or test development, you can use simplified implementations of the -mailer that does not send emails. The package provides these -implementations: +在本地或测试开发环境中,可以使用不实际发送邮件的简化邮件发送器实现。该包提供了以下实现: -- `Yiisoft\Mailer\StubMailer` - A simple mailer that stores messages in a - local array. -- `Yiisoft\Mailer\FileMailer` - A mock mailer that saves email messages as - files instead of sending them. -- `Yiisoft\Mailer\NullMailer` - A mailer that discards messages without - sending or storing them. +- `Yiisoft\Mailer\StubMailer` - 将消息存储在本地数组中的简单邮件发送器。 +- `Yiisoft\Mailer\FileMailer` - 将邮件消息保存为文件而非实际发送的模拟邮件发送器。 +- `Yiisoft\Mailer\NullMailer` - 直接丢弃消息、不发送也不存储的空邮件发送器。 -To use one of these mailers, configure it in your development environment -file Example: `environments/local/di.php` +要使用其中一种发送器,请在开发环境配置文件中进行配置,例如 `environments/local/di.php`: ```php return [ diff --git a/src/zh-CN/guide/tutorial/performance-tuning.md b/src/zh-CN/guide/tutorial/performance-tuning.md index bf43d4a4..17da04c4 100644 --- a/src/zh-CN/guide/tutorial/performance-tuning.md +++ b/src/zh-CN/guide/tutorial/performance-tuning.md @@ -1,82 +1,60 @@ -# Performance tuning - -There are many factors affecting the performance of your application. Some -are environmental, some are related to your code, while some others are -related to Yii itself. In this section, we will count most of these factors -and explain how you can improve your application performance by adjusting -these factors. - - -## Optimizing your PHP Environment - -A well-configured PHP environment is important. To get maximum performance: - -- Use the latest stable PHP version. Major releases of PHP may bring - significant performance improvements. -- Enable bytecode caching with [Opcache](https://secure.php.net/opcache). - Bytecode caching avoids the time spent on parsing and including PHP - scripts for every incoming request. -- [Tune `realpath()` - cache](https://github.com/samdark/realpath_cache_tuner). -- Make sure [XDebug](https://xdebug.org/) isn't installed in the production - environment. -- Try [PHP 7 preloading](https://wiki.php.net/rfc/preload). - -## Optimizing your code - -Beyond environment configuration, there are code-level optimizations that -can improve your application's performance: - -- Look out for [algorithm - complexity](https://en.wikipedia.org/wiki/Time_complexity). Especially - give attention to `foreach` within `foreach` loops but look out for using - [heavy PHP - functions](https://stackoverflow.com/questions/2473989/list-of-big-o-for-php-functions) - in loops as well. -- [Speeding up - array_merge()](https://www.exakat.io/speeding-up-array_merge/) -- [Move that foreach() inside the - method](https://www.exakat.io/move-that-foreach-inside-the-method/) -- [Array, classes and anonymous classes memory - usage](https://www.exakat.io/array-classes-and-anonymous-memory-usage/) -- Use fully qualified function names with leading backslashes to optimize - opcache performance. When calling [certain global - functions](https://github.com/php/php-src/blob/944b6b6bbd6f05ad905f5f4ad07445792bee4027/Zend/zend_compile.c#L4291-L4353) - from within a namespace, PHP first searches in the current namespace - before falling back to the global namespace. Adding a leading backslash - (e.g., `\count()` instead of `count()`) tells PHP to directly use the - global function, avoiding the namespace lookup and improving opcache - efficiency. This optimization is best implemented automatically using - tools like [PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) - with the `native_function_invocation` rule. - -The above optimizations would give you a significant performance boost only -if the code in question is executed frequently. That is usually the case for -big loops or batch processing. - -## Using caching techniques - -You can use various caching techniques to significantly improve the -performance of your application. For example, if your application allows -users to enter text in Markdown format, you may consider caching the parsed -Markdown content to avoid parsing the same Markdown text repeatedly in every -request. Please refer to the [Caching](../caching/overview.md) section to -learn about the caching support provided by Yii. - - -## Optimizing session storage - -By default, session data is stored in files. The implementation is locking a file from opening a session to the point it's -closed either by `$session->close()` or at the end of request. -While the session file is locked, all other requests that are trying to use the same session are blocked. That's waiting for the -initial request to release a session file. This is fine for development and probably small projects. But when it comes -to handling massive concurrent requests, it's better to use more sophisticated storage, such as Redis. - -It could be done either by [configuring PHP via -php.ini](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-redis-server-as-a-session-handler-for-php-on-ubuntu-14-04) -or [implementing +# 性能调优 + +影响应用程序性能的因素有很多,有些与运行环境有关,有些与您的代码有关,还有一些与 Yii +框架本身有关。本节将列举这些主要因素,并说明如何通过调整它们来提升应用程序性能。 + + +## 优化 PHP 环境 + +合理配置 PHP 环境至关重要。为获得最佳性能,建议: + +- 使用最新稳定版 PHP。PHP 的主要版本通常会带来显著的性能提升。 +- 通过 [Opcache](https://secure.php.net/opcache) 启用字节码缓存。字节码缓存可避免在每次请求时重复解析和加载 + PHP 脚本的开销。 +- [调优 `realpath()` 缓存](https://github.com/samdark/realpath_cache_tuner)。 +- 确保生产环境中未安装 [XDebug](https://xdebug.org/)。 +- 尝试 [PHP 7 预加载](https://wiki.php.net/rfc/preload)。 + +## 优化代码 + +除环境配置外,代码层面的优化同样能提升应用程序性能: + +- 注意 [算法复杂度](https://en.wikipedia.org/wiki/Time_complexity)。尤其要留意 `foreach` + 嵌套循环,同时也要避免在循环中使用[高开销的 PHP + 函数](https://stackoverflow.com/questions/2473989/list-of-big-o-for-php-functions)。 +- [加速 array_merge()](https://www.exakat.io/speeding-up-array_merge/) +- [将 foreach() + 移入方法内部](https://www.exakat.io/move-that-foreach-inside-the-method/) +- [数组、类与匿名类的内存占用](https://www.exakat.io/array-classes-and-anonymous-memory-usage/) +- 使用带前导反斜杠的完全限定函数名以优化 opcache 性能。在命名空间内调用 + [某些全局函数](https://github.com/php/php-src/blob/944b6b6bbd6f05ad905f5f4ad07445792bee4027/Zend/zend_compile.c#L4291-L4353) + 时,PHP 会先在当前命名空间中查找,再回退到全局命名空间。添加前导反斜杠(例如用 `\count()` 代替 `count()`)可告知 PHP + 直接使用全局函数,避免命名空间查找,提升 opcache 效率。建议通过 + [PHP-CS-Fixer](https://github.com/FriendsOfPHP/PHP-CS-Fixer) 的 + `native_function_invocation` 规则自动完成此优化。 + +上述代码层面的优化只有在相关代码被频繁执行时才能带来显著提升,通常适用于大型循环或批量处理场景。 + +## 使用缓存技术 + +您可以使用多种缓存技术来显著提升应用程序性能。例如,如果应用程序允许用户输入 Markdown 格式文本,可以考虑缓存解析后的 Markdown +内容,避免每次请求都重复解析相同的 Markdown 文本。请参阅[缓存](../caching/overview.md)章节了解 Yii +提供的缓存支持。 + + +## 优化会话存储 + +默认情况下,会话数据存储在文件中。该实现会在会话打开时锁定文件,直到 +通过 `$session->close()` 或请求结束时关闭会话为止。 +在会话文件被锁定期间,所有尝试使用同一会话的其他请求都将被阻塞,等待 +初始请求释放会话文件。这对于开发环境和小型项目来说没有问题,但当需要 +处理大量并发请求时,最好使用更完善的存储方案,例如 Redis。 + +可以通过 [在 php.ini 中配置 +PHP](https://www.digitalocean.com/community/tutorials/how-to-set-up-a-redis-server-as-a-session-handler-for-php-on-ubuntu-14-04),或 +[实现 SessionHandlerInterface](https://www.sitepoint.com/saving-php-sessions-in-redis/) -and configuring session service as follows: +并按如下方式配置会话服务来实现: ```php \Yiisoft\Session\SessionInterface::class => [ @@ -85,106 +63,73 @@ and configuring session service as follows: ], ``` -## Optimizing databases +## 优化数据库 -Executing DB queries and fetching data from databases are often the main -performance bottleneck in a Web application. Although using [data -caching](../caching/data.md) techniques may ease the performance hit, it -doesn't fully solve the problem. When the database has enormous amounts of -data and the cached data are invalid, fetching the latest data could be -prohibitively expensive without a proper database and query design. +执行数据库查询和从数据库获取数据通常是 Web +应用程序的主要性能瓶颈。尽管使用[数据缓存](../caching/data.md)技术可以缓解性能压力,但并不能彻底解决问题。当数据库中的数据量极大且缓存数据失效时,如果没有合理的数据库和查询设计,获取最新数据的代价可能会非常高昂。 -A general technique to improve the performance of DB queries is to create -indices for table columns that need to be filtered by. For example, if you -need to look for a user record by `username`, you should create an index on -`username`. Note that while indexing can make SELECT queries much faster, it -will slow down INSERT, UPDATE and DELETE queries. +提升数据库查询性能的通用方法是为需要过滤的表列创建索引。例如,如果需要通过 `username` 查找用户记录,应在 `username` +列上创建索引。请注意,索引虽然能大幅提升 SELECT 查询速度,但会降低 INSERT、UPDATE 和 DELETE 操作的速度。 -For complex DB queries, it's recommended that you create database views to -save the query parsing and preparation time. +对于复杂的数据库查询,建议创建数据库视图以节省查询解析和准备的时间。 -Last but not least, use `LIMIT` in your `SELECT` queries. This avoids -fetching an overwhelming amount of data from the database and exhausting the -memory allocated to PHP. +最后同样重要的一点是,在 `SELECT` 查询中使用 `LIMIT`,以避免从数据库获取过量数据而耗尽 PHP 分配的内存。 -## Optimizing composer autoloader +## 优化 Composer 自动加载器 -Because Composer autoloader is used to include most third-party class files, -you should consider optimizing it by executing the following command: +由于 Composer 自动加载器用于加载大多数第三方类文件,建议通过执行以下命令对其进行优化: ``` composer dumpautoload -o ``` -Additionally, you may consider using [authoritative class -maps](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-a-authoritative-class-maps) -and [APCu -cache](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-b-apcu-cache). -Note that both optimizations may or may not be suitable for your particular -case. +此外,您还可以考虑使用 +[权威类映射](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-a-authoritative-class-maps) +和 [APCu +缓存](https://getcomposer.org/doc/articles/autoloader-optimization.md#optimization-level-2-b-apcu-cache)。请注意,这两种优化不一定适用于所有情况。 -## Processing data offline +## 离线处理数据 -When a request involves some resource-intensive operations, you should think -of ways to perform those operations in offline mode without having users -wait for them to finish. +当某个请求涉及资源密集型操作时,应考虑以离线方式执行这些操作,避免让用户等待其完成。 -There are two methods to process data offline: pull and push. +离线处理数据有两种方式:拉取(pull)和推送(push)。 -In the pull method, whenever a request involves some complex operation, you -create a task and save it in a persistent storage, such as a database. You -then use a separate process (such as a cron job) to pull the tasks and -process them. This method is straightforward to implement, but it has some -drawbacks. For example, the task process needs to periodically pull from the -task storage. If the pull frequency is too low, the tasks may be processed -with great delay, but if the frequency is too high, it will introduce high -overhead. +在拉取模式中,每当请求涉及复杂操作时,您创建一个任务并将其保存到持久化存储(如数据库)中,然后使用独立进程(如定时任务)来拉取并处理这些任务。这种方式实现简单,但有一些缺点:例如,任务进程需要周期性地从任务存储中拉取数据,拉取频率过低会导致任务处理延迟较大,而频率过高则会引入较大开销。 -In the push method, you would use a message queue (e.g., RabbitMQ, ActiveMQ, -Amazon SQS, etc.) to manage the tasks. Whenever a new task is put in the -queue, it will initiate or notify the task handling process to trigger the -task processing. +在推送模式中,您使用消息队列(例如 RabbitMQ、ActiveMQ、Amazon SQS +等)来管理任务。每当有新任务加入队列时,它会启动或通知任务处理进程以触发任务执行。 -## Using preloading +## 使用预加载 -As of PHP 7.4.0, PHP can be configured to preload scripts into the opcache -when the engine starts. You can read more in the -[documentation](https://www.php.net/manual/en/opcache.preloading.php) and -the corresponding [RFC](https://wiki.php.net/rfc/preload). +自 PHP 7.4.0 起,可以配置 PHP 在引擎启动时将脚本预加载到 opcache 中。详情请参阅 +[官方文档](https://www.php.net/manual/en/opcache.preloading.php) 和对应的 +[RFC](https://wiki.php.net/rfc/preload)。 -Note that the optimal tradeoff between performance and memory may vary with -the application. "Preload everything" may be the easiest strategy, but not -necessarily the best strategy. +请注意,性能与内存之间的最优权衡因应用程序而异。“预加载所有内容”可能是最简单的策略,但未必是最佳策略。 -For example, we conducted a simple -[yiisoft/app](https://github.com/yiisoft/app) application template -benchmark. Without preloading and with preloading of the entire composer -class map. +例如,我们对 [yiisoft/app](https://github.com/yiisoft/app) +应用程序模板进行了简单基准测试,分别测试了未启用预加载和预加载整个 Composer 类映射两种情况。 -### Preloading benchmarks +### 预加载基准测试 -The application template benchmark includes configuring classes to injected -dependencies in the bootstrap script. +该应用程序模板基准测试包含在引导脚本中配置依赖注入的相关类。 -For both variants, -[ApacheBench](https://httpd.apache.org/docs/2.4/programs/ab.html) was used -with the following run parameters: +两种情况均使用 [ApacheBench](https://httpd.apache.org/docs/2.4/programs/ab.html) +进行测试,运行参数如下: ```shell ab -n 1000 -c 10 -t 10 ``` -Also, the debug mode was disabled. And an optimized autoloader of the -[Composer](https://getcomposer.org) was used, and development dependencies -weren't used: +同时,调试模式已禁用,使用了 [Composer](https://getcomposer.org) 的优化自动加载器,且未安装开发依赖: ```shell composer install --optimize-autoloader --no-dev ``` -With preloading enabled, the entire composer class map (825 files) was used: +启用预加载时,使用了完整的 Composer 类映射(825 个文件): ```php $files = require 'vendor/composer/autoload_classmap.php'; @@ -194,26 +139,22 @@ foreach (array_unique($files) as $file) { } ``` -#### Test results +#### 测试结果 -| Benchmark | Preloaded files | Opcache memory used | Per request memory used | Time per request | Requests per second | +| 基准测试 | 预加载文件数 | Opcache 内存用量 | 每请求内存用量 | 每请求耗时 | 每秒请求数 | |--------------------|-----------------|---------------------|-------------------------|------------------|---------------------| -| Without preloading | 0 | 12.32 mb | 1.71 mb | 27.63 ms | 36.55 rq/s | -| With preloading | 825 | 17.86 mb | 1.82 mb | 26.21 ms | 38.42 rq/s | +| 未预加载 | 0 | 12.32 mb | 1.71 mb | 27.63 ms | 36.55 rq/s | +| 已预加载 | 825 | 17.86 mb | 1.82 mb | 26.21 ms | 38.42 rq/s | -As you can see, the test results aren't much different, since this is just a -clean application template that contains a few classes. More discussion of -preloading, including benchmarks, can be found in the [composer's -issue](https://github.com/composer/composer/issues/7777). +如您所见,测试结果差异不大,因为这只是一个仅包含少量类的干净应用程序模板。关于预加载的更多讨论(包括基准测试)可参阅 [Composer 的相关 +issue](https://github.com/composer/composer/issues/7777)。 -## Performance profiling +## 性能分析 -You should profile your code to find out the performance bottlenecks and -take appropriate measures accordingly. The following profiling tools may be -useful: +应对代码进行性能分析以找出瓶颈,并采取相应措施。以下分析工具可能对您有所帮助: - [Blackfire](https://blackfire.io/) - [XHProf](https://secure.php.net/manual/en/book.xhprof.php) -- [XDebug profiler](https://xdebug.org/docs/profiler) +- [XDebug 分析器](https://xdebug.org/docs/profiler) diff --git a/src/zh-CN/guide/tutorial/using-with-event-loop.md b/src/zh-CN/guide/tutorial/using-with-event-loop.md index 5b2c09df..58708930 100644 --- a/src/zh-CN/guide/tutorial/using-with-event-loop.md +++ b/src/zh-CN/guide/tutorial/using-with-event-loop.md @@ -1,22 +1,20 @@ -# Using Yii with event loop +# 在事件循环中使用 Yii -A normal PHP web request execution cycle consists of setting up an environment, getting a request, processing it to form a response -and sending the result. After the response is sent, execution is terminated and its context is lost. So, for the further - request, the whole sequence is repeated. Such an approach has a big advantage in ease of development since a developer doesn't -have to take much care about memory leaks or properly clean up context. On the other side, initializing everything for -every request takes time and overall consumes up to 50% of processing resources. +普通 PHP Web 请求的执行周期包括设置环境、获取请求、处理请求以生成响应 +以及发送结果。响应发送后,执行终止,其上下文也随之丢失。因此,对于后续 +请求,整个流程会重复执行。这种方式的一大优点是开发简便,开发者无需 +过多关注内存泄漏或上下文清理问题。但另一方面,为每个请求初始化所有内容 +需要消耗时间,整体上会占用多达 50% 的处理资源。 -There is an alternative way of running an application. Event loop. The idea -is to initialize everything possible at once and then process a number of -requests using it. Such an approach is usually called event loop. +还有一种运行应用程序的方式——事件循环。其思路是一次性初始化所有可初始化的内容,然后利用它来处理多个请求。这种方式通常被称为事件循环。 -There are multiple tools that could be used to achieve it. Notably, -[FrankenPHP](https://frankenphp.dev/), [RoadRunner](https://roadrunner.dev/) -and [Swoole](https://www.swoole.co.uk/). +可以使用多种工具来实现这一目标,其中较为知名的有 +[FrankenPHP](https://frankenphp.dev/)、[RoadRunner](https://roadrunner.dev/) +和 [Swoole](https://www.swoole.co.uk/)。 -## Event loop implications +## 事件循环的影响 -Event loop worker basically looks like the following: +事件循环的 worker 基本结构如下: ```php initializeContext(); @@ -26,28 +24,21 @@ while ($request = getRequest()) { } ``` -Usually, there are multiple workers processing requests at the same time as -with traditional php-fpm. +通常会有多个 worker 同时处理请求,与传统的 php-fpm 方式类似。 -That means that there's more to consider when developing applications. +这意味着在开发应用程序时需要考虑更多因素。 -### Processing is blocking +### 处理是阻塞的 -Worker process requests one by one that's current processing is blocking -processing next request. That means that long-running processes, same as in -general PHP applications, should be put into a background via using a queue. +Worker 逐一处理请求,当前请求的处理会阻塞下一个请求的处理。这意味着与普通 PHP 应用程序一样,耗时较长的任务应通过队列放到后台执行。 -### Services and state +### 服务与状态 -Since the context in the event loop is shared between all request-responses -processed by a single worker, all changes in the state of a service made by -the previous request may affect the current request. Moreover, it can be a -security problem if data from one user is available to another user. +由于事件循环中的上下文由同一 worker +处理的所有请求-响应共享,上一个请求对服务状态所做的任何修改都可能影响当前请求。此外,如果一个用户的数据可被另一个用户访问,还会带来安全问题。 -There are two ways of dealing with it. First, you can avoid having state by -making services stateless. PHP's `readonly` keyword may be handy for -it. Second, you can reset the services' state at the end of the request -processing. In this case, a state resetter will help you: +有两种应对方式。第一种是将服务设计为无状态,从而避免状态问题,PHP 的 `readonly` +关键字在此很有用。第二种是在每次请求处理结束后重置服务状态,此时可以使用状态重置器: ```php initializeContext(); @@ -59,7 +50,7 @@ while ($request = getRequest()) { } ``` -## Integrations +## 集成 - [RoadRunner](using-yii-with-roadrunner.md) - [Swoole](using-yii-with-swoole.md) diff --git a/src/zh-CN/guide/tutorial/using-yii-with-roadrunner.md b/src/zh-CN/guide/tutorial/using-yii-with-roadrunner.md index 5f6104a4..b9900bb9 100644 --- a/src/zh-CN/guide/tutorial/using-yii-with-roadrunner.md +++ b/src/zh-CN/guide/tutorial/using-yii-with-roadrunner.md @@ -1,31 +1,29 @@ -# Using Yii with RoadRunner +# 在 Yii 中使用 RoadRunner -[RoadRunner](https://roadrunner.dev/) is a Golang-powered application server that integrates well with PHP. It runs -it as workers and each worker may handle multiple requests. Such an operation mode is often called -[event loop](using-with-event-loop.md) and allows not re-initializing a framework for each request that improves -performance significantly. +[RoadRunner](https://roadrunner.dev/) 是一个由 Golang 驱动的应用服务器,可以与 PHP 良好集成。它将 PHP 作为 worker 运行, +每个 worker 可以处理多个请求。这种操作模式通常称为 +[事件循环](using-with-event-loop.md),无需为每个请求重新初始化框架, +从而显著提升性能。 ## 安装 -RoadRunner works on Linux, macOS and Windows. The best way to install it is -to use a Composer: +RoadRunner 支持 Linux、macOS 和 Windows。安装它的最佳方式是使用 Composer: ``` composer require yiisoft/yii-runner-roadrunner ``` -After installation is done, run +安装完成后,运行: ``` ./vendor/bin/rr get ``` -That would download ready to use RoadRunner server `rr` binary. +这将下载可直接使用的 RoadRunner 服务器 `rr` 二进制文件。 ## 配置 -First, we need to configure the server itself. Create `/.rr.yaml` and add -the following config: +首先,我们需要配置服务器本身。创建 `/.rr.yaml` 并添加以下配置: ```yaml server: @@ -57,15 +55,13 @@ logs: ``` > [!INFO] -> Read more about TLS, HTTP/2, HTTP/3 configuration and other middleware [on the RoadRunner docs](https://docs.roadrunner.dev/docs/http/http). +> 了解更多关于 TLS、HTTP/2、HTTP/3 配置和其他中间件的信息,请参阅 [RoadRunner 文档](https://docs.roadrunner.dev/docs/http/http)。 -We're specifying that the entry script is `worker.php`, the server listens -on port 8080, `public` directory files are served statically except `.php` -and `.htaccess`. The `max_worker_memory` is a soft limit: if a worker -exceeds 192 MB, it will restart after finishing its current request. Also, -we're sending an additional header. +我们指定入口脚本为 `worker.php`,服务器监听 8080 端口,`public` 目录中的文件(除 `.php` 和 `.htaccess` +外)以静态方式提供服务。`max_worker_memory` 是一个软限制:如果 worker 超过 192 +MB,它将在完成当前请求后重启。此外,我们还发送了一个额外的响应头。 -Create `/worker.php`: +创建 `/worker.php`: ```php run(); ``` -## Starting a server +## 启动服务器 -To start a server, execute the following command: +要启动服务器,请执行以下命令: ``` ./rr serve ``` -## On worker scope +## 关于 Worker 作用域 -- Each worker's scope is isolated from other workers. Memory isn't shared. -- A single worker serves multiple requests where the scope is shared. -- At each iteration of the event loop, every service that depends on state - should be reset. +- 每个 worker 的作用域与其他 worker 隔离,内存不共享。 +- 单个 worker 服务多个请求,请求之间共享作用域。 +- 在事件循环的每次迭代中,所有依赖状态的服务都应进行重置。 diff --git a/src/zh-CN/guide/tutorial/using-yii-with-swoole.md b/src/zh-CN/guide/tutorial/using-yii-with-swoole.md index 807f0ae7..6b8707b7 100644 --- a/src/zh-CN/guide/tutorial/using-yii-with-swoole.md +++ b/src/zh-CN/guide/tutorial/using-yii-with-swoole.md @@ -1,31 +1,28 @@ -# Using Yii with Swoole +# 在 Swoole 中使用 Yii -[Swoole](https://www.swoole.co.uk/) is a PHP network framework distributed as a PECL extension. It allows you built-in async, -multiple threads I/O modules. Developers can use sync or async, coroutine API to write the applications. +[Swoole](https://www.swoole.co.uk/) 是一个以 PECL 扩展形式发布的 PHP 网络框架,内置了异步、 +多线程 I/O 模块。开发者可以使用同步或异步、协程 API 来编写应用程序。 -In the context of Yii, it allows running request handlers as workers. Each -worker may handle multiple requests. Such an operation mode is often called -[event loop](using-with-event-loop.md) and allows not re-initializing a -framework for each request that improves performance significantly. +在 Yii 的使用场景中,Swoole 允许将请求处理器作为 worker 运行,每个 worker +可处理多个请求。这种运行模式通常称为[事件循环](using-with-event-loop.md),无需为每个请求重新初始化框架,从而显著提升性能。 ## 安装 -Swoole works on Linux and macOS and can be installed via pecl: +Swoole 支持 Linux 和 macOS,可通过 pecl 安装: ```bash pecl install swoole ``` -## Putting up a server +## 搭建服务器 -Since Swoole doesn't have built-in PSR-7 support, you need a package fixing -so: +由于 Swoole 没有内置的 PSR-7 支持,需要安装一个补充包: ```php composer require ilexn/swoole-convent-psr7 ``` -Create an entry script, `server.php`: +创建入口脚本 `server.php`: ```php on('shutdown', static function (Swoole\Http\Server $server) use ($appli $server->start(); ``` -## Starting a server +## 启动服务器 -To start a server, execute the following command: +要启动服务器,请执行以下命令: ``` php server.php ``` -## On scope +## 关于作用域 -A scope is shared, so at each iteration of the event loop every service that -depends on state should be reset. +作用域是共享的,因此在事件循环的每次迭代中,所有依赖状态的服务都应进行重置。 diff --git a/src/zh-CN/guide/views/asset.md b/src/zh-CN/guide/views/asset.md index 267d9822..b5ecacd9 100644 --- a/src/zh-CN/guide/views/asset.md +++ b/src/zh-CN/guide/views/asset.md @@ -1,43 +1,33 @@ -# Assets +# 资源 -Asset management is crucial for modern web applications. Assets include CSS -stylesheets, JavaScript files, images, fonts, and other static -resources. Yii3 provides a comprehensive asset management system through the -`yiisoft/assets` package that handles dependencies, optimization, and -deployment of these resources. +资源管理对现代 Web 应用程序至关重要。资源包括 CSS 样式表、JavaScript 文件、图像、字体及其他静态资源。Yii3 通过 +`yiisoft/assets` 包提供了一套完整的资源管理系统,用于处理这些资源的依赖、优化和部署。 ## 安装 -The asset management functionality is provided by the `yiisoft/assets` -package: +资源管理功能由 `yiisoft/assets` 包提供: ```bash composer require yiisoft/assets ``` -This package is included by default in the `yiisoft/app` application -template. +该包默认包含在 `yiisoft/app` 应用程序模板中。 -## Basic Concepts +## 基本概念 -### Asset Bundles +### 资源包 -An asset bundle is a collection of related asset files (CSS, JavaScript, -images) that are logically grouped together. Asset bundles can depend on -other bundles, allowing for proper dependency management. +资源包是一组相关资源文件(CSS、JavaScript、图像)的集合,它们在逻辑上被组合在一起。资源包可以依赖其他包,从而实现适当的依赖关系管理。 -### Asset Manager +### 资源管理器 -The Asset Manager is responsible for: - Resolving asset bundle dependencies -- Publishing assets from protected directories to web-accessible locations - -Combining and minifying assets (when configured) - Generating proper URLs -for assets +资源管理器负责:- 解析资源包依赖 - 将资源从受保护目录发布到 Web 可访问的位置 - 合并和压缩资源(当配置时)- 生成资源的正确 URL -## Creating Asset Bundles +## 创建资源包 -### Basic Asset Bundle +### 基本资源包 -Here's a simple asset bundle definition: +下面是一个简单的资源包定义: ```php register(ProductAsset::class); ``` -### With WebView Integration +### 与 WebView 集成 -The recommended approach is to integrate with WebView for automatic asset -rendering: +推荐的方式是与 WebView 集成,以自动渲染资源: ```php addJsVars($assetManager->getJsVars()); ``` -## Asset Publishing +## 资源发布 -### Source Path Publishing +### 源路径发布 -When assets are located in non-web-accessible directories (like vendor -packages), they need to be published: +当资源位于不可通过 Web 访问的目录(如 vendor 包)时,需要发布它们: ```php publish('@vendor/company/package/assets'); $publishedUrl = $assetManager->getPublishedUrl('@vendor/company/package/assets'); ``` -## Third-party Library Assets +## 第三方库资源 -### jQuery Asset Bundle +### jQuery 资源包 ```php setCombineOptions([ ]); ``` -### Asset Compression +### 资源压缩 -Configure asset compression for production: +为生产环境配置资源压缩: ```php // In your asset manager configuration @@ -483,9 +471,9 @@ Configure asset compression for production: ], ``` -## Working with Asset Converter +## 使用资源转换器 -### SCSS/SASS Compilation +### SCSS/SASS 编译 ```php addCssFiles()` and `$this->addJsFiles()` in your layout -- Verify that `$this->head()`, `$this->beginBody()`, and `$this->endBody()` are called in the layout +**资源未出现在 HTML 中:** +- 确保在布局中调用了 `$this->addCssFiles()` 和 `$this->addJsFiles()` +- 验证布局中是否调用了 `$this->head()`、`$this->beginBody()` 和 `$this->endBody()` -**Permission issues:** -- Check that the web server has write permissions to the assets directory -- Verify the published assets directory is web-accessible +**权限问题:** +- 检查 Web 服务器是否具有资源目录的写入权限 +- 验证已发布的资源目录是否可通过 Web 访问 diff --git a/src/zh-CN/guide/views/script-style-meta.md b/src/zh-CN/guide/views/script-style-meta.md index 4a899f47..c7c5dced 100644 --- a/src/zh-CN/guide/views/script-style-meta.md +++ b/src/zh-CN/guide/views/script-style-meta.md @@ -1,26 +1,23 @@ -# Scripts, styles and meta tags +# 脚本、样式与 meta 标签 -Modern web applications require careful management of CSS styles, JavaScript -code, and HTML meta tags. Yii3 provides a comprehensive system for -registering and organizing these resources through the `WebView` class, -which is part of the `yiisoft/view` package. +现代 Web 应用程序需要对 CSS 样式、JavaScript 代码和 HTML meta 标签进行精细管理。Yii3 通过 +`yiisoft/view` 包中的 `WebView` 类提供了一套完整的系统,用于注册和组织这些资源。 -## Overview +## 概述 -The `WebView` class extends the basic `View` class with web-specific -functionality, allowing you to: +`WebView` 类在基础 `View` 类的基础上扩展了 Web 特有的功能,使你可以: -- Register CSS files and inline styles -- Register JavaScript files and inline scripts -- Manage HTML meta tags and link tags -- Control the position where resources are rendered -- Handle dependencies between resources +- 注册 CSS 文件和内联样式 +- 注册 JavaScript 文件和内联脚本 +- 管理 HTML meta 标签和 link 标签 +- 控制资源的渲染位置 +- 处理资源之间的依赖关系 -## CSS management +## CSS 管理 -### Registering CSS Files +### 注册 CSS 文件 -You can register CSS files to be included in your HTML pages: +你可以注册需要包含在 HTML 页面中的 CSS 文件: ```php registerCssFile('/css/print.css', WebView::POSITION_HEAD, [ $this->registerCssFile('/css/theme.css', WebView::POSITION_HEAD, [], 'theme-css'); ``` -### Registering Inline CSS +### 注册内联 CSS -For inline CSS styles, use the `registerCss()` method: +对于内联 CSS 样式,使用 `registerCss()` 方法: ```php // Register inline CSS @@ -70,9 +67,9 @@ $this->registerCss(' ', WebView::POSITION_HEAD, ['id' => 'print-styles']); ``` -### CSS from Files +### 从文件注册 CSS -You can also register CSS content from external files: +你也可以从外部文件读取 CSS 内容并注册为内联样式: ```php // Read CSS from a file and register as inline CSS @@ -81,9 +78,9 @@ $this->registerCssFromFile('/path/to/dynamic-styles.css', WebView::POSITION_HEAD ]); ``` -### Using Style Tags +### 使用 Style 标签 -For more control, you can use HTML style tags directly: +如需更精细的控制,可以直接使用 HTML style 标签: ```php use Yiisoft\Html\Html; @@ -100,11 +97,11 @@ $styleTag = Html::style(' $this->registerStyleTag($styleTag, WebView::POSITION_HEAD); ``` -## JavaScript management +## JavaScript 管理 -### Registering JavaScript Files +### 注册 JavaScript 文件 -Include external JavaScript files using `registerJsFile()`: +使用 `registerJsFile()` 引入外部 JavaScript 文件: ```php // Register a JavaScript file @@ -125,9 +122,9 @@ $this->registerJsFile('https://cdn.jsdelivr.net/npm/jquery@3.6.0/dist/jquery.min WebView::POSITION_END, [], 'jquery'); ``` -### Registering Inline JavaScript +### 注册内联 JavaScript -Add inline JavaScript code with `registerJs()`: +使用 `registerJs()` 添加内联 JavaScript 代码: ```php // Register inline JavaScript @@ -146,9 +143,9 @@ $this->registerJs(' ', WebView::POSITION_READY); ``` -### JavaScript Variables +### JavaScript 变量 -Pass PHP data to JavaScript using `registerJsVar()`: +使用 `registerJsVar()` 将 PHP 数据传递给 JavaScript: ```php // Register JavaScript variables @@ -164,7 +161,7 @@ $this->registerJsVar('config', [ ]); ``` -This generates JavaScript code like: +这将生成如下 JavaScript 代码: ```html ``` -### Using Script Tags +### 使用 Script 标签 -For more control over script tags: +如需对 script 标签进行更精细的控制: ```php use Yiisoft\Html\Html; @@ -192,9 +189,9 @@ $scriptTag = Html::script(' $this->registerScriptTag($scriptTag, WebView::POSITION_END); ``` -## Position Constants +## 位置常量 -Resources can be positioned at different locations in the HTML document: +资源可以定位到 HTML 文档的不同位置: ```php use Yiisoft\View\WebView; @@ -215,7 +212,7 @@ WebView::POSITION_READY WebView::POSITION_LOAD ``` -Example layout showing where each position is rendered: +以下布局示例展示了各位置的渲染位置: ```php endPage() ?> ``` -## Meta tags +## Meta 标签 -### Basic Meta Tags +### 基本 Meta 标签 -Register meta tags for SEO and page information: +为 SEO 和页面信息注册 meta 标签: ```php // Register meta tags using array syntax @@ -270,9 +267,9 @@ $this->registerMeta(['property' => 'og:description', 'content' => 'Page descript $this->registerMeta(['property' => 'og:image', 'content' => 'https://example.com/image.jpg']); ``` -### Using Meta Tag Objects +### 使用 Meta 标签对象 -For more control, use the `Html::meta()` helper: +如需更精细的控制,使用 `Html::meta()` 辅助方法: ```php use Yiisoft\Html\Html; @@ -291,9 +288,9 @@ $this->registerMetaTag( ); ``` -### Preventing Duplicate Meta Tags +### 防止重复 Meta 标签 -Use keys to prevent duplicate meta tags: +使用键名防止 meta 标签重复注册: ```php // First registration @@ -309,11 +306,11 @@ $this->registerMeta([ ], 'description'); ``` -## Link tags +## Link 标签 -### Basic Link Tags +### 基本 Link 标签 -Register various types of link tags: +注册各类 link 标签: ```php // Favicon @@ -347,7 +344,7 @@ $this->registerLink([ ]); ``` -### Using Link Tag Objects +### 使用 Link 标签对象 ```php use Yiisoft\Html\Html; @@ -367,11 +364,11 @@ $this->registerLinkTag( ); ``` -## Practical Examples +## 实践示例 -### Complete Page Setup +### 完整页面配置 -Here's how you might set up a complete page with all types of resources: +以下示例展示如何为页面配置所有类型的资源: ```php registerCss(' ``` -### Conditional Resource Loading +### 条件资源加载 -Load resources based on conditions: +根据条件加载资源: ```php registerJsVar('userPermissions', [ ?> ``` -## Best Practices +## 最佳实践 -1. **Use appropriate positions**: Place CSS in `POSITION_HEAD`, JavaScript - at `POSITION_END` -2. **Minimize inline resources**: Prefer external files for better caching -3. **Use keys for duplicates**: Prevent duplicate resources with meaningful - keys -4. **Optimize loading**: Use `async` and `defer` attributes for non-critical - JavaScript -5. **Group related resources**: Keep related CSS and JS files together -6. **Use CDNs wisely**: Balance performance with reliability -7. **Validate meta tags**: Ensure proper SEO meta tags are set -8. **Consider security**: Be careful with inline scripts and CSP policies +1. **使用合适的位置**:将 CSS 放在 `POSITION_HEAD`,JavaScript 放在 `POSITION_END` +2. **减少内联资源**:优先使用外部文件以获得更好的缓存效果 +3. **使用键名去重**:通过有意义的键名防止资源重复注册 +4. **优化加载**:对非关键 JavaScript 使用 `async` 和 `defer` 属性 +5. **分组管理相关资源**:将相关的 CSS 和 JS 文件放在一起 +6. **合理使用 CDN**:在性能与可靠性之间取得平衡 +7. **验证 meta 标签**:确保正确设置 SEO 所需的 meta 标签 +8. **注意安全性**:谨慎处理内联脚本与 CSP 策略 -## Working with Asset Bundles +## 使用资源包 -For more complex asset management, consider using asset bundles: +对于更复杂的资源管理需求,可以考虑使用资源包: ```php // Register an asset bundle (covered in detail in the Assets guide) diff --git a/src/zh-CN/guide/views/template-engines.md b/src/zh-CN/guide/views/template-engines.md index 9d15ee9f..8a2b147c 100644 --- a/src/zh-CN/guide/views/template-engines.md +++ b/src/zh-CN/guide/views/template-engines.md @@ -1,24 +1,19 @@ -# Template engines +# 模板引擎 -Yii3 supports multiple template engines through a flexible renderer -system. By default, PHP is used as the template engine, but you can easily -add support for other engines like Twig and -[Blade](https://github.com/lee-to/yii-blade), or create your own custom -renderers. +Yii3 通过灵活的渲染器系统支持多种模板引擎。默认情况下,PHP 用作模板引擎,但您可以轻松添加对其他引擎(如 Twig 和 +[Blade](https://github.com/lee-to/yii-blade))的支持,或创建自己的自定义渲染器。 -PHP templates were described in the "[View](view.md)" guide section. +PHP 模板在“[视图](view.md)”指南部分中有描述。 -## Twig Template Engine +## Twig 模板引擎 -Twig is a modern template engine that provides a more designer-friendly -syntax. To use Twig in your Yii3 application, you need to install the Twig -extension. +Twig 是一种现代模板引擎,提供更适合设计师的语法。要在您的 Yii3 应用程序中使用 Twig,您需要安装 Twig 扩展。 ```bash composer require yiisoft/view-twig ``` -Now you can use `.twig` templates. For example, `views/site/about.twig`: +现在您可以使用 `.twig` 模板。例如,`views/site/about.twig`: ```twig {# Variable type hints for IDE support #} @@ -46,9 +41,9 @@ Now you can use `.twig` templates. For example, `views/site/about.twig`: ``` -### Twig Features +### Twig 特性 -**Automatic Escaping**: Twig automatically escapes variables for HTML context: +**自动转义**:Twig 自动转义 HTML 上下文中的变量: ```twig {# Automatically escaped #} @@ -58,7 +53,7 @@ Now you can use `.twig` templates. For example, `views/site/about.twig`:
{{ content|raw }}
``` -**Filters and Functions**: Twig provides many built-in filters and functions: +**过滤器和函数**:Twig 提供了许多内置过滤器和函数: ```twig {# Date formatting #} @@ -71,7 +66,7 @@ Now you can use `.twig` templates. For example, `views/site/about.twig`: Profile ``` -**Template Inheritance**: Twig supports template inheritance: +**模板继承**:Twig 支持模板继承: **views/layout/main.twig** ```twig @@ -100,9 +95,9 @@ Now you can use `.twig` templates. For example, `views/site/about.twig`: {% endblock %} ``` -### Rendering Twig Templates +### 渲染 Twig 模板 -Use Twig templates the same way as PHP templates: +以与 PHP 模板相同的方式使用 Twig 模板: ```php // In your controller @@ -115,10 +110,9 @@ public function about(): ResponseInterface } ``` -## Custom Template Engines +## 自定义模板引擎 -You can create custom template engines by implementing the -`TemplateRendererInterface`: +您可以通过实现 `TemplateRendererInterface` 来创建自定义模板引擎: ```php [ @@ -68,14 +62,11 @@ Add your new Injection to `params.php`: ], ``` -## Using Separate Injections for Different Layouts +## 为不同布局使用独立注入 -If your application has multiple layouts, you can create separate parameter -injections for each layout. This approach allows you to tailor the -parameters injected into each layout according to its specific needs, -enhancing the flexibility and maintainability of your application. +如果您的应用程序有多个布局,可以为每个布局创建独立的参数注入类。这种方式允许您根据每个布局的具体需求定制注入的参数,从而提高应用程序的灵活性和可维护性。 -Create your custom ViewInjection for a specific layout: +为特定布局创建自定义视图注入类: ```php readonly final class CartViewInjection implements CommonParametersInjectionInterface @@ -93,8 +84,7 @@ readonly final class CartViewInjection implements CommonParametersInjectionInter } ``` -Add your new injection to `params.php` under specific layout name. In the -following example, it's `@layout/cart`: +在 `params.php` 中,将新建的注入类添加到指定布局名称下。以下示例中布局名称为 `@layout/cart`: ```php 'yiisoft/yii-view' => [ diff --git a/src/zh-CN/guide/views/view.md b/src/zh-CN/guide/views/view.md index 3655a915..82bbcd13 100644 --- a/src/zh-CN/guide/views/view.md +++ b/src/zh-CN/guide/views/view.md @@ -1,10 +1,6 @@ -# Views +# 视图 -View is responsible for presenting data to end users. You give it a template -with some placeholders and presentation logic and some data. The view is -passing data to the template executing template logic. The end result is -ready to be passed to end user, be it a browser, a file to download, an -email to send or something else. +视图负责向最终用户呈现数据。您为其提供一个包含一些占位符、表示逻辑和数据的模板。视图将数据传递给模板,执行模板逻辑。最终结果准备好传递给最终用户,无论是浏览器、要下载的文件、要发送的电子邮件还是其他内容。 ```mermaid flowchart LR @@ -14,39 +10,31 @@ flowchart LR C --> D[Browser] ``` -In Yii3 views are typically PHP files that contain presentation logic and -HTML markup. The view system provides a flexible way to organize your -presentation layer and supports features like layouts and partial -views. Instead of using plain PHP templates, you can leverage one of the -template engines such as [Twig](template-engines.md) or -[Blade](https://github.com/lee-to/yii-blade). +在 Yii3 中,视图通常是包含表示逻辑和 HTML 标记的 PHP +文件。视图系统提供了一种灵活的方式来组织您的表示层,并支持布局和局部视图等功能。除了使用纯 PHP 模板,您还可以利用模板引擎,例如 +[Twig](template-engines.md) 或 [Blade](https://github.com/lee-to/yii-blade)。 ## 安装 -For basic view functionality, you need the `yiisoft/view` package: +对于基本的视图功能,您需要 `yiisoft/view` 包: ```sh composer require yiisoft/view ``` -For web applications, you should also install the -`yiisoft/yii-view-renderer` package which provides -[PSR-7](https://www.php-fig.org/psr/psr-7/) compatibility and web-specific -features: +对于 Web 应用程序,您还应该安装 `yiisoft/yii-view-renderer` 包,它提供 +[PSR-7](https://www.php-fig.org/psr/psr-7/) 兼容性和 Web 特定功能: ```sh composer require yiisoft/yii-view-renderer ``` -These packages are included by default in the `yiisoft/app` application -template. +这些包默认包含在 `yiisoft/app` 应用程序模板中。 -## Basic Concepts +## 基本概念 -A view template file contains presentation logic. In the `yiisoft/app` -template, view files are typically stored alongside their controllers (e.g., -`src/Web/Echo/Action.php`). Here's a simple view file example, -`src/Web/Echo/template.php`: +视图模板文件包含表示逻辑。在 `yiisoft/app` +模板中,视图文件通常与它们的控制器存储在一起(例如,`src/Web/Echo/Action.php`)。这是一个简单的视图文件示例,`src/Web/Echo/template.php`: ```php The message is:

``` -Here `$message` is a view data that is passed when you render a template -with the help of `WebViewRenderer`. For example, `src/Web/Echo/Action.php`: +这里 `$message` 是通过 `WebViewRenderer` +渲染模板时传递的视图数据。例如,`src/Web/Echo/Action.php`: ```php beginPage() endPage() ?> ``` -In the template above `$applicationParams` is an array of parameters from -`config/common/application.php`. +在上面的模板中,`$applicationParams` 是来自 `config/common/application.php` 的参数数组。 -`$aliases` refers to [aliases component](../concept/aliases.md) that is used -to get the base URL of the application at the server for URLs. +`$aliases` 指的是[别名组件](../concept/aliases.md),用于获取服务器上应用程序的基础 URL。 -`$this` is an instance of the view that we use to get page title and output -assets. Both standard and custom. +`$this` 是视图的实例,我们用它来获取页面标题和输出资源,包括标准的和自定义的。 -With `$assetManager->register(MainAsset::class);` we register an asset that defines `css` to include to the page. It is -automatically copied to `public/assets` on first use. It is not very useful for a single CSS file but becomes handy as -the number of assets grows. +使用 `$assetManager->register(MainAsset::class);` 我们注册一个资源,定义要包含在页面中的 `css`。它在 +首次使用时会自动复制到 `public/assets`。对于单个 CSS 文件来说用处不大,但随着 +资源数量的增加,它会变得很方便。 > [!IMPORTANT] -> No output in plain PHP templates is encoded you should not forget to use `Html::encode()` to prevent -XSS security vulnerabilities. +> 纯 PHP 模板中的输出不会被编码,您不应忘记使用 `Html::encode()` 来防止 +XSS 安全漏洞。 -More about what's available in layout could be read in -[yiisoft/view](https://github.com/yiisoft/view) documentation. +更多关于布局中可用内容的信息可以在 [yiisoft/view](https://github.com/yiisoft/view) 文档中阅读。 -### Rendering without layout +### 不使用布局渲染 -Sometimes you need to render a view without a layout (for example, for AJAX -responses): +有时您需要渲染没有布局的视图(例如,对于 AJAX 响应): ```php public function ajaxContent(): ResponseInterface @@ -213,11 +192,11 @@ public function ajaxContent(): ResponseInterface } ``` -## Nested Views and Partials +## 嵌套视图和局部视图 -### Rendering Sub-views +### 渲染子视图 -You can render other views from within a view using the `$this->render()` method: +您可以使用 `$this->render()` 方法从视图中渲染其他视图: ```php ``` -### Using Blocks +### 使用块 -Blocks allow you to define content in one view and display it in another, -typically in layouts: +块允许您在一个视图中定义内容,并在另一个视图(通常是布局)中显示它: ```php // In a view file @@ -271,9 +249,9 @@ typically in layouts: ``` -## Rendering as String +## 渲染为字符串 -If you need the rendered content as a string instead of a PSR-7 response: +如果您需要将渲染内容作为字符串而不是 PSR-7 响应: ```php public function getEmailContent(): string @@ -284,10 +262,9 @@ public function getEmailContent(): string } ``` -## View Events +## 视图事件 -The view system triggers events during the rendering process that you can -listen to: +视图系统在渲染过程中触发您可以监听的事件: ```php use Yiisoft\View\Event\WebView\BeforeRender; diff --git a/src/zh-CN/guide/views/widget.md b/src/zh-CN/guide/views/widget.md index fd05ada5..1a6acd10 100644 --- a/src/zh-CN/guide/views/widget.md +++ b/src/zh-CN/guide/views/widget.md @@ -1,49 +1,43 @@ -# Widgets +# 小部件 -Widgets are reusable, self-contained components that encapsulate complex -HTML generation logic. They provide a clean way to create configurable UI -elements that can be used across different views and applications. Yii3 -provides a flexible widget system through the `yiisoft/widget` package. +小部件是可重用的独立组件,封装了复杂的 HTML 生成逻辑。它们提供了一种简洁的方式来创建可配置的 UI 元素,可在不同的视图和应用程序中使用。Yii3 +通过 `yiisoft/widget` 包提供了灵活的小部件系统。 ## 安装 -The widget functionality is provided by the `yiisoft/widget` package: +小部件功能由 `yiisoft/widget` 包提供: ```bash composer require yiisoft/widget ``` -For ready-made widgets (like forms, navigation, etc.), you can also install: +对于现成的小部件(如表单、导航等),您还可以安装: ```bash composer require yiisoft/yii-widgets ``` -These packages are included by default in the `yiisoft/app` application -template. +这些包默认包含在 `yiisoft/app` 应用程序模板中。 -## Basic Concepts +## 基本概念 -### Widget Class +### 小部件类 -A widget is a PHP class that extends the abstract `Widget` class and -implements a `render()` method that returns HTML content as a string. +小部件是一个 PHP 类,继承自抽象的 `Widget` 类,并实现一个返回 HTML 内容字符串的 `render()` 方法。 -### Widget Factory +### 小部件工厂 -The `WidgetFactory` is responsible for creating widget instances and can -inject dependencies through the DI container. +`WidgetFactory` 负责创建小部件实例,并可以通过 DI 容器注入依赖。 -### Widget Configuration +### 小部件配置 -Widgets can be configured with properties and methods, making them highly -customizable and reusable across different contexts. +小部件可以通过属性和方法进行配置,使其在不同上下文中具有高度可定制性和可重用性。 -## Creating Custom Widgets +## 创建自定义小部件 -### Simple Widget +### 简单小部件 -Here's a basic widget that displays an alert message: +以下是一个显示警告消息的基础小部件: ```php ``` -### Widget with Dependencies +### 带依赖的小部件 -Widgets can use dependency injection for services: +小部件可以通过依赖注入使用服务: ```php ``` -### Form Widget +### 表单小部件 -A widget that simplifies form rendering: +一个简化表单渲染的小部件: ```php ``` -## Testing Widgets +## 测试小部件 -### Unit Testing +### 单元测试 -Test widget rendering logic: +测试小部件的渲染逻辑: ```php