PHP — комментарии объёмнее кода

Несправедливо, что я так много пишу на PHP и так мало пишу о PHP. Этот пост призван восстановить справедливость.

Логично предположить, что между языком программирования и русским языком должна быть связь: ведь я формулирую задачу на языке своего мышления, а потом перевожу её на язык программирования. Программисты — словно переводчики с языков человеческих на языки программирования. Но это не так. А кто считает программистов переводчиками, тот может стать даже хорошим учителем информатики, но никогда не станет хорошим программистом.

Надюша попросила сделать ей заметную ссылку «Веганские рецепты от Надежды ЗДЕСЬ» на первой картинке к постам с меткой «блюда постной кухни». Визуально задача была поставлена так:

Стикер

Такая вот краткая и понятная задача. Код её реализации занял 2 строки (считая только те строки, над которыми пришлось подумать). А комментарии к коду получились примерно такого же объёма. И то я записал в комментарии только самое важное, что могу забыть и буду потом полчаса вычислять, почему я это реализовал именно так, а не иначе. Вот код для сайта на WordPress:

# Поиск в таблице term_relationships строки с указанием, что у текущего поста есть метка id=163 (Блюда постной кухни)
if ( $wpdb->get_var( "SELECT * FROM $wpdb->term_relationships WHERE object_id = $post->ID AND term_taxonomy_id = 163" ) ) {
	function vegan_gif( $content ) {
		# вставляем стикер сразу после открытия контейнера (<p>) с контентной картинкой (признак: "wp-image-")
		# контейнеру присваиваем id="vegan-gif", учтён вариант необязательной обёрнутости img в ссылку на full size
		return preg_replace( '|<p([^>]*)>(.*<img[^>]*wp-image-)|i',
			'<p id="vegan-gif"\\1><a href="http://hope-recipes.ru/vegan-recipes" title="Веганские рецепты">'.
			'<img src="'.GET_TEMPLATE_DIRECTORY_URI.'/i/vegan.gif" alt="Веганские рецепты" /></a>\\2', $content, 1 );
	}
	add_filter( 'the_content', 'vegan_gif', 20000 );
}

Если вы думаете, то комментарии — это перевод кода на человеческий язык, то ошибаетесь. Как я сказал — это подсказки на будущее. Попросите программиста перевести этот код на человеческий язык, и он либо удивится вашей просьбе, либо расскажет, что делает этот код. Но объяснение, что делает код — это не перевод его на человеческий язык. Это аналогично тому, как если подойти к лингвисту с инструкцией для чайника на английском языке, попросить перевести на русский, а он бы вам ответил: «Эта инструкция поможет вам правильно эксплуатировать чайник и не допустить случайного повреждения прибора или вашего травмирования». Он, конечно, вам правильно описал, для чего нужна эта книжка, но не перевёл её на ваш язык.

Комментарии (строки 4-5) появились после нескольких не совсем точных попыток реализовать строку 6 (которую я для удобства чтения поделил на 3 строки: 6-7-8). Когда желаемый результат был достигнут, появился комментарий 4-5, чтобы не забыть, для чего понадобилась именно такая сложная конструкция.

Технически надо было вставить абсолютно позиционируемую ссылку-картинку (далее: «стикер») перед первой картинкой в посте. И в CSS стикера установить его позиционирование относительно правого верхнего угла картинки. Но поставленная таким образом задача обречена на провал, поскольку позиционировать элемент можно лишь относительно родительского контейнера (без написания детективов на JavaScript), а картинка (которая первая в посте) не может являться контейнером для нашей цели.

Нужный контейнер долго искать не пришлось: WordPress оборачивает все картинки в контейнер абзаца <p>. Потому теперь задача технически звучала так: поместить стикер между первым в посте <p>, содержащим <img>. Только требуемое позиционирование стикера невозможно, если у его родителя атрибут position не имеет значения relative. Решено было добавить к интересующему нас <p> атрибут id="vegan-gif", таким образом выполнив 2 задачи (не уместно писать про убийство зайцев в одном предложении со словом «vegan»):

  1. получить возможность определить стиль контейнера <p>;
  2. и стиль его дочернего элемента — стикера.

CSS для наглядности:

#vegan-gif { position: relative; }
#vegan-gif a:first-child { position: absolute; right: -23px; top: -23px; }

Но <p> часто имеет указанные редактором стили. Например, при выравнивании картинки по центру в визуальном редакторе <p> получает style="text-align:center". Это тоже было учтено в коде.

