PhpDoc для конкретной переменной

10.12.2009
Занятия на беговой дорожке - беговая дорожка. Ищете беговые дорожки?. Подбор контактных линз - контактные линзы. Снижение цен на контактные линзы.

Мне никогда не нравился паттерн Factory в php. Не потому что он плохой или неудобный, нет. Просто IDE никак не понимали то что фабрика собственно возвращает. Это как и вечная проблема, что в phpDoc-ах можно указать какие параметры принимаются методом, какие возвращаются им, но никак нельзя указать класс для конкретной переменной.

Но недавно оказалось что можно. На примере:

$input = Input_Factory::factory('text'); /*@var $input Input_Text*/

И ура, подсказки работают :)

Продажа дом из клееного бруса только у нас. Желание клиента - закон.

MySQL альтернативный синтаксис INSERT

10.12.2009

Недавно узнал, что оказывается MySQL поддерживает 2-й альтернативный синтаксис оператора INSERT :)

Ну традиционный понятно:

INSERT INTO sometable (`field1`, `field2`,  `field3`)  VALUES ('value1', 'value2', 'value3');

А альтернативный как и UPDATE:

INSERT INTO sometable SET `field1`='value1' , `field2`='value2', `field3`='value3';

PHP_EOL

23.10.2009

Наткнулся на прикольную предопределенную константу PHP_EOL в которой лежит "\n", если сервер линуксовый или "\r\n" если виндошный. Ниче особенного, просто прикольная штука

Смена базы данных на php-проектах

27.05.2009

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

Суть ситуации в том, что люди намеряно сводят работу с базой данных до уровня insert, update, select, delete, создавая особо извращенные варианты доступа к этим самим данным. Любые - лишь бы не SQL. В итоге, понятное дело, без извращений в таких вещах очень сложно сделать простые с точки зрения запросов вещи. Ну например, счетчик посещений сайта и например ORM.

Алгоритм какой будет?

1. Выбрали данные;

2. Увеличили на 1;

3. Сохранили данные.

А что если на сайт почти одновременно зайдут 2 пользователя? :) Причем до шагов этого алгоритма они дойдут параллельно и в одно время. Т.е. 1-й делает выбор данных, потом второй, потом первый - увеличивает счетчик и т.п.? понимаете? :)

В самой базе все проще - UPDATE четотам SET `count`=`count`+1 WHERE четотам. И никаких глюков - потому что запросы будут выполняться последовательно.

Когда же копаешь глубже о причинах таких диких абстракций - оказывается, что все для того, чтобы:

Если заказчик захочет сменить базу данных скажем с MySQL на Oracle - то мы всего лишь переписали бы конфиг и все запалило на ура вместо того, чтобы переколбашивать весь сайт.

Я однажды не выдержал и поспрашивал всех кого знал, а сталкивался ли кто-нить из них с такой задачей - и оказалось что такое всплыло 1 раз на примерно 500-700 проектов, в которых участвовали опрошенные :)

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

Надеюсь, кому-то этот пост поможет перестать наступать себе на яйца при разработке. Помните: какой бы ни была по сложности задача смены СУБД - вы или фирма все равно на ней нагреетесь - заказчик хочет - заказчик платит :)

Многострочные строки в javascript

27.05.2009

Мож кто и в курсе, но я не знал и не сразу вкурил. Оказывается,  в джаваскрипте многострочные строки можно писать не только вот так:
var val = 'Индикатор ядовито'+
' гидролизует сернистый газ,'+
' таким образом за синтез';

А еще и вот так:
var val = 'Индикатор ядовито\
гидролизует сернистый газ,\
таким образом за синтез';

Не сказать, чтобы было гораздо читабельнее, но есть и такой вариант :)

Сравнение строк и чисел в MySQL

14.05.2009

За время работы я как-то привык, что если в интовые поля вставлять числа, оформленные как строки - то оно палит. Аналогично и если выбирает по id='5' например то тоже все ок и конвертируется в нужное...

Но вот недавно столкнулся с интересной ситуацией - поле varchar - там лежат числа. И получается что-то вроде:

