Правильный код на PHP (PHP стандарты кодирования)
Наверное, каждый разработчик рано или поздно сталкивается с потребностью приведения своего кода в порядок. Этот порядок можно придумать самому, а можно использовать уже готовый стандарт кодирования.
Стандарт кодирования - это набор определенных правил, которых следует придерживаться при написании кода для того, чтобы код был легко читаем, чтобы в нем могли разобраться другие разработчики, чтобы его было легче тестировать, исправлять в нем баги и поддерживать.
В php существует довольно много различных стандартов:
- PEAR Coding Standards
- Zend Framework Coding Standard
- Symfony Coding Standards
- Cake PHP Coding Standards
- DB Medialab PHP Coding Standard
- Стандарты оформления кода PHP (производная предыдущего пункта)
- PHP Coding Guidelines
- GForge: PHP Coding Standards
Источник - https://habrahabr.ru/post/38214/.
Помимо стандартов отдельных проектов существует некий единый стандарт, вернее сборник стандартов, имеющих общее название PSR - PHP Standards Recommendations или Рекомендации по Стандартам в ПХП. Разрабатывает и согласовывает эти стандарты организация Группа по обеспечению совместимости фреймворков (Framework Interoperability Group или FIG), куда входят представители разных проектов (фреймворокв, cms и др.). Официальный сайт FIG. Также стандарты можно посмотреть на github.
В данной статье расмотрим 2 стандарта - PSR-1 и PSR-2.
PSR-1 – Базовый стандарт оформления кода.
Данный раздел описывает стандартные элементы, являющиеся существенными для обеспечения высокой технической совместимости кода, созданного и/или поддерживаемого различными разработчиками.
Слова «НЕОБХОДИМО» / «ДОЛЖНО» («MUST»), «НЕДОПУСТИМО» («MUST NOT»), «ТРЕБУЕТСЯ» («REQUIRED»), «НУЖНО» («SHALL»), «НЕ ПОЗВОЛЯЕТСЯ» («SHALL NOT»), «СЛЕДУЕТ» («SHOULD»), «НЕ СЛЕДУЕТ» («SHOULD NOT»), «РЕКОМЕНДУЕТСЯ» («RECOMMENDED»), «МОЖЕТ» / «ВОЗМОЖНО» («MAY») и «НЕОБЯЗАТЕЛЬНО» («OPTIONAL») в этом документе следует понимать так, как это описано в RFC 2119 (и его переводе).
1. Общие положения
- В файлах НЕОБХОДИМО использовать только теги <?php и <?=.
- Файлы НЕОБХОДИМО представлять только в кодировке UTF-8 без BOM-байта.
- В файлах СЛЕДУЕТ либо объявлять структуры (классы, функции, константы и т.п.), либо генерировать побочные эффекты (выполнять действия) (например: передавать данные в выходной поток, модифицировать настройки и т.п.), но НЕ СЛЕДУЕТ делать одновременно и то, и другое.
- Имена пространств имён и имена классов ДОЛЖНЫ следовать стандарту PSR-0.
- Имена классов ДОЛЖНЫ быть объявлены с использованием т.н. «StudlyCaps» (каждое слово начинается с большой буквы, между словами нет разделителей).
- Константы классов ДОЛЖНЫ быть объявлены исключительно в верхнем регистре с использованием символа подчёркивания для разделения слов.
- Имена методов ДОЛЖНЫ быть объявлены с использованием т.н. «camelCase» (первое слово пишется в нижнем регистре, далее каждое слово начинается с большой буквы, а между словами нет разделителей).
2. Файлы
2.1. PHP-теги
PHP-код ОБЯЗАТЕЛЬНО следует заключать в полную версию (<?php ?>) тегов или укороченную (сокращённую запись echo) версию (<?= ?>) тегов и НЕДОПУСТИМО заключать ни в какие иные разновидности тегов.
2.2. Кодировка символов
PHP-код ДОЛЖЕН быть представлен только в кодировке UTF-8 без BOM-байта.
2.3. Побочные эффекты
В файлах СЛЕДУЕТ либо объявлять структуры (классы, функции, константы и т.п.) и не создавать побочных эффектов (например: передавать данные в выходной поток, модифицировать настройки и т.п.), либо реализовывать логику, порождающую побочные эффекты, но НЕ СЛЕДУЕТ делать одновременно и то, и другое.
Под «побочными эффектами» понимается реализация логики, не связанной с объявлением классов, функций, констант и т.п. – даже подключение внешнего файла уже является «побочным эффектом».
«Побочные эффекты» включают (но не ограничиваются этим перечнем): передачу данных в выходной поток, явное использование require или include, изменение настроек, генерирование ошибочных ситуаций или порождение исключений, изменение глобальных или локальных переменных, чтение из файла или запись в файл и т.п.
Ниже представлен пример файла, содержащий в себе как объявления структур, так и порождение побочных эффектов, т.е. ситуации, которой стоит избегать:
<?php // побочный эффект: изменение настроек ini_set('error_reporting', E_ALL); // побочный эффект: подключение файла include "file.php"; // побочный эффект: передача данных в выходной поток echo "\n"; // объявление function foo() { //тело функции }
Следующий пример демонстрирует файл с объявлениями без побочных эффектов – т.е. образец рекомендуемой реализации:
<?php // объявление function foo() { //тело функции } // условное объявление -- это НЕ побочный эффект if (! function_exists('bar')) { function bar() { //тело функции } }
3. Имена пространств имён и имена классов
Имена пространств имён и имена классов ДОЛЖНЫ следовать стандарту PSR-0. В конечном итоге это означает, что каждый класс должен располагаться в отдельном файле и в пространстве имён с хотя бы одним верхним уровнем (именем производителя).
Имена классов ДОЛЖНЫ быть объявлены с использованием т.н. «StudlyCaps» (каждое слово начинается с большой буквы, между словами нет разделителей).
Код, написанный для PHP 5.3 и более новых версий, ДОЛЖЕН использовать формальные пространства имён, например:
<?php // PHP 5.3 и новее: namespace Vendor\Model; class Foo { }
В коде, написанном для PHP 5.2.x и ниже, СЛЕДУЕТ при именовании классов соблюдать соглашение о псевдопространствах имён с префиксом в виде имени производителя (Vendor_):
<?php //PHP 5.2.x и ранее: class Vendor_Model_Foo { }
4. Константы, свойства и методы классов
Здесь под «классом» следует понимать также интерфейсы (interface) и примеси (trait).
4.1. Константы
Константы классов ДОЛЖНЫ быть объявлены в верхнем регистре с использованием символа подчёркивания в качестве разделителя слов, например:
<?php namespace Vendor\Model; class Foo { const VERSION = '1.0'; const DATE_APPROVED = '2012-06-01'; }
4.2. Свойства
В данном руководстве намеренно не приводится никаких рекомендаций относительно использования $StudlyCaps, $camelCase или $under_score вариантов именования свойств.
Какой бы вариант именования ни был выбран, СЛЕДУЕТ сохранять его неизменным в рамках некоторого разумного объёма кода (например, на уровне производителя, пакета, класса или метода).
4.3. Методы
Имена методов ДОЛЖНЫ быть объявлены с использованием т.н. «camelCase» (первое слово пишется в нижнем регистре, далее каждое слово начинается с большой буквы, а между словами нет разделителей).
PSR-2 – Рекомендации по оформлению кода
Данные рекомендации расширяют и дополняют базовый стандарт оформления кода PSR-1.
Цель данных рекомендаций – снижение сложности восприятия кода, написанного разными авторами; она достигается путём рассмотрения серии правил и ожиданий относительно форматирования PHP-кода.
Стилистические правила, представленные здесь, получены путём обобщения опыта различных проектов. Сотрудничество многих авторов из многих проектов позволяет выработать единый набор принципов и использовать его в этих проектах. Таким образом, польза представленных рекомендаций – не столько в самих рекомендациях, сколько в их распространении.
Слова «НЕОБХОДИМО» / «ДОЛЖНО» («MUST»), «НЕДОПУСТИМО» («MUST NOT»), «ТРЕБУЕТСЯ» («REQUIRED»), «НУЖНО» («SHALL»), «НЕ ПОЗВОЛЯЕТСЯ» («SHALL NOT»), «СЛЕДУЕТ» («SHOULD»), «НЕ СЛЕДУЕТ» («SHOULD NOT»), «РЕКОМЕНДУЕТСЯ» («RECOMMENDED»), «МОЖЕТ» / «ВОЗМОЖНО» («MAY») и «НЕОБЯЗАТЕЛЬНО» («OPTIONAL») в этом документе следует понимать так, как это описано в RFC 2119 (и его переводе).
1. Общие положения
- Код ДОЛЖЕН быть оформлен согласно стандарту PSR-1.
- Для оформления отступов ДОЛЖНЫ использоваться четыре пробела (но не знак табуляции).
- НЕДОПУСТИМО жёстко ограничивать длину строки; мягкое ограничение ДОЛЖНО составлять 120 символов; СЛЕДУЕТ стараться, чтобы длина строки составляла 80 символов или менее.
- После определения пространства имён (namespace) и после блока импорта пространств имён (use) ДОЛЖНА быть одна пустая строка.
- Открывающая фигурная скобка в определении класса ДОЛЖНА располагаться на новой строке, а закрывающая фигурная скобка ДОЛЖНА располагаться на следующей строке после тела класса.
- Открывающая фигурная скобка в определении метода ДОЛЖНА располагаться на новой строке, а закрывающая фигурная скобка ДОЛЖНА располагаться на следующей строке после тела метода.
- Область видимости ДОЛЖНА быть указана явно для всех свойств и методов; модификаторы abstract и final ДОЛЖНЫ располагаться перед модификаторами области видимости; модификатор static ДОЛЖЕН располагаться после модификаторов области видимости.
- После ключевых слов в управляющих конструкциях ДОЛЖЕН располагаться один пробел, а после вызовов функций и методов – НЕ ДОЛЖЕН.
- Открывающая фигурная скобка в управляющих конструкциях ДОЛЖНА располагаться в той же строке, что и сама конструкция, а закрывающая фигурная скобка ДОЛЖНА располагаться на следующей строке после тела конструкции.
- После открывающей круглой скобки и перед закрывающей круглой скобкой в управляющих конструкциях НЕ ДОЛЖНО быть пробела.
1.1. Пример
Следующий пример охватывает часть из вышеописанных правил:
<?php namespace Vendor\Package; use FooInterface; use BarClass as Bar; use OtherVendor\OtherPackage\BazClass; class Foo extends Bar implements FooInterface { public function sampleFunction($a, $b = null) { if ($a === $b) { bar(); } elseif ($a > $b) { $foo->bar($arg1); } else { BazClass::bar($arg2, $arg3); } } final public static function bar() //тело метода } }
2. Основные положения
2.1. Базовый стандарт оформления кода
Код ДОЛЖЕН быть оформлен согласно всем правилам, указанным в стандарте PSR-1.
2.2. Файлы
- Во всех файлах с PHP-кодом ДОЛЖЕН быть использован Unix-вариант переноса строк (Unix linefeed, т.е. \n).
- В конце каждого файла с PHP-кодом ДОЛЖНА быть одна пустая строка.
- Закрывающий тег ?> ДОЛЖЕН отсутствовать в файлах, содержащих только PHP-код.
2.3. Строки
- НЕ ДОЛЖНО быть жёсткого ограничения длины строки.
- Мягкое ограничение длины строки ДОЛЖНО составлять 120 символов; автоматические системы проверки стиля ДОЛЖНЫ выдавать предупреждение при превышении этого ограничения, но НЕ ДОЛЖНЫ считать это ошибочной ситуацией.
- СЛЕДУЕТ стараться, чтобы длина строки составляла 80 символов или менее; более длинные строки СЛЕДУЕТ разбивать на несколько отдельных строк, длина каждой из которых не превышала бы 80 символов.
- В конце непустых строк НЕ ДОЛЖНО быть пробелов.
- Пустые строки МОГУТ быть добавлены в код для повышения удобочитаемости и разделения блоков кода.
- В одной строке НЕ ДОЛЖНО быть более одного выражения.
2.4. Отступы
Для оформления отступов ДОЛЖНЫ использоваться четыре пробела (но не знак табуляции).
Примечание: использование только лишь пробелов (без смешивания их с табуляциями) позволяет избежать проблем с обработкой истории изменения кода, определением самих изменений, патчами и комментариями. Использование пробелов также позволяет легко добавлять небольшие отступы для выравнивания отдельных вложенных строк.
2.5. Ключевые слова и константы true / false / null
- Ключевые слова PHP ДОЛЖНЫ быть написаны в нижнем регистре.
- Константы PHP true, false и null ДОЛЖНЫ быть написаны в нижнем регистре.
3. Определение пространств имён и блоков импорта
- В случае наличия определения пространства имён, после него ДОЛЖНА располагаться одна пустая строка.
- В случае наличия импорта пространств имён, он ДОЛЖЕН располагаться после определения пространства имён.
- При реализации импорта каждое пространство имён ДОЛЖНО импортироваться отдельно (со своим ключевым словом use).
- После блока импорта ДОЛЖНА быть одна пустая строка.
Пример:
<?phpnamespace Vendor\Package;use FooClass;use BarClass as Bar;use OtherVendor\OtherPackage\BazClass;// ... далее следует PHP-код ...
4. Классы, свойства и методы
Здесь под «классом» следует понимать также интерфейсы (interface) и примеси (trait).
4.1. Наследование и реализация
- Ключевые слова extends и implements ДОЛЖНЫ находиться на той же строке, на которой находится имя класса.
- Открывающая фигурная скобка в определении класса ДОЛЖНА располагаться на новой строке, а закрывающая фигурная скобка ДОЛЖНА располагаться на следующей строке после тела класса.
<?phpnamespace Vendor\Package;use FooClass;use BarClass as Bar;use OtherVendor\OtherPackage\BazClass;class ClassName extends ParentClass implements \ArrayAccess, \Countable{// константы, свойства, методы}
- Список реализуемых интерфейсов МОЖЕТ быть разделён на несколько строк, каждая из которых дополнена слева одним отступом (четырьмя пробелами). В таком случае первый элемент списка интерфейсов ДОЛЖЕН начинаться с новой строки, и в каждой строке ДОЛЖЕН быть указан только один интерфейс.
<?phpnamespace Vendor\Package;use FooClass;use BarClass as Bar;use OtherVendor\OtherPackage\BazClass;class ClassName extends ParentClass implements\ArrayAccess,\Countable,\Serializable{// константы, свойства, методы}
4.2. Свойства
- Область видимости ДОЛЖНА быть явно указана для каждого свойства.
- При определении свойства НЕ ДОЛЖНО применяться ключевое слово var.
- В одном выражении НЕ ДОЛЖНО быть определено более одного свойства.
- Одиночный знак подчёркивания в начале имени свойства НЕ СЛЕДУЕТ использовать как признак защищённой (protected) или приватной (private) области видимости.
В общем случае определение свойства выглядит так:
<?phpnamespace Vendor\Package;class ClassName{public $foo
4.3. Методы
- Область видимости ДОЛЖНА быть явно указана для каждого метода.
- Одиночный знак подчёркивания в начале имени метода НЕ СЛЕДУЕТ использовать как признак защищённой (protected) или приватной (private) области видимости.
- После имени метода НЕ ДОЛЖНО быть пробела. Открывающая фигурная скобка ДОЛЖНА находиться на отдельной строке, а закрывающая фигурная скобка ДОЛЖНА находиться на следующей за телом метода строке. НЕ ДОЛЖНО быть пробелов после открывающей и перед закрывающей круглыми скобками в определении метода.
В общем случае определение метода выглядит так. Обратите внимание на круглые скобки, запятые, пробелы и фигурные скобки:
<?phpnamespace Vendor\Package;class ClassName{public function fooBarBaz($arg1, &$arg2, $arg3 = []){// тело метода}}
4.4. Аргументы методов
- В списке аргументов НЕ ДОЛЖНО быть пробела перед запятыми, но ДОЛЖЕН быть пробел после каждой запятой.
- Аргументы со значениями по умолчанию ДОЛЖНЫ располагаться в конце списка (после аргументов без значений по умолчанию). {Примечание переводчика: и тут дело не в красоте, нарушение этого правила может привести ко вполне явным ошибкам выполнения программы, когда аргументу без значения по умолчанию «не хватит» значения при вызове метода.}
<?phpnamespace Vendor\Package;class ClassName{public function foo($arg1, &$arg2, $arg3 = []){// тело метода}}
- Список аргументов МОЖЕТ быть разделён на несколько строк, каждая из которых дополнена слева одним отступом (четырьмя пробелами). В таком случае первый элемент списка аргументов ДОЛЖЕН начинаться с новой строки, и в каждой строке ДОЛЖЕН быть указан только один аргумент.
- В случае, если список аргументов разделён на несколько строк, закрывающая круглая скобка и открывающая фигурная скобка ДОЛЖНЫ располагаться вместе на своей отдельной строке, а между ними должен быть один пробел.
<?phpnamespace Vendor\Package;class ClassName{public function aVeryLongMethodName(ClassTypeHint $arg1,&$arg2,array $arg3 = []) {// тело метода}}
4.5. Ключевые слова abstract, final и static
- Ключевые слова abstract и final, в случае их наличия, ДОЛЖНЫ располагаться перед указанием области видимости.
- Ключевое слово static, в случае его наличия, ДОЛЖНО располагаться после указания области видимости.
<?phpnamespace Vendor\Package;abstract class ClassName{protected static $foo;abstract protected function zim();final public static function bar(){// тело метода}}
4.6. Вызовы методов и функций
В коде вызова функций и методов НЕ ДОЛЖНО быть пробела между именем функции или метода и открывающей круглой скобкой, НЕ ДОЛЖНО быть пробела после открывающей круглой скобки, НЕ ДОЛЖНО быть пробела перед закрывающей круглой скобкой. В списке аргументов НЕ ДОЛЖНО быть пробелов перед запятыми, но ДОЛЖЕН быть пробел после каждой запятой.
<?phpbar();$foo->bar($arg1);Foo::bar($arg2, $arg3);
Список аргументов МОЖЕТ быть разделён на несколько строк, каждая из которых дополнена слева одним отступом (четырьмя пробелами). В таком случае первый элемент списка аргументов ДОЛЖЕН начинаться с новой строки, и в каждой строке ДОЛЖЕН быть указан только один аргумент.
<?php$foo->bar($longArgument,$longerArgument,$muchLongerArgument);
5. Управляющие конструкции
Общие правила оформления управляющих конструкций:
- После ключевого слова, определяющего управляющую конструкцию, ДОЛЖЕН быть один пробел.
- После открывающих круглых скобок НЕ ДОЛЖНО быть пробелов.
- Перед закрывающими круглыми скобками НЕ ДОЛЖНО быть пробелов.
- Между закрывающей круглой скобкой и открывающей фигурной скобкой ДОЛЖЕН быть один пробел.
- Тело конструкции ДОЛЖНО быть дополнено одним отступом (четырьмя пробелами).
- Закрывающая фигурная скобка ДОЛЖНА располагаться на следующей строке после тела конструкции.
Тело каждой управляющей конструкции ДОЛЖНО быть заключено в фигурные скобки. Это позволяет стандартизировать внешний вид управляющих конструкций с снизить риск возникновения ошибок при добавлении новых строк в тело конструкции.
5.1. Конструкции if, elseif и else
Конструкция if выглядит следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки, а также на тот факт, что слова else и elseif располагаются в той же строке, что и закрывающая фигурная скобка предшествующего тела конструкции.
<?phpif ($expr1) {// тело if} elseif ($expr2) {// тело elseif} else {// тело else}
Ключевое слово elseif СЛЕДУЕТ использовать вместо отдельного сочетания else и if. Так конструкция будет представлять собой одно слово.
5.2. Конструкции switch и case
Конструкция switch выглядит следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки. Выражение case ДОЛЖНО быть смещено на один отступ (четыре пробела) от switch, а ключевое слово break (или иное слово, обозначающее выход из конструкции) ДОЛЖНО располагаться на том же уровне отступов, что и тело case. В том случае, когда в непустом теле case умышленно не используется break, ДОЛЖЕН быть комментарий в стиле // no break.
<?phpswitch ($expr) {case 0:echo 'First case, with a break';break;case 1:echo 'Second case, which falls through';// no breakcase 2:case 3:case 4:echo 'Third case, return instead of break';return;default:echo 'Default case';break;}
5.3. Конструкции while и do while
Конструкция while выглядит следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки.
<?phpwhile ($expr) {// тело конструкции}
Соответственно, конструкция do while выглядит следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки.
<?phpdo {// тело конструкции} while ($expr);
5.4. Конструкция for
Конструкция for выглядит следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки.
<?phpfor ($i = 0; $i < 10; $i++) {// тело for}
5.5. Конструкция foreach
Конструкция foreach выглядит следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки.
<?phpforeach ($iterable as $key => $value) {// тело foreach}
5.6. Конструкция try catch
Блоки конструкции try catch выглядят следующим образом. Обратите внимание на круглые скобки, пробелы и фигурные скобки.
<?phptry {// тело try} catch (FirstExceptionType $e) {// тело catch} catch (OtherExceptionType $e) {// тело catch}
6. Замыкания
- Замыкания ДОЛЖНЫ описываться с использованием пробела после ключевого слова function и пробелами до и после ключевого слова use.
- Открывающая фигурная скобка ДОЛЖНА располагаться на одной строке с именем замыкания строке, а закрывающая фигурная скобка ДОЛЖНА располагаться на следующей строке после тела замыкания.
- После открывающей круглой скобки и перед закрывающей круглой скобкой в списке аргументов или переменных НЕ ДОЛЖНО быть пробела.
- В списке аргументов или переменных НЕ ДОЛЖНО быть пробелов перед запятыми, но ДОЛЖЕН быть один пробел после каждой запятой.
- Аргументы замыкания со значениями по умолчанию ДОЛЖНЫ располагаться в конце списка (после аргументов без значений по умолчанию). {Примечание переводчика: и тут дело не в красоте, нарушение этого правила может привести ко вполне явным ошибкам выполнения программы, когда аргументу без значения по умолчанию «не хватит» значения при вызове.}
Описание замыкания выглядит следующим образом. Обратите внимание на круглые скобки, запятые, пробелы и фигурные скобки.
<?php$closureWithArgs = function ($arg1, $arg2) {// тело};$closureWithArgsAndVars = function ($arg1, $arg2) use ($var1, $var2) {// тело};
Список аргументов и переменных МОЖЕТ быть разделён на несколько строк, каждая из которых дополнена слева одним отступом (четырьмя пробелами). В таком случае первый элемент списка ДОЛЖЕН начинаться с новой строки, и в каждой строке ДОЛЖЕН быть указан только один элемент.
Когда последний список (аргументов или переменных) разделён на несколько строк, закрывающая круглая скобка и открывающая фигурная скобка ДОЛЖНЫ располагаться на одной строке и быть разделены одним пробелом.
Ниже представлены примеры замыканий со списком аргументов и без него, а также со списком переменных, располагающимся на нескольких строках.
<?php$longArgs_noVars = function ($longArgument,$longerArgument,$muchLongerArgument) {// тело};$noArgs_longVars = function () use ($longVar1,$longerVar2,$muchLongerVar3) {// тело};$longArgs_longVars = function ($longArgument,$longerArgument,$muchLongerArgument) use ($longVar1,$longerVar2,$muchLongerVar3) {// тело};$longArgs_shortVars = function ($longArgument,$longerArgument,$muchLongerArgument) use ($var1) {// тело};$shortArgs_longVars = function ($arg) use ($longVar1,$longerVar2,$muchLongerVar3) {// тело};
Обратите внимание, что правила оформления замыканий также распространяются на случай, когда замыкание используется в качестве аргумента прямо в вызове функции или метода.
<?php$foo->bar($arg1,function ($arg2) use ($var1) {// тело},$arg3);
7. Заключение
В этом руководстве намеренно не рассмотрены правила и лучшие практики по оформлению многих элементов, список которых включает в себя, но не ограничивается следующим:
- Определение глобальных переменных и констант.
- Определение функций.
- Использование операторов и присваивание.
- Межстрочное выравнивание.
- Блоки комментариев и документации.
- Префиксы и суффиксы в именах классов.
- Лучшие практики.
В будущем данные рекомендации МОГУТ быть пересмотрены и расширены, чтобы охватить те или иные элементы кода и практики оформления.
Источник перевода стандартов - http://svyatoslav.biz/misc/psr_translation/
- Войдите или зарегистрируйтесь, чтобы отправлять комментарии