И это ещё не всё. Первая картинка в посте бывает обёрнута ссылкой на полноразмерное изображение. Требуется сохранить эту ссылку, а стикер вставить перед этой ссылкой при её наличии, иначе получится ссылка в ссылке, что не валидно и не функционирует должным образом. Тоже было учтено. Также в CSS добавился момент «:first-child», чтобы не воздействовать на стиль ссылки, не являющейся стикером.

Но в некоторых постах первая картинка — это смайл в первом абзаце. Можно, конечно, стикер вставить ещё до того, как текстовые смайлы «превратились» в картинки. Но я предпочёл работать с окончательным результатом WP-колдовства над текстом поста — так меньше вероятность неявных багов и проще отладка. Для решения новых подробностей задачи я воспользовался тем, что контентные картинки имеют класс wp-image-[id-картинки]. Добавил в формулу успеха признак «wp-image-» и, конечно же, написал комментарий на память.

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

Запись опубликована в рубрике Web-мастеринг, Размышлизмы с метками , , . Короткая ссылка для добавления в закладки: PHP — комментарии объёмнее кода.

6 Responses

  1. pilat говорит:

    А какая задача была поставлена?

    а то не могу сообразить зачем ты картинку из текста меняешь на другую статическую...

    ну и почему id? предполагается что будет один элемент на странице?

    ну а первое обращение к mysql...для меня вообще загадка. Если так, то нужно хотя бы $post вызвать глоабльно. Ну или выводить уже конкретно в фильтре.

    • Павлуха говорит:

      Спасибо за интерес к моему коду. :) Правда, мне казалось, что пост больше философский, чем представляющий практический интерес.

      Задача: прилепить стикер (ссылку-картинку) на видном месте в посте, у которого есть метка id=163 (Блюда постной кухни). А первая картинка в посте — как раз подходящее видное место для стикера. В посте есть ссылка: hope-recipes.ru/vegan-recipes — это как раз все блюда постной кухни, перейдя на любое блюдо можно увидеть реализацию задачи. Перейдя на любой другой (не постный) рецепт можно заметить, что такого стикера нет.

      Я ничего не меняю, только добавляю: добавляю стикер поверх картинки в тексте.

      Да, на странице будет один элемент. Задача поставлена в 3-м абзаце: стикер нужен именно на первой картинке.

      Кусок кода я выдрал из контекста, потому не очень понятно. Это обращение к mysql происходит не в functions.php, а в шаблоне single.php внутри цикла WP, потому $post->ID без проблем возвращает id текущего поста. И никакой загадки нет: если в таблице term_relationships встречается строка, в которой object_id = id текущего поста и term_taxonomy_id = 163 (Блюда постной кухни), то метод $wpdb->get_var возвращает ненулевое значение.

      • pilat говорит:

        Код это интересно всегда...особенно если он для WP.

        Спасибо за ответ. Теперь понял. Я сначала не разобрался о каком стикере идёт речь.

        • Павлуха говорит:

          Да пожалуйста! Буду почаще коды писать, если это интересно хотя бы одному читателю блога. :)

  2. Как жаль, что постановкой задачи зачастую занимается сам заказчик, что заставляет исполнителя решать её в лоб.

    Например, я бы отдал предпочтению JavaScript, что позволило бы снизить нагрузку на сервер, предоставив сделать всё тоже самое ресурсам компьютера пользователя. В частности, найти картинку в нужной секции, обернуть её в тот же DIV и вставить в него тикет — это как вариант на скорую руку. А если отбросить старички браузеры, то не исключено, что всё это можно было бы реализовать и на голом CSS.

    Как вариант можно было бы сделать и несложную предобработку картинок на PHP с использованием mod_rewrite. Т.е. речь идёт о php-скрипте, который накладывал бы стикер на картинку и генерировал бы новый одноименный файл... думаю, идея понятна, а реализация по желанию.

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

    • Павлуха говорит:

      Да и не стоит становиться учителем информатики, лучше преподом — у них хоть есть прикольное занятие: писать курсовые для студентов по своему же заданию за бабло. :)

      На счёт JavaScript-магии была мысль. Но решено было поисковикам выдать нормальную html-ссылку, которая станет частью раскрутки модной страницы, на которую ссылается стикер.

      А вот вариант с генерацией одноимённого файла — это шедевр! Идя таким путём не трудно случайно и свою CMS написать, начав с какого-то мелкого стикера. :) Мне такой вариант даже в голову бы не пришёл, даже если бы я для развлечения решил всевозможные варианты решения задачи придумать.

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

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

Иногда ваш комментарий может не отобразиться сразу после публикации - будто пропал. Не волнуйтесь, он не пропадёт и появится потом, после моего одобрения.