select '33' > '5';

причем выбирает есесна 0 :) т.е. фолс, т.к. сравнивает строки. Такое вполне очевидно, но привыкаешь постепенно что с нестрогой нет проблем :) вот тебе и такое :)

Антиюзабилити в регистрации и авторизации

14.05.2009

Хотел вначале по посту о каждой - но понял что лучше все написать вместе. Вот самые распространенные тупые решения при создании авторизации пользователей на сайте:

  1. Email в качестве логина -  пожалуй, первое место в списке тупых идей. Сама идея такого подхода как раз-таки направлена на то, чтобы пользователю было проще регистрироваться. Типа вбивать меньше данных и все такое. Но на деле получается как раз наоборот - пользователь регистрируется не только на этом сайте, причем в большинстве случаев он вводит логин и пароль и ни разу не мыло в качестве логина. Он привыкает к этой паре логин-пароль и для него вбивать емэйл просто неочевидно, непривычно, не говоря уже о том, что если мыльников штук 5 - то какой именно был вбит при регистрации - вопрос достойный Что? Где? Когда?. Ну а если в форме авторизации еще и не подписано что вводить надо емэйл - ууууууууу :)
  2. Ограничения на выбор пароля - секъюрность - это круто, несомненно. Только вот пользователь привыкает к своей привычной паре логин-пароль. А вот если привычный пароль не проходит ограничения, выбирает новый, который с 90%-й вероятностью забудет тут же как вбил. На следующем заходе запросит восстановление - и пароль будет пылиться на мыле и каждый раз он будет заходить на мыло, смотреть пароль и вставлять в форму :) Вы считаете, что ваш аккаунт на вашем сайте - самое важно в жизни пользователя? ну-ну :)) Безопасность - это важно, когда нужно. Пусть пользователи сами решают, важен для них ваш сайт или он достоин пароля 12345.
  3. Капча + подтверждение email-а в регистрации - одной капчи с головой хватит чтобы вырубить ботов. Да есть метод леммингов для ее обхода, но много ли кому не влом его прикручивать? С подтверждением по emailу (активацией аккаунта) есть вечная проблема - обязательно у какого-нить письма не будут приходить. Или они в спам уйдут или еще какая-то фигня случится - неважно, так есть и будет. Не лучше ли высылать письмо со ссылкой на отписку, если ввели не правильный мыльник, чем на активацию? Да и настолько ли важно знать мыло пользователя для вашего сайта?
  4. Нераспознаваемая капча - кто-то криворукий создал новый тип капчи и все начали его пользовать. Не знаю видел ли кто - но я, человек из плоти и крови, вбиваю ее верно раза с 10-го.
  5. Капча без возможности перезагрузки - какой бы капча не была простой - обязательно однажды она сгенерит что-то ну просто совсем нечитаемое. А если пользователь уже вбил всю анкету - перегружать страницу не есть круто, ибо чревато потерей данных в некоторых браузерах.
  6. Лишние обязательные поля - какое вам дело как меня зовут или где я живу? Хочу введу хочу нет и нефиг делать это обязательным, поэтому для вас зовут меня "вапва" и фамилия "водаплвопвпвпавап".
  7. Малое ограничение на количество безпроблемных попыток ввода верного пароля - например, после 5 паролей начинает вылетать опять же капча или пишет типа подождите 20 минут. Лично у меня паролей штук 20, не меньше, и юзал я разные в зависимости от ситуации, вначале одни, потом другие и т.п. за лет 10 накопилось немало вариантов... А тут 5 - и потом мучайся... а в сочетании с п.4 - уххх  как весело авторизоваться становится...
  8. Блок при N неверных попыток авторизации - тут скорее дело не в идее блокировать доступ к аккаунту на время если кажется, что подбирают пароль, а в кривой реализации этого некоторыми товарищами. Так как куки чистятся - надо учитывать ip, с которого пытались это сделать, иначе кто угодно набьет другому N попыток авторизоваться всяким шлаком и заблочит ему на время аккаунт.

