2

Относительные пути в svn:externals

При переезде рабочего Subversion-репозитория на другой сервер «посыпались» экстерналы. Старый svn-репозиторий был не доступен, а правила для svn:externals были указаны в виде:

foo_ext http://old-server.com/repo/foo 
bar_ext http://old-server.com/repo/bar

И естественно выпадали в ошибки.

Здесь и далее рассматривается условный репозиторий с такой структурой: корень находится в repo, а мы хотим подключить внешние папки foo и bar в папку lib:

repo\
   |-- bar\
   |-- foo\
   +-- lib\
       |-- bar_ext
       +-- foo_ext

Захотелось во избежание подобных проблем в будущем указать пути относительно. Оказалось, такая возможность в Subversion доступна, начиная с версии 1.5. При этом был изменен формат описания подключения внешних папок. Старый формат также допустим, но только при указании абсолютных путей. Предыдущий пример в новом формате должен выглядеть так:

http://new-server.com/repo/foo foo_ext 
http://new-server.com/repo/bar bar_ext

Т.е. сначала путь, потом папка.

Допустимы несколько способов указания относительных путей:

../ — относительно текущей папки:

../../foo foo_ext 
../../bar bar_ext

^/ — относительно корня репозитория:

^/foo foo_ext 
^/bar bar_ext

// — независимо от схемы сети (http/https):

//new-server.com/repo/foo foo_ext 
//new-server.com/repo/bar bar_ext

/ —относительно корня сервера:

/repo/foo foo_ext 
/repo/bar bar_ext

Что интересно, версии 1.5, описавшей новый формат указания svn:externals, уже три года. Но при этом практически все примеры и статьи в интернете используют старый формат.

0

Объявление полей классов в PHP

Давно хотел разобраться, что будет если поле не объявлено явно в классе, но используется для чтения/записи. Периодически натыкался на такие конструкции в чужом коде, считал неверным, а потому сам никогда  не использовал и ответа на вопрос «Что же все-таки будет?» не знал. Кстати, в официальном мануале ничего об этом не нашел. Буду рад, если подскажете, где просмотрел.

Итак. Поля классов могут задаваться явно с помощью ключевых слов private, protected и public, определяющих видимость поля:


class A {

    private $foo;

    protected $bar;

    public $baz;
}

Есть еще конструкция var, но это просто устаревший аналог public.

А могут задаваться неявно, просто обращением к этому полю:


class A {

    public function getFoo() {
        return $this->foo;
    }

    public function setFoo($value) {
        $this->foo = $value;
    }
}

Второй способ никуда не годится:

  • Неявно определенное поле получает уровень доступ public. При явном определении — мы сразу указываем уровень доступа.
  • Если вызвать метод, читающий значение поля до его инициализации, то PHP сгенерирует Notice (при первом способе его нет). А поле будет инициализировано значением null.
  • То, что это поле есть в объекте, не получится узнать через Reflectionproperty_exists и get_class_vars. Только через isset и get_object_vars, и то только, если полю было присвоено значение.
  • С такими полями неудобно работать в редакторе — IDE их не подсказывает и вообще подсвечивает, как ошибочные. Можно описать эти поля с помощью PHPDoc тегами property, но непонятно, почему бы тогда не описать их явно как поля класса :).

В общем, не пользуйтесь никогда вторым способом. Он усложняет и запутывает код и является источником ошибок. Единственно, когда он имеет право на существование — это динамическое создание полей объекта. И даже тогда можно справиться геттерами и сеттерами (правда с потерями в производительности, при малом количестве вызовов потери незначительны).

5

Сокращенный тернарный оператор в PHP

Тернарный оператор — вещь известная и скучная:


$a = $expr1 ? $expr2 : $expr3;

Если $expr1 истинно, результатом $a станет $expr2, иначе $expr3.

А теперь об интересном! Начиная с версии PHP 5.3 можно опустить $expr2.


