diff --git a/000-packages.md b/000-packages.md index 92e1d0f1..0701190e 100644 --- a/000-packages.md +++ b/000-packages.md @@ -1,4 +1,4 @@ -# 000 - Packages +# 000 — Packages Yii3 team divided the framework into several packages that conform to the following agreements. diff --git a/001-yii-values.md b/001-yii-values.md index c3d14421..cf0b2b57 100644 --- a/001-yii-values.md +++ b/001-yii-values.md @@ -1,4 +1,4 @@ -# 001 - Yii goal and values +# 001 — Yii goal and values ## Goal diff --git a/002-issue-workflow.md b/002-issue-workflow.md index cbbf3652..1eedfe9a 100644 --- a/002-issue-workflow.md +++ b/002-issue-workflow.md @@ -1,4 +1,4 @@ -# 002 - Issue workflow +# 002 — Issue workflow The process of handing incoming issues is the following: @@ -14,7 +14,7 @@ We've many roles: - Contributors - create code for pull requests. - Code reviewers - review pull requests. -A single person may take one or more roles in the issue resolving process. +A single person may take one or more roles in the issue-resolving process. ## Labels diff --git a/003-roadmap.md b/003-roadmap.md index b58dc4b1..8c9f6667 100644 --- a/003-roadmap.md +++ b/003-roadmap.md @@ -1,15 +1,15 @@ -# 003 - Roadmap +# 003 — Roadmap We want Yii 3 to: -- Not limit a developer in choosing architecture. Allow anything from "classic" MVC to DDD. -- Be based on best practices such as SOLID, GRASP etc. and teach them to community. +- Not limit a developer to choosing architecture. Allow anything from "classic" MVC to DDD. +- Be based on the best practices such as SOLID, GRASP, etc. and teach them to the community. - Keep the most good things from Yii 2. - Be more open to the global PHP community and infrastructure. ## PSRs compliance -PSR compliance helps with customizability, ability to use general PHP libraries and implement fewer wrappers. +PSR compliance helps with customizability, the ability to use general PHP libraries and implement fewer wrappers. Here's the list of PSRs we want to implement. ### PSR-3 Logger @@ -118,7 +118,7 @@ Implemented as a [separate package that isn't dependent on a framework](https:// - [x] Separate web and console application - [x] Possibly eliminate base application (still needed) -- [x] Create interface for console (using Symfony one) +- [x] Create an interface for the console (using Symfony one) - [x] Implementation may be one of the popular ones (using Symfony one) - [x] Ensure application can add commands via config diff --git a/004-namespaces.md b/004-namespaces.md index a49e7c6c..df360b67 100644 --- a/004-namespaces.md +++ b/004-namespaces.md @@ -1,4 +1,4 @@ -# 004 - Namespaces +# 004 — Namespaces Package namespace rules are the following: @@ -10,12 +10,12 @@ Package namespace rules are the following: Some examples: -| Package | Namespace -|----------------------------|----------------- -| yiisoft/yii-web | Yiisoft\Yii\Web -| yiisoft/di | Yiisoft\Di -| yiisoft/db-mysql | Yiisoft\Db\Mysql -| yiisoft/friendly-exception | Yiisoft\FriendlyException +| Package | Namespace | +|----------------------------|---------------------------| +| yiisoft/yii-web | Yiisoft\Yii\Web | +| yiisoft/di | Yiisoft\Di | +| yiisoft/db-mysql | Yiisoft\Db\Mysql | +| yiisoft/friendly-exception | Yiisoft\FriendlyException | ## References diff --git a/005-development-tool.md b/005-development-tool.md index 0e88de46..7e9876d7 100644 --- a/005-development-tool.md +++ b/005-development-tool.md @@ -1,7 +1,7 @@ -# 005 - Yii development tool +# 005 — Yii development tool -For Yii 3 the number of packages increased significantly to achieve more reusability and independent releases. -To ease development of the framework itself we've created a special tool available from [yiisoft/yii-dev-tool](https://github.com/yiisoft/yii-dev-tool). +For Yii3, the number of packages increased significantly to achieve more reusability and independent releases. +To ease development of the framework itself, we've created a special tool available from [yiisoft/yii-dev-tool](https://github.com/yiisoft/yii-dev-tool). ``` $ ./yii-dev @@ -36,9 +36,9 @@ There are many commands available. The most important ones are `install` and `up 1. Install/update all packages listed in [`packages.php`](https://github.com/yiisoft/yii-dev-tool/blob/master/packages.php) or individual package from that list if specified. 2. For every package installed check `vendor` directory for packages listed in `packages.php`. - If there is any, replace package directory with a symlink to another package source. + If there is any, replace the package directory with a symlink to another package source. -As a result you will have many packages using each other, so there is no need to `git push` and `composer install` / `composer update` +As a result, you will have many packages using each other, so there is no need to `git push` and `composer install` / `composer update` during development. A [detailed example](https://github.com/yiisoft/yii-dev-tool#usage-example) of using the tool is available in its README. diff --git a/006-git-commit-messages.md b/006-git-commit-messages.md index ba1b2c42..aba7c934 100644 --- a/006-git-commit-messages.md +++ b/006-git-commit-messages.md @@ -1,17 +1,17 @@ -# 006 - Git commit messages +# 006 — Git commit messages ## Subject line - Use `#123` to reference issue by number - Use imperative mood that's `Fix`, not `Fixed` -- Don't add period at the end +- Don't add a period at the end - Use `[skip ci]` if there is no need to run unit tests - Start with a capital letter - Limit to 50 characters ## Body -Use message body **if** you need an extra explanation. Explain why, not how. +Use the message body **if** you need an extra explanation. Explain why, not how. - Limit line length to 72 characters diff --git a/007-exceptions.md b/007-exceptions.md index bc15a809..b33a0ffa 100644 --- a/007-exceptions.md +++ b/007-exceptions.md @@ -1,4 +1,4 @@ -# 007 - Exceptions +# 007 — Exceptions - Throw exceptions instead of returning an error code. - Exception class name must be suffixed with `Exception`. diff --git a/008-interfaces.md b/008-interfaces.md index 004d5e11..139ef481 100644 --- a/008-interfaces.md +++ b/008-interfaces.md @@ -1,4 +1,4 @@ -# 008 - Interfaces +# 008 — Interfaces - Interface name should be suffixed with `Interface`. diff --git a/009-design-decisions.md b/009-design-decisions.md index cb7ceaae..b2eadc31 100644 --- a/009-design-decisions.md +++ b/009-design-decisions.md @@ -1,21 +1,21 @@ -# 009 - Design Decisions +# 009 — Design Decisions -In this document we list important design decisions taken during Yii 3 development. +In this document, we list important design decisions taken during Yii3 development. ## Remove magic properties -Magic properties in Yii 2 were an interesting idea that allowed developer to start with -public property and then seamlessly migrate to getter/setter called via magic +Magic properties in Yii 2 were an interesting idea that allowed a developer to start with +public property and then seamlessly migrate to using getter/setter called via magic methods without changing the code. The main reason for removal in Yii 3 is that it resulted in using public properties everywhere, thus lack of encapsulation and code fragility. -## Remove service locator +## Remove the service locator Service locator both Yii 1 and Yii 2 was convenient but was also abused a lot. -Despite dependency injection container was available in Yii 2, service locator -was generally preferred causing both dependency on the service locator itself, +Although a dependency injection container was available in Yii 2, service locator +was generally preferred to cause both a dependency on the service locator itself, high coupling, hard to test code. Yii 3 relies on dependency injection only lowering coupling significantly and @@ -24,12 +24,12 @@ making code way more testable. ## Extract general packages Yii 1 and Yii 2 were fully closed communities. All the code we had wasn't useful -outside of Yii, and most of the "external" code wasn't useful in Yii without +outside Yii, and most of the "external" code wasn't useful in Yii without wrappers. It was noted many times by communities external to Yii that many parts of Yii are well-designed and unique, and they'd use these if these were available as standalone packages. -As part of Yii 3 packages such as cache, RBAC, view etc. were extracted into +As part of Yii 3 packages such as cache, RBAC, view, etc. were extracted into framework-independent packages. Benefits are: - Increased usage and contribution @@ -38,24 +38,24 @@ framework-independent packages. Benefits are: ## Adopt PSRs -The team adopted some PSRs in Yii 2 such as PSR-4 and PSR-2. -Interfaces in general weren't although Yii is part of PHP-FIG. +The team adopted some PSRs in Yii 2, such as PSR-4 and PSR-2. +Interfaces in general weren't, although Yii is part of PHP-FIG. Mainly because when Yii 2 was released, these were either in the making or not adopted enough. -Yii 3 benefits from PSRs since there are nowadays many ready to use libraries -that one can get via Composer: cache backends, middleware, loggers, DI containers +Yii3 benefits from PSRs since there are nowadays many ready-to-use libraries +that one can get via Composer: cache backends, middleware, loggers, DI containers, etc. -By implementing PSRs in general packages we allow these to be used in more +By implementing PSRs in general packages, we allow these to be used in more projects, thus raising the contribution level. ## Improve DI container -The problem with Yii 2 container was that it's tailored to be used with Yii 2 +The problem with the Yii 2 container was that it's tailored to be used with Yii 2 components. API isn't well-designed to be used with general PHP classes. -In Yii 3 we ensured that container can be used to conveniently configure any +In Yii3, we ensured that container can be used to conveniently configure any PHP class. That should result in the absence of Yii-specific wrapper packages and more direct @@ -75,12 +75,12 @@ Yii 2 has its own version policy. Problems: - It wasn't standard - Composer relies on SemVer -- It's hard to support a framework built on top of packages if versioning policy +- It's hard to support a framework built on top of packages if the versioning policy isn't strict ## Prevent validators mutating data -In Yii 1 and Yii 2 validators such as "date" were mutating data. -It was confusing for a validation process that wasn't initially meant to mutate data it validates. +In Yii 1 and Yii 2, validators such as "date" were mutating data. +It was confusing for a validation process not initially meant to mutate data it validates. [See related discussion](https://forum.yiiframework.com/t/saving-or-killing-non-validation-in-validators/126086). diff --git a/010-code-style.md b/010-code-style.md index 1fa55909..f86310fd 100644 --- a/010-code-style.md +++ b/010-code-style.md @@ -1,4 +1,4 @@ -# 010 - Code Style +# 010 — Code style Code formatting used in Yii 3 packages is based on [PSR-1](https://www.php-fig.org/psr/psr-1/) and [PSR-12](https://www.php-fig.org/psr/psr-12/) with extra rules added on top of it. @@ -8,7 +8,7 @@ Code formatting used in Yii 3 packages is based on [PSR-1](https://www.php-fig.o - Use English only. - Use camelCase notation, including abbreviations (e.g., `enableIdn`). - Use the shortest possible, but an explanatory name. -- Never trim or abbreviate name. +- Never trim or abbreviate a name. - Postfix classes, interfaces, traits and variables, which is a [collection](https://en.wikipedia.org/wiki/Collection_(abstract_data_type)), with `Collection`. ## Types @@ -148,7 +148,7 @@ should be two methods instead of one. public function login(bool $refreshPage = true): void; ``` -Is better to be two methods: +It is better to be two methods: ```php public function login(): void; diff --git a/011-error-correction.md b/011-error-correction.md index 743ab226..58da6fb8 100644 --- a/011-error-correction.md +++ b/011-error-correction.md @@ -1,4 +1,4 @@ -# 011 - Error correction +# 011 — Error correction -If it's unambiguous within a class what developer who incorrectly used the class meant, it's OK to correct the error. -Otherwise, error MUST NOT be corrected. +If it's unambiguous within a class what the developer who incorrectly used the class meant, it's OK to correct the error. +Otherwise, the error MUST NOT be corrected. diff --git a/012-tests.md b/012-tests.md index 95df5735..2ceb4e74 100644 --- a/012-tests.md +++ b/012-tests.md @@ -1,15 +1,14 @@ -# 012 - Tests +# 012 — Tests -For each package we're adding unit-tests that are run via [PHPUnit](https://phpunit.de/). +For each package, we're adding unit-tests that are run via [PHPUnit](https://phpunit.de/). When designing tests, the following guidelines should be taken into account. - Test class should be marked as `final` by default. - `@test` annotation must not be used, prefix methods with `test`. - The test method name must reflect the purpose of the test. -- "should" must not be used in test method name. +- "should" must not be used in the test method name. - If necessary, the test method phpdoc may describe the desired behavior. -- The test must be structured as AAA - arrange, act, assert that's first we're preparing what's necessary then making calls - then asserting everything is correct. +- The test must follow AAA: first arrange the necessary preconditions, then act, then assert expected results. - There must be one test case per test method that's a single AAA. - Test must use public API. Private properties or methods shouldn't be accessed, assumptions on internals diff --git a/013-code-review.md b/013-code-review.md index 7b533046..8932e1b4 100644 --- a/013-code-review.md +++ b/013-code-review.md @@ -1,8 +1,8 @@ -# 013 - Code Review +# 013 — Code review Code reviews are essential for the success of the project and are as important as contributing code. -Reviews are handled via GitHub pull requests. When the request is ready for review "status: code review" label +Reviews are handled via GitHub pull requests. When the request is ready for review, the "status: code review" label is added to it. [A full list of pull requests that need review](https://github.com/search?q=org%3Ayiisoft+label%3A"status%3Acode+review"&state=open&type=Issues) @@ -10,14 +10,14 @@ is available at GitHub. ## Guidelines -- Check out pull request branch, open project in IDE, get a big picture. -- Does pull request make sense overall? +- Check out the pull request branch, open the project in the IDE, get a big picture. +- Does the pull request make sense overall? - Run tests and/or application using code from the pull request. Are these OK? - Read all lines of code in the pull request. - Could it be done simpler? - Are there security issues? - Are there performance issues? -- When leaving comments be polite. +- When leaving comments, be polite. - Avoid code-formatting comments. ## Mandatory parts diff --git a/014-docs.md b/014-docs.md index 2b14741d..be7c5634 100644 --- a/014-docs.md +++ b/014-docs.md @@ -1,4 +1,4 @@ -# 014 - Documentation +# 014 — Documentation Documentation is one of the most important parts of Yii. @@ -30,7 +30,7 @@ Blocks use the Markdown `> Type: `. There are four block types: * `Warning`, for bad security things and other problems * `Note`, to emphasize key concepts, things to avoid * `Info`, general information (an aside); not as strong as a "Note" -* `Tip`, pro tips, extras, can be useful but may not be needed by everyone all the time +* `Tip`, pro tips, extras. It can be useful but may not be needed by everyone all the time The sentence after the colon should begin with a capital letter. @@ -96,8 +96,8 @@ Each package readme should be placed into `README.md` and contain the following: - [ ] Screenshot (if applicable). - [ ] Requirements. - [ ] Installation. Usually `composer require`. -- [ ] Getting started. One or two common usage examples demonstrated. +- [ ] Getting started. One or two common usage examples are demonstrated. - [ ] Configuration. -- [ ] Contributing. Should contain a link to guidelines. +- [ ] Contributing. It should contain a link to guidelines. - [ ] Running tests. - [ ] License. diff --git a/015-phpstorm.md b/015-phpstorm.md index da19659a..11b63c36 100644 --- a/015-phpstorm.md +++ b/015-phpstorm.md @@ -1,8 +1,8 @@ -# 015 - PhpStorm metadata and attributes +# 015 — PhpStorm metadata and attributes ## PhpStorm metadata -[PhpStorm metadata](https://www.jetbrains.com/help/phpstorm/ide-advanced-metadata.html) helps IDE to understand +[PhpStorm metadata](https://www.jetbrains.com/help/phpstorm/ide-advanced-metadata.html) helps the IDE to understand code better in cases when regular types and PHPDoc tags don't help. We use the following set of coding styles for metadata. diff --git a/016-security-workflow.md b/016-security-workflow.md index 048032a3..cfde7680 100644 --- a/016-security-workflow.md +++ b/016-security-workflow.md @@ -1,8 +1,8 @@ -# 016 - Security workflow +# 016 — Security workflow Security issues are typically sent via [a security form](https://www.yiiframework.com/security). -If an issue is reported directly to a public page such as repository issue or a forum topic, get the message +If an issue is reported directly to a public page such as a repository issue or a forum topic, get the message and delete the issue. Say thanks to the reporter and point to the security form for next time. ## Verify @@ -11,7 +11,7 @@ Verify that the issue is valid. Request more information if needed. ## Add security advisory -Create draft GitHub security advisory. +Create a draft GitHub security advisory. ### Find out severity @@ -20,7 +20,7 @@ Create draft GitHub security advisory. ### Give credit to the reporter -Ask reporter if he wants a credit for finding the issue. If so, point to his GitHub account. +Ask the reporter if he wants a credit for finding the issue. If so, point to his GitHub account. ## Request a CVE number @@ -30,13 +30,13 @@ When you're ready, request a CVE. Prepare a pull request fixing the issue. GitHub allows doing it in a private fork. -## Wait till CVE number is allocated +## Wait till the CVE number is allocated It usually takes several days. ## Release -- Merge the patch pull request right before tagging next package release. +- Merge the patch pull request right before tagging the next package release. - Publish security advisory. - Add CVE to [FriendsOfPHP/security-advisories](https://github.com/FriendsOfPHP/security-advisories). See [#488](https://github.com/FriendsOfPHP/security-advisories/pull/488) as example. diff --git a/017-tags.md b/017-tags.md index 219eebf1..cfdedd57 100644 --- a/017-tags.md +++ b/017-tags.md @@ -1,19 +1,19 @@ # 017 - Tags -Unlike regular classes, tags are used in view templates so syntax is important. +Unlike regular classes, tags are used in view templates, so syntax is important. It should be both easy to write, easy to read and not too verbose because similar constructs are meant to be used over and over again. ## Class names - Tags aren't postfixed or prefixed unless it's an abstract base class. -- If the tag represents a specification, use a name that's used in the specification. +- If the tag represents a specification, use a name used in the specification. ## Inheritance Inheritance is allowed with some restrictions: -- If class isn't abstract, it should be final. +- If a class isn't abstract, it should be final. - Hierarchy should be kept as linear as possible. ## Immutability @@ -21,17 +21,17 @@ Inheritance is allowed with some restrictions: Tags should: - Have no state. -- Be immutable. Every method which modifies a setting, returns a clone with the setting changed. +- Be immutable. Every method that modifies a setting returns a clone with the setting changed. - Be free of side effects. Many calls of the same method with the same argument should give the same result. ## Methods ### Names -- Unlike other classes, methods that return a clone of the object with some properties modified, aren't prefixed. +- Unlike other classes, methods that return a clone of the object with some properties modified aren't prefixed. - Keep method names as short as possible but don't hurt readability. -- If the tag represents a specification, use a name that's used in the specification. +- If the tag represents a specification, use a name used in the specification. ### Boolean flags -The Method that corresponds to boolean attribute should be named after the attribute and accept a boolean flag argument. +The method that corresponds to the boolean attribute should be named after the attribute and accept a boolean flag argument. diff --git a/018-widgets.md b/018-widgets.md index 9459bdb0..c801f1d1 100644 --- a/018-widgets.md +++ b/018-widgets.md @@ -12,7 +12,7 @@ Widgets aren't postfixed or prefixed. Inheritance is allowed with some restrictions: -- If class isn't abstract, it should be final. +- If a class isn't abstract, it should be final. - Hierarchy should be kept as linear as possible. ## Immutability @@ -26,9 +26,9 @@ Widgets should: ### Names -- Unlike other classes, methods that return a clone of the object with some properties modified, aren't prefixed. +- Unlike other classes, methods that return a clone of the object with some properties modified aren't prefixed. - Keep method names as short as possible but don't hurt readability. ### Boolean flags -The Method that corresponds to boolean attribute should be named after the attribute and accept a boolean flag argument. +The method that corresponds to the boolean attribute should be named after the attribute and accept a boolean flag argument. diff --git a/019-view-code-style.md b/019-view-code-style.md index 3c75c190..db9dd126 100644 --- a/019-view-code-style.md +++ b/019-view-code-style.md @@ -1,4 +1,4 @@ -# 019 - View code style +# 019 — View code style The PHP code in the view files shouldn't be complicated. The code must contain the logic responsible for formatting the data, but not the logic for requesting this data. diff --git a/020-package-release.md b/020-package-release.md index a4ef8eae..ee41c781 100644 --- a/020-package-release.md +++ b/020-package-release.md @@ -1,11 +1,11 @@ -# 020 - Package Release +# 020 — Package release ## Criteria - No critical issues. - Public API changes aren't likely. Some time passed w/o issues reported that may require API changes. - All dependencies are stable. -- Close to 100% test coverage with, ideally, 100% MSI score. +- Close to 100% test coverage with, ideally, a 100% MSI score. - README is alright. - Everything is type-hinted unless special cases. - Psalm analysis passes on at least level 2. @@ -34,8 +34,8 @@ Release a package via [Yii Development Tool](005-development-tool.md). ./yii-dev release/make package-name ``` -5. Select version type (major, minor or path). +5. Select the version type (major, minor or path). -6. On the question "Push commits and tags, and release on GitHub?" check a diff. If the diff is alright, answer "yes". +6. On the question "Push commits and tags, and release on GitHub?" check a diff. If the diff is alright, answer "yes." -7. For major and minor releases add a record with release notes on [Yii Framework News](https://www.yiiframework.com/news). +7. For major and minor releases, add a record with release notes on [Yii Framework News](https://www.yiiframework.com/news). diff --git a/021-changelog-upgrade.md b/021-changelog-upgrade.md index 4afee42f..51280769 100644 --- a/021-changelog-upgrade.md +++ b/021-changelog-upgrade.md @@ -1,4 +1,4 @@ -# 021 - Changelog and upgrade +# 021 — Changelog and upgrade For all released packages, we've a detailed changelog and upgrade guide. @@ -23,19 +23,19 @@ Changelog is written for each version released. The file name is `CHANGELOG.md`. ``` There "My package" is the name of the package, `1.0.1` is the version released followed by release date. -For each version there are a number of lines listing the changes. +For each version, there are a number of lines listing the changes. "Bug" refers to a change type. The following types are used: -- New - New features. -- Chg - General changes. -- Enh - Existing feature enhancements. -- Bug - Bug fixes. +- New — New features. +- Chg — General changes. +- Enh — Existing feature enhancements. +- Bug — Bug fixes. In the changelog file lines should be ordered as New, Chg, Enh, Bug. -"#42" above is the number of issue or pull request corresponding to the change. "author1" is the GitHub nickname of the -code author. "author2" is additional author. An author's nickname MUST be prefixed with `@`. +"#42" above is the number of issue or pull requests corresponding to the change. "author1" is the GitHub nickname of the +code author. "author2" is an additional author. An author's nickname MUST be prefixed with `@`. ## Upgrade @@ -52,7 +52,7 @@ application when you upgrade the package from one version to another. > **Important!** The following upgrading instructions are cumulative. That is, if you want > to upgrade from version A to version C and there is version B between A and C, you need -> to following the instructions for both A and B. +> to follow the instructions for both A and B. ## Upgrade from 2.x diff --git a/022-config-groups.md b/022-config-groups.md index 27aa4fde..62719b8d 100644 --- a/022-config-groups.md +++ b/022-config-groups.md @@ -1,12 +1,12 @@ -# 022 - Config groups +# 022 — Config groups This document defines naming convention for the framework groups used with [yiisoft/config](https://github.com/yiisoft/config). -Note that this isn't naming convention for config files. -These are could be anything and are mapped to group names via `composer.json`. +Note that this isn't a naming convention for config files. +These could be anything and are mapped to group names via `composer.json`. ## Config group name postfixes -- "web" postfix applies to web only that's classic server HTML generation, REST, RPC etc. +- "web" postfix applies to web only that's classic server HTML generation, REST, RPC, etc. - "console" postfix applies to console - If there's no postfix, it's "common" and applies to both web and console - "web" and "console" may override what's defined in "common" diff --git a/README.md b/README.md index 9ad298ea..6d117d58 100644 --- a/README.md +++ b/README.md @@ -8,26 +8,26 @@ # Internals -- [000 - Packages](000-packages.md) -- [001 - Yii goals and values](001-yii-values.md) -- [002 - Issue workflow](002-issue-workflow.md) -- [003 - Roadmap](003-roadmap.md) -- [004 - Namespaces](004-namespaces.md) -- [005 - Development tool](005-development-tool.md) -- [006 - Git commit messages](006-git-commit-messages.md) -- [007 - Exceptions](007-exceptions.md) -- [008 - Interfaces](008-interfaces.md) -- [009 - Design decisions](009-design-decisions.md) -- [010 - Code style](010-code-style.md) -- [011 - Error correction](011-error-correction.md) -- [012 - Tests](012-tests.md) -- [013 - Code review](013-code-review.md) -- [014 - Documentation](014-docs.md) -- [015 - PhpStorm metadata and attributes](015-phpstorm.md) -- [016 - Security workflow](016-security-workflow.md) -- [017 - Tags](017-tags.md) -- [018 - Widgets](018-widgets.md) -- [019 - View code style](019-view-code-style.md) -- [020 - Package release](020-package-release.md) -- [021 - Changelog and upgrade](021-changelog-upgrade.md) -- [022 - Config groups](022-config-groups.md) +- [000 — Packages](000-packages.md) +- [001 — Yii goals and values](001-yii-values.md) +- [002 — Issue workflow](002-issue-workflow.md) +- [003 — Roadmap](003-roadmap.md) +- [004 — Namespaces](004-namespaces.md) +- [005 — Development tool](005-development-tool.md) +- [006 — Git commit messages](006-git-commit-messages.md) +- [007 — Exceptions](007-exceptions.md) +- [008 — Interfaces](008-interfaces.md) +- [009 — Design decisions](009-design-decisions.md) +- [010 — Code style](010-code-style.md) +- [011 — Error correction](011-error-correction.md) +- [012 — Tests](012-tests.md) +- [013 — Code review](013-code-review.md) +- [014 — Documentation](014-docs.md) +- [015 — PhpStorm metadata and attributes](015-phpstorm.md) +- [016 — Security workflow](016-security-workflow.md) +- [017 — Tags](017-tags.md) +- [018 — Widgets](018-widgets.md) +- [019 — View code style](019-view-code-style.md) +- [020 — Package release](020-package-release.md) +- [021 — Changelog and upgrade](021-changelog-upgrade.md) +- [022 — Config groups](022-config-groups.md) diff --git a/cookbook/en/README.md b/cookbook/en/README.md index 5864c954..3620b5de 100644 --- a/cookbook/en/README.md +++ b/cookbook/en/README.md @@ -6,7 +6,7 @@ PHP framework. - The Yii community creates the cookbook. - Yii core team members curate and edit it. -Feel free to pull request your own writings. Team members will review it, give feedback and merge the best possible way. +Feel free to pull-request your own writings. Team members will review it, give feedback and merge the best possible way. This book conforms to the [Terms of Yii Documentation](https://www.yiiframework.com/license#docs). diff --git a/cookbook/en/organizing-code/structuring-by-use-case-with-vertical-slices.md b/cookbook/en/organizing-code/structuring-by-use-case-with-vertical-slices.md index b9ece33a..068a720d 100644 --- a/cookbook/en/organizing-code/structuring-by-use-case-with-vertical-slices.md +++ b/cookbook/en/organizing-code/structuring-by-use-case-with-vertical-slices.md @@ -7,11 +7,11 @@ Vertical slices are self-contained pieces of functionality that cover the entire the data access layer. Developer organizes each slice around a specific use case, such as creating a new user or updating a product. -When structuring code classically by type (such as models, views, controllers, helpers, etc,.), it can be easy to lose +When structuring code classically by type (such as models, views, controllers, helpers, etc.), it can be easy to lose sight of the bigger picture and how different pieces of code interact to support specific features or use cases. This can lead to code duplication, tight coupling, and poor maintainability as the application grows. -On the other hand, structuring code by use-case makes developers to focus on a specific feature or workflow and +On the other hand, structuring code by use-case makes developers focus on a specific feature or workflow and understand how different pieces of code work together to support that feature. This approach also helps to keep related code together in a single directory, making it easier to navigate and support. Vertical slicing also encourages the use of domain-driven design concepts, such as entities, repositories, and services, which can help to promote diff --git a/cookbook/en/preface.md b/cookbook/en/preface.md index f18c2f45..8708fce2 100644 --- a/cookbook/en/preface.md +++ b/cookbook/en/preface.md @@ -11,13 +11,13 @@ it's especially suitable for developing large-scale applications such as portals e-commerce, REST APIs, etc. Together with a comprehensive set of documentation and an enthusiastic user community, Yii can reduce your development -time in a long run significantly compared with other frameworks. +time in the long run significantly compared with other frameworks. ## What's the book about This book is for you if you're familiar with Yii3, building Yii applications, and read the official Yii3 guide. It covers fundamentally important development concepts, application architecture approaches, integrating third party -services with Yii3 etc. +services with Yii3, etc. The book consists of individual recipes gathered from Yii experts that you can apply in your applications. These go by topic, but you are free to read them in any order as there is no dependency between them. diff --git a/guide/en/README.md b/guide/en/README.md index ef87f248..eef368ba 100644 --- a/guide/en/README.md +++ b/guide/en/README.md @@ -12,7 +12,7 @@ Introduction + Getting started - --------------- -* [What do you need to know](start/prerequisites.md) + +* [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) + diff --git a/guide/en/caching/data.md b/guide/en/caching/data.md index 759b9be8..89297d7b 100644 --- a/guide/en/caching/data.md +++ b/guide/en/caching/data.md @@ -1,6 +1,6 @@ # Data caching -Data caching is about storing some PHP variables in cache and retrieving it later from cache. +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). To use cache, install [yiisoft/cache](https://github.com/yiisoft/cache) package: @@ -19,7 +19,7 @@ public function getTopProducts(\Yiisoft\Cache\CacheInterface $cache): array // Try retrieving $data from cache. $data = $cache->getOrSet($key, function (\Psr\SimpleCache\CacheInterface $cache) use ($count) { - // $data isn't found in cache, calculate it from scratch. + // $data isn't found in the cache, calculate it from scratch. return getTopProductsFromDatabase($count); }, 3600); @@ -35,26 +35,26 @@ If the anonymous function requires some data from the outer scope, you can pass ## 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, databases. +cache storages, such as memory, files, and databases. Yii provides the following handlers: -- `NullCache` - serves as a cache placeholder which does no real caching. The purpose of this handler is to simplify +- `NullCache` — serves as 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. +- `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 chunk of data, such as page content. -- [Memcached](https://github.com/yiisoft/cache-memcached) - uses a PHP [memcached](https://secure.php.net/manual/en/book.memcached.php) +- [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 [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 distributed application (e.g., with several servers, load balancers, etc.) -- [Wincache](https://github.com/yiisoft/cache-wincache) - ses PHP [WinCache](https://iis.net/downloads/microsoft/wincache-extension) +- [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. [You could find more handlers at packagist.org](https://packagist.org/providers/psr/simple-cache-implementation). @@ -71,8 +71,8 @@ with a different one. You can do it by reconfiguring the application without mod ### Cache keys -A key uniquely identifies each data item stored in cache. When you store a data item in cache, -you have to specify a key for it. Later, when you retrieve the data item from cache, you should give +A key uniquely identifies each data item stored in a cache. When you store a data item in a cache, +you have to specify a key for it. Later, when you retrieve the data item from the cache, 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 @@ -106,7 +106,7 @@ The `$ttl` parameter indicates for how many seconds the data item can remain val the data item, if it has passed the expiration time, the method will execute the function and set the resulting value into cache. -You may set default TTL for the cache: +You may set the default TTL for the cache: ```php $cache = new \Yiisoft\Cache\Cache($arrayCache, 60 * 60); // 1 hour @@ -122,7 +122,7 @@ $cache->remove($key); 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 modifies the corresponding file. +When this dependency changes, it means something modifying the corresponding file. As a result, any outdated file content found in the cache should invalidate. Cache dependencies are objects of `\Yiisoft\Cache\Dependency\Dependency` descendant classes. When you @@ -155,7 +155,7 @@ Below is a summary of the available cache dependencies: 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`. +To implement your own dependency, extend from `\Yiisoft\Cache\Dependency\Dependency`. ### Cache stampede prevention diff --git a/guide/en/caching/overview.md b/guide/en/caching/overview.md index a9fe64f5..c999591b 100644 --- a/guide/en/caching/overview.md +++ b/guide/en/caching/overview.md @@ -1,8 +1,8 @@ # Caching -Caching is a cheap 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 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; diff --git a/guide/en/concept/aliases.md b/guide/en/concept/aliases.md index 769920ca..48b02a8e 100644 --- a/guide/en/concept/aliases.md +++ b/guide/en/concept/aliases.md @@ -23,7 +23,7 @@ return [ '@foo' => '/path/to/foo', // an alias of a URL - '@bar' => 'http://www.example.com', + '@bar' => 'https://www.example.com', // an alias of a concrete file that contains a \foo\Bar class '@foo/Bar.php' => '/definitely/not/foo/Bar.php', @@ -57,7 +57,7 @@ public function actionIndex(Aliases $aliases) ## Using aliases in configuration -It's preferred to resolve aliases at configuration level, so services get URLs and paths as ready to use strings: +It's preferred to resolve aliases at the configuration level, so services get URLs and paths as ready to use strings: ```php get('@foo'); // /path/to/foo - $bar = $aliases->get('@bar'); // http://www.example.com + $bar = $aliases->get('@bar'); // https://www.example.com $file = $aliases->get('@foo/bar/file.php'); // /path/to/foo/bar/file.php } ``` diff --git a/guide/en/concept/autoloading.md b/guide/en/concept/autoloading.md index 9d0fdbe0..e89ee406 100644 --- a/guide/en/concept/autoloading.md +++ b/guide/en/concept/autoloading.md @@ -22,7 +22,7 @@ Where `App\\` is a root namespace and `src/` is a directory where you have your needed. When done, execute `composer dump-autoload` or simply `composer du` and classes from the corresponding namespaces will start loading automatically. -If you need development environment specific autoloading that isn't used when executing Composer with `--no-dev` flag, +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`. ## References diff --git a/guide/en/concept/configuration.md b/guide/en/concept/configuration.md index 5fbbaf9a..23d38566 100644 --- a/guide/en/concept/configuration.md +++ b/guide/en/concept/configuration.md @@ -15,7 +15,7 @@ copying these into the application. 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 together into a single big array +`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). Take a look at what's in the "yiisoft/app" `composer.json` by default: @@ -235,7 +235,7 @@ return [ // Just a regular closure, it will be called from the Dispatcher "as is". static fn (EventName $event) => someStuff($event), - // A regular closure with extra dependency. All the parameters after the first one (the event itself) + // A regular closure with an extra dependency. All the parameters after the first one (the event itself) // will be resolved from your DI container within `yiisoft/injector`. static fn (EventName $event, DependencyClass $dependency) => someStuff($event), @@ -335,7 +335,7 @@ For convenience, there is a naming convention about parameters: 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 together. +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. diff --git a/guide/en/concept/events.md b/guide/en/concept/events.md index c0ee4a74..828baafc 100644 --- a/guide/en/concept/events.md +++ b/guide/en/concept/events.md @@ -5,12 +5,12 @@ You can attach a custom code called "handler" to an event so that when the event 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 will additionally need to resize user's avatar image you'll have +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. 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 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`. @@ -51,7 +51,7 @@ class WelcomeEmailSender } ``` -The `attach()` method is accepting a callback. Based on a type of this callback argument event type is +The `attach()` method is accepting a callback. Based on the type of this callback argument, the event type is determined. ## Event handlers order diff --git a/guide/en/glossary.md b/guide/en/glossary.md index 75693547..989f348d 100644 --- a/guide/en/glossary.md +++ b/guide/en/glossary.md @@ -2,7 +2,7 @@ ## alias -Alias is a string that's used by Yii to refer to the class or directory such as `@app/vendor`. +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). ## asset @@ -27,7 +27,7 @@ Dependency Injection is a programming technique where an object injects a depend ## installation Installation is a process of preparing something to work either by following a readme file or by executing a specially -prepared script. In case of Yii, it's setting permissions and fulfilling software requirements. +prepared script. In the case of Yii, it's setting permissions and fulfilling software requirements. # M @@ -38,7 +38,7 @@ action and pass processing to the next middleware. Read more in ["Middleware"](s ## module -The module is a sub-application which groups some code based on use-case. It's typically used within the main application +The module is a sub-application that groups some code based on a use-case. It's typically used within the main application and may contain URL handlers or console commands. # N diff --git a/guide/en/intro/upgrade-from-v2.md b/guide/en/intro/upgrade-from-v2.md index 89c07bf1..28f68118 100644 --- a/guide/en/intro/upgrade-from-v2.md +++ b/guide/en/intro/upgrade-from-v2.md @@ -4,7 +4,7 @@ > section. While sharing some common ideas and values, Yii 3 is conceptually different from Yii 2. There is no easy upgrade -path, so first [check maintenance policy and end of life dates for Yii 2](https://www.yiiframework.com/release-cycle) +path, so first [check maintenance policy and end-of-life dates for Yii 2](https://www.yiiframework.com/release-cycle) and consider starting new projects on Yii 3 while keeping existing ones on Yii 2. ## PHP requirements @@ -24,7 +24,7 @@ Yii3 requires PHP 8.0 or above. As a result, there are language features used th It's a good idea to refactor your Yii 2 project before porting it to Yii 3. That would both make porting easier and benefit the project in question while it's not moved to Yii 3 yet. -### Use DI instead of service locator +### Use DI instead of the service locator Since Yii 3 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). @@ -37,7 +37,7 @@ See [Dependency injection and container](../concept/di-container.md) for an expl ### Introduce repositories for getting data Since Active Record isn't the only way to work with a database in Yii 3, consider introducing repositories that would -hide details of getting data and gather them in a single place you can later re-do: +hide details of getting data and gather them in a single place. You can later redo it: ```php class PostRepository @@ -57,7 +57,7 @@ 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 framework +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 diff --git a/guide/en/intro/what-is-yii.md b/guide/en/intro/what-is-yii.md index 5a247d4a..ab2b5d0d 100644 --- a/guide/en/intro/what-is-yii.md +++ b/guide/en/intro/what-is-yii.md @@ -12,7 +12,7 @@ Because of its architecture and sophisticated caching support, it's especially suitable for developing large-scale applications such as portals, content management systems, e-commerce, REST APIs, etc. -## How does Yii Compare with Other Frameworks +## How does Yii Compare with Other Frameworks? If you're already familiar with another framework, you may appreciate knowing how Yii compares: @@ -24,12 +24,11 @@ If you're already familiar with another framework, you may appreciate knowing ho - Explicitness. - Consistency. - Yii will never try to over-design things mainly for the purpose of following - some design patterns. + 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. + 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. @@ -43,10 +42,10 @@ found elsewhere are regularly incorporated into the core framework and exposed v ## Yii versions -Yii currently has three major versions available: 1.1, 2.0 and 3.0. +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 that's 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. @@ -55,6 +54,6 @@ Yii currently has three major versions available: 1.1, 2.0 and 3.0. Yii3 requires PHP 8.0 or above, but some packages also support 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 features of PHP, such as type declarations and generators. Understanding these +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. diff --git a/guide/en/runtime/cookies.md b/guide/en/runtime/cookies.md index dac658d5..4af37a24 100644 --- a/guide/en/runtime/cookies.md +++ b/guide/en/runtime/cookies.md @@ -1,7 +1,7 @@ # Cookies Cookies are for persisting data between requests by sending it to the client browser using HTTP headers. -The client sends data back to server in request headers thus cookies are handy to store small amounts of data, +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. ## Reading cookies @@ -17,8 +17,10 @@ private function actionProfile(\Psr\Http\Message\ServerRequestInterface $request } ``` -In addition to obtaining cookie values directly from the server request, you can also utilize 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. +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. Here’s an example of how to work with cookies using the `\Yiisoft\RequestProvider\RequestCookieProvider`: @@ -71,7 +73,7 @@ To prevent the substitution of the cookie value, the package provides two implem `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. -Encryption is more secure than signing, but has less performance. +Encryption is more secure than signing but has lower performance. ```php $cookie = new \Yiisoft\Cookies\Cookie('identity', 'identityValue'); @@ -168,7 +170,7 @@ $middleware = new \Yiisoft\Cookies\CookieMiddleware( ); // The cookie parameter values from the request are decrypted/validated. -// The cookie values are encrypted/signed, and appended to the response. +// The cookie values are encrypted/signed and appended to the response. $response = $middleware->process($request, $handler); ``` @@ -181,6 +183,6 @@ 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. + 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. diff --git a/guide/en/runtime/handling-errors.md b/guide/en/runtime/handling-errors.md index 9185aa1d..df56d450 100644 --- a/guide/en/runtime/handling-errors.md +++ b/guide/en/runtime/handling-errors.md @@ -8,11 +8,11 @@ a much more pleasant experience than before. In particular, the Yii error handle - 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. +- 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. -- Has ability to implement your own error rendering for extra types. +- 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). @@ -39,13 +39,13 @@ return [ // ... ErrorHandler::class => static function (LoggerInterface $logger, ThrowableRendererInterface $renderer) { $errorHandler = new ErrorHandler($logger, $renderer); - // Set the size of the reserved memory 512KB. Defaults to 256KB. + // Set the size of the reserved memory to 512 KB. Defaults to 256KB. $errorHandler->memoryReserveSize(524_288); return $errorHandler; }, ThrowableRendererInterface::class => static fn () => new HtmlRenderer([ - // Defaults to package file "templates/production.php". + // Defaults to the package file "templates/production.php". 'template' => '/full/path/to/production/template/file', // Defaults to package file "templates/development.php". 'verboseTemplate' => '/full/path/to/development/template/file', @@ -53,7 +53,7 @@ return [ 'maxSourceLines' => 20, // Maximum number of trace source code lines to be displayed. Defaults to 13. 'maxTraceLines' => 5, - // Trace header line with placeholders (file, line, icon) to be be substituted. Defaults to null. + // Trace the header line with placeholders (file, line, icon) to be substituted. Defaults to `null`. 'traceHeaderLine' => '{icon}', ]), // ... @@ -67,7 +67,7 @@ As aforementioned, the error handler turns all non-fatal PHP errors into catchab try { 10 / 0; } catch (\Yiisoft\ErrorHandler\Exception\ErrorException $e) { - // Write log or something else. + // Write a log or something else. } // execution continues... ``` @@ -180,7 +180,7 @@ Example of HTML rendering with debugging mode on and a dark theme: 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. +By default, it supports JSON, XML, and plain text. ### Implementing your own renderer @@ -237,7 +237,7 @@ return [ ## Friendly exceptions Yii error renderer supports [friendly exceptions](https://github.com/yiisoft/friendly-exception) that make -error handling even more pleasant experience for your team. The idea is to offer a readable name and possible +error handling an even more pleasant experience for your team. The idea is to offer a readable name and possible solutions to the problem: ```php @@ -260,4 +260,4 @@ SOLUTION; ``` When the application throws such an exception, -error renderer would display the name and the solution if the debug mode is on. +the error renderer would display the name and the solution if the debug mode is on. diff --git a/guide/en/runtime/logging.md b/guide/en/runtime/logging.md index 06bb83bf..c2cce7da 100644 --- a/guide/en/runtime/logging.md +++ b/guide/en/runtime/logging.md @@ -18,7 +18,7 @@ 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 dependency: +A class that writes log messages should receive it as a dependency: ```php class MyService @@ -32,7 +32,7 @@ class MyService } ``` -Recording log message is as simple as calling one of the following logging methods that correspond to log levels: +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. @@ -47,11 +47,11 @@ Recording log message is as simple as calling one of the following logging metho - `debug` - Detailed debug information. Each method has two arguments. -First is a message. +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 exception as context, you should pass in "exception" key. -Another special key is "category". Categories are handy to better organize and filter log messages. +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. ```php class MyService @@ -92,7 +92,7 @@ can assume that logger is always present. 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 an [[Yiisoft\Log\Target\Email\EmailTarget|email target]] exports the log messages to specified email addresses. +while a [[Yiisoft\Log\Target\Email\EmailTarget|email target]] exports the log messages to specified email addresses. You can register many log targets in an application by configuring them through the `\Yiisoft\Log\Logger` constructor: @@ -115,14 +115,14 @@ $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 +* 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`. 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. * [[\Yiisoft\Log\PsrTarget]]: passes log messages to another PSR-3 compatible logger. -* [[\Yiisoft\Log\StreamTarget]]: writes log messages into specified output stream. +* [[\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. @@ -133,7 +133,7 @@ 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, +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. @@ -237,7 +237,7 @@ 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 in the by the log target. +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. @@ -257,7 +257,7 @@ $logger = new \Yiisoft\Log\Logger($targets); $logger->setTraceLevel(3); ``` -This application configuration sets trace level to be 3 so each log message will be appended with at most 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 [[\Yiisoft\Log\Logger::setExcludedTracePaths()|setExcludedTracePaths()]] method. @@ -337,7 +337,7 @@ to define a dynamic condition for whether the log target should be enabled or no ### Creating New Targets -Creating a new log target class is simple. You mainly need to implement the [[\Yii\Log\Target::export()]] +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. The following protected methods will also be available for child targets: diff --git a/guide/en/runtime/request.md b/guide/en/runtime/request.md index e10bd499..3bd9ff20 100644 --- a/guide/en/runtime/request.md +++ b/guide/en/runtime/request.md @@ -17,7 +17,7 @@ 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 JSON payload. +In this case, it's a JSON payload. 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: @@ -31,7 +31,7 @@ public function view(ServerRequestInterface $request): ResponseInterface ## Method -The method could be obtained from request object: +The method could be obtained from a request object: ```php $method = $request->getMethod(); @@ -96,19 +96,19 @@ foreach ($headers as $name => $values) { } ``` -To obtain a single header: +To get a single header: ```php $values = $request->getHeader('Accept-Encoding'); ``` -Also, you could obtain value as a comma-separated string instead of an array. +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') { - // This is AJAX request made with jQuery. + // This is an AJAX request made with jQuery. // Note that header presence and name may vary depending on the library used. } ``` @@ -123,7 +123,7 @@ if ($request->hasHeader('Accept-Encoding')) { ## Body -There are two methods to obtain body contents. First is getting body as is without parsing: +There are two methods to get body contents. The first is getting the body as it is without parsing: ```php $body = $request->getBody(); @@ -131,7 +131,7 @@ $body = $request->getBody(); The `$body` would be an instance of `Psr\Http\Message\StreamInterface`. -Also, you could obtain a parsed body: +Also, you could get a parsed body: ```php $bodyParameters = $request->getParsedBody(); @@ -181,4 +181,4 @@ foreach ($files as $file) { ## Attributes Application middleware may set custom request attributes using `withAttribute()` method. -You can obtain these attributes with `getAttribute()`. +You can get these attributes with `getAttribute()`. diff --git a/guide/en/runtime/response.md b/guide/en/runtime/response.md index 21eacd5b..26636fe6 100644 --- a/guide/en/runtime/response.md +++ b/guide/en/runtime/response.md @@ -16,7 +16,7 @@ Hello! Yii uses [PSR-7 `Response`](https://www.php-fig.org/psr/psr-7/) in the web application to represent response. -The object should be constructed and returned as a result of execution of controller actions or other middleware. +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 @@ -44,7 +44,7 @@ class PostAction ## Status code -You can set status code like the following: +You can set a status code like the following: ```php use Yiisoft\Http\Status; @@ -62,7 +62,7 @@ You can set headers like this: $response = $response->withHeader('Content-type', 'application/json'); ``` -If there is a need to append a header value to existing header: +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'); diff --git a/guide/en/runtime/routing.md b/guide/en/runtime/routing.md index cdfdc445..56c3b311 100644 --- a/guide/en/runtime/routing.md +++ b/guide/en/runtime/routing.md @@ -1,8 +1,8 @@ # Routing and URL generation Usually, a Yii application processes certain requests with certain handlers. -It selects a handler based on request URL. -The part of the application that does the job is a router and the process of selecting a handler, instantiating it +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*. The reverse process of routing is *URL generation*, which creates a URL from a given named route @@ -33,7 +33,7 @@ return [ ]; ``` -File returns an array of routes. When defining a route, you start with a method corresponding to a certain +The file returns an array of routes. When defining a route, you start with a method corresponding to a certain HTTP request type: - get @@ -97,7 +97,7 @@ static function (ServerRequestInterface $request, RequestHandlerInterface $next) } ``` -For handler action and callable typed parameters are automatically injected using dependency +For handler action and callable typed parameters are automatically injected using the dependency injection container passed to the route. Current request and handler could be obtained by type-hinting for `ServerRequestInterface` and `RequestHandlerInterface`. @@ -152,7 +152,7 @@ return [ Router executes `ApiDataWrapper` before handling any URL starting with `/api`. -You could name a route with a `name()` method. It's a good idea to choose a route name based on handler's name. +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. You can set a default value for a route parameter. For example: @@ -187,7 +187,7 @@ The actual matching algorithm may vary, but the basic idea stays the same. Router matches routes defined in config from top to bottom. If there is a match, further matching isn't performed and -the router executes route handler to get the response. +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). @@ -239,9 +239,9 @@ class TestController extends AbstractController } ``` -In the above code we obtain generator instance with the help of [automatic dependency injection](../concept/di-container.md) +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 obtain the instance with similar constructor injection. +In another service, you can get the instance with similar constructor injection. In views URL generator is available as `$url`. Then we use `generate()` method to get actual URL. It accepts a route name and an array of named query parameters. @@ -250,7 +250,7 @@ The code will return "/test/submit/42". If you need absolute URL, use `generateA ## Route patterns Route patterns used depend on the underlying implementation used. -Default the implementation is [nikic/FastRoute](https://github.com/nikic/FastRoute). +The default implementation is [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. @@ -261,7 +261,7 @@ of `{ParamName:RegExp}`, where `ParamName` specifies the parameter name and `Reg expression used to match parameter values. If `RegExp` isn't specified, it means the parameter value should be a string without any slash. -> Note: You can only use regular expressions inside of parameters. The rest of a pattern is considered plain text. +> 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)}`. @@ -277,7 +277,7 @@ Let's use some examples to illustrate how named parameters work. Assume you've d 2. `'posts'` 3. `'post/{id:\d+}'` -- `/posts` match second pattern; +- `/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; @@ -297,7 +297,7 @@ 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. -For this case, you could specify default value: +In this case, you could specify the default value: ```php use \Yiisoft\Router\Route; diff --git a/guide/en/runtime/sessions.md b/guide/en/runtime/sessions.md index 47ed874b..7b83c03b 100644 --- a/guide/en/runtime/sessions.md +++ b/guide/en/runtime/sessions.md @@ -62,7 +62,7 @@ return [ ```php public function actionProfile(\Yiisoft\Session\SessionInterface $session) { - // start session if it's not yet started + // start a session if it's not yet started $session->open(); // work with session @@ -73,17 +73,17 @@ public function actionProfile(\Yiisoft\Session\SessionInterface $session) ``` > Note: Closing session as early as possible is a good practice since many session implementations are blocking other -> requests while session is open. +> requests while the session is open. -There are two more ways to close session: +There are two more ways to close a session: ```php public function actionProfile(\Yiisoft\Session\SessionInterface $session) { - // discard changes and close session + // discard changes and close the session $session->discard(); - // destroy session completely + // destroy the session completely $session->destroy(); } ``` @@ -104,7 +104,7 @@ public function actionProfile(\Yiisoft\Session\SessionInterface $session) // set a value $session->set('lastAccessTime', time()); - // check if value exists + // check if the value exists if ($session->has('lastAccessTime')) { // ... } @@ -122,9 +122,9 @@ 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 with displaying a message on the next page, +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. +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: diff --git a/guide/en/security/best-practices.md b/guide/en/security/best-practices.md index a24aa1ef..a7e80945 100644 --- a/guide/en/security/best-practices.md +++ b/guide/en/security/best-practices.md @@ -28,7 +28,7 @@ if (!in_array($sortBy, ['title', 'created_at', 'status'])) { } ``` -In Yii, most probably you'll use [form validation](../input/validation.md) to do alike checks. +In Yii, most probably you'll use [form validation](../input/validation.md) to do similar checks. Further reading on the topic: @@ -42,7 +42,7 @@ 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 for different contexts. +Since it's error-prone to escape manually, Yii provides various tools to perform escaping in different contexts. Further reading on the topic: @@ -71,7 +71,7 @@ This is a valid query that will search for users with empty username and then wi resulting in a broken website and data loss (you've set up regular backups, right?). Make sure to either use PDO prepared statements directly or ensure that the library you prefer is doing it. -In case of prepared statements, it's impossible to manipulate the query as was demonstrated above. +In the case of prepared statements, it's impossible to manipulate the query as was demonstrated above. 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: @@ -97,7 +97,7 @@ Further reading on the topic: 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 website instead of innocent alert, such a script could send messages using your name or even +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. Avoiding XSS is quite easy in Yii. There are two cases: @@ -105,14 +105,14 @@ Avoiding XSS is quite easy in Yii. There are two cases: 1. You want to output data as plain text. 2. You want to output data as HTML. -If all you need is plain text, then escaping is as easy as following: +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/). +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. Further reading on the topic: @@ -133,14 +133,14 @@ the browser will send the GET request to that URL and the user will be logged ou 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 much more things one could do using this approach. +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 GET request to load an image, +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 to send POST requests to that URL as well. +can put some JavaScript code instead of `` tag, which allows sending POST requests to that URL as well. For this reason, Yii applies extra mechanisms to protect against CSRF attacks. @@ -161,10 +161,10 @@ 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 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. +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. -If so, don't forget to deny access to everything except `web`. +If so, remember to deny access to everything except `web`. If it's impossible, consider hosting your application elsewhere. @@ -178,7 +178,7 @@ 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. -You should avoid the debug toolbar at production unless necessary. +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. @@ -198,8 +198,8 @@ Nowadays, anyone can get a certificate for free and automatically update it than ## 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 +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. ### Avoiding `Host`-header attacks diff --git a/guide/en/security/cryptography.md b/guide/en/security/cryptography.md index 0c8ae9d6..d06fd2d7 100644 --- a/guide/en/security/cryptography.md +++ b/guide/en/security/cryptography.md @@ -1,6 +1,6 @@ # Cryptography -In this section we'll review the following security aspects: +In this section, we'll review the following security aspects: - Generating random data - Encryption and Decryption @@ -15,7 +15,7 @@ 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 end user which in turn will allow them to prove ownership of +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. @@ -25,17 +25,17 @@ can predict the token's value and reset the user's password. $key = \Yiisoft\Security\Random::string(42); ``` -Code above would give you a random string consisting of 42 characters. +The code above would give you a random string consisting of 42 characters. If you need bytes or integers, use PHP functions directly: -- `random_bytes()` for bytes. Note that output may not be ASCII. +- `random_bytes()` for bytes. Note that the output may not be ASCII. - `random_int()` for integers. ## Encryption and Decryption Yii provides convenient helper functions to encrypt/decrypt data using a secret key. -The data are passed through the encryption function so that only the person which has the secret key will be able +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): @@ -43,32 +43,32 @@ the user who has the secret key can view it (even if one compromises the applica ```php $encryptedData = (new \Yiisoft\Security\Crypt())->encryptByPassword($data, $password); -// save data to database or another storage +// save data to a database or another storage saveData($encryptedData); ``` Decrypting it: ```php -// obtain encrypted data from a database or another storage +// collect encrypted data from a database or another storage $encryptedData = getEncryptedData(); $data = (new \Yiisoft\Security\Crypt())->decryptByPassword($encryptedData, $password); ``` -You could use a key instead of password: +You could use a key instead of a password: ```php $encryptedData = (new \Yiisoft\Security\Crypt())->encryptByKey($data, $key); -// save data to database or another storage +// save data to a database or another storage saveData($encryptedData); ``` Decrypting it: ```php -// obtain encrypted data from a database or another storage +// collect encrypted data from a database or another storage $encryptedData = getEncryptedData(); $data = (new \Yiisoft\Security\Crypt())->decryptByKey($encryptedData, $key); @@ -76,7 +76,7 @@ $data = (new \Yiisoft\Security\Crypt())->decryptByKey($encryptedData, $key); ## Confirming data integrity -There are situations in which you need to verify that your data haven't been tampered with by a third party or even +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. The `$key` should be present at both sending and receiving sides. On the sending side: @@ -87,7 +87,7 @@ $signedMessage = (new \Yiisoft\Security\Mac())->sign($message, $key); sendMessage($signedMessage); ``` -At the receiving side: +On the receiving side: ```php $signedMessage = receiveMessage($signedMessage); @@ -101,8 +101,8 @@ try { ## Masking token length -Masking a token helps to mitigate BREACH attack by randomizing how token outputted on each request. -A random mask applied to the token making the string always unique. +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. To mask a token: @@ -110,7 +110,7 @@ To mask a token: $maskedToken = \Yiisoft\Security\TokenMask::apply($token); ``` -To get original value from the masked one: +To get the original value from the masked one: ```php $token = \Yiisoft\Security\TokenMask::remove($maskedToken); diff --git a/guide/en/security/overview.md b/guide/en/security/overview.md index 3385e2bf..07ba8748 100644 --- a/guide/en/security/overview.md +++ b/guide/en/security/overview.md @@ -2,7 +2,7 @@ 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-powered application as secure as possible, Yii has included several excellent and easy-to-use security features. * [Authentication](authentication.md) * [Authorization](authorization.md) diff --git a/guide/en/security/passwords.md b/guide/en/security/passwords.md index 2ec0edd8..179a9b40 100644 --- a/guide/en/security/passwords.md +++ b/guide/en/security/passwords.md @@ -31,7 +31,7 @@ When a user attempts to log in, the submitted password must be verified against ```php -// obtain hash from a database or another storage +// get hash from a database or another storage $hash = getHash(); if ((new PasswordHasher())->validate($password, $hash)) { diff --git a/guide/en/security/trusted-request.md b/guide/en/security/trusted-request.md index b2185f18..47eb4bec 100644 --- a/guide/en/security/trusted-request.md +++ b/guide/en/security/trusted-request.md @@ -1,6 +1,6 @@ # 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 +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. @@ -20,7 +20,7 @@ $trustedHostsNetworkResolver = $trustedHostsNetworkResolver->withAddedTrustedHos The proxy sends the IP in the `X-Forwarded-For` header by default, and the protocol (`http` or `https`) is in `X-Forwarded-Proto`. -In case your proxies are using different headers you can use the request configuration to adjust these, e.g.: +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 */ diff --git a/guide/en/start/creating-project.md b/guide/en/start/creating-project.md index ba1c92f8..e45fe7f6 100644 --- a/guide/en/start/creating-project.md +++ b/guide/en/start/creating-project.md @@ -67,7 +67,7 @@ console command while in the project root directory: ./yii serve ``` -> Note: By default, the HTTP-server will listen to port 8080. However, if that port is already in use, or you wish to +> Note: By default, the HTTP server will listen to port 8080. However, if that port is already in use, or you wish to serve many applications this way, you might want to specify what port to use via the --port argument: ```bash @@ -92,13 +92,13 @@ Yii's requirements by using [yiisoft/requirements package](https://github.com/yi of deploying it to a production server. The application installed according to the instructions should work out of the box with either -an [Apache HTTP server](https://httpd.apache.org/) or a [Nginx HTTP server](https://nginx.org/), on +an [Apache HTTP server](https://httpd.apache.org/) or an [Nginx HTTP server](https://nginx.org/), on Windows, Mac OS X, or Linux running PHP 8.0 or higher. On a production server, we recommend configuring your Web server so that a user can access the application via the URL `http://www.example.com/index.php` instead of `http://www.example.com/app/public/index.php`. Such a configuration requires pointing the document root of your Web server to the `app/public` folder. -In this subsection, you'll learn how to configure your webserver achieve it. +In this subsection, you'll learn how to configure your webserver to achieve it. > Info: By setting `app/public` as the document root, you also prevent end users from accessing > your private application code and sensitive data files that are stored in the sibling directories @@ -278,9 +278,9 @@ in the same configuration. ### IIS -When using [IIS](https://www.iis.net/), we recommend hosting the application in a virtual host (Web site) where document -root points to `path/to/app/web` folder and that Web site is configured to run PHP. In that `web` folder you have to -place a file named `web.config` that's `path/to/app/web/web.config`. Content of the file should be the following: +When using [IIS](https://www.iis.net/), we recommend hosting the application in a virtual host (Website) where document +root points to `path/to/app/web` folder and that website is configured to run PHP. In that `web` folder you have to +place a file named `web.config` that's `path/to/app/web/web.config`. The Content of the file should be the following: ```xml diff --git a/guide/en/start/forms.md b/guide/en/start/forms.md index 49b21ddb..89ab01b7 100644 --- a/guide/en/start/forms.md +++ b/guide/en/start/forms.md @@ -1,6 +1,6 @@ # Working with Forms -This section continues to improve on "Saying Hello". Instead of using URL, you will now ask user for a message via form. +This section continues to improve on "Saying Hello." Instead of using URL, you will now ask a user for a message via form. Through this tutorial, you will learn how to: @@ -48,9 +48,9 @@ The `EchoForm` class has `$message` property and related getter. ## Using the form -Now, that you have a form, use it in your action from "[Saying Hello](hello.md)". +Now that you have a form, use it in your action from "[Saying Hello](hello.md)". -You also need to install hydrator package +You also need to install a hydrator package ``` composer require yiisoft/hydrator @@ -157,11 +157,11 @@ use Yiisoft\Html\Html; close() ?> ``` -If a form has a message set, you're displaying a box with the message. The rest if about rendering the form. +If a form has a message set, you're displaying a box with the message. The rest is about rendering the form. You get the action URL from the URL manager service. You access it as `$urlGenerator` that's a default parameter available in all views. -This variable and alike ones such as `$csrf` are provided by view injections listed in `config/common/params.php`: +This variable and similar ones such as `$csrf` are provided by view injections listed in `config/common/params.php`: ```php 'yiisoft/yii-view-renderer' => [ @@ -174,7 +174,7 @@ This variable and alike ones such as `$csrf` are provided by view injections lis ], ``` -You set the value of CSRF token, and it is rendered as a hidden input to ensure that the request originates from +You set the value of a CSRF token, and it is rendered 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). @@ -213,7 +213,7 @@ return [ // ... ``` -You use `Text::widget()` to output "message" field, so it takes case about filling the value, escaping it, +You use `Text::widget()` to output "message" field, so it takes care about filling the value, escaping it, rendering field label and validation errors you're going to take care of next. ## Adding validation @@ -264,7 +264,7 @@ class EchoController } ``` -You've obtained validator instance through type-hinting and used it to validate the form. +You've got a validator instance through type-hinting and used it to validate the form. Now you need to add validation rules to `/src/Form/EchoForm.php`: ```php @@ -285,7 +285,7 @@ class EchoForm } ``` -Now, in case you will submit an empty message you will get a validation error: "Message cannot be blank." +Now, in case you submit an empty message, you will get a validation error: "Message cannot be blank." Also, you can add required attribute to text field in `views/echo/say.php`. ```php @@ -341,13 +341,13 @@ To see how it works, use your browser to access the following URL: http://localhost:8080/say ``` -You will see a page displaying a form an input field that has a label that indicates what data are to be entered. -Also, there is a submit button labeled "Say". If you click the submit button without entering anything, you will see +You will see a page displaying a form input field that has a label that indicates what data are to be entered. +Also, there is a "submit" button labeled "Say". If you click the "submit" button without entering anything, you will see an error message displayed next to a problematic input field. ![Form with a validation error](img/form-error.png) -After entering a message and clicking the submit button, you will see a new page +After entering a message and clicking the "submit" button, you will see a new page displaying the data that you just entered. ![Form with a success message](img/form-success.png) diff --git a/guide/en/start/hello.md b/guide/en/start/hello.md index b861ef10..5d845524 100644 --- a/guide/en/start/hello.md +++ b/guide/en/start/hello.md @@ -1,6 +1,6 @@ # Saying hello -> Note: This document reflects the current configuration. The Yii team is going to make it simpler before release. +> Note: This document reflects the current configuration. The Yii team is going to simplify it before release. 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!". @@ -11,7 +11,7 @@ Then you will improve it to use [view](../structure/views.md) for building the r Through this tutorial, you will learn three things: -1. How to create a handler to respond to request. +1. How to create a handler to respond to a request. 2. How to map URL to the handler. 3. How to create a [view](../structure/view.md) to compose the response's content. @@ -55,7 +55,7 @@ class EchoController } ``` -The `say` method in your example is given `$currentRoute` parameter that you can use to obtain +The `say` method in your example is given `$currentRoute` parameter that you can use to get a message, whose value defaults to `"Hello"`. If the request is made to `/say/Goodbye`, the `$message` variable within the action will be assigned that value. @@ -123,9 +123,9 @@ before being printed. This is necessary as the parameter comes from an end user, malicious JavaScript in the parameter. 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 `say` view is a PHP script that's executed by the view service. +PHP statements. In fact, the `say` view is a PHP script executed by the view service. -To use the view you need to change `src/Controller/EchoController.php`: +To use the view, you need to change `src/Controller/EchoController.php`: ```php Info: For simplicity, throughout this "Getting Started" tutorial use "serve" command. It shouldn't be used +> Info: For simplicity, throughout this "Getting Started" tutorial use the "serve" command. It shouldn't be used > to serve the project in production. When setting up a real server, use `app/public` as the document root. Note that unlike the framework itself, after you install a project template, it's all yours. You're free to add or delete @@ -89,8 +89,8 @@ and shouldn't be. Each application has an entry script `public/index.php` which is the only Web accessible PHP script in the application. The entry script is using 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. An application contains a set of middleware that are executed sequentially processing the request. -The result is passed further to emitter that takes care of sending a response to the browser. +instance. An application contains a set of middleware that is executed sequentially processing the request. +The result is passed further to the emitter that takes care of sending a response to the browser. Depending on the middleware used, the application may behave differently. By default, there is a router that, based on URL requested and configuration, chooses a handler that's executed to produce a response. @@ -105,10 +105,10 @@ The following diagram shows how an application handles a request. ![Request Lifecycle](img/request-lifecycle.svg) 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 application runner loads +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 raw request that came from a user. +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. diff --git a/guide/en/structure/action.md b/guide/en/structure/action.md index 09a4c165..466cdb92 100644 --- a/guide/en/structure/action.md +++ b/guide/en/structure/action.md @@ -1,8 +1,8 @@ # Actions -In a web application, what's executed is determined by request URL. Matching is made by router that's +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 next middleware, +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. There are multiple ways to describe an action. The simplest one is using a closure: @@ -28,7 +28,7 @@ use Yiisoft\Router\Route; Route::get('/')->action([FrontPageAction::class, 'run']), ``` -The class itself would like: +The class itself would be like: ```php use \Psr\Http\Message\ServerRequestInterface; @@ -74,12 +74,12 @@ class PostController } ``` -We usually call such class a "controller". +We usually call such a class "controller." ## Autowiring Both constructors of action-classes and action-methods are automatically getting services from -dependency injection container: + the dependency injection container: ```php use \Psr\Http\Message\ServerRequestInterface; diff --git a/guide/en/structure/application.md b/guide/en/structure/application.md index 078e76bf..43e5f150 100644 --- a/guide/en/structure/application.md +++ b/guide/en/structure/application.md @@ -7,7 +7,7 @@ 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 by passing request object 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), + 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. diff --git a/guide/en/structure/domain.md b/guide/en/structure/domain.md index 6b407b6e..56580b15 100644 --- a/guide/en/structure/domain.md +++ b/guide/en/structure/domain.md @@ -3,18 +3,18 @@ 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 -infrastructure part of the system (that's how to save data into a database, how to form HTTP response etc.). + the infrastructure part of the system (that's how to save data into a database, how to form HTTP response, etc.). > 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. -> Individual concepts of domain design below could be applied separately so make sure to check these even if your +> 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 isn't too complicated by itself. Therefore, +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". +Such separated models are called "bounded contexts." ## Building blocks @@ -23,14 +23,14 @@ them all. ### Entity -Entity is a uniquely identifiable object such as user, product, payment etc. When comparing them, you're checking ID, +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. ### 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 being the same. +comparing such objects, you're checking actual values. If they match, an object is considered to be the same. ### Aggregate @@ -47,7 +47,7 @@ be risen so other parts of the system may react on these. ### Data transfer object -Data transfer object or DTO is an object which only purpose is to hold data as is. It's commonly used to pass data +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. ### Service @@ -57,15 +57,15 @@ components](service.md)". ### Repository -The repository task is to abstract away how domain objects are obtained. These are usually separated in two parts: an interface -that stays in the domain layer and implementation that's situated in infrastructure layer. In such a way, domain doesn't -care how data are obtained and saves and may be focused around the complicated business logic instead. +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 event aren't services and shouldn't be instantiated through DI container. +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. ## References diff --git a/guide/en/structure/entry-script.md b/guide/en/structure/entry-script.md index 934e53a6..18c41b0b 100644 --- a/guide/en/structure/entry-script.md +++ b/guide/en/structure/entry-script.md @@ -4,7 +4,7 @@ Entry scripts are the first step in the application bootstrapping process. An ap 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. -Entry scripts for Web applications must be stored under Web accessible directories so that they +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. @@ -14,10 +14,10 @@ Entry scripts mainly perform the following work with the help of `ApplicationRun * Register [Composer autoloader](https://getcomposer.org/doc/01-basic-usage.md#autoloading); * Obtain configuration; -* Use configuration to initialize dependency injection container; -* Get an instance of request. +* 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 emitter that transforms response object into actual HTTP response that's sent to client browser. +* With the help of an emitter that transforms a response object into an actual HTTP response that's sent to the client browser. ## Web Applications diff --git a/guide/en/structure/overview.md b/guide/en/structure/overview.md index 65414b0a..12f08b22 100644 --- a/guide/en/structure/overview.md +++ b/guide/en/structure/overview.md @@ -2,7 +2,7 @@ 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, context could be: +For example, if the application is an online store, the context could be: - Customer - Profile @@ -46,13 +46,13 @@ 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 what's returned by domain layer. +[a response](../runtime/response.md) based on domain layer return. Besides, Yii applications also have the following: * [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 - whole application. + 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 diff --git a/guide/en/structure/package.md b/guide/en/structure/package.md index 724f74e1..29f889aa 100644 --- a/guide/en/structure/package.md +++ b/guide/en/structure/package.md @@ -6,7 +6,7 @@ reusable code. ## Using packages -By default, Composer installs packages registered on [Packagist](https://packagist.org/) - the biggest repository +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. @@ -31,7 +31,7 @@ Classes from the package will be available immediately via [autoloading](../conc 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, whole module, etc. +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. @@ -46,7 +46,7 @@ Below are the basic steps you may follow. ### `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 complete specification about this file in the [Composer Manual](https://getcomposer.org/doc/01-basic-usage.md#composer-json-project-setup). +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: ```json @@ -164,13 +164,13 @@ 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. +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 public. +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 @@ -187,11 +187,11 @@ You should give each release of your extension a version number (e.g. `1.0.1`). 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 on a Composer repository, such as +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 simply create a release tag (for example, `v1.0.1`) +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. +then be able to find the new release and install or update the package through the Composer repository. 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: @@ -205,4 +205,4 @@ help other people learn about and use your extension: 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. +* API documentation: your code should be well-documented to allow other people to more easily read and understand it. diff --git a/guide/en/structure/service.md b/guide/en/structure/service.md index 7b20db50..fb481cf9 100644 --- a/guide/en/structure/service.md +++ b/guide/en/structure/service.md @@ -19,17 +19,17 @@ 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. -Services either perform a task or return data. They're created once, put into DI container and then could be used +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. ## Service dependencies and configuration Services should always define all their dependencies on other services via `__construct()`. It both allows you to use -service right away after it's created and serves as an indicator of a service doing too much if there are too many +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. -- After the service created, it shouldn't be re-configured in runtime. +- 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. @@ -79,7 +79,7 @@ class Dsn ## Service methods -Service method usually does something. It could be a simple thing that's repeated exactly, but usually it depends on the +Service method usually does something. It could be a simple thing repeated exactly, but usually it depends on the context. For example: ```php @@ -99,11 +99,11 @@ class PostPersister } ``` -There's a service saving posts into permanent storage such as a database. An object allowing +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 +## Is everything a service? Often it makes sense to choose another class type to place your code into. Check: diff --git a/guide/en/tutorial/console-applications.md b/guide/en/tutorial/console-applications.md index 34f17b4f..a794b315 100644 --- a/guide/en/tutorial/console-applications.md +++ b/guide/en/tutorial/console-applications.md @@ -9,7 +9,7 @@ To get support for console application in your project, get `yiisoft/yii-console composer require yiisoft/yii-console ``` -After it's installed, you can access entry point as +After it's installed, you can access the entry point as ``` ./yii diff --git a/guide/en/tutorial/mailing.md b/guide/en/tutorial/mailing.md index cce1c3ba..502b0456 100644 --- a/guide/en/tutorial/mailing.md +++ b/guide/en/tutorial/mailing.md @@ -11,7 +11,7 @@ is used in the examples below. ## Configuring the Mailer -The mailer service allows you to create a message instance, populate it with data, and send it. Typically, you obtain an +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`. You can also create an instance manually as follows: @@ -62,7 +62,7 @@ $message = new \Yiisoft\Mailer\Message( ### HTML Message from template -For this example we will use package rendering package [view](https://github.com/yiisoft/view). +For this example, we will use package rendering package [view](https://github.com/yiisoft/view). ```php /** @@ -84,7 +84,7 @@ $message = new \Yiisoft\Mailer\Message( ### Using Layouts -You can also pass parameters to layouts from you template message: +You can also pass parameters to layouts from your template message: ```php /** @@ -280,8 +280,8 @@ interfaces. ## For Development -For local or test development, you can use simplified implementations of the mailer that do not actually send emails. -These implementations are provided by the package: +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. @@ -294,4 +294,4 @@ return [ Yiisoft\Mailer\MailerInterface::class => Yiisoft\Mailer\StubMailer::class, //or any other ]; -``` \ No newline at end of file +``` diff --git a/guide/en/tutorial/performance-tuning.md b/guide/en/tutorial/performance-tuning.md index 192987b2..e25c2565 100644 --- a/guide/en/tutorial/performance-tuning.md +++ b/guide/en/tutorial/performance-tuning.md @@ -13,7 +13,7 @@ A well-configured PHP environment is important. To get maximum performance: - Enable bytecode caching with [Opcache](https://secure.php.net/opcache). Bytecode caching avoids the time spent in 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 production environment. +- Make sure [XDebug](https://xdebug.org/) isn't installed in the production environment. - Try [PHP 7 preloading](https://wiki.php.net/rfc/preload). ## Using Caching Techniques @@ -26,10 +26,10 @@ the [Caching](../caching/overview.md) section to learn about the caching support ## Optimizing Session Storage -By default, session data are stored in files. The implementation is locking a file from opening a session to the point it's +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, which are trying to use the same session are blocked, that's waiting for the -initial request to release session file. This is fine for development and probably small projects. But when it comes +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) @@ -47,7 +47,7 @@ session service as follows: 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, +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. A general technique to improve the performance of DB queries is to create indices for table columns that @@ -77,19 +77,19 @@ Note that both optimizations may or may not be suitable for your particular case ## Processing Data Offline -When a request involves some resource intensive operations, you should think of ways to perform those operations +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. 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 easy to implement, but it has some drawbacks. For example, the task process needs to periodically pull +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 on the queue, it will initiate or notify the task handling process to trigger the task processing. +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. ## Using preloading @@ -114,7 +114,7 @@ was used with the following run parameters: ab -n 1000 -c 10 -t 10 ``` -Also, a debug mode was disabled. And an optimized autoloader of the [Composer](https://getcomposer.org) was used +Also, the debug mode was disabled. And an optimized autoloader of the [Composer](https://getcomposer.org) was used and development dependencies weren't used: ```shell @@ -139,7 +139,7 @@ foreach (array_unique($files) as $file) { | With preloading | 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 doesn't contain many classes. More discussion of preloading, including benchmarks, +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). ## Performance Profiling diff --git a/guide/en/tutorial/using-with-event-loop.md b/guide/en/tutorial/using-with-event-loop.md index 867815d9..a7d4d973 100644 --- a/guide/en/tutorial/using-with-event-loop.md +++ b/guide/en/tutorial/using-with-event-loop.md @@ -1,12 +1,12 @@ # Using Yii with event loop -Normal PHP web request execution cycle consists of setting up environment, getting response, processing it to form response -and sending response. After response is sent, execution is terminated and its context is lost. So, for the subsequent -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 cleaning up context. On the other side, initializing everything for +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. -There is an alternative way of running an application. Event loop. The idea is to initialize everything possible once +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, [RoadRunner](https://roadrunner.dev/) and @@ -14,7 +14,7 @@ There are multiple tools that could be used to achieve it. Notably, [RoadRunner] ## Event loop implications -Event loop worker basically looks the following: +Event loop worker basically looks like the following: ```php initializeContext(); @@ -24,7 +24,7 @@ while ($request = getRequest()) { } ``` -Usually, there are multiple workers processing requests at the same time same as with traditional php-fpm. +Usually, there are multiple workers processing requests at the same time as with traditional php-fpm. That means that there's more to consider when developing applications. @@ -35,11 +35,11 @@ long-running processes, same as in general PHP applications, should be put into ### Services and state -Since context in event loop is shared between all request-responses processed by a single worker, all changes -in the state of a service made by previous request may affect current request. Moreover, it can be a security problem -if data from one user are available to another user. +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. -There are two ways dealing with it. First, you can avoid having state by making services stateless. Second, you can +There are two ways of dealing with it. First, you can avoid having state by making services stateless. Second, you can clean up services at the end of the request processing. In this case, a state resetter will help you: ```php @@ -48,7 +48,7 @@ $resetter = $container->get(\Yiisoft\Di\StateResetter::class); while ($request = getRequest()) { $response = process($request); emit($response); - $resetter->reset(); // We should reset the state of such services every request. + $resetter->reset(); // We should reset the state of such services on every request. } ``` diff --git a/guide/en/tutorial/using-yii-with-roadrunner.md b/guide/en/tutorial/using-yii-with-roadrunner.md index 18b559bf..c897f591 100644 --- a/guide/en/tutorial/using-yii-with-roadrunner.md +++ b/guide/en/tutorial/using-yii-with-roadrunner.md @@ -2,7 +2,7 @@ [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 to re-initialize a framework for each request that improves +[event loop](using-with-event-loop.md) and allows not re-initializing a framework for each request that improves performance significantly. ## Installation @@ -59,7 +59,7 @@ logs: ``` We're specifying that entry script is `worker.php`, there should be three workers on port 8080, `public` directory -files are static ones except `.php` and `.htaccess`. Also, we're sending additional header. +files are static ones except `.php` and `.htaccess`. Also, we're sending an additional header. Create `/worker.php`: @@ -89,5 +89,5 @@ To start a server, execute the following command: ## On worker scope - Each worker's scope is isolated from other workers. Memory isn't shared. -- A single worker serves multiple requests where scope is shared. -- At each iteration of event loop every service that depends on state should be reset. +- 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. diff --git a/guide/en/tutorial/using-yii-with-swoole.md b/guide/en/tutorial/using-yii-with-swoole.md index c3c55a28..cbc3fc43 100644 --- a/guide/en/tutorial/using-yii-with-swoole.md +++ b/guide/en/tutorial/using-yii-with-swoole.md @@ -123,4 +123,4 @@ php server.php ## On scope -A scope is shared so at each iteration of event loop every service that depends on state should be reset. +A scope is shared, so at each iteration of the event loop every service that depends on state should be reset. diff --git a/guide/en/views/view-injections.md b/guide/en/views/view-injections.md index 9cf9710d..fec00be8 100644 --- a/guide/en/views/view-injections.md +++ b/guide/en/views/view-injections.md @@ -1,7 +1,6 @@ # View injections The view injections are designed to provide a standardized way to pass parameters to the common layer - of views in an application. Implementing this interface allows developers to manage the data that will be available across various views, ensuring flexibility and reusability of code. @@ -64,7 +63,7 @@ If your application has multiple layouts, you can create separate parameter inje 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 specific layout: +Create your custom ViewInjection for a specific layout: ```php readonly final class CartViewInjection implements CommonParametersInjectionInterface diff --git a/guide/ru/concept/autoloading.md b/guide/ru/concept/autoloading.md index 34ebeb08..f6ff254f 100644 --- a/guide/ru/concept/autoloading.md +++ b/guide/ru/concept/autoloading.md @@ -4,7 +4,7 @@ При установке пакетов он создает [автозагрузчик, совместимый с PSR-4](https://www.php-fig.org/psr/psr-4/). Чтобы использовать его, подключите `/vendor/autoload.php` через `require_once` в ваш входной скрипт `index.php` -Вы можете использовать автозагрузчик не только для установленных пакетов, но и для всего вашего приложения, поскольку оно тоже является пакетом. Чтобы загрузить классы определенного пространства имен добавьте в `composer.json`: +Вы можете использовать автозагрузчик не только для установленных пакетов, но и для всего вашего приложения, поскольку оно тоже является пакетом. Чтобы загрузить классы определенного пространства имен, добавьте в `composer.json`: ```json { diff --git a/guide/ru/concept/di-container.md b/guide/ru/concept/di-container.md index 4c9a8412..e1a17114 100644 --- a/guide/ru/concept/di-container.md +++ b/guide/ru/concept/di-container.md @@ -4,7 +4,7 @@ В ООП существует два способа повторного использования кода: наследование и композиция. -Наследование - это просто: +Наследование — это просто: ```php class Cache @@ -69,19 +69,19 @@ final class CachedWidget Мы избежали ненужного наследования и использовали интерфейс, чтобы уменьшить сопряженность. Вы можете заменить реализацию кэша без изменения класса `CachedWidget`, поэтому он становится более стабильным. -Здесь `CacheInterface` это зависимость - объект, от которого зависит другой объект. +Здесь `CacheInterface` это зависимость — объект, от которого зависит другой объект. Процесс помещения экземпляра объекта зависимости в объект (`CachedWidget`) называется внедрением зависимости. Существует множество способов его реализации: -- Внедрение через конструктор. Лучше всего подходит для обязательных зависиомостей. +- Внедрение через конструктор. Лучше всего подходит для обязательных зависимостей. - Через метод. Лучше использовать для необязательных зависимостей. - Через свойство. Лучше избегать использования в PHP, за исключением, может быть, объектов передачи данных (DTO) ## Контейнер внедрения зависимостей Внедрять базовые зависимости просто и легко. -Вы выбираете место где вас не волнуют зависимости, которые обычно являются обработчиками действий и которые вы не собираетесь тестировать, создаете экземпляры необходимых зависимостей и передаете их в зависимые классы. +Вы выбираете место, где вас не волнуют зависимости, которые обычно являются обработчиками действий и которые вы не собираетесь тестировать, создаете экземпляры необходимых зависимостей и передаете их в зависимые классы. Это хорошо работает, когда в целом зависимостей немного и нет вложенных зависимостей. Когда их много, и каждая зависимость сама имеет зависимости, создание всей иерархии становится утомительным процессом, который требует большого количества кода и может привести к трудно отлаживаемым ошибкам. @@ -94,7 +94,7 @@ final class CachedWidget Именно для этого нужны контейнеры зависимостей. -Контейнер внедрения зависимостей (DI-контейнер) - это объект, который знает, как создавать и настраивать объекты и все зависимые от них объекты. +Контейнер внедрения зависимостей (DI-контейнер) — это объект, который знает, как создавать и настраивать объекты и все зависимые от них объекты. [Статья Мартина Фаулера](https://martinfowler.com/articles/injection.html) хорошо объясняет почему DI-контейнер полезен. Здесь мы в основном поясним использование DI-контейнера, предоставляемого Yii. @@ -120,7 +120,7 @@ class MyService implements MyServiceInterface } ``` -конфигурация может быть: +Конфигурация может быть: ```php return [ @@ -169,7 +169,7 @@ return [ ### Внедрение зависимостей -Непосредственное обращение к контейнеру в классе - плохая идея, так как код становится неуниверсальным, сопряжен с интерфейсом контейнера и, что еще хуже, зависимости становятся скрытыми. +Непосредственное обращение к контейнеру в классе — плохая идея, так как код становится не универсальным, сопряжен с интерфейсом контейнера и, что еще хуже, зависимости становятся скрытыми. Поэтому Yii инвертирует управление, автоматически вводя объекты из контейнера в конструкторы и методы, основываясь на типах аргументов. diff --git a/guide/ru/intro/what-is-yii.md b/guide/ru/intro/what-is-yii.md index d4fad77b..62b1624c 100644 --- a/guide/ru/intro/what-is-yii.md +++ b/guide/ru/intro/what-is-yii.md @@ -35,11 +35,13 @@ Yii разрабатывается [сильной командой разраб В настоящее время доступны три основные ветки: 1.1, 2.0 и 3.0. - Ветка 1.1 является предыдущим поколением и находится в состоянии исправления ошибок и заморозки добавления новой функциональности. -- Ветка 2.0 - текущая стабильная версия, находится в состоянии исправления ошибок и заморозки добавления новой функциональности. -- Ветка 3.0 - текущая разрабатываемая версия. Данное руководство именно о версии 3.0. +- Ветка 2.0 — текущая стабильная версия. Находится в состоянии исправления ошибок и заморозки добавления новой функциональности. +- Ветка 3.0 — текущая разрабатываемая версия. Данное руководство именно о версии 3.0. ## Требования к ПО и знаниям Yii3 требует PHP 8.0 или выше, но некоторые пакеты также поддерживают PHP 7.4. -Для разработки на Yii потребуется общее понимание объектно-ориентированного программирования (ООП), так как фреймворк полностью следует этой парадигме. Yii3 также использует новейшие возможности PHP, такие как декларация типов и генераторы. Понимание этих концепций поможет вам быстрее разобраться с Yii3 +Для разработки на Yii потребуется общее понимание объектно-ориентированного программирования (ООП), так как фреймворк +полностью следует этой парадигме. Yii3 также использует новейшие возможности PHP, такие, как декларация типов и генераторы. +Понимание этих концепций поможет вам быстрее разобраться с Yii3. diff --git a/guide/ru/security/best-practices.md b/guide/ru/security/best-practices.md index 08367c6c..513a5dad 100644 --- a/guide/ru/security/best-practices.md +++ b/guide/ru/security/best-practices.md @@ -31,7 +31,8 @@ if (!in_array($sortBy, ['title', 'created_at', 'status'])) { ### Экранирование вывода -Экранирование вывода означает, что в зависимости от контекста, в котором вы используете данные, вам следует добавить к ними специальные символы, чтобы экранировать их значение. +Экранирование вывода означает, что в зависимости от контекста, в котором вы используете данные, вам следует добавить +к ним специальные символы, чтобы экранировать их значение. В контексте HTML вы должны экранировать `<`, `>` и похожие специальные символы. В контексте JavaScript или SQL это будет другой набор символов. Так как ручное экранирование чревато ошибками, Yii предоставляет различные утилиты для экранирования в различных контекстах. @@ -51,7 +52,8 @@ $username = $_GET['username']; $sql = "SELECT * FROM user WHERE username = '$username'"; ``` -Вместо того, чтобы подставлять корректное имя пользователя, злоумышленник может передать в ваше приложение что-то вроде `'; DROP TABLE user; --`. В результате SQL будет следующий: +Вместо того чтобы подставлять корректное имя пользователя, злоумышленник может передать в ваше приложение что-то вроде +`'; DROP TABLE user; --`. В результате SQL будет следующий: ```sql SELECT * FROM user WHERE username = ''; DROP TABLE user; --' @@ -59,7 +61,7 @@ SELECT * FROM user WHERE username = ''; DROP TABLE user; --' Это валидный запрос, который сначала будет искать пользователей с пустым именем, а затем удалит таблицу user. Скорее всего будет сломано приложение и будут потеряны данные (вы ведь делаете регулярное резервное копирование?). -Убедитесь, что либо вы напрямую используете подготовленные PDO запросы, либо это делает выбранная вами библиотека. +Убедитесь, что-либо вы напрямую используете подготовленные PDO запросы, либо это делает выбранная вами библиотека. В случае подготовленных запросов невозможно манипулированть запросом, как было продемонстрировано выше. Если вы используете данные для указания имен столбцов или таблиц, лучше всего разрешить только предопределенный набор значений: @@ -105,23 +107,32 @@ XSS или кросс-сайтинговый скриптинг становит ## Как избежать CSRF -CSRF - это аббревиатура для межсайтинговой подмены запросов. Идея заключается в том, что многие приложения предполагают, что запросы, приходящие от браузера, отправляются самим пользователем. Это может быть неправдой. +CSRF — это аббревиатура для межсайтинговой подмены запросов. Идея заключается в том, что многие приложения предполагают, +что запросы, приходящие от браузера, отправляются самим пользователем. Это может быть неправдой. -Например, сайт `an.example.com` имеет URL `/logout`, который, используя простой GET, разлогинивает пользователя. Пока это запрос выполняется самим пользователем - всё в порядке, но в один прекрасный день злоумышленники размещают код '' на форуме с большой посещаемостью. Браузер не делает никаких отличий между запросом изображения и запросом страницы, так что когда пользователь откроет страницу с таким тегом ``, браузер отправит GET-запрос на указанный адрес, и пользователь будет разлогинен с `an.example.com`. +Например, сайт `an.example.com` имеет URL `/logout`, который, используя простой GET, разлогинивает пользователя. +Пока это запрос выполняется самим пользователем — всё в порядке, но в один прекрасный день злоумышленники размещают +код '' на форуме с большой посещаемостью. Браузер не делает никаких отличий +между запросом изображения и запросом страницы, так что когда пользователь откроет страницу с таким тегом ``, +браузер отправит GET-запрос на указанный адрес, и пользователь будет разлогинен с `an.example.com`. Вот основная идея того, как работает CSRF-атака. Можно сказать, что в разлогинивании пользователя нет ничего серьёзного. -Однако, это был всего лишь пример. +Однако это был всего лишь пример. С помощью этого подхода можно сделать гораздо больше опасных вещей. Например, оплату или изменение данных. -Представьте, что существует страница `http://an.example.com/purse/transfer?to=anotherUser&amount=2000`, обращение к которой с помощью GET-запроса, приводит к перечислению 2000 единиц валюты со счета авторизованного пользователя на счет пользователя с логином `anotherUser`. -Учитывая, что браузер для загрузки контента отправляет GET-запросы, можно подумать, что разрешение на выполнение такой операции только POST-запросом на 100% обезопасит от проблем. -К сожалению, это не спасет вас, так как вместо тега ``, злоумышленник может внедрить JavaScript код, который будет отправлять нужные POST-запросы на этот URL. +Представьте, что существует страница `http://an.example.com/purse/transfer?to=anotherUser&amount=2000`, обращение +к которой с помощью GET-запроса, приводит к перечислению 2000 единиц валюты со счета авторизованного пользователя +на личный счёт пользователя с логином `anotherUser`. +Учитывая, что браузер для загрузки контента отправляет GET-запросы, можно подумать, что разрешение на выполнение такой +операции только POST-запросом на 100% обезопасит от проблем. +К сожалению, это не спасет вас, так как вместо тега ``, злоумышленник может внедрить JavaScript код, который будет +отправлять нужные POST-запросы на этот URL. По этой причине Yii применяет дополнительные механизмы защиты от CSRF-атак. -Для того, чтоб избежать CSRF вы должны всегда: +Для того чтобы избежать CSRF вы должны всегда: 1. Следовать спецификации HTTP. Например, GET-запрос не должен менять состояние приложения. Дополнительные сведения см. в [RFC2616](https://www.w3.org/Protocols/rfc2616/rfc2616-sec9.html) @@ -138,18 +149,22 @@ Yii имеет защиту от CSRF в middleware `Yiisoft\Yii\Web\Middleware\ ## Как избежать нежелательного доступа к файлам По умолчанию, webroot сервера указывает на каталог `public`, где лежит `index.php`. -В случае использования виртуального хостинга, это может быть недостижимо, в конечном итоге весь код, конфиги и логи могут оказаться в webroot сервера. +В случае использования виртуального хостинга это может быть недостижимо, в конечном итоге весь код, конфиги и логи могут оказаться в webroot сервера. Если это так, то нужно запретить доступ ко всему, кроме директории `web`. Если на вашем хостинге такое невозможно, рассмотрите возможность смены хостинга. ## Как избежать вывода отладочной информации и инструментов в боевом окружении -В режиме отладки, Yii отображает довольно подробные ошибки, которые полезны во время разработки. Однако, подробные ошибки удобны и для нападающего, так как могут раскрыть структуру базы данных, параметров конфигурации и части вашего кода. +В режиме отладки, Yii отображает довольно подробные ошибки, которые полезны во время разработки. Однако подробные ошибки +удобны и для нападающего, так как могут раскрыть структуру базы данных, параметров конфигурации и части вашего кода. -Вы никогда не должны оставлять Debug панель или Gii доступной для всех в боевом окружении. Это может быть использовано для получения информации о структуре базы данных или коде, может позволить заменить файлы, генерируемые Gii автоматически. +Вы никогда не должны оставлять Debug панель или Gii доступной для всех в боевом окружении. Это может быть использовано +для получения информации о структуре базы данных или коде, может позволить заменить файлы, генерируемые Gii автоматически. -Следует избегать включения в боевом окружении панели отладки, если только в этом нет острой необходимости. Она раскрывает всё приложение и детали конфигурации. Если вам всё-таки нужно запустить панель отладки, проверьте дважды, что доступ ограничен только вашими IP-адресами. +Следует избегать включения в боевом окружении панели отладки, если только в этом нет острой необходимости. +Она раскрывает всё приложение и детали конфигурации. Если вам всё-таки нужно запустить панель отладки, проверьте дважды, +что доступ ограничен только вашими IP-адресами. Дополнительная информация по теме: @@ -167,7 +182,7 @@ Yii предоставляет функции, которые зависят о ## Безопасная конфигурация сервера -Цель этого раздела - выявить риски, которые необходимо учитывать при создании конфигурации сервера для обслуживания веб-сайта на основе Yii. +Цель этого раздела — выявить риски, которые необходимо учитывать при создании конфигурации сервера для обслуживания веб-сайта на основе Yii. Помимо перечисленных здесь пунктов есть и другие параметры, связанные с безопасностью, которые необходимо учитывать, поэтому не рассматривайте этот раздел как завершенный. ### Как избежать атаки типа `Host`-header @@ -196,7 +211,7 @@ stream_socket_enable_crypto(): SSL operation failed with code 1. OpenSSL Error m Многие источники ошибочно предлагают отключить проверку одноранговых соединений SSL. Этого никогда не следует делать, поскольку это допускает атаки типа «man-in-the-middle». -Вместо этого, PHP должен быть правильно настроен: +Вместо этого PHP должен быть правильно настроен: 1. Скачайте файл [https://curl.haxx.se/ca/cacert.pem](https://curl.haxx.se/ca/cacert.pem). 2. Добавьте в свой php.ini следующее: diff --git a/guide/ru/security/cryptography.md b/guide/ru/security/cryptography.md index 26ca27cc..cd7ee59d 100644 --- a/guide/ru/security/cryptography.md +++ b/guide/ru/security/cryptography.md @@ -15,8 +15,10 @@ composer install yiisoft/security ## Генерация псевдослучайных данных Псевдослучайные данные используются во многих ситуациях. -Например, при изменении пароля по email, вам необходимо сгенерировать токен, сохранить его в базу данных и отправить по email пользователю, чтобы он с помощью него подтвердил владение аккаунтом. -Важно чтобы этот токен был уникальным и его было трудно угадать, иначе есть вероятность, что атакующий может предсказать значение токена и сбросить пароль пользователя. +Например, при изменении пароля по email, вам необходимо сгенерировать токен, сохранить его в базу данных и отправить +по email пользователю, чтобы он с помощью него подтвердил владение аккаунтом. +Важно, чтобы этот токен был уникальным и его было трудно угадать, иначе есть вероятность, что атакующий может +предсказать значение токена и сбросить пароль пользователя. Класс `\Yiisoft\Security\Random` делает генерацию псевдослучайных данных простой: @@ -28,12 +30,12 @@ $key = \Yiisoft\Security\Random::string(42); Если вам нужны байты или целые числа, напрямую используйте функции PHP: -- `random_bytes()` для байт. Обратите внимание, что вывод может быть не ASCII. -- `random_int()` для целых чисел. +- `random_bytes()` для генерации байт. Обратите внимание, что вывод может быть не ASCII. +- `random_int()` для генерации целых чисел. ## Шифрование и расшифровка -Yii предоставляет удобные вспомогательные функции для шифрования/расшифровки данных с помощью секретного кллюча. +Yii предоставляет удобные вспомогательные функции для шифрования/расшифровки данных с помощью секретного ключа. Данные проходят через функцию шифрования таким образом, что только тот, кто знает секретный ключ, может расшифровать их. Например, вам нужно сохранить некоторую информацию в вашей базе данных, но вы должны быть уверены, что только пользователь, который знает секретный ключ, сможет расшифровать их (даже если кто-нибудь скомпрометирует базу данных приложения) @@ -106,7 +108,7 @@ try { $maskedToken = \Yiisoft\Security\TokenMask::apply($token); ``` -Получить исходное начение из замаскированного: +Получить исходное значение из замаскированного: ```php $token = \Yiisoft\Security\TokenMask::remove($maskedToken);