База знаний по веб-разработке

Стандарты кодирования

У всех есть проблемы с пониманием чужого кода, если он написан неаккуратно, и я не верю, что код, претендующий на что-то, можно писать абы как. На привыкание, выработку привычки может уйти максимум несколько дней, сосчитать пользу от внедрения — не возможно.

 

Для погружения в проблему

Применение теории разбитых окон (ru.wikipedia.org/wiki/Теория_разбитых_окон) в нью-йорском метро: ayrat-galiullin.livejournal.com/65038.html
Видео-лекция Яндекса про стандарты кодирования: events.yandex.ru/events/shri/msk-2012/talks/566.
Стандарты кодирования (HTML/CSS) от Google (перевод): habrahabr.ru/post/143452

 

Отступы

Табуляция, 4 символа.

Единообразие в именах и названиях: файлы, папки, классы, методы, функции, переменные, атрибуты

Не транслит. Названия на английском понятном языке. Из нескольких синонимов выбирать наиболее часто используемое. slovari.yandex.ru в помощь.

При выборе названия для элемента, содержащего логического значение, имя должно начинаться с is или has.

 

Названия файлов и папок

Используется только латиница, цифры и дефис. Никакой кириллицы, пробелов и знака подчеркивания. Знак подчеркивания нельзя использовать, чтобы не получался винегрет в адресах страниц в браузере, так как в качестве разделителя в имени домени используется только дефис.

 

Длина строки

Длина строки кода не должна превышать 80 символов, чтобы она с большей вероятностью помещалась у всех в экран, не зависимо от редактора (может быть консоль, окно браузера) и ширины окна. Пользоваться удобнее вертикальной прокруткой.

В редакторе удобно включить подсветку границы 80 символов и стараться не вылезать за нее. Естественно, не стоит к 80 символам относиться буквально и принудительно переносить строку при заступе на небольшое количество символов. Также нужно учитывать важность фрагмента кода, который не помещается: если работающему с кодом будет понятно, что скрывается (например, если там закрывающая конструкция) и вряд ли нужно будет редактировать длинную часть без изменения всей конструкции, то длина требования к длине строки менее актуальны.

Для кода, для которого характерен большой уровень вложенности, например, HTML-XML-XSLT стоить использовать принудительные переносы и специальное форматирование элементов:

<xsl:stylesheet>
    <xsl:template match="input">
        <form>
            <fieldset>
                <div class="fieldset">
                    <div class="row"><div class="control"><xsl:choose>
                        <xsl:when test="@type = 'checkbox'">
                            <label for="is-published">
                                <input type="checkbox"
                                    value="1"
                                    checked="true"
                                    name="is-published"
                                    id="is-published"
                                    class="required"
                                    style="border-color: red;"
                                />

                                Да
                            </label>
                        </xsl:when>
                        <xsl:otherwise>
                            <input type="text" />
                        </xsl:otherwise>
                    </xsl:choose></div></div>
                </div>
            </fieldset>
        </form>
    </xsl:template>
</xsl:stylesheet>

 

Тезисы

Код должен выглядеть так, как будто его пишет один человек.

На проектах нужно использовать файл ~/Contribute.md, в котором давать ссылку на общий (этот) документ со стандартами, описывать принятые договоренности, если они отличаются от стандартных.

Не нужно использовать «партизанский» code review. Если разработчик сделал неправильно, нужно ему на это указать, чтобы исправил именно он, за него исправлять не нужно.

Важно документировать неявный код.

Написание примеров использования.

Уменьшение чрезмерного количества уровней вложенности.

 

Автоматизированная проверка кода (IDE + Pre commit hook to check style of the code)

git-scm.com/book/en/Customizing-Git-Git-Hooks
gist.github.com/davetron5000/37350
checkstyle.sourceforge.net

 

PHP

Подробно по ссылке framework.zend.com/manual/1.12/ru/coding-standard.html. Выжимка MyObject.php:

<?php

class MyObject
{
    /**
     * @var integer
     */
    protected $_variable;

    /**
     * @var string
     */
    protected $_result;