$a = $expr1 ?: $expr3;

Это равносильно записи:


$a = $expr1 ? $expr1 : $expr3;

Примеры:


$a = true ?: false; // true

$a = false ?: true; // true

$a = 1 ?: 2; // 1

$a = 0 ?: 2; // 2

В мануале об этом упоминается очень сухо и коротко. Ну а что еще добавить?

0

Показываем картинки в статистике AWStats

AWStats — одна их популярных серверных систем учета статистики, работающая по принципу анализа логов доступа (access-log) Apache. Система хорошая, но часто попадалась мне недонастроенной: не показываются картинки. Картинки для AWStats, чтобы не копировать их для каждого домена, прописываются алиасами в файле конфигурации, который подключается к апачу. А не показываются потому что пути к реальным картинкам указаны неверные. Задача простая — найти иконки, найти конфиг, указать в нем правильный путь, перезапустить апач. У меня на Debian пути были такие:

Путь к иконкам:

/usr/share/awstats/icon

Конфиг апача:

/etc/apache2/httpd.conf

Соответственно новая строка в конфиге выглядит так:

Alias /icon /usr/share/awstats/icon

Ну и не забываем сделать рестарт апача. Готово!

0

Правим размеры элементов средствами для разработчика

В процессе дебага верстки наткнулся на классную фичу в браузерных средствах для разработчика. В них всех есть вкладка, показывающая выбранный элемент и его размеры и отступы. В Firebug и IE Developer Tools это вкладка Layout, в Safari и Chrome Web Inspector’е — вкладка Metrics, в Opera Dragonfly — Разметка (в русской версии).

Так вот оказывается Firebug, IE Developer Tools и Web Inspector не только показывают метрики выбранного элемента, но и позволяют править! А Firebug-умничка еще и умеет это делать стрелочками вверх-вниз. В IE и FF достаточно просто кликнуть на размер, в Web Inspector кликнуть дважды. Ну а в Dragonfly можно кликать бесконечно :) Не поможет — править метрики там нельзя. Или я просто не разобрался как. Буду рад, если подскажете.

В IE новые размеры нужно обязательно вводить с размерами, иначе они сбрасываются в ноль. В остальных средствах для разработчика, если вводить цифры без размера, то по умолчанию считается, что размер указан в пикселах. Если же указывать с размерами, то все ведут себя по разному. Firebug не позволяет указывать единицы измерения. Web Inspector всё переводит в пикселы. IE Dev Tools, как уже было указано выше, вообще без единиц размеры не принимает, показывает в тех единицах, которые были указаны, пересчитывает в пиксели только ширину и высоту элемента.

Точно также все ведут себя и с размерами, указаными через стили. То есть все (в том числе Opera Dragonfly) показывают размеры в пикселах, а IE — в указанных единицах (кроме ширины и высоты).

2

Noindex и nofollow

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

Тег <noindex> позволяет скрыть кусок страницы от Яндекс- и Rambler-ботов.

<noindex>скрываемый контент</noindex>

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

Для заграничных поисковиков нет возможности спрятать кусок страницы, но можно скрыть ссылку, указав ей атрибут rel="nofollow".

<a href="..." rel="nofollow">скрываемая ссылка</a>

Этот атрибут для ссылок понимают Google, Yahoo, Bing. Использование его не скрывает ссылки от индексации поисковиками, но говорит им, что не надо передавать по таким ссылкам рейтинг. В работе поисковиков с этим тегом есть небольшие отличия.

Обновление от 25.08.2010. В мае 2010 года поисковый робот Яндекс начал поддерживать новые возможности. Появилась возможность писать тег <noindex> в валидном виде — комментарием:

<!--noindex-->неиндексируемый текст<!--/noindex-->

Тогда же Яндекс начал поддерживать для ссылок атрибут rel="nofollow".

0

Регистр в именах таблиц MySQL