С чего начать?

02.05.2009

В мире программирования задача никогда не бывает одна, если это так - значит поставлена она не верно. Зачада "Сделать сайт" - поставлена неверно, к примеру. Большие задачи обычно дробятся и каждому периоду работы обычно предшествует список определенных задач на реализацию. Среди таких задач бывают большие - например "Сделать фотогалерею" и тз, дизайн и т.п. по ней. А бывают маленькие - например, сменить фразу "Выбранные товары" на фразу "Корзина".

С чего начать? С больших или с маленьких задач?

Обычно начинают всегда с больших. И так в целом абсолютно здраво делать, когда проектируется новый сайт или вы знаете систему отлично. На маленькие задачи надо меньше сил, а если вначале сделать мелочь - то на большое не всегда останется рвения. Да и если система создается новая - то вначале надо сделать "скелет", а уже потом навешивать мышцы и кожу :)

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

Например, пришел проект написанный фиг знает на чем, фиг знает кем и когда. Что внутри - непонятно. Делаем мелкий таск - изменение надписи. Дело пятиминутное - тупо прогнать поиск по коду (и базе если по коду не найдется) по этому слову - и поменять его. Задачу сделали - и уже кое-чему научились, например, как устроена система локализации, есть ли она вообще. Какие шаблоны есть в коде. Т.е. решение мелкой задачи помогло попутно разобраться с проектом и узнать что-то о нем, без того чтобы специально колупать его и смотреть что там и где. И так далее - от мелкого к крупному.

Такой подход позволяет убить сразу 2-х зайцев:

  1. Тратится минимум времени на изучение архитектуры проекта;
  2. Всегда можно показать заказчику, что работа над проектом идет. Ему не придется месяц трястись и трахать мозг менеджеру, ожидая выполнения самой большой задачи.

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

$i++ vs. ++$i

02.05.2009

Есть у меня товарищ, который кодит на c++. И как-то в его коде в цикле я заметил, что он пишет не i++; а ++i; - оказалось что так производительнее (ну они сишники вообще помешаны на этом всем). Почему лушче писать так, я как-то поленился разобраться, но пример я естесственно запомнил - и старался по мере сил писать такое же и в php, хуже ведь не будет все равно. Оказалось недавно, что и у нас это тоже оправдано.

Оказывается:

При использовании инструкции $count++ увеличение переменной $count выполняется после того, как будет рассчитано выражение с использованием данной переменной. Например, $i =$count++; — переменной $i будет присвоено значение переменной $count до того, как последнее будет увеличено на единицу. Это означает, что машина должна сохранить значение $count, чтобы использовать его в любом выражении с переменной $count. В инструкции же ++$count значение переменной увеличивается на единицу до вычислений, поэтому нет необходимости хранить временное значение (а это менее накладно). Если инструкция $count++ применяется в выражении, где значение переменной не используется (это называется пустым контекстом), то ее можно безопасно преобразовать в преинкрементную инструкцию.

Конечно, фигня там получается, а не оптимизация, но зато в таком коде сразу видна рука мастера :)

Метод леммингов

02.05.2009

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

На деле же, нормальные ботописцы забили давно болт на распознавание компом капчи - потому что это слишком бессмысленно когда есть Его Величество "Метод Леммингов".

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

Гораздо эффективнее защищаться тем, что может браузер, но не может бот. Например, с выполнением javascript-а насколько я знаю у всех языков реальные проблемы. Конечно, можно пользоваться и браузерами как помошниками в спаме и т.п. - в винде например IE как ком-объект отлично вызывается. Да вот только программист, который это наколбасит будет стоить гораздо больше, чем годы работы голодающих детей банановых стран.

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

Вычисление констант в коде

02.05.2009

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

$seconds_count = 86400;

Не, я тут не буду писать про переменные и т.п. я буду писать про числа. Возьмем число в примере - слету и не разберешь че это такое вообще... Вот если бы:

$seconds_count = 24*60*60;

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

