diff --git a/docs/guide-zh-CN/README.md b/docs/guide-zh-CN/README.md index 9d2f4e7..31ae463 100644 --- a/docs/guide-zh-CN/README.md +++ b/docs/guide-zh-CN/README.md @@ -38,7 +38,7 @@ Yii 2.0 权威指南 * **已定稿** [过滤器](structure-filters.md) * **已定稿** [小部件(Widget)](structure-widgets.md) * **已定稿** [模块(Module)](structure-modules.md) -* **编撰中** [前端资源(Asset)](structure-assets.md) +* **已定稿** [前端资源(Asset)](structure-assets.md) * **已定稿** [扩展(extensions)](structure-extensions.md) 请求处理 @@ -46,13 +46,12 @@ Yii 2.0 权威指南 * **已定稿** [运行概述](runtime-overview.md) * **已定稿** [引导(Bootstrapping)](runtime-bootstrapping.md) -* **已定稿** [路由(Routing)](runtime-routing.md) +* **已定稿** [路由(Route)引导与创建 URL](runtime-routing.md) * **已定稿** [请求(Request)](runtime-requests.md) * **已定稿** [响应(Response)](runtime-responses.md) * **已定稿** [Sessions(会话)和 Cookies](runtime-sessions-cookies.md) -* **编撰中** [URL 解析和生成](runtime-url-handling.md) -* **编撰中** [错误处理](runtime-handling-errors.md) -* **编撰中** [日志](runtime-logging.md) +* **已定稿** [错误处理](runtime-handling-errors.md) +* **已定稿** [日志](runtime-logging.md) 关键概念 -------- @@ -90,7 +89,7 @@ Yii 2.0 权威指南 显示数据 -------- -* **待定中** [格式化输出数据](output-formatter.md) +* **编撰中** [格式化输出数据](output-formatter.md) * **待定中** [分页(Pagination)](output-pagination.md) * **待定中** [排序(Sorting)](output-sorting.md) * **编撰中** [数据提供器](output-data-providers.md) diff --git a/docs/guide-zh-CN/caching-fragment.md b/docs/guide-zh-CN/caching-fragment.md index c379b90..d8dd970 100644 --- a/docs/guide-zh-CN/caching-fragment.md +++ b/docs/guide-zh-CN/caching-fragment.md @@ -114,7 +114,7 @@ if ($this->beginCache($id1)) { 可以为嵌套的缓存设置不同的配置项。例如,内层缓存和外层缓存使用不同的过期时间。甚至当外层缓存的数据过期失效了,内层缓存仍然可能提供有效的片段缓存数据。但是,反之则不然。如果外层片段缓存没有过期而被视为有效,此时即使内层片段缓存已经失效,它也将继续提供同样的缓存副本。因此,你必须谨慎处理缓存嵌套中的过期时间和依赖,否则外层的片段很有可能返回的是不符合你预期的失效数据。 -> 译者注:外层的失效时间应该短于内层,外层的依赖条件应该低于内层,以确保最小的片段,返回的是最新的数据。 +> 译注:外层的失效时间应该短于内层,外层的依赖条件应该低于内层,以确保最小的片段,返回的是最新的数据。 ## 动态内容 diff --git a/docs/guide-zh-CN/concept-autoloading.md b/docs/guide-zh-CN/concept-autoloading.md index ee6ca92..0fe7684 100644 --- a/docs/guide-zh-CN/concept-autoloading.md +++ b/docs/guide-zh-CN/concept-autoloading.md @@ -15,7 +15,7 @@ Yii 依靠[类自动加载机制](http://www.php.net/manual/en/language.oop5.aut * 每个类都必须保存为单独文件,且其完整路径能用以下算法取得: ```php -// $className 是一个开头包含反斜杠的完整类名(译者注:请自行谷歌:fully qualified class name) +// $className 是一个开头包含反斜杠的完整类名(译注:请自行谷歌:fully qualified class name) $classFile = Yii::getAlias('@' . str_replace('\\', '/', $className) . '.php'); ``` diff --git a/docs/guide-zh-CN/concept-behaviors.md b/docs/guide-zh-CN/concept-behaviors.md index aad7739..833aa68 100644 --- a/docs/guide-zh-CN/concept-behaviors.md +++ b/docs/guide-zh-CN/concept-behaviors.md @@ -267,7 +267,7 @@ class User extends ActiveRecord 保存 `User` 对象,将会发现它的 `created_at` 和 `updated_at` 属性自动填充了当前时间戳: -``php +```php $user = new User; $user->email = 'test@example.com'; $user->save(); diff --git a/docs/guide-zh-CN/concept-events.md b/docs/guide-zh-CN/concept-events.md index 07ae569..1824fbd 100644 --- a/docs/guide-zh-CN/concept-events.md +++ b/docs/guide-zh-CN/concept-events.md @@ -65,7 +65,7 @@ $foo->on(Foo::EVENT_HELLO, function ($event) { ``` -时间处理器顺序 +事件处理器顺序 ----------------- 可以附加一个或多个处理器到一个事件。当事件被触发,已附加的处理器将按附加次序依次调用。如果某个处理器需要停止其后的处理器调用,可以设置 `$event` 参数的 [yii\base\Event::handled]] 属性为真,如下: @@ -78,7 +78,7 @@ $foo->on(Foo::EVENT_HELLO, function ($event) { 默认新附加的事件处理器排在已存在处理器队列的最后。因此,这个处理器将在事件被触发时最后一个调用。在处理器队列最前面插入新处理器将使该处理器最先调用,可以传递第四个参数 `$append` 为假并调用 [[yii\base\Component::on()]] 方法实现: -``php +```php $foo->on(Foo::EVENT_HELLO, function ($event) { // 这个处理器将被插入到处理器队列的第一位... }, $data, false); @@ -238,4 +238,4 @@ Yii::$app->trigger('bar', new Event(['sender' => new Foo])); 全局事件的一个好处是当附加处理器到一个对象要触发的事件时,不需要产生该对象。相反,处理器附加和事件触发都通过单例(如应用实例)完成。 -然而,因为全局事件的命名空间由各方共享,应合理命名全局事件,如引入一些命名空间(例:"frontend.mail.sent", "backend.mail.sent")。 \ No newline at end of file +然而,因为全局事件的命名空间由各方共享,应合理命名全局事件,如引入一些命名空间(例:"frontend.mail.sent", "backend.mail.sent")。 diff --git a/docs/guide-zh-CN/db-active-record.md b/docs/guide-zh-CN/db-active-record.md index 3012c41..18ff81b 100644 --- a/docs/guide-zh-CN/db-active-record.md +++ b/docs/guide-zh-CN/db-active-record.md @@ -166,7 +166,7 @@ $sql = 'SELECT * FROM customer'; $customers = Customer::findBySql($sql)->all(); ``` -> 小技巧:在上面的代码中,`Customer::STATUS_ACTIVE` 是一个在 `Customer` 类里定义的常量。(译者注:这种常量的值一般都是tinyint)相较于直接在代码中写死字符串或数字,使用一个更有意义的常量名称是一种更好的编程习惯。 +> 小技巧:在上面的代码中,`Customer::STATUS_ACTIVE` 是一个在 `Customer` 类里定义的常量。(译注:这种常量的值一般都是tinyint)相较于直接在代码中写死字符串或数字,使用一个更有意义的常量名称是一种更好的编程习惯。 有两个快捷方法:`findOne` 和 `findAll()` 用来返回一个或者一组`ActiveRecord`实例。前者返回第一个匹配到的实例,后者返回所有。 例如: @@ -847,7 +847,7 @@ public static function find() } ``` -注意,你之后所有的查询都不能用 [[yii\db\ActiveQuery::where()|where()]],但是可以用 [[yii\db\ActiveQuery::andWhere()|andWhere()]] 和 [[yii\db\ActiveQuery::orWhere()|orWhere()]],他们不会覆盖掉默认作用域。(译者注:如果你要使用默认作用域,就不能在 xxx::find()后使用where()方法,你必须使用andXXX()或者orXXX()系的方法,否则默认作用域不会起效果,至于原因,打开where()方法的代码一看便知) +注意,你之后所有的查询都不能用 [[yii\db\ActiveQuery::where()|where()]],但是可以用 [[yii\db\ActiveQuery::andWhere()|andWhere()]] 和 [[yii\db\ActiveQuery::orWhere()|orWhere()]],他们不会覆盖掉默认作用域。(译注:如果你要使用默认作用域,就不能在 xxx::find()后使用where()方法,你必须使用andXXX()或者orXXX()系的方法,否则默认作用域不会起效果,至于原因,打开where()方法的代码一看便知) 事务操作 @@ -894,7 +894,7 @@ class ProductController extends \yii\web\Controller } } ``` -(译者注:我觉得上面应该是原手册里的bug) +(译注:我觉得上面应该是原手册里的bug) 在控制器层使用事务: diff --git a/docs/guide-zh-CN/runtime-bootstrapping.md b/docs/guide-zh-CN/runtime-bootstrapping.md index 3829658..8c2e318 100644 --- a/docs/guide-zh-CN/runtime-bootstrapping.md +++ b/docs/guide-zh-CN/runtime-bootstrapping.md @@ -24,7 +24,7 @@ Composer 自动加载器,以及通过 `Yii` 类加载的 Yii 自动加载器 因为引导工作必须在处理**每一次**请求之前都进行一遍,因此让该过程尽可能轻量化就异常重要,请尽可能地优化这一步骤。 请尽量不要注册太多引导组件。只有他需要在 HTTP 请求处理的全部生命周期中都作用时才需要使用它。举一个用到它的范例:一个模块需要注册额外的 URL 解析规则,就应该把它列在应用的 -[bootstrap 属性](structure-applications.md#bootstrap)之中,这样该 URL 解析规则才能在解析请求之前生效。(译者注:换言之,为了性能需要,除了 URL +[bootstrap 属性](structure-applications.md#bootstrap)之中,这样该 URL 解析规则才能在解析请求之前生效。(译注:换言之,为了性能需要,除了 URL 解析等少量操作之外,绝大多数组件都应该按需加载,而不是都放在引导过程中。) 在生产环境中,可以开启字节码缓存,比如 APC,来进一步最小化加载和解析 PHP 文件所需的时间。 diff --git a/docs/guide-zh-CN/runtime-handling-errors.md b/docs/guide-zh-CN/runtime-handling-errors.md new file mode 100644 index 0000000..1cb5af7 --- /dev/null +++ b/docs/guide-zh-CN/runtime-handling-errors.md @@ -0,0 +1,204 @@ +错误处理 +=============== + +Yii 内置了一个[[yii\web\ErrorHandler|error handler]]错误处理器,它使错误处理更方便, +Yii错误处理器做以下工作来提升错误处理效果: + +* 所有非致命PHP错误(如,警告,提示)会转换成可获取异常; +* 异常和致命的PHP错误会被显示,在调试模式会显示详细的函数调用栈和源代码行数。 +* 支持使用专用的 [控制器操作](structure-actions.md) 来显示错误; +* 支持不同的错误响应格式; + +[[yii\web\ErrorHandler|error handler]] 错误处理器默认启用, +可通过在应用的[入口脚本](structure-entry-scripts.md)中定义常量`YII_ENABLE_ERROR_HANDLER`来禁用。 + + +## 使用错误处理器 + +[[yii\web\ErrorHandler|error handler]] 注册成一个名称为`errorHandler`[应用组件](structure-application-components.md), +可以在应用配置中配置它类似如下: + +```php +return [ + 'components' => [ + 'errorHandler' => [ + 'maxSourceLines' => 20, + ], + ], +]; +``` + +使用如上代码,异常页面最多显示20条源代码。 + +如前所述,错误处理器将所有非致命PHP错误转换成可获取异常,也就是说可以使用如下代码处理PHP错误: + +```php +use Yii; +use yii\base\ErrorException; + +try { + 10/0; +} catch (ErrorException $e) { + Yii::warning("Division by zero."); +} + +// execution continues... +``` + +如果你想显示一个错误页面告诉用户请求是无效的或无法处理的,可简单地抛出一个 [[yii\web\HttpException|HTTP exception]]异常, +如 [[yii\web\NotFoundHttpException]]。错误处理器会正确地设置响应的HTTP状态码并使用合适的错误视图页面来显示错误信息。 + +```php +use yii\web\NotFoundHttpException; + +throw new NotFoundHttpException(); +``` + + +## 自定义错误显示 + +[[yii\web\ErrorHandler|error handler]]错误处理器根据常量`YII_DEBUG`的值来调整错误显示, +当`YII_DEBUG` 为 true (表示在调试模式),错误处理器会显示异常以及详细的函数调用栈和源代码行数来帮助调试, +当`YII_DEBUG` 为 false,只有错误信息会被显示以防止应用的敏感信息泄漏。 + +> 补充: 如果异常是继承 [[yii\base\UserException]],不管`YII_DEBUG`为何值,函数调用栈信息都不会显示, +这是因为这种错误会被认为是用户产生的错误,开发人员不需要去修正。 + +[[yii\web\ErrorHandler|error handler]] 错误处理器默认使用两个[视图](structure-views.md)显示错误: + +* `@yii/views/errorHandler/error.php`: 显示不包含函数调用栈信息的错误信息是使用, + 当`YII_DEBUG` 为 false时,所有错误都使用该视图。 +* `@yii/views/errorHandler/exception.php`: 显示包含函数调用栈信息的错误信息时使用。 + +可以配置错误处理器的 [[yii\web\ErrorHandler::errorView|errorView]] 和 [[yii\web\ErrorHandler::exceptionView|exceptionView]] 属性 +使用自定义的错误显示视图。 + + +### 使用错误操作 + +使用指定的错误[操作](structure-controllers.md) 来自定义错误显示更方便, +为此,首先配置`errorHandler`组件的 [[yii\web\ErrorHandler::errorAction|errorAction]] 属性,类似如下: + +```php +return [ + 'components' => [ + 'errorHandler' => [ + 'errorAction' => 'site/error', + ], + ] +]; +``` + +[[yii\web\ErrorHandler::errorAction|errorAction]] 属性使用[路由](structure-controllers.md#routes)到一个操作, +上述配置表示不用显示函数调用栈信息的错误会通过执行`site/error`操作来显示。 + +可以创建`site/error` 操作如下所示: + +```php +namespace app\controllers; + +use Yii; +use yii\web\Controller; + +class SiteController extends Controller +{ + public function actions() + { + return [ + 'error' => [ + 'class' => 'yii\web\ErrorAction', + ], + ]; + } +} +``` + +上述代码定义`error` 操作使用[[yii\web\ErrorAction]] 类,该类渲染名为`error`视图来显示错误。 + +除了使用[[yii\web\ErrorAction]], 可定义`error` 操作使用类似如下的操作方法: + +```php +public function actionError() +{ + $exception = Yii::$app->errorHandler->exception; + if ($exception !== null) { + return $this->render('error', ['exception' => $exception]); + } +} +``` + +现在应创建一个视图文件为`views/site/error.php`,在该视图文件中,如果错误操作定义为[[yii\web\ErrorAction]], +可以访问该操作中定义的如下变量: + +* `name`: 错误名称 +* `message`: 错误信息 +* `exception`: 更多详细信息的异常对象,如HTTP 状态码,错误码,错误调用栈等。 + +> 补充: 如果你使用 [基础应用模板](start-installation.md) 或 [高级应用模板](tutorial-advanced-app.md), +错误操作和错误视图已经定义好了。 + + +### 自定义错误格式 + +错误处理器根据[响应](runtime-responses.md)设置的格式来显示错误, +如果[[yii\web\Response::format|response format]] 响应格式为`html`, 会使用错误或异常视图来显示错误信息,如上一小节所述。 +对于其他的响应格式,错误处理器会错误信息作为数组赋值给[[yii\web\Response::data]]属性,然后转换到对应的格式, +例如,如果响应格式为`json`,可以看到如下响应信息: + +``` +HTTP/1.1 404 Not Found +Date: Sun, 02 Mar 2014 05:31:43 GMT +Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y +Transfer-Encoding: chunked +Content-Type: application/json; charset=UTF-8 + +{ + "name": "Not Found Exception", + "message": "The requested resource was not found.", + "code": 0, + "status": 404 +} +``` + +可在应用配置中响应`response`组件的`beforeSend`事件来自定义错误响应格式。 + +```php +return [ + // ... + 'components' => [ + 'response' => [ + 'class' => 'yii\web\Response', + 'on beforeSend' => function ($event) { + $response = $event->sender; + if ($response->data !== null) { + $response->data = [ + 'success' => $response->isSuccessful, + 'data' => $response->data, + ]; + $response->statusCode = 200; + } + }, + ], + ], +]; +``` + +上述代码会重新格式化错误响应,类似如下: + +``` +HTTP/1.1 200 OK +Date: Sun, 02 Mar 2014 05:31:43 GMT +Server: Apache/2.2.26 (Unix) DAV/2 PHP/5.4.20 mod_ssl/2.2.26 OpenSSL/0.9.8y +Transfer-Encoding: chunked +Content-Type: application/json; charset=UTF-8 + +{ + "success": false, + "data": { + "name": "Not Found Exception", + "message": "The requested resource was not found.", + "code": 0, + "status": 404 + } +} +``` diff --git a/docs/guide-zh-CN/runtime-routing.md b/docs/guide-zh-CN/runtime-routing.md index eeb8db3..949e781 100644 --- a/docs/guide-zh-CN/runtime-routing.md +++ b/docs/guide-zh-CN/runtime-routing.md @@ -2,40 +2,27 @@ ======= 当[入口脚本](structure-entry-scripts.md)在调用 [[yii\web\Application::run()|run()]] -方法时,它进行的第一个操作就是解析输入的请求,然后实例化对应的[控制器操作](structure-controllers.md)处理这个请求。该过程就被称为**引导路由(routing)**。(译者注:中文里既是动词也是名词) +方法时,它进行的第一个操作就是解析输入的请求,然后实例化对应的[控制器操作](structure-controllers.md)处理这个请求。该过程就被称为**引导路由(routing)**。(译注:中文里既是动词也是名词) ## 解析路由 -引导路由第一步,是解析输入请求为一个路由。如 [控制器(Controllers)](structure-controllers.md#routes) -所描述的那样,路由是一个用于定位控制器操作的地址。这个过程通过 `request` 应用组件的 [[yii\web\Request::resolve()|resolve()]] +路由引导的第一步,是把传入请求解析为一个路由。如我们在 [控制器(Controllers)](structure-controllers.md#routes) +章节中所描述的那样,路由是一个用于定位控制器操作的地址。这个过程通过 `request` 应用组件的 [[yii\web\Request::resolve()|resolve()]] 方法实现,该方法会调用 [URL 管理器](runtime-url-handling.md) 进行实质上的请求解析工作。 -The first step of routing is to parse the incoming request into a route which, as described in -the [Controllers](structure-controllers.md#routes) section, is used to address a controller action. -This is done by [[yii\web\Request::resolve()|resolve()]] method of the `request` application component. -The method invokes the [URL manager](runtime-url-handling.md) to do the actual request parsing work. - -默认情况下,输入请求会包含一个名为 `r` 的 `GET` 参数,它的值即被视为路由。但是如果启用 -[[yii\web\UrlManager::enablePrettyUrl|pretty URL feature]],确定请求路由时则会进行更多处理。具体的细节请参考 +默认情况下,传入请求会包含一个名为 `r` 的 `GET` 参数,它的值即被视为路由。但是如果启用 +[[yii\web\UrlManager::enablePrettyUrl|美化 URL 功能]],那么在确定请求的路由时,就会进行更多处理。具体的细节请参考 [URL 的解析与生成](runtime-url-handling.md) 章节。 -By default, if the incoming request contains a `GET` parameter named `r`, its value will be considered -as the route. However, if the [[yii\web\UrlManager::enablePrettyUrl|pretty URL feature]] is enabled, -more work will be done to determine the requested route. For more details, please refer to -the [URL Parsing and Generation](runtime-url-handling.md) section. - -若好死不死地路由最终无法被确定,那么 `request` 组件会抛出 [[yii\web\NotFoundHttpException]] 异常(译者注:大名鼎鼎的 404)。 - -In case a route cannot be determined, the `request` component will throw a [[yii\web\NotFoundHttpException]]. +假使某路由最终实在无法被确定,那么 `request` 组件会抛出 [[yii\web\NotFoundHttpException]] 异常(译注:大名鼎鼎的 404)。 -### 默认路由 +### 缺省路由 -If an incoming request does not specify a route, which often happens to the request for homepages, -the route specified by [[yii\web\Application::defaultRoute]] will be used. The default value of this property -is `site/index`, which refers to the `index` action of the `site` controller. You may customize this property -in the application configuration like the following: +如果传入请求并没有提供一个具体的路由,(一般这种情况多为于对首页的请求)此时就会启用由 +[[yii\web\Application::defaultRoute]] 属性所指定的缺省路由。该属性的默认值为 `site/index`,它指向 `site` 控制器的 `index` +操作。你可以像这样在应用配置中调整该属性的值: ```php return [ @@ -47,9 +34,9 @@ return [ ### `catchAll` 路由(全拦截路由) -Sometimes, you may want to put your Web application in maintenance mode temporarily and display the same -informational page for all requests. There are many ways to accomplish this goal. But one of the simplest -ways is to configure the [[yii\web\Application::catchAll]] property like the following in the application configuration: +有时候,你会想要将你的 Web +应用临时调整到维护模式,所有的请求下都会显示相同的信息页。当然,要实现这一点有很多种方法。这里面最简单快捷的方法就是在应用配置中设置下 +[[yii\web\Application::catchAll]] 属性: ```php return [ @@ -58,35 +45,25 @@ return [ ]; ``` -The `catchAll` property should take an array whose first element specifies a route, and -the rest of the elements (name-value pairs) specify the parameters to be bound to the action. +`catchAll` 属性需要传入一个数组做参数,该数组的第一个元素为路由,剩下的元素会(以名值对的形式)指定绑定于该操作的各个参数。 -When the `catchAll` property is set, it will replace any route resolved from the incoming requests. -With the above configuration, the same `site/offline` action will be used to handle all incoming requests. +当设置了 `catchAll` 属性时,它会替换掉所有从输入的请求中解析出来的路由。如果是上文的这种设置,用于处理所有传入请求的操作都会是相同的 `site/offline`。 -## 创建一个操作 +## 创建操作 -Once the requested route is determined, the next step is to create the action object corresponding to the route. +一旦请求路由被确定了,紧接着的步骤就是创建一个“操作(action)”对象,用以响应该路由。 -The route is broken down into multiple parts by the slashes in it. For example, `site/index` will be -broken into `site` and `index`. Each part is an ID which may refer to a module, a controller or an action. +路由可以用里面的斜杠分割成多个组成片段,举个栗子,`site/index` 可以分解为 `site` 和 `index` +两部分。每个片段都是指向某一模块(Module)、控制器(Controller)或操作(action)的 ID。 -Starting from the first part in the route, the application conducts the following steps to create modules (if any), -the controller and the action: +从路由的首个片段开始,应用会经过以下流程依次创建模块(如果有),控制器,以及操作: -1. Set the application as the current module. -2. Check if the [[yii\base\Module::controllerMap|controller map]] of the current module contains the current ID. - If so, a controller object will be created according to the controller configuration found in the map, - and do Step 5 with the rest parts of the route. -3. Check if the ID refers to a module listed in the [[yii\base\Module::modules|modules]] property of - the current module. If so, a module is created according to the configuration found in the module list, - and do Step 2 with the next part in the route under the context of the newly created module. -4. Treat the ID as a controller ID and create a controller object. Do the next step with the rest part of - the route. -5. The controller looks for the current ID in its [[yii\base\Controller::actions()|action map]]. If found, - it creates an action according to the configuration found in the map. Otherwise, the controller will - attempt to create an inline action which is defined by an action method corresponding to the current ID. +1. 设置应用主体为当前模块。 +2. 检查当前模块的 [[yii\base\Module::controllerMap|controller map(控制器映射表)]] 是否包含当前 ID。如果是,会根据该表中的配置创建一个控制器对象,然后跳到步骤五执行该路由的后续片段。 +3. 检查该 ID 是否指向当前模块中 [[yii\base\Module::modules|modules]] 属性里的模块列表中的一个模块。如果是,会根据该模块表中的配置创建一个模块对象,然后会以新创建的模块为环境,跳回步骤二解析下一段路由。 +4. 将该 ID 视为控制器 ID,并创建控制器对象。用下个步骤解析路由里剩下的片段。 +5. 控制器会在他的 [[yii\base\Controller::actions()|action map(操作映射表)]]里搜索当前 ID。如果找得到,它会根据该映射表中的配置创建一个操作对象;反之,控制器则会尝试创建一个与该 ID + 相对应,由某个 action 方法所定义的行内操作(inline action)。 -Among the above steps, if any error occurs, a [[yii\web\NotFoundHttpException]] will be thrown, indicating -failure of the routing. +在上面的步骤里,如果有任何错误发生,都会抛出 [[yii\web\NotFoundHttpException]],指出路由引导的过程失败了。 \ No newline at end of file diff --git a/docs/guide-zh-CN/start-forms.md b/docs/guide-zh-CN/start-forms.md index a459ec8..26b7509 100644 --- a/docs/guide-zh-CN/start-forms.md +++ b/docs/guide-zh-CN/start-forms.md @@ -41,7 +41,7 @@ class EntryForm extends Model 该类继承自Yii 提供的一个基类 [[yii\base\Model]],该基类通常用来表示数据。 -> 补充:[[yii\base\Model]] 被用于普通模型类的父类并与数据表**无关**。[[yii\db\ActiveRecord]] 通常是普通模型类的父类但与数据表有关联(译者注:[[yii\db\ActiveRecord]] 类其实也是继承自 [[yii\base\Model]],增加了数据库处理)。 +> 补充:[[yii\base\Model]] 被用于普通模型类的父类并与数据表**无关**。[[yii\db\ActiveRecord]] 通常是普通模型类的父类但与数据表有关联(译注:[[yii\db\ActiveRecord]] 类其实也是继承自 [[yii\base\Model]],增加了数据库处理)。 `EntryForm` 类包含 `name` 和 `email` 两个公共成员,用来储存用户输入的数据。它还包含一个名为 `rules()` 的方法,用来返回数据验证规则的集合。上面声明的验证规则表示: diff --git a/docs/guide-zh-CN/start-installation.md b/docs/guide-zh-CN/start-installation.md index c05e34e..acc0895 100644 --- a/docs/guide-zh-CN/start-installation.md +++ b/docs/guide-zh-CN/start-installation.md @@ -30,7 +30,7 @@ Composer 安装后,切换到一个可通过 Web 访问的目录,执行如下 > 注意:在安装过程中 Composer 可能会询问你 GitHub 账户的登录信息,因为可能在使用中超过了 GitHub API (对匿名用户的)使用限制。因为 Composer 需要为所有扩展包从 GitHub -中获取大量信息,所以超限非常正常。(译者注:也意味着作为程序猿没有 GitHub 账号,就真不能愉快地玩耍了)登陆 GitHub +中获取大量信息,所以超限非常正常。(译注:也意味着作为程序猿没有 GitHub 账号,就真不能愉快地玩耍了)登陆 GitHub 之后可以得到更高的 API 限额,这样 Composer 才能正常运行。更多细节请参考 [Composer 文档](https://getcomposer.org/doc/articles/troubleshooting.md#api-rate-limit-and-oauth-tokens)(该段 Composer 中文文档[期待您的参与](https://github.com/5-say/composer-doc-cn/blob/master/cn-introduction/articles/troubleshooting.md#api-rate-limit-and-oauth-tokens))。 @@ -117,7 +117,7 @@ http://localhost/basic/web/index.php DocumentRoot "path/to/basic/web" - # 开启 mod_rewrite 用于美化 URL 功能的支持(译者注:对应 pretty URL 选项) + # 开启 mod_rewrite 用于美化 URL 功能的支持(译注:对应 pretty URL 选项) RewriteEngine on # 如果请求的是真实存在的文件或目录,直接访问 RewriteCond %{REQUEST_FILENAME} !-f diff --git a/docs/guide-zh-CN/structure-assets.md b/docs/guide-zh-CN/structure-assets.md new file mode 100644 index 0000000..e3018ee --- /dev/null +++ b/docs/guide-zh-CN/structure-assets.md @@ -0,0 +1,528 @@ +资源 +====== + +Yii中的资源是和Web页面相关的文件,可为CSS文件,JavaScript文件,图片或视频等, +资源放在Web可访问的目录下,直接被Web服务器调用。 + +通过程序自动管理资源更好一点,例如,当你在页面中使用 [[yii\jui\DatePicker]] 小部件时, +它会自动包含需要的CSS和JavaScript文件,而不是要求你手工去找到这些文件并包含, +当你升级小部件时,它会自动使用新版本的资源文件,在本教程中,我们会详述Yii提供的强大的资源管理功能。 + + +## 资源包 + +Yii在*资源包*中管理资源,资源包简单的说就是放在一个目录下的资源集合, +当在[视图](structure-views.md)中注册一个资源包,在渲染Web页面时会包含包中的CSS和JavaScript文件。 + + +## 定义资源包 + +资源包指定为继承[[yii\web\AssetBundle]]的PHP类,包名为可[自动加载](concept-autoloading.md)的PHP类名, +在资源包类中,要指定资源所在位置,包含哪些CSS和JavaScript文件以及和其他包的依赖关系。 + +如下代码定义[基础应用模板](start-installation.md)使用的主要资源包: + +```php + + +资源根据它们的位置可以分为: + +* 源资源: 资源文件和PHP源代码放在一起,不能被Web直接访问,为了使用这些源资源,它们要拷贝到一个可Web访问的Web目录中 + 成为发布的资源,这个过程称为*发布资源*,随后会详细介绍。 +* 发布资源: 资源文件放在可通过Web直接访问的Web目录中; +* 外部资源: 资源文件放在你的Web应用不同的Web服务器上; + +当定义资源包类时候,如果你指定了[[yii\web\AssetBundle::sourcePath|sourcePath]] 属性,就表示任何使用相对路径的资源会被 +当作源资源;如果没有指定该属性,就表示这些资源为发布资源(因此应指定[[yii\web\AssetBundle::basePath|basePath]] 和 +[[yii\web\AssetBundle::baseUrl|baseUrl]] 让Yii知道它们的位置)。 + +推荐将资源文件放到Web目录以避免不必要的发布资源过程,这就是之前的例子指定 +[[yii\web\AssetBundle::basePath|basePath]] 而不是 [[yii\web\AssetBundle::sourcePath|sourcePath]]. + +对于 [扩展](structure-extensions.md)来说,由于它们的资源和源代码都在不能Web访问的目录下, +在定义资源包类时必须指定[[yii\web\AssetBundle::sourcePath|sourcePath]]属性。 + +> 注意: [[yii\web\AssetBundle::sourcePath|source path]] 属性不要用`@webroot/assets`,该路径默认为 + [[yii\web\AssetManager|asset manager]]资源管理器将源资源发布后存储资源的路径,该路径的所有内容会认为是临时文件, + 可能会被删除。 + + +### 资源依赖 + +当Web页面包含多个CSS或JavaScript文件时,它们有一定的先后顺序以避免属性覆盖, +例如,Web页面在使用jQuery UI小部件前必须确保jQuery JavaScript文件已经被包含了, +我们称这种资源先后次序称为资源依赖。 + +资源依赖主要通过[[yii\web\AssetBundle::depends]] 属性来指定, +在`AppAsset` 示例中,资源包依赖其他两个资源包: [[yii\web\YiiAsset]] 和 [[yii\bootstrap\BootstrapAsset]] +也就是该资源包的CSS和JavaScript文件要在这两个依赖包的文件包含 *之后* 才包含。 + +资源依赖关系是可传递,也就是人说A依赖B,B依赖C,那么A也依赖C。 + + +### 资源选项 + +可指定[[yii\web\AssetBundle::cssOptions|cssOptions]] 和 [[yii\web\AssetBundle::jsOptions|jsOptions]] +属性来自定义页面包含CSS和JavaScript文件的方式, +这些属性值会分别传递给 [[yii\web\View::registerCssFile()]] 和 [[yii\web\View::registerJsFile()]] 方法, +在[视图](structure-views.md) 调用这些方法包含CSS和JavaScript文件时。 + +> 注意: 在资源包类中设置的选项会应用到该包中 *每个* CSS/JavaScript 文件,如果想对每个文件使用不同的选项, + 应创建不同的资源包并在每个包中使用一个选项集。 + +例如,只想IE9或更高的浏览器包含一个CSS文件,可以使用如下选项: + +```php +public $cssOptions = ['condition' => 'lte IE9']; +``` + +这会是包中的CSS文件使用以下HTML标签包含进来: + +```html + +``` + +为链接标签包含`