Каждая таблица MySQL связана с файлом в системе. Потому при переносе проекта с Windows на рабочий *nix-хостинг нажно помнить, что под Windows имена таблиц не чувствительны к регистру, а на большинстве систем *nix чувствительны. Хорошим решением не наткнуться на эти грабли будет везде использовать строчные буквы при именовании таблиц. Тем более, что официальный мануал именно такой вариант и рекомендует. Тем не менее существует возможность влиять на то, как система работает с регистром с помощью параметра lower_case_table_names. Этот параметр может принимать три значения:

  • 0 — значение по-умолчанию на *nix-системах. Идентификаторы хранятся в том виде, в каком были указаны при создании. Имена регистрозависимы.
  • 1 — значение по умолчанию для Windows. Идентификаторы хранятся на диске в строчных буквах, имена регистронезависимы.
  • 2 — значение по умолчанию для MacOS. Идентификаторы хранятся в том виде, в каком были указаны при создании, но при поиске MySQL конвертирует их в строчные. Поиск имен регистронезависим. Это работает только на регистронезависимых системах! Таблицы InnoDB хранятся в строчных, как при lower_case_table_names=1.

Стоит добавить, что названия столбцов и индексов во всех системах регистронезависимы.

Подробнее читайте в мануале.

0

Переадресация на домен с www

Если сайт досупен по и по адресу с www, и по адресу без www, возникают проблемы с поисковиками. Они видят один и тот же сайт как два разных. Если ваш сайтовый движок не обрабатывает сам такие ситуации (в WordPress, например, задается адрес по-умолчанию), то можно исправить это с помощью апача. Пишем в .htaccess правило для редиректа:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTP_HOST} ^dec5e\.ru$ [NC]
  RewriteRule ^(.*)$ http://www.dec5e.ru/$1 [L,R=301]
</IfModule>

Если есть желание сделать основным домен без www, то правила будут выглядеть так:

<IfModule mod_rewrite.c>
  RewriteEngine On
  RewriteCond %{HTTP_HOST} ^www\.dec5e\.ru$ [NC]
  RewriteRule ^(.*)$ http://dec5e.ru/$1 [L,R=301]
</IfModule>

dec5e.ru надо заменить соответственно на нужный домен.

Если секция уже есть в файле, то вставляем в нее перед другими правилами. При попытке открыть сайт без www будет выполнен 301-ый редирект (Moved Permanently — перемещен постоянно). Этот код скажет поисковикам, что сайт навсегда перехал на адрес с www. Параметр L означает, что все правила указанные после этого RewriteRule не сработают. Параметр NC в RewriteCond обозначает, что ведется регистронезависимый поиск правила. Для более полного описания этих и других параметров смотрите официальную документацию по mod_rewrite (или по-русски).

0

Как проверить поддерживает ли браузер SVG

Для проверки нативной поддержки можно использовать два метода. Первый из презентации (страница 27) Дмитрия Барановского, автора Raphaël:

if (window.SVGAngle) {...}

основан на проверке доступности интерфейса SVGAngle и позволяет определить наличие поддержки в принципе. Второй из обсуждения на Stack Overflow:

if (document.implementation.hasFeature("http://www.w3.org/TR/SVG11/feature#BasicStructure", "1.1")) {...}

проверяет наличие поддержки определенной версии спецификации и даже определенных возможностей.

Оба метода работают в браузерах Firefox 2+ Win, Opera 9.0+ Win, Safari 3+ Win, Chrome 3+ Win, IE+ChromeFrame. Версии для других платформ у меня нет возможности  проверить, но, думаю, ситуация аналогичная. Хотя в Safari 3.0.4 для MacOS есть баг, из-за которого первый способ не работает. После выхода 4й версии в августе доля Safari 3 составляет меньше 1 процента. Но все же второй вариант проверки выглядит предпочтительным и более правильным.

Copyright © 2017 — dec5e | Site design by Trevor Fitzgerald