    /**
     * @param array[integer] $_inputParams
     * @return integer|false
     */
    protected function _doSomethingInsideObject(array $_inputParams = null)
    {
        if ($_inputParams) {

            // Делаем какую-то значимую работу

            if (isset($this->_variable)) {
                $this->_variable = 0;
            }


            // Делаем что-то еще, что нужно выделить, но выносить
            // в отдельный метод не хотим

            foreach ($_inputParams as $item) {
                $this->_variable += $item;
            }

            return $this->_variable;
        }

        return false;
    }

    public function __construct()
    {
        $result = $this->_doSomethingInsideObject(array(1, 2, 3, 4, 5));
        echo $result !== false ? 'OK' : 'Empty';
    }
}

 

Отступления

Блоковые комментарии /**/ используем только для документирования или отладочного комментирования большого объема кода. Для отключения кода // нужно ставить в начале строки, а для добавления комментария к коду — с отступом согласно уровню отступа кода, к которому комментарий относится.

Перед комментарием желательно добавлять два переноса строки, после него — один:

if (isset($this->_variable)) {
    $this->_variable = 0;
}


// Делаем что-то еще

foreach ($_inputParams as $item) {
    $this->_variable += $item;
}

Вместо слитной конструкции elseif используется раздельное написание else if.

Параметры (передаваемые в метод или функцию переменные) нужно называть, начиная со знака подчеркивания.

В большинстве случаев с параметром нужно что-то сделать прежде, чем использовать дальше. При этом может понадобиться и исходное значение. Поэтому вводится соглашение, что параметр не меняется. Если нужно произвести операцию с ним, то можно инициализировать одноименную переменную без подчеркивания.

function printPhone($_number)
{
    $number = '+7 (495) ' . $_number;
    echo $number;
}

 

MySQL

Название таблицы — существительное в единственном числе. В качестве разделителя — подчеркивание.

Название первичного ключа — название таблицы + _id.

Название таблицы, реализующей связь многие-ко-многим — основная_таблица_has_вспомогательная_таблица.

Атрибуты таблиц, реализующие логическое поведение — is_ + название.
Тип — TINYINT(1) UNSIGNED NOT NULL DEFAULT 0 (при проектировании в MySQL Workbench тип — BOOLEAN).

 

Javascript

Как в PHP, но в строковых конструкциях используются двойные кавычки.

 

XML, XSLT, HTML

Названия элементов, атрибутов, переменных и остальное — строчными буквами, в качестве разделителя слов — дефис.

Для вложенных элементов обязательны переносы строк и отступы, отражающие уровень иерархии.

Все HTML-тэги нужно закрывать, так как часто верстка переносится в XSL-таблицы стилей.

 

CSS

Описание последнего свойства должно заканчиваться точкой запятой, чтобы не доставлять ее при копировании.

Каждое свойство и каждый селектор — с новой строки.

Открывающая фигурная скобка на новую строку не переносится.

div.error,
div.success {
    border-width: 1px;
    padding: 0.5em 1em;
    color: #000;
}

Для вложенных элементов обязательны переносы строк и отступы, отражающие уровень иерархии.

div.error,
div.success {
    border-width: 1px;
    padding: 0.5em 1em;
    color: #000;
}

    div.error a {
        text-decoration: none;
        color: #f00;
    }

        div.error a span {
            border-bottom: #333 1px dashed;
        }

Кодировка символов и Юникод: что нужно знать разработчику

Photo by Tomas Martinez on Unsplash

Если вы пишете международное приложение, в котором будут использоваться разные языки, вы должны разбираться в кодировке символов. Впрочем, эту статью стоит почитать, даже если вам просто любопытно, как слова выводятся на экран.

Я расскажу краткую историю кодировки символов (и о том, сколь мало она была стандартизирована), а затем чуть подробнее остановлюсь на том, чем мы пользуемся в настоящее время.

Введение в кодирование символов

Компьютер понимает только двоичный код. То есть только нули и единицы. Каждая из этих цифр — один бит. Восемь таких цифр (нулей и/или единиц) — один байт.