Другими словами, если код транслируется один раз, а потом берется уже откешированый, то смысла в этом нет вообще - ну один раз сделает комп вычисление умножения, которое само по себе очень легкое - что с того? Ну а если же нет - и php-код будет каждый раз интерпретироваться без сохранения промежуточных вариантов - то не проще ли врубить eAccelerator? Да и нужна ли такая типа оптимизация в проекте в котором все положили на реальное ускорение через кеширование?

Объявление объекта без скобок

01.05.2009

Иногда встречаю вот такую вот запись создания нового объекта:

$obj = new Typed;

Вначале мне казалось, что это просто от криворукости программистов и работает также как и массивы, в которых индексы пишутся без кавычек типа $a[index], где автоматом заводится константа с тем же значением и это на удивление работает. Оказалось констант никаких не заводится - а это просто особенность языка.

Оказалось, что такая манера создания классов была описана в мануале по классам и объектом самими разрабочиками php для php4 на php.net.

Вопрос, нафига? В самых распространенных языках программирования везде пишутся скобки после имени класса. IDE от тех же Зендов тоже подсказывает $obj = new Typed(); По-моему, это только запутывает.

P.S. Кстати и в 5-м php та же фигня в описании...

Отправка писем с ошибками администратору

01.05.2009

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

Представим себе проект, который посещает человек 300 в день и у которого внезапно отвалилась база данных. Ну например, место кончилось или еще че-нить. Пользователь, который видит, что страница не загрузилась есстественно попробует ее перезагрузить несколько раз :) для верности. Ну и каждый раз есстественно письмо админу :)

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

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

Форматирование sql-кода

01.05.2009

$res = mysql_query("select articles.title, articles.text, articles.id, articles.user_id, users.name from articles left join users on articles.user_id=users.id where $condition order by id desc limit 5, 10");

Такой жестяк часто встретишь, когда пишут код студенты или просто люди торопятся да так что ппц. Нифига не понятно. Запрос написан в стиле write-only. В противовес индусам - нормальные программисты используют определенные правила форматирования кода в запросах. И хоть каждый использует свои, как правило они очень похожи.

Прочитать остальную часть записи »

Чем echo отличается от print

01.05.2009

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

<?php
print "Hello World!";
echo "Hello World!";

И то и то выдаст "Hello World!", однако разница между ними все же есть, просто сложно придумать ситуацию, в которой она была бы заметна:

  1. print возвращает true/false в зависимости от того, удачен вывод или нет. Я не представляю себе ситуации, в которой она бы вернула false, но наверное есть... echo ничего не возвращает;
  2. echo нельзя использовать со скобками, т.е. echo(123) - выдаст ошибку, print(123) - нормально отработает;
  3. Понятное дело что из-за п.1 echo работает быстрее чем print. Разница несущественная, но есть и это неплохо знать;
  4. В echo можно передать несколько параметров для вывода через запятую (echo 123, 'aaaa', 33 ;) и они выведутся последовательно. В print нет.

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

Строки и is_int

01.05.2009

Интересное наблюдение вычитал в книжке "Профессиональное программирование в php". Автор пишет, что:

Использование вместо функции is_int регулярного выражения для определения того, является ли $п целым числом, может показаться странным. Однако функция is_int не делает того, что в данном случае требуется. Она только проверяет, типизирована ли переменная $п как строковая или как целочисленная, но не проверяет, является ли значение переменной $п целым числом. Данный нюанс может ввести разработчика в заблуждение, если он использует функцию is_int для проверки данных HTML-форм (среди прочего).

Я как-то не сталкивался с этим раньше и решил проверить. Оказалось действительно:

<?php
var_dump(is_int("56"));
var_dump(is_int(56));

Выдает: bool(false) bool(true) 

Как вставить javascript в smarty

01.05.2009

Недавно постучался ко мне в аську знакомый сеошник с проблемой - дескать не могут они с верстальщиком в уже готовый проект, написанный фиг_знает_кем_кого_уже_нет_рядом, код то ли счетчика то ли еще чего, другими словами javascript вставить не получается. Какой там шаблонизатор, да и вообще на чем проект этот написан, они понятное дело не в курсе, потому что один верстальщик, а второй сеошник а спросить не у кого. Я попросил прислать пример кода в html-ке (текста шаблона) и, как я и ожидал, оказалось что это Smarty.

