elysdir
10 years ago
15 changed files with 802 additions and 104 deletions
@ -0,0 +1,61 @@
|
||||
Propriedades |
||||
=========== |
||||
|
||||
No PHP, atributos da classe são sempre chamadas de *propriedades*. Esses atributos fazem parte da definição da classe e são usadas para representar o estado de uma instância da classe (para diferenciar uma instância da classe de outra). Na prática, muitas vezes você pode querer lidar com a leitura ou a escrita de propriedades de maneiras especiais. Por Exemplo, você pode querer trimar uma string sempre que for atribuído um valor para a propriedade `label`. Você *poderia* usar o código a seguir para realizar esta tarefa: |
||||
|
||||
```php |
||||
$object->label = trim($label); |
||||
``` |
||||
|
||||
A desvantagem do código acima é que você teria que chamar `trim ()` em todos os lugares onde você definir a propriedade `label` no seu código. Se, no futuro, a propriedade `label` receber um novo requisito, tais como a primeira letra deve ser capitalizado, você teria que modificar novamente todos os pedaços de código que atribui um valor para a propriedade `label`. A repetição de código leva a erros, e é uma prática que você deve evitar sempre que possível. |
||||
|
||||
Para resolver este problema, Yii introduz uma classe base chamada [[yii\base\Object]] que suporta definições de propriedades baseadas nos métodos *getter* e *setter* da classe. Se uma classe precisa dessa funcionalidade, ela deve estender de [[yii\base\Object]], ou de uma classe-filha. |
||||
|
||||
> Informação: Quase todas as classes nativas (core) do framework Yii estendem de [[yii\base\Object]] ou de uma classe-filha. Isto significa que sempre que você vê um método *getter* ou *setter* em uma classe nativa (core), você pode usá-lo como uma propriedade. |
||||
|
||||
Um método getter é um método cujo nome inicia com a palavra `get`; um método setter inicia com `set`. |
||||
O nome depois do prefixo `get` ou `set` define o nome da propriedade. Por exemplo, um getter `getLabel()` e/ou um setter `setLabel()` define a propriedade chamada `label`, como mostrado no código a seguir: |
||||
|
||||
```php |
||||
namespace app\components; |
||||
|
||||
use yii\base\Object; |
||||
|
||||
class Foo extends Object |
||||
{ |
||||
private $_label; |
||||
|
||||
public function getLabel() |
||||
{ |
||||
return $this->_label; |
||||
} |
||||
|
||||
public function setLabel($value) |
||||
{ |
||||
$this->_label = trim($value); |
||||
} |
||||
} |
||||
``` |
||||
|
||||
(Para ser claro, os métodos getter e setter criam a propriedade `label`, que neste caso internamente refere-se ao atributo privado chamado `_label`.) |
||||
|
||||
Propriedades definidas por getters e setters podem ser usados como atributos da classe. A principal diferença é que quando tal propriedade é iniciada para leitura, O método getter correspondente será chamado; quando a propriedade é iniciada atribuindo um valor, o método setter correspondente será chamado. Por Exemplo: |
||||
|
||||
```php |
||||
// equivalent to $label = $object->getLabel(); |
||||
$label = $object->label; |
||||
|
||||
// equivalent to $object->setLabel('abc'); |
||||
$object->label = 'abc'; |
||||
``` |
||||
|
||||
A propriedade definida por um método getter sem um método setter é *somente de leitura*. Tentando atribuir um valor a tal propriedade causará uma exceção [[yii\base\InvalidCallException|InvalidCallException]]. Semelhantemente, uma propriedade definida por um método setter sem um método getter é *somente de gravação *, e tentar ler tal propriedade também causará uma exceção. Não é comum ter propriedade *somente de gravação*. |
||||
|
||||
Existem várias regras especiais para, e limitações sobre, as propriedades definidas via getters e setters: |
||||
|
||||
* Os nomes dessas propriedades são *case-insensitive*. Por exemplo, `$object->label` e `$object->Label` são a mesma coisa. Isso ocorre porque nomes de métodos no PHP são case-insensitive. |
||||
* Se o nome de uma tal propriedade é o mesmo que um atributo da classe, esta última terá precedência. Por exemplo, se a classe `Foo` descrita acima tiver um atributo `label`, então a atribuição `$object->label = 'abc'` afetará o *atributo* 'label'; esta linha não executaria `setLabel()` método setter. |
||||
* Essas propriedades não suportam visibilidade. Não faz nenhuma diferença para a definição dos métodos getter ou setter se a propriedade é pública, protegida ou privada. |
||||
* As propriedades somente podem ser definidas por getters e/ou setters *não estáticos*. Os métodos estáticos não serão tratados da mesma maneira. |
||||
|
||||
Voltando para o problema descrito no início deste guia, em vez de chamar `trim()` em todos os lugares que um valor for atribuído a `label`, `trim()`Agora, só precisa ser invocado dentro do setter `setLabel()`.E se uma nova exigência faz com que seja necessário que o 'label' seja inicializado capitalizado, o método `setLabel()` pode rapidamente ser modificado sem tocar em nenhum outro código. Esta única mudança afetará de forma global cada atribuição à propriedade `label`. |
@ -0,0 +1,177 @@
|
||||
Лучшие практики безопасности |
||||
============================ |
||||
|
||||
Ниже мы рассмотрим основные принципы безопасности и опишем, как избежать угроз при разработке на Yii. |
||||
|
||||
Основные принципы |
||||
----------------- |
||||
|
||||
Есть два основных принципа безопасности, независимо от того, какое приложение разрабатывается: |
||||
|
||||
1. Фильтрация ввода. |
||||
2. Экранирование вывода. |
||||
|
||||
|
||||
### Фильтрация ввода |
||||
|
||||
Фильтрация ввода означает, что входные данные никогда не должны считаться безопасными и вы всегда должны проверять, |
||||
являются ли полученные данные допустимыми. Например, если мы знаем, что сортировка может быть осуществлена только |
||||
по трём полям `title`, `created_at` и `status`, и поле может передаваться через ввод пользователем, лучше проверить |
||||
значение там, где мы его получили: |
||||
|
||||
```php |
||||
$sortBy = $_GET['sort']; |
||||
if (!in_array($sortBy, ['title', 'created_at', 'status'])) { |
||||
throw new Exception('Invalid sort value.'); |
||||
} |
||||
``` |
||||
|
||||
В Yii, вы, скорее всего, будете использовать [валидацию форм](input-validation.md), чтоб делать такие проверки. |
||||
|
||||
|
||||
### Экранирование вывода |
||||
|
||||
Экранирование вывода означает, что данные в зависимости от контекста должны экранироваться, например в контексте |
||||
HTML вы должны экранировать `<`, `>` и похожие специальные символы. В контексте JavaScript или SQL будет другой набор |
||||
символов. Так как ручное экранирование черевато ошибками, Yii предоставляет различные утилиты для экранирования в |
||||
различных контекстах. |
||||
|
||||
Как избежать SQL-иньекций |
||||
------------------------- |
||||
|
||||
SQL-иньекции происходят, когда текст запроса формируется склеиванием неэкранированных строк, как показано ниже: |
||||
|
||||
```php |
||||
$username = $_GET['username']; |
||||
$sql = "SELECT * FROM user WHERE username = '$username'"; |
||||
``` |
||||
|
||||
Вместо того, чтобы подставлять корректное имя пользователя, злоумышленник может передать вам в приложение что-то вроде |
||||
`'; DROP TABLE user; --`. |
||||
В результате SQL будет следующий: |
||||
|
||||
```sql |
||||
SELECT * FROM user WHERE username = ''; DROP TABLE user; --' |
||||
``` |
||||
|
||||
Это валидный запрос, который сначала будет искать пользователей с пустым именем, а затем удалит таблицу `user`. |
||||
Скорее всего будет сломано приложение и будут потеряны данные (вы ведь делаете регулярное резервное копирование?). |
||||
|
||||
Большинство запросов к базе данных в Yii происходит через [Active Record](db-active-record.md), который правильно |
||||
использует подготовленные запросы PDO внутри. При использовании подготовленных запросов невозможно манипулировать |
||||
запросом как это показано выше. |
||||
|
||||
Тем не менее, иногда нужны [сырые запросы](db-dao.md) или [построитель запросов](db-query-builder.md). В этом случае |
||||
вы должны использовать безопасные способы передачи данных. Если данные используются для сравнения со значением |
||||
столбцов предпочтительнее использовать подготовленные запросы: |
||||
|
||||
```php |
||||
// query builder |
||||
$userIDs = (new Query()) |
||||
->select('id') |
||||
->from('user') |
||||
->where('status=:status', [':status' => $status]) |
||||
->all(); |
||||
|
||||
// DAO |
||||
$userIDs = $connection |
||||
->createCommand('SELECT id FROM user where status=:status') |
||||
->bindValues([':status' => $status]) |
||||
->queryColumn(); |
||||
``` |
||||
|
||||
Если данные используются в качестве имён столбцов или таблиц, то лучший путь - это разрешить только предопределённый |
||||
набор значений: |
||||
|
||||
```php |
||||
function actionList($orderBy = null) |
||||
{ |
||||
if (!in_array($orderBy, ['name', 'status'])) { |
||||
throw new BadRequestHttpException('Only name and status are allowed to order by.') |
||||
} |
||||
|
||||
// ... |
||||
} |
||||
``` |
||||
|
||||
Если это невозможно, то имена столбцов и таблиц должны экранироваться. Yii использует специальный синтаксис |
||||
для экранирования для всех поддерживаемых баз данных: |
||||
|
||||
```php |
||||
$sql = "SELECT COUNT([[$column]]) FROM {{table}}"; |
||||
$rowCount = $connection->createCommand($sql)->queryScalar(); |
||||
``` |
||||
|
||||
Вы можете получить подробную информацию о синтаксисе в [Экранирование имён таблиц и столбцов](db-dao.md#quoting-table-and-column-names). |
||||
|
||||
|
||||
Как избежать XSS |
||||
---------------- |
||||
|
||||
XSS или крос-сайтинговый скриптинг становится возможен, когда не экранированный выходной HTML попадает в браузер. |
||||
Например, если пользователь должен ввести свой имя, но вместо `Alexander` он вводит `<script>alert('Hello!');</script>`, то |
||||
все страницы, которые его выводят без экранирования, будут выполнять JavaScript `alert('Hello!');`, и в результате |
||||
будет выводится окно сообщения в браузере. В зависимости от сайта, вместо невинных скриптов с выводом всплывающего |
||||
hello, злоумышленниками могут быть отправлены скрипты, похищающие личные данные пользователей сайта, |
||||
либо выполняющие операции от их имени. |
||||
|
||||
В Yii избежать XSS легко. На месте вывода текста необходими выбрать один из двух вариантов: |
||||
|
||||
1. Вы хотите вывести данные в виде обычного текста. |
||||
2. Вы хотите вывести данные в виде HTML. |
||||
|
||||
Если вам нужно вывести простой текст, то экранировать лучше следующим образом: |
||||
|
||||
```php |
||||
<?= \yii\helpers\Html::encode($username) ?> |
||||
``` |
||||
|
||||
Если нужно вывести HTML, вам лучше воспользоваться HtmlPurifier: |
||||
|
||||
```php |
||||
<?= \yii\helpers\HtmlPurifier::process($description) ?> |
||||
``` |
||||
|
||||
Обратите внимание, что обработка с помощью HtmlPurifier довольно тяжела, так что неплохо бы задуматься о кешировании. |
||||
|
||||
Как избежать CSRF |
||||
----------------- |
||||
|
||||
CSRF - это аббревиатура для межсайтинговой подмены запросов. Идея заключается в том, что многие приложения предполагают, |
||||
что запросы, приходящие от браузера, отправляются самим пользователем. Это может быть неправдой. |
||||
|
||||
Например, сайт `an.example.com` имеет URL `/logout`, который, используя простой GET, разлогинивает пользователя. Пока |
||||
это запрос выполняется самим пользователем - всё в порядке, но в один прекрасный день злоумышленники размещают код |
||||
`<img src="http://an.example.com/logout">` на форуме с большой посещаемостью. Браузер не делает никаких отличий |
||||
между запросом изображения и запросом страницы, так что когда пользователь откроет страницу с таким тегом `img`, браузер отправит GET запрос на указанный адрес, и пользователь будет разлогинен. |
||||
|
||||
Вот основная идея. Можно сказать, что в разлогировании пользователя нет ничего серьёзного, но с помощью этой уязвимости, можно выполнять опасные операции. Представьте, что существует страница http://an.example.com/purse/transfer?to=anotherUser&amout=2000, обращение к которой с помощью GET запроса, приводит к перечислению 2000 единиц валюты со счета авторизированного пользователя на счет пользователя с логином anotherUser. Учитывая, что браузер для загрузки контента отправляет GET запросы, можно подумать, что разрешение на выполнение такой операции только POST запросом на 100% обезопасит от проблем. К сожалению. это не совсем правда. Учитывайте, что вместо тега <img>, злоумышленник может внедрить JavaScript код, который будет отправлять нужные POST запросы на этот URL. |
||||
|
||||
Для того, чтоб избежать CSRF вы должны всегда: |
||||
|
||||
1. Следуйте спецификациям HTTP, например запрос GET не должен менять состояние приложения. |
||||
2. Держите защиту CSRF в Yii включенной. |
||||
|
||||
|
||||
Как избежать нежелательного доступа к файлам |
||||
-------------------------------------------- |
||||
|
||||
По умолчанию, webroot сервера указывает на каталог `web`, где лежит `index.php`. В случае использования виртуального |
||||
хостинга, это может быть недостижимо, в конечном итоге весь код, конфиги и логи могут оказаться в webroot сервера. |
||||
|
||||
Если это так, то нужно запретить доступ ко всему, кроме директории `web`. Если на вашем хостинге такое невозможно, |
||||
рассмотрите возможность смены хостинга. |
||||
|
||||
Как избежать отладочной информации и утилит в продуктиве |
||||
-------------------------------------------------------- |
||||
|
||||
В режиме отладки, Yii отображает довольно подробные ошибки, которые полезны во время разработки. Дело в том, что |
||||
подробные ошибки удобны для нападающего, так как могут раскрыть структуру базы данных, параметров конфигурации и части |
||||
вашего кода. Никогда не запускайте продуктивное приложение с `YII_DEBUG` установленным в `true` в вашем `index.php`. |
||||
|
||||
Вы никогда не должны включать Gii на продуктиве. Он может быть использован для получения информации о структуре |
||||
базы данных, кода и может позволить заменить файлы, генерируемые Gii автоматически. |
||||
|
||||
Также следует избегать включения на продуктиве панели отладки, если только в этом нет острой необходимости. |
||||
Она раскрывает всё приложение и детали конфигурации. Если вам все таки нужно запустить панель отладки на продуктиве, |
||||
проверьте дважды что доступ ограничен только вашими IP-адресами. |
@ -0,0 +1,152 @@
|
||||
Работа с паролями |
||||
================= |
||||
|
||||
> Примечание: этот раздел находится на стадии разработки. |
||||
|
||||
Хорошая безопасность является жизненно важной для жизни и успеха любого приложения. |
||||
К сожалению, многие разработчики предпочитают упрощять, когда речь заходит о безопасности, |
||||
либо из-за отсутствия понимания, либо потому, что считают реализацию слишком сложной. |
||||
Для того, чтобы сделанное вами на Yii приложение было как можно более безопасным, в Yii есть несколько удобных |
||||
и простых в использовании функций обеспечения безопасности. |
||||
|
||||
|
||||
Хеширование и проверка пароля |
||||
----------------------------- |
||||
|
||||
Многие разработчики знают, что хранить пароль открытым текстом нельзя, но многие до сих пор считают безопасным |
||||
использование для хеширования паролей `md5` или `sha1`. Раньше упомянутых алгоритмов было достаточно, но современное |
||||
оборудование позволяет подобрать эти хеши очень быстро, методом простого перебора. |
||||
|
||||
Для того, чтобы обеспечить повышенную безопасность паролей ваших пользователей даже в худшем случае (ваше |
||||
приложение взломано), нужно использовать алгоритм шифрования, устоичивый к атаке перебором. Лучший вариант в текущий |
||||
момент `bcrypt`. В PHP вы можете использовать хеши `bcrypt` через [функцию crypt](http://php.net/manual/en/function.crypt.php). |
||||
Yii обеспечивает две вспомогательные функции, которые упрощают использование функции `crypt` для генерации и проверки |
||||
пароля. |
||||
|
||||
Когда пользователь задаёт пароль (например во время регистрации), пароль должен быть захеширован: |
||||
|
||||
|
||||
```php |
||||
$hash = Yii::$app->getSecurity()->generatePasswordHash($password); |
||||
``` |
||||
|
||||
Хеш можно связать с соответствующим аттрибутом модели, так чтобы он сохранялся в базе для последующего использования. |
||||
|
||||
Когда пользователь попытается войти, отправленый пароль должен быть хеширован и сравнён с ранее сохранённым хешем: |
||||
|
||||
```php |
||||
if (Yii::$app->getSecurity()->validatePassword($password, $hash)) { |
||||
// всё хорошо, пользователь может войти |
||||
} else { |
||||
// неправильный пароль |
||||
} |
||||
``` |
||||
|
||||
Генерация псевдослучайных данных |
||||
-------------------------------- |
||||
|
||||
Псевдослучайные данные полезны во многих ситуациях. Например, для сброса пароля с помощью электронной почты |
||||
вам необходимо сгенерировать специальный токен, сохранить его в БД, и отправить по почте конечному пользователю, |
||||
который в свою очередь подтвердит им свою личность. Очень важно, чтобы этот маркер был уникальным и сложно |
||||
подделываемым и злоумышленник не мог предсказать токен и сбросить пароль пользователя. |
||||
|
||||
Помощник безопасности Yii делает генерацию псевдослучайных данных простой: |
||||
|
||||
```php |
||||
$key = Yii::$app->getSecurity()->generateRandomString(); |
||||
``` |
||||
|
||||
Обратите внимание, что у вас должно быть установлено расширение `openssl` для генерации криптографически безопасных данных. |
||||
|
||||
Шифрование и Расшифровка |
||||
------------------------ |
||||
|
||||
Yii предоставляет удобные вспомогательные функции, которые позволяют шифровать/дешифровать данные, используя секретный ключ. |
||||
Данные, переданные в функцию шифрования, могут быть расшифрованы только человеком, имеющим секретный ключ. Например, нам |
||||
нужно хранить некоторую информацию в базе данных, но мы должны быть уверены, что только пользователь, который имеет |
||||
секретный ключ, сможет посмотреть их (даже если база данных будет скомпрометирована): |
||||
|
||||
```php |
||||
// $data и $secretKey передаются из формы |
||||
$encryptedData = Yii::$app->getSecurity()->encryptByPassword($data, $secretKey); |
||||
// сохраняем $encryptedData в базу данных |
||||
``` |
||||
|
||||
Позднее, когда пользователь захочет прочитать данные: |
||||
|
||||
```php |
||||
// $secretKey получается из формы, $encryptedData получается из базы данных |
||||
$data = Yii::$app->getSecurity()->decryptByPassword($encryptedData, $secretKey); |
||||
``` |
||||
|
||||
Подтверждение целостности данных |
||||
-------------------------------- |
||||
|
||||
Есть ситуации, в которых вам нужно убедиться, что ваши данные не были подделаны третьей стороной, или как-то повреждены. |
||||
Yii обеспечивает простой способ подтверждения целостности данных в виде двух вспомогательных функций. |
||||
|
||||
Префикс данных генерируются из секретного ключа и данных |
||||
|
||||
```php |
||||
// $secretKey получается от приложения или от пользователя, $genuineData получаются из надёжного источника |
||||
$data = Yii::$app->getSecurity()->hashData($genuineData, $secretKey); |
||||
``` |
||||
|
||||
Проверка целостности данных |
||||
|
||||
```php |
||||
// $secretKey получается от приложения или от пользователя, $data данные полученные из ненадёжного источника |
||||
$data = Yii::$app->getSecurity()->validateData($data, $secretKey); |
||||
``` |
||||
|
||||
|
||||
todo: предотвращение XSS, CSRF, защита cookie, смотрите руководство 1.1 |
||||
|
||||
Вы также можете отключить проверку CSRF для контроллера и/или действия, через настройку его свойства: |
||||
|
||||
```php |
||||
namespace app\controllers; |
||||
|
||||
use yii\web\Controller; |
||||
|
||||
class SiteController extends Controller |
||||
{ |
||||
public $enableCsrfValidation = false; |
||||
|
||||
public function actionIndex() |
||||
{ |
||||
// CSRF валидация не будет проводится для этого и других действий |
||||
} |
||||
|
||||
} |
||||
``` |
||||
|
||||
Чтобы отключить проверку CSRF в отдельном действии: |
||||
|
||||
```php |
||||
namespace app\controllers; |
||||
|
||||
use yii\web\Controller; |
||||
|
||||
class SiteController extends Controller |
||||
{ |
||||
public function beforeAction($action) |
||||
{ |
||||
// ...установите здесь `$this->enableCsrfValidation` в зависимости от каких-то условий... |
||||
// вызываем родительский метод для проверки CSRF если свойство установлено в `true` |
||||
return parent::beforeAction($action); |
||||
} |
||||
} |
||||
``` |
||||
|
||||
Безопасные Cookies |
||||
------------------ |
||||
|
||||
- валидация |
||||
- httpOnly по умолчанию |
||||
|
||||
Смотрите также |
||||
-------------- |
||||
|
||||
- [Безопасность представлений](structure-views.md#security) |
||||
|
@ -0,0 +1,15 @@
|
||||
Автоматизация |
||||
============= |
||||
|
||||
При работе над Yii, некоторые задачи, можно выполнять автоматически: |
||||
|
||||
- Генерация карты классов в файл `classes.php`, который находится в корневой директории фреймворка. |
||||
Запустите `./build/build classmap` для его генерации. |
||||
|
||||
- Генерация аннотаций `@property` в файлах классов, описывающих свойства введённые геттерами и сеттерами. |
||||
Запустите `./build/build php-doc/property` для их обновления. |
||||
|
||||
- Исправление стиля кодирования и других мелких ошибок в коментариях phpdoc. |
||||
Запустите `./build/build php-doc/fix` для их исправления. |
||||
Проверьте изменения перед тем как их закомитить, так как могут быть нежелательные изменения, потому что команда не |
||||
является совершенной. Вы можете использовать `git add -p` для обзора изменеий. |
@ -0,0 +1,233 @@
|
||||
Рабочий процесс Git для разработчиков Yii2 |
||||
========================================== |
||||
|
||||
Итак, вы хотите разрабатывать Yii? Хорошо! Но для того чтоб увеличить шанс принятия ваших изменений, |
||||
пожалуйста следуйте следующим шагам. Если вы новичок в git и github, вы можете сначала проверить |
||||
[github help](http://help.github.com/), [try git](https://try.github.com) или прочитать о |
||||
[внутренней модели данных git](http://nfarina.com/post/9868516270/git-is-simpler). |
||||
|
||||
Подготовка вашего рабочего окружения |
||||
------------------------------------ |
||||
|
||||
Следующие шаги будут создавать рабочее окружение для Yii, которое вы можете использовать для работы над основным кодом |
||||
фреймворка. *Эти шаги будут нужны только в первый раз*. |
||||
|
||||
### 1. [Форкаем](http://help.github.com/fork-a-repo/) репозиторий Yii на github и клонируйте ваш форк в ваше рабочее окружение. |
||||
|
||||
``` |
||||
git clone git@github.com:YOUR-GITHUB-USERNAME/yii2.git |
||||
``` |
||||
|
||||
Если у вас есть проблемы с настройкой GIT для работы с GitHub в Linux, или вы получаете ошибку похожую на "Permission Denied |
||||
(publickey)", тогда вы должны настроить ваш GIT по [этой инструкции](http://help.github.com/linux-set-up-git/) |
||||
|
||||
### 2. Добавляем главный репозиторий Yii как дополнительный внешний git репозиторий назывемый "upstream" |
||||
|
||||
Перейдите в каталог, куда вы склонировали Yii, как правило "yii2". Затем введите следующую команду: |
||||
|
||||
``` |
||||
git remote add upstream git://github.com/yiisoft/yii2.git |
||||
``` |
||||
|
||||
### 3. Настройка тестовой среды |
||||
|
||||
Следующие шаги не обязательны, если вы хотите работать только с переводом или документацией. |
||||
|
||||
- выполните `composer update` для установки зависимостей (если [composer у вас установлен глобально](https://getcomposer.org/doc/00-intro.md#globally)). |
||||
- выполните `php build/build dev/app basic` для клонирования базового приложения и установки его зависимостей. |
||||
Эта команда установит сторонние пакеты composer обычным образом, но создаст ссылку с репозитория yii2 на только |
||||
что загуженный репозиторий. Таким образом у вас будет только один экземпляр кода. |
||||
|
||||
При необходимости делаем тоже самое для приложения advanced: `php build/build dev/app advanced`. |
||||
|
||||
Данная команда также может быть использована для обновления зависимостей, внутри она использует `composer update`. |
||||
|
||||
**Теперь у нас есть рабочая площадка для экспериментов с Yii 2.** |
||||
|
||||
Следующие шаги не обязательны. |
||||
|
||||
### Модульные тесты |
||||
|
||||
Вы можете выполнить модульные тесты с помощью команды `phpunit` в корневой директории приложения. Если у вас phpunit |
||||
не установлен глобально, вы можете запустить `php vendor/bin/phpunit`. |
||||
|
||||
Некоторые тесты требуют дополнительно установки и настройки баз данных. Вы можете создать `tests/data/config.local.php` |
||||
для переопределения настроек, которые определены в `tests/data/config.php`. |
||||
|
||||
Вы можете ограничить тестирование группой тестов, с которой вы сейчас работаете, например запускать только тесты для |
||||
валидаторов и redis. Вы можете получить список доступных групп выполнив `phpunit --list-groups`. |
||||
|
||||
### Расширения |
||||
|
||||
Для работы над расширениями вы можете склонировать репозиторий расширения. Мы сделали команду, которая поможет вам |
||||
сделать это: |
||||
|
||||
``` |
||||
php build/build dev/ext <extension-name> |
||||
``` |
||||
|
||||
где `<extension-name>` это имя расширения, например `redis`. |
||||
|
||||
Если вы хотите протестировать расширение в одном из шаблонов приложений, просто добавьте его в `composer.json` |
||||
приложения, например добавив `"yiisoft/yii2-redis": "*"` в секцию `require` базового приложения. |
||||
Запустите `php build/build dev/app basic` для установки расширения и его зависимостей и создания символической |
||||
ссылки на `extensions/redis` так чтоб вы работали не папке вендорных пакетов composer, а напрямую в репозитории yii2. |
||||
|
||||
|
||||
Работа над багами и новыми функциями |
||||
------------------------------------ |
||||
|
||||
Приготовив вашу среду разработки вы можете начать работу над исправлением багов и разработкой новых функций. |
||||
|
||||
### 1. Убедитесь, что issue создана для того, над чем вы работаете, если потребуется много времени для исправления |
||||
|
||||
Все новые функции и баги должны быть связаны с issue для того, чтоб иметь единое место для обсуждения и документирования. |
||||
Пртратьте несколько минут на поиск существующей issue, которая соответствует вашим изменениям. Если вы найдёте её в |
||||
списке, то пожалуста откоментируйте, что вы начали над ней работать. Если вы не нашли нужной issue пожалуйста |
||||
[создайте новую issue](report-an-issue.md) или создайте сразу запрос на изменения если это простые изменения. |
||||
Это позволит команде проверить ваше предложение, и обеспечивать соответствующую обратную связь. |
||||
|
||||
> Для небольших изменении или документации, или простых исправлений, вам нет необходимости создавать issue, |
||||
запрос на изменения в этом случае подходит лучше. |
||||
|
||||
### 2. Вытягивание последнего кода из основного репозитория Yii |
||||
|
||||
``` |
||||
git fetch upstream |
||||
``` |
||||
|
||||
Вы должны начинать с этого действия работу над каждым новым предложением, убеждайтесь что вы работаете над самой |
||||
последней версией кода. |
||||
|
||||
### 3. Создание новой ветки для ваших изменений, основанных на текущем мастере Yii |
||||
|
||||
> Это очень важно, так как вы не сможете отправлять более одного запроса на изменения из вашего репозитория, если |
||||
будете использовать ветку master. |
||||
|
||||
Каждая отдельное исправление или изменение должно разрабатываться в своей ветке. Имя ветки должно быть описательным |
||||
и начинаться с номера issue, с которым связан ваш код. Если вы не исправляете какой-то конкретный issue, просто |
||||
пропустите номер. |
||||
Например: |
||||
|
||||
``` |
||||
git checkout upstream/master |
||||
git checkout -b 999-name-of-your-branch-goes-here |
||||
``` |
||||
|
||||
### 4. Делайте свою магию, пишите ваш код |
||||
|
||||
Убедитесь, что он работает :) |
||||
|
||||
Модульные тесты всегда приветствуются. Протестированный и с хорошим покрытием код значительно упрощает задачу проверки |
||||
вашего предложения. Сломанные модульные тесты, как описание проблемы, тоже приветствуются. |
||||
|
||||
### 5. Обновите CHANGELOG |
||||
|
||||
Отредактируйте файл CHANGELOG, включив ваши изменения. Для этого нужно вставить строки в начало файла под заголовком |
||||
"Work in progress", строки с описанием изменений должны выглядеть похожими на следующие: |
||||
|
||||
``` |
||||
Bug #999: a description of the bug fix (Your Name) |
||||
Enh #999: a description of the enhancement (Your Name) |
||||
``` |
||||
|
||||
`#999` это номер issue описывающей `Bug` или `Enh`. |
||||
Лог изменений должен быть сгруппирован по типу (`Bug`,`Enh`) и отсортирован по номеру issue. |
||||
|
||||
Для очень маленьких исправлений, например опечаток и изменений документации, нет необходимости обновлять CHANGELOG. |
||||
|
||||
### 6. Фиксация ваших изменений |
||||
|
||||
Добавляем файлы/изменения которые вы хотите зафиксировать в [staging area](http://gitref.org/basic/#add) |
||||
|
||||
``` |
||||
git add path/to/my/file.php |
||||
``` |
||||
|
||||
Вы можете использовать опцию `-p` для того, чтоб выбрать, какие изменения вы хотите добавить в коммит. |
||||
|
||||
Фиксируйте ваши изменения с описательным сообщением. Убедитесь что в сообщение есть номер `#XXX`, так github |
||||
автоматически свяжет ваш коммит с тикетом: |
||||
|
||||
``` |
||||
git commit -m "A brief description of this change which fixes #999 goes here" |
||||
``` |
||||
|
||||
### 7. Получение последнего кода из апстрима Yii в вашу ветку |
||||
|
||||
``` |
||||
git pull upstream master |
||||
``` |
||||
|
||||
Это гарантирует, что вы используете самый последний код в вашей ветке перед отправкой запроса на изменения. Если есть |
||||
какие-либо конфликты слияния, вы должны исправить их и зафиксировать изменения ещё раз. Это гарантирует, что команда Yii |
||||
сможет слить ваши изменения одним кликом. |
||||
|
||||
### 8. Разрешив зависимости, оптравляем код на github |
||||
|
||||
``` |
||||
git push -u origin 999-name-of-your-branch-goes-here |
||||
``` |
||||
|
||||
Опция `-u` сохранит указание на ветку в github, чтобы при следующем выполнении `git push`, git знал, куда отправлять |
||||
изменения. Это полезно, если вы хотите позже отправлять ещё комиты в этот запрос на слияние. |
||||
|
||||
### 9. Открываем [запрос на слияние](http://help.github.com/send-pull-requests/) в *upstream*. |
||||
|
||||
Перейдите в репозиторий на github и нажмите "Pull Request", выберите ветку справа и введите больше информации |
||||
в поле комментариев. Чтобы связать запрос на изменение с issue, добавьте в комментарий `#999` - где 999 это номер issue. |
||||
|
||||
> Обратите внимание, что каждый запрос на слияние должен исправлять единственное изменение. Для множества независимых |
||||
изменений, пожалуйста откройте несколько запросов на слияние. |
||||
|
||||
### 10. Проверка вашего кода кем-то |
||||
|
||||
Кто-то будет проверять ваш код, и, возможно, вам будет предложено внести некоторые изменения, если это так, то перейдите |
||||
к шагу #6 (вам не надо открывать новый запрос на слияние, если текущий ещё открыт). Если код будет принят, он будет |
||||
влит в основную ветку и станет частью следующего релиза Yii. Если нет, не унывайте, разным людям необходимы различные |
||||
функции и Yii не может реализовывать всё для всех, ваш код будет ещё доступен на github как ссылка для людей кому он |
||||
может пригодится. |
||||
|
||||
### 11. Очистка |
||||
|
||||
После того, как код был принят или отклонён, вы можете удалить ветки, над которыми вы работали в локальном репозитории |
||||
и в `origin`. |
||||
|
||||
``` |
||||
git checkout master |
||||
git branch -D 999-name-of-your-branch-goes-here |
||||
git push origin --delete 999-name-of-your-branch-goes-here |
||||
``` |
||||
|
||||
### Примечание: |
||||
|
||||
Для обнаружения регрессии как можно раньше, каждое слияние кодовой базы Yii на github будет подхвачено |
||||
[Travis CI](http://travis-ci.org) для автоматического запуска тестов. Люди из *core team* не хотят нагружать |
||||
этот сервис, поэтому добавляют текст [`[ci skip]`](http://about.travis-ci.org/docs/user/how-to-skip-a-build/) в описание |
||||
запроса на слияние, в следующих ситуациях: |
||||
|
||||
* затронуты только javascript, css файлы или файлы изображений, |
||||
* обновление документации, |
||||
* изменения затрагивают только строки (например обновление переводов). |
||||
|
||||
Это защитит travis от запуска тестов на изменениях, которые не покрыты тестами. |
||||
|
||||
### Обзор команд (для продвинутых участников) |
||||
|
||||
``` |
||||
git clone git@github.com:YOUR-GITHUB-USERNAME/yii2.git |
||||
git remote add upstream git://github.com/yiisoft/yii2.git |
||||
``` |
||||
|
||||
``` |
||||
git fetch upstream |
||||
git checkout upstream/master |
||||
git checkout -b 999-name-of-your-branch-goes-here |
||||
|
||||
/* ваша магия, обновление changelog если нужно */ |
||||
|
||||
git add path/to/my/file.php |
||||
git commit -m "A brief description of this change which fixes #999 goes here" |
||||
git pull upstream master |
||||
git push -u origin 999-name-of-your-branch-goes-here |
||||
``` |
@ -0,0 +1,53 @@
|
||||
Стиль кодирования представлений Yii2 |
||||
==================================== |
||||
|
||||
Данный стиль кодирования используется для представлений в ядре Yii 2.x и оффициальных представлениях. Мы не заставляем |
||||
вас использовать данный стиль кодирования для ваших приложений. Не стесняйтесь использовать тот стиль, который вам |
||||
больше подходит. |
||||
|
||||
```php |
||||
<?php |
||||
// Открывающий PHP тег должен быть в каждом файле шаблона. Пустая строка после открывающего тега также необходима. |
||||
|
||||
// Описывайте входные переменные, переданные сюда контроллером. |
||||
/* @var $this yii\base\View */ |
||||
/* @var $form yii\widgets\ActiveForm */ |
||||
/* @var $posts app\models\Post[] */ |
||||
/* @var $contactMessage app\models\ContactMessage */ |
||||
// Пустая строка ниже необходима. |
||||
|
||||
// Описание классов с пространствами имён. |
||||
use yii\helpers\Html; |
||||
use yii\widgets\ActiveForm; |
||||
// Пустая строка ниже необходима. |
||||
|
||||
// Установка свойств контекста, вызов сеттеров и другие действия. |
||||
$this->title = 'Posts'; |
||||
?> |
||||
<!-- Отдельные блоки PHP являются предпочтительными для foreach, for, if и т.д. --> |
||||
<?php foreach ($posts as $post): ?> |
||||
<!-- Заметьте здесь есть отступ. --> |
||||
<h2><?= Html::encode($post['title']) ?></h2> |
||||
<p><?= Html::encode($post['shortDescription']) ?></p> |
||||
<!-- `endforeach;`, `endfor;`, `endif;`, и другие должны ипользоваться вместо `}` в случае использования множественных PHP блоков --> |
||||
<?php endforeach; ?> |
||||
|
||||
<!-- Описание виджета может быть, а может и не быть, разбито на разных строках. --> |
||||
<?php $form = ActiveForm::begin([ |
||||
'options' => ['id' => 'contact-message-form'], |
||||
'fieldConfig' => ['inputOptions' => ['class' => 'common-input']], |
||||
]); ?> |
||||
<!-- Заметьте здесь есть отступ. --> |
||||
<?= $form->field($contactMessage, 'name')->textInput() ?> |
||||
<?= $form->field($contactMessage, 'email')->textInput() ?> |
||||
<?= $form->field($contactMessage, 'subject')->textInput() ?> |
||||
<?= $form->field($contactMessage, 'body')->textArea(['rows' => 6]) ?> |
||||
|
||||
<div class="form-actions"> |
||||
<?= Html::submitButton('Submit', ['class' => 'common-button']) ?> |
||||
</div> |
||||
<!-- Завершающий вызов виджета должен быть в индивидуальном PHP теге. --> |
||||
<?php ActiveForm::end(); ?> |
||||
<!-- Завершающий символ переноса строки обязателен. --> |
||||
|
||||
``` |
Loading…
Reference in new issue