В конечном итоге все в компьютере сводится к двоичному коду: языки программирования, движения мыши, ввод текста и все слова на экране.

Но если весь текст, который вы читаете, тоже был в форме нулей и единиц, то как же произошло его превращение в понятные человеку слова? Чтобы в этом разобраться, давайте вернемся к истокам.

Краткая история кодировки

На заре интернета в нем все было исключительно на английском. Нам не приходилось беспокоиться о символах, которых в английском языке просто нет. Для сопоставления всех нужных символов с числовыми кодами использовалась таблица ASCII (American standard code for information interchange).

Получаемый компьютером двоичный код:

01001000 01100101 01101100 01101100 01101111 00100000 01110111 01101111 01110010 01101100 01100100

при помощи ASCII переводился в «Hello world».

Одного байта (8 бит) вполне хватало, чтобы уникально закодировать любой символ английского языка, а также некоторое количество управляющих символов. Часть этих управляющих символов использовалась для телетайпов, которые были довольно распространены в то время. Сейчас, впрочем, не используются ни телетайпы, ни эти символы.

Что из себя представляют управляющие символы? Например, управляющий символ с кодом 7 (111 в двоичной системе) служит для подачи компьютером звукового сигнала. Символ с кодом 8 (1000 в двоичной системе) перемещает позицию печати на один символ назад (например, для наложения одного символа на другой или для стирания предшествующего символа). Символ с кодом 12 (1100 в двоичной системе) отвечает за очистку экрана терминала.

В то время компьютеры использовали 8 бит для одного байта (хотя так было не всегда), так что проблем не было. Это позволяло закодировать все управляющие символы, все цифры и буквы английского алфавита, да еще и свободные коды оставались! Дело в том, что 1 байт может принимать 256 (0 — 255) разных значений. То есть потенциально можно было закодировать 255 символов, а в ASCII их было всего 127. Так что 128 кодов оставались неиспользованными.

Давайте посмотрим на саму таблицу ASCII. Все символы алфавита в верхнем и нижнем регистре, а также цифры получили двоичные коды. Первые 32 символа таблицы — управляющие, они не имеют графического отображения.

Таблица ASCII

Как видите, символы кончаются кодом 127. У нас осталось свободное место в таблице.

Проблемы с ASCII

При помощи кодов 128-255 можно было бы закодировать еще какие-нибудь символы. Люди задумались, какими именно символами лучше заполнить таблицу. Но у всех были разные идеи на этот счет.

Американский институт национальных стандартов (American national standards institute, ANSI) разметил, за какие символы должны отвечать коды 0-127 (т. е., те, которые уже были размечены ASCII). Но остальные коды остались открытыми.

Примечание: не путайте ANSI (институт) и ASCII (таблица).

Назначение кодов 0-127 никто не оспаривал. Проблема была в том, что делать с оставшимися.

В первых компьютерах IBM коды ASCII 128-255 представляли следующие символы:

Коды 128-255 для ASCII от IBM.

Но в других компьютерах было по-другому. И буквально каждый производитель стремился по-своему применить свободные коды из конца таблицы ASCII.

Эти разные варианты концовок таблицы ASCII назывались кодовыми страницами.

Что такое кодовые страницы ASCII?

Пройдя по ссылке, вы найдете коллекцию из более чем 465 различных кодовых страниц! Как видите, даже для одного языка существовали разные кодовые страницы. Например, для греческого и китайского есть по нескольку кодовых страниц.

Но как же, черт побери, все это стандартизировать? Как работать с несколькими языками? А с одним языком, но разными кодовыми страницами? А с не-английским языком?

В китайском языке больше 100 тысяч различных символов. Даже если бы мы договорились отдать под символы китайского языка все оставшиеся коды, их бы все равно не хватило.

Выглядело все это довольно плохо. Для этой проблемы даже придумали отдельный термин: mojibake (на японском это слово означает «трансформация символа»).

Это неправильно декодированный текст, в котором символы систематически заменяются другими, причем часто — даже из других систем письменности.

Пример mojibake

 

С ума сойти…

Вот именно! У нас не было ни единого шанса надежно обмениваться данными.