Если кто не знает, в смарти используются разделители для того, чтобы обозначить что данный кусок кода все-таки написан на смарти а не просто текст. И хоть в доке по нему явно написано, что разделители дескать можно настроить любые какие только душе угодно - на деле же все используют именно то что там по умолчанию ( фигурные скобки ), ибо все готовое написано именно так, а переписывать готовое ради разделителя не айс ни разу.  Вот и получается что код javascript-а, обрамленный в блок (например function foo() { ... }, да или просто любой блок) шаблонизатор воспринимает как директиву Smarty и пытается его исполнить. И чтобы такого не возникало, придумали специальный костыль - обрамлять куски html, в которых встречаются разделители тегами {literal}тут код{/literal}.

Приятель, для которого код - это что-то из серии магии, воспринял это нормально. Их с версталем не бесило то, что они убили полдня на выполнение простейшей задачи. Но если бы они знали, что оффициально смарти (да и вообще любой шаблонизатор) нужен для того, чтобы разделить логику работы приложения от логики отображения и в куче зомбирующих постов про него написано, что верстальщикам проще редактировать шаблоны, написанные в нем, чем в чистом php, то наверное реакция у них была бы совершенно другая.

Грабли с короткими тегами и заголовком xml

01.05.2009

За все время программирования я так привык к тому, что в проекте используется какой-либо шаблонизатор для html-страниц да и вообще все что отдается пользователю идет через какой-то компонент и отвык от проектов с мелкими кусками php-кода прям посреди html-разметки, что просто не мог наступить на эти грабли. Оказывается, если short_open_tag включен (php.ini ну или php_value в .htaccess и т.п.), то  можно поймать вот такую вот проблему:

Если у нас есть php-ка, которая начинается с xml заголовка, то при включенном short_open_tag - заголовок будет интерпретироваться как php-код. Ну собственно вот для наглядности:

info.php c кодом:

<?xml version="1.0" ?>

[Дальше xml или html]

Выдаст: Parse error: syntax error, unexpected T_STRING in ...info.php on line 1

На относительно больших проектах, написаннх ровноруко, такой баг врятли поймаешь, но если писать скажем самопальную rss-ку без mod_rewrite или скажем XML Sitemap, то вполне.

Насчет же тегов мне всегда казалось, что в тех же шаблонах, сделанных например в стиле Zend_View, гораздо удобнее писать <?=$variable?>, чем <?php echo $variable; ?>, но на мелких доделках и самопальных решениях не все может прокатить, поэтому надо быть осторожными и стараться использовать чужие наработки.

Жесткая табуляция vs. Мягкая табуляция

01.05.2009

Чтобы немного прояснить для тех кто не в курсе, напишу определения обоих вещей. Итак:

Жесткая табуляция (hard tabs)— это обычные символы табуляции.

Мягкая табуляция (soft tabs) в действительности вообще не является табуляцией; каждый отступ в мягкой табуляции фактически представлен определенным количеством обычных пробелов.

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

Прочитать остальную часть записи »

Приоритеты операций

20.04.2009

Программист, помни, на собеседовании всегда найдется человек, который высушит тебе мозги приоритетами операций и вот такой вот фигней - $a = ++$b - $a * ($b--) > 5 ? ++$a^$b : $b-=5;

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

Прочитать остальную часть записи »

REGEXP и RLIKE

20.04.2009

Наткнулся недавно в коде проекта на вот такую вот конструкцию:

...AND (`struct`.`regions` = "" OR `struct`.`regions` REGEXP "^a:[0-9]+:\{.*(i:[0-9]+;s:[0-9]+:\"'.$current_region_id.'\"\;).*\}$" OR `struct`.`regions` REGEXP "^a:[0-9]+:\{.*(i:[0-9]+;s:[0-9]+:\"'.ALL_REGIONS_ID.'\"\;).*\}$" OR `struct`.`regions` REGEXP "^a:[0-9]+:\{+(i:[0-9]+;s:[0-9]+:\"0\"\;)*\}$" )...

и не сразу вкурил что это за загадочный REGEXP. Оказалось что это синоним старого доброго RLIKE, ну точнее последний синоним первого :) так-то :)

This page contains both secure and nonsecure items

17.04.2009

Недавно наткнулся на хабре на стетейку о «//» в ссылках, т.е. идея писать абсолютные пути без указания протокола типа http://ya.ru заменять на //ya.ru/.

Не буду копипастить - статья лежит тут: http://bolknote.ru/2009/04/04/~2074 советую прочитать всем.

Раскажу я о том, что это может поправить. Так вот, дело в том, что когда IE подгружает страницу по https, в которой есть ссылки на цсски или джээсники по http - ругается, дескать "This page contains both secure and nonsecure items". Такой баг я поймал когда прикручивал WorldPay - там страница ответа подгружается системой и отображается как своя - т.е. ваша страница ответа будет по урлу http://www.worldpay.com/etc.... Ясное дело, что если ссылки в урлах относительные - то css не загрузится и дизайну кабзда :) поэтому ссылки делаются абсолютными - ну а если они генерятся автоматом - то путь на них будет по http - вот и получаем такой варнинг. Если же пользоваться «Common Internet Scheme Syntax», то все будет окей :) жаль что я не знал этого пару лет назад :(

Тег <colgroup>

17.04.2009

Ширина ячеек таблицы - отдельная песня для создания сайтов. В больших таблицах, где линий много, тегов <td> еще больше. Чтобы указать ширину ячеек один раз - я обычно указывал ее только для первой линии (т.е. для td-шек 1-й tr-ки), а остальные уже подстраивались под первую. Если же таблица генерилась циклом, то width получалось был в каждой ячейке.

Прочитать остальную часть записи »

Тег <nobr>

17.04.2009

Мне нравится работать в команде опытных ребят, постоянно тибрим друг у друга идеи и учимся чему-нить. На этот раз открытием для меня стал тег <nobr>. Я раньше часто мучался, выискавая место куда можно тыркнуть nowrap, а оказывается все гораздо проще:

Тег <NOBR> (NO BReak line) запрещает перевод строки. Бывают случаи, когда возникает надобность в операции противоположного назначения – запретить перевод строки. Текст, заключенный между тэгами <NOBR> и </NOBR>, будет гарантированно располагаться в одной строке без переноса на другую. Длинная строка не уместится на экране, и для ее просмотра придется использовать горизонтальную полосу прокрутки. Закрывающий тег обязателен

Атрибутов нет, хотя какие-тут могуть быть аттрибуты :)

Поиск через POST

12.04.2009

Концепция "Friendly URLs " в последнее время полностью извратила метод GET протокола HTTP. Никаких тебе index.php?path='blog'&record_id=100500 - все разделено слешами, даже этот пост, сайт без mod_rewrite кажется просто неполноценным. Однако остались еще места, где GET незаменим. Одно из таких мест - форма поиска.

У многих программистов (как правило, начинающих) в голове почему-то строится странное соответствие: формы = POST. Понятное дело, форма авторизации - постом, ибо показывать кому-то логин-пароль в урле - брррр, контактная форма - тоже пост и т.п.

Прочитать остальную часть записи »

CSV-парсеры

11.04.2009

CSV - один из форматов файлов. Удобен он тем, что позволяет заказчикам, непросвященным в вопросах технологий редактировать данные в обычном экселе, а программистам легко забирать то что они там понаписали. Заказчик делает обычную таблицу, сохраняет ее в формате csv - и получается файлик, в котором записи разделены по определенным правилам.

1. Каждая строка - это отдельная запись;

2. Записи разных колонок разделяются определенным разделителем (в основном зяпятая или точка с запятой);

3. Если в записи есть разделитель, то запись берется в кавычки;

4. Если в записи есть кавычки, то они представляются в виде 2-х кавычек;

Прочитать остальную часть записи »

Избавиться от LIMIT через id последней записи

11.04.2009

Иногда нужно перебрать много записей из базы. Если таблицы большие, то сразу выбрать все - довольно тупое решение, поэтому обычно выбираются записи с лимитом. Вначале первые N, потом от N до 2N и т.д.  Недавно я узнал, что использовать конструкцию с лимитом ( LIMIT n, m ) на больших таблицах - не верно, потому что при выборке скажем:

SELECT * FROM table WHERE true LIMIT 100500, 100600;

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

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

Например:

SELECT * FROM table WHERE id>100500 LIMIT 100;

Такое будет гораздо быстрее работать на больших базах (а иногда только оно и будет работать :) ). Конечно, не самый красивый костыль, но какой есть :)

href=”#” vs. href=”javascript: ;”

11.04.2009

Ссылки, как известно, не всегда нужно делать именно ссылками, иногда нужно чтобы они выполняли роли кнопок - чтобы по событию на клик отрабатывал нужный скрипт. В таких случаях, понятное дело, нужно, чтобы по клику на ссылку страница не перегружалась. И делают это обычно через жопу, а именно как:

<a href="#" onclick="return someScript(this);" >Ссылка</a>

И вроде бы все соответствует тому, что нужно - ссылка не нажимается, перехода на другую страницу не происходит - солнце светит, птички поют, тестеры и заказчик довольны - все кул. НО! это пока не появляется вертикальной прокрутки на странице и пользователь ее не прокрутит вниз до того как нажмет на такую ссылку. Потому что как только он это сделает, прокрутка магическим образом прокрутится вверх :)

Проблема такого подхода собственно в том, что в html по ссылкам можно переходить не только на другие страницы - но и прокручиваться к элементам текущей. Сделано это через так называемые якоря. То есть, если к примеру, в каком-то месте страницы у нас есть:

<div id="aaa">дивка</div>

и есть ссылка:

<a href="#aaa">ссылка</a>

то по клику на ссылку - произойдет прокрутка к блоку div.

Если же указано просто href="#", то почему-то, браузеры считают что нужно сделать прокрутку в самое начало страницы.

Помнится, я долго бился с этой проблемой - и таки нашел альтернативу:

<a href="javascript: ;">ссылка</a>

По клику - никуда он не переходит и никуда ничего не прокручивает :)

alert anchor-а выдает то что в href :(

10.04.2009

3 часа времени убил недавно на непонятное поведение браузеров. Было у меня примерно следующее:

<div id="aa">

<a href="javascript: ;">Ссылочка</a>

<a href="javascript: ;">и еще ссылочка</a>

<a href="javascript: ;">и еще</a>

</div>

через jQuery дергаю массив ссылок:

var links = $('#aa a');

и когда пробегаюсь по ним циклом - то при алерте элемента (другими словами, alert(a), где a - anchor) - получаю текст "javascript: ;".

2,5 часа я думал что дело в том как я выбираю данные в массив - мне казалось что цикл пробегает по полям <a /> и выводит собственно их, пробовал даже через $('#aa').getElementsByTagName('a'), но потом оказалось, что браузеры почему-то ведут себя неадекватно, если делается alert по <a />.

К примеру:

<a id="diablog" href="http://www.diablog.ru">Диаблогъ</a>
<span id="oneone">АДЫНАДЫН</span>
<script type="text/javascript">
alert(document.getElementById('diablog'));
alert(document.getElementById('oneone'));
</script>

Про спан все честно скажут, что это Object HTMLElement (Opera),  Object HTMLSpanElement (FF) и просто object в IE6, а вот зато про анчор - тупо выведется то, что в параметре href.

this is kind of magic o-o-ou :)

autocomplete=”off”

10.04.2009

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

Прочитать остальную часть записи »


Информеры с тИЦ и PR: получить код для сайта
Коммерческие микроавтобусы IVECO: аренда автобуса микроавтобуса.. Канализация для дачи от 56500 р: септик. Зимняя распродажа септиков.