Интернет — всего лишь огромная сеть компьютеров по всему миру. Представьте, что было бы, если бы каждая страна самостоятельно определяла стандарты кодировки. Тогда компьютеры в Греции нормально выводили бы только греческий язык, а в США — только английский.

ASCII не подходила для использования в реальном мире. Чтобы интернет был всемирным, нам нужно было что-то менять. Ну, или вечно работать с сотнями кодовых страниц.

���Если только вам������, конечно, не ���нравится ��� расшифровывать такие абзацы.�֎֏0590֐��׀ׁׂ׃ׅׄ׆ׇ

И тут пришел Юникод

Юникод (Unicode) иногда называют UCS — универсальным набором символов (Universal Coded Character Set), и даже ISO/IEC 10646. Но Юникод — наиболее распространенное название.

Юникод состоит из множества кодовых пунктов (code points, по сути — шестнадцатеричные числа), связанных с символами. Коллекция кодовых пунктов называется набором символов. Вот этот набор — и есть Юникод.

Люди проделали огромную работу, назначив коды всем символам всех языков, а мы можем просто пользоваться результатами их труда. Отображение кодов выглядит так:

"Hello World"

U+0048 : LATIN CAPITAL LETTER H
U+0065 : LATIN SMALL LETTER E
U+006C : LATIN SMALL LETTER L
U+006C : LATIN SMALL LETTER L
U+006F : LATIN SMALL LETTER O
U+0020 : SPACE [SP]
U+0057 : LATIN CAPITAL LETTER W
U+006F : LATIN SMALL LETTER O
U+0072 : LATIN SMALL LETTER R
U+006C : LATIN SMALL LETTER L
U+0064 : LATIN SMALL LETTER D

U+ указывает на то, что это стандарт Unicode, а номер — число, в которое переведен двоичный код для данного символа. В Юникоде используется шестнадцатеричная система — просто потому, что в нее проще переводить двоичный код. Впрочем, вам не придется делать это вручную, так что можно не волноваться.

Вот ссылка на ресурс, где вы можете впечатать в форму любой символ и получить его кодировку в Юникод. Или же можете просмотреть все 143859 символов здесь. В таблице можно увидеть, из какой части света происходит каждый символ!

Просто для ясности подобью итоги. В настоящее время у нас есть большой словарь кодовых пунктов с отображением на символы. Это очень большое множество символов. Н

Наконец, переходим к последнему ингредиенту.

Unicode Transform Format (UTF)

UTF («Формат преобразования Юникода») — это способ представления Юникод. Кодировки UTF определены стандартом Юникод и позволяют закодировать любой нужный нам кодовый пункт Юникод.

Есть несколько разных видов UTF-стандартов. Они отличаются количеством байтов, используемых для кодирования одного кодового пункта. В UTF-8 используется один байт на кодовый пункт, в UTF-16 — 2 байта, в UTF-32 — 4 байта.

Поскольку кодировок так много, как понять, какую использовать? Есть такая вещь как маркер последовательности байтов (англ. Byte order mark, BOM) Это двубайтный маркер в начале файла, который говорит о том, какая кодировка используется в этом файле.

UTF-8 — самая распространенная кодировка в интернете. В HTML5 она определена как предпочтительная для новых документов. Поэтому я уделю ей особое внимание.

Даже по диаграмме 2012 года видно, что UTF-8 становится самой распространенной кодировкой.
Диаграмма от W3 показывает, насколько интенсивно используется UTF-8 на сайтах

Что такое кодировка UTF-8 и как она работает?

UTF-8 кодирует кодовые пункты Юникод 0-127 в одном байте (т. е. так же, как в ASCII). Это значит, что если вы для своей программы использовали кодировку ASCII, а ваши пользователи используют UTF-8, они не заметят никакой разницы. Все будет нормально работать.

Просто обратите внимание, насколько это классно. Нам нужно было начать внедрять и повсеместно использовать UTF-8 и при этом сохранить обратную совместимость с ASCII. Это удалось сделать, UTF-8 ничего не ломает.

В названии кодировки заложено указание на количество бит (8 бит = 1 байт), которые используются для одного кодового пункта. Но есть символы Юникод, для хранения которых требуется по нескольку байтов (раньше было до 6, теперь — до 4, в зависимости от символа). Именно это имеется в виду, когда говорят, что UTF-8 — кодировка переменной длины (см. UTF-32, — прим. ред.).

Тут все зависит от языка. Символ английского алфавита — 1 байт. Европейская латиница, иврит, арабские символы представляются 2 байтами. Для китайских, японских, корейских символов и символов других азиатских языков используются 3 байта.

Чтобы символ мог занимать больше одного байта, есть битовая комбинация, идентифицирующая знак продолжения. Она сообщает о том, что этот символ продолжается в нескольких последующих байтах. Таким образом, для английского языка вы по-прежнему будете использовать по одному байту на символ, но сможете составить и документ, содержащий символы на других языках.

Радостно сознавать, что теперь у нас полное согласие по части того, как кодировать шумерскую клинопись, а также смайлики!

Если описать весь процесс в общих чертах, то:

  1. сначала вы читаете BOM, чтобы узнать кодировку,
  2. затем расшифровываете файл в кодовые пункты Юникод,
  3. затем представляете символы из набора Юникод в символы, которые отрисовываются на экране.

 

Еще немного о UTF

Помните, что кодировка это ключ. Если я пошлю совершенно неправильную кодировку, вы не сможете ничего прочесть. Имейте это в виду, отсылая или получая данные. Зачастую в постоянно используемых нами инструментах это абстрагировано, но программист должен понимать, что происходит под капотом.

Как мы указываем кодировку? Поскольку HTML написан на английском и практически все кодировки прекрасно справляются с английскими символами, мы можем указать кодировку прямо сверху, в разделе .

<html lang=«en»>
<head>
<meta charset=«utf-8»>
</head>

Это важно сделать в самом начале , потому что если будет использована не та кодировка, парсинг HTML может начаться заново.

Мы также можем получить кодировку из заголовка Content-Type в HTTP-запросе или ответе.

В спецификации HTML5 есть любопытный способ угадать кодировку, если HTML-документ не содержит соответствующего тега, — BOM sniffing («вынюхивание BOM»). В этом случае кодировка определяется по маркеру последовательности байтов, который мы упоминали ранее.

Это все?

Работа над Юникодом продолжается. Как в любом стандарте, мы можем что-то добавлять, удалять, вносить предложения. Никакая спецификация никогда не считается окончательно завершенной.

Обычно бывает 1-2 релиза Юникода в год, найти их можно здесь.

Недавно мне попалась статья об очень интересном баге: Twitter неверно рендерил русские символы Юникода.

Если вы дочитали до сюда, — снимаю шляпу. Я знаю, информации много.

Советую также выполнить «домашнее задание».

Посмотрите, как могут ломаться сайты из-за неправильной кодировки. Я использовал вот это расширение Google Chrome для смены кодировки и пробовал читать разные страницы. Текст был совершенно непонятен. Попробуйте прочесть эту статью, например. Зайдите на Википедию. Посмотрите на Mojibake своими глазами.

Это поможет вам проникнуться важностью кодировок.

Окно выбора кодировки

 

Заключение

Название этой статьи — дань уважения статье Джоела Спольски, которая познакомила меня с кодировкой и многими концепциями, о которых я и не подозревал. Именно после прочтения этой статьи я углубился в тему кодировки. Также я очень многое почерпнул из этого источника.

Изучая информацию и пытаясь упростить свою статью, я узнал о Майкле Эверсоне. С 1993 года он предложил больше 200 изменений в Юникод и добавил в стандарт тысячи символов. В 2003 году он был одним из ведущих контрибьюторов предложений в Юникод. Своим современным видом Юникод (а значит, и вообще интернет) во многом обязан именно Майклу Эверсону.

Надеюсь, у меня получилось сделать хороший обзор того, зачем нам нужны кодировки, какие проблемы они решают и что случается, если с кодировкой происходит сбой.

Источники:  sitedev.ru

Источники:  techrocks.ru

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Переводчик »