Открыть список
Как стать автором
Обновить

Комментарии 108

Половины указанных ошибок можно было бы избежать, используя готовые проверенные решения.
Да, главный полученный урок: «не изобретайте колесо».
Ага, и не научиться ничему.
Ну одно дело пробовать, изучать, мастерить, другое дело — продакшн клиента. Есть разница. Не, я все понимаю, это палка о двух концах, спорить не буду.
В статье с таким названием ожидал увидеть нечто действительно стоящее, а увидел PHP
наиболее популярный язык для веб-разработки это уже не стояшее?: )
Вы исходите из предпосылки, что массовость определяет полезность. Продолжая вашу логику: каждый житель планеты Земля производит дефекацию минимум раз в день. Вывод: говно популярнее пхп. Вывод: даже говно лучше, чем пхп. (кстати, в этом выводе что-то есть)
есть разница между необходимыми функциями организма и выбором.
Хорошо, вот вам другая аналогия: дошираком питается больше людей, чем пишет на пхп (хотя эти множества и пересекается). Вывод: доширак лучше похапэ. Доширак — говно. Вывод: говно лучше похапэ.
вы опять же сравниваете котов со слонами
попробуйте провести аналогию с языками для веб-разработки
С чего это? Нищеёбствовать и питаться дошираком — выбор. Нищеёбствовать интеллектуально и писать на похапэ — тоже выбор. Конечно, люди любят оправдывать свои выборы («мне платят за похапэ», «мне достаточно похапэ», «мне нравится вкус доширака», «а чо — дёшево и норм, под пивасик особенно»), но это не отрицает возможности строить по выборам людей суждение о них.
питаться дошираком не выбор, а суровая необходимость, вызванная нехваткой денег.
что за бред
Точно в той же мере писать на похапэ не выбор, а суровая необходимость, вызванная недостатком интеллекта и образования. Вы в точности уловили мою позицию.
Не место красит человека, а человек место.

Так же и с языками.

А глупость про недостаток интеллекта и образования, хабраюзеры вам не простят и правильно сделают. ЧСВ надо лечить.
… а быдлокодить «программить» на PHP — необходимость, вызванная отсутствием чего?
УПС! Мой фэйл. уже ответили также. Заминусованный коммент не заметил. Мои два пойдут туда же в виду массовости оппозиции.
А вот вам правильная аналогия с дошираком:
1) Доширак легко купить и перевозить с собой. Гораздо проще, чем кусок отбивной + овощи, которые перед употреблением надо еще и пожарить и сварить. Да и контейнер нужно купить для перевозки.
2) Стоит не дорого, и способен удовлетворить голод, а при прочих равных еще и хранится дольше.
3) Если есть в арсенале овощи, мясо, — можно выкинуть из пакетика приправы и глутамат натрия и сварить вполне себе диетический и полезный суп.
4) Среди дошираков есть вполне себе дорогие и более-менее полезные наборы, так же как среди мяса баранины может попасться крыса или дохлая кошка. Это как выбирать и где и почём покупать ;)
5) Есть овер 9000 рецептов прикольных и полезных блюд из яичной лапши — (а это основа дошираков). Огромный плюс в простоте приготовления элементарного и в наличии возможностей приготовить изысканное блюдо, добавив нужные ингредиенты и навыки.

Так что ваша аналогия откуда то из детских холиваров уровня «я на третьем курсе учуся, мне преподаватель сказал, что ПХП — говно, и ваще там нет типизации и т.д. и т.п.».

Ой, фейсбук там с ПХП мучается, ой ой ой, какая печалька… Интересно с чем другим он бы смог так быстро стартануть, вполне себе сносно работать и развиваться.
Продолжайте питаться говномдошираком, я же не мешаю. На улице, разве что, постараюсь обойти стороной, чтобы не так вонь в нос била, но в целом это ваше право ;)
>> фейсбук там с ПХП мучается, ой ой ой, какая печалька…

Да вроде ж FB с РНР уже давно отмучался, оставив на нём совсем маленький кусок по историческим причинам.
Если за год ничего не поменялось, то «Facebook по-прежнему использует PHP, но перед исполнением скрипты компилируются в родной код процессора, ускоряя таким образом работу».

Источник: habrahabr.ru/blogs/personal/100020/
Ну да. В статье, на которую вы ссылаетесь есть подтверждение моим словам: всё работает на С++ а РНР остался для парсинга страниц вроде.

Так-же и с mysql — он какбэ есть, но на практике это key-value хранилище, запросы ограничиваются словсми select, insert, update и where.
Если верить поиску, C++ упоминается в статье два раза:

1:
«HipHop конвертирует скрипты на PHP в исходные коды на C++, которые затем компилируются для обеспечения хорошей производительности.»

2:
«PHP используется как фронт-энд, Erlang для чата, Ява и C++ тоже не остались без дела.»

Не вижу здесь подтверждения ваших слов. Да, php компилируется в C++, но, насколько я понял, программисты пишут на php, C++ используется только для компиляции.

Да и в тексте есть такие фразы:
«PHP в Facebook используется практически повсеместно.»

Как вы подметили, автор похоже слабо понимает разницу между key-value хранилищем и даже, ограниченной простыми запросами, реляционной базой данных.
Уже второй комментарий подряд вы пишете про говно. Вывод: все ваши комментарии — говно.
Так?
Отличная аналогия.
Уже второй день подряд вы посещаете туалет. Вывод: вы — говно. Так?
Расскажи об этом Цукербергу
Вывод: дефекация важнее пхп, все правильно. Или вы скорее предпочтете проблемы с дефекацией, чем с пхп?
Для таких как Вы, авторы топиков пишут теги.
Говорить это 1-2 тысячам читателей, использующим PHP — тоже в своём роде ошибка. Как вторая, описанная в статье, про рассылку e-mail. И, наверное, Вы не прочитаали совет по этому поводу :)
3. Всегда писать что-либо вежливое в тексте письма, например, «Пожалуйста, проигнорируйте это тестовое сообщение». Нежелательно писать что-то вроде «Мой клиент — дурень» — мало ли это прочитают 20 тысяч ничего не подозревающих инвесторов.
Говорить это 1-2 тысячам читателей, использующим PHP — тоже в своём роде ошибка. Как вторая, описанная в статье, про рассылку e-mail. И, наверное, Вы не прочитаали совет по этому поводу :)
3. Всегда писать что-либо вежливое в тексте письма, например, «Пожалуйста, проигнорируйте это тестовое сообщение». Нежелательно писать что-то вроде «Мой клиент — дурень» — мало ли это прочитают 20 тысяч ничего не подозревающих инвесторов.
Сорри, дубль.
Трололо, какая разница, на чём писать? Если у тебя руки из ануса — не поможет даже твой любимый язык программирования.
По количеству заработанных минусов можно судить о сплоченности PHP-разработчиков. Браво! Не каждое сообщество умеет день ото дня употреблять дерьмо и радоваться этому, а также отстаивать честь тех, кто наслаждается вместе с ними.
По количеству минусов видно, что человек навязывающий свое мнение всем и каждому не пользуется уважением в обществе.
Вы судите об уважении по количеству плюсов и минусов? А по карме, очевидно, определяете, с кем вам дружить.
Когда я говорю об обществе — я имею множество пользователей ресурса — у всех этих пользователей есть право один раз проголосовать за любое высказывание любого другого. Все абсолютно в равных условиях. То что ваш комментарий ушел в минус говорит только о том, что большинство пользователей, которые сочли нужным проголосовать, считают ваше суждение неверным.
Спасибо. И как же я сам не догадался.
Причем я не думаю, что среди них все любители или программисты на PHP, какая-то часть просто переросла понятия типа «моя пиписька длинее чем твоя» и дают оценку конкретным результатам а не инструментальным средствам.
Главный вывод: учить матчасть и думать перед тем, как что-то делаешь.
Деньги и плавающая точка — зло.
именно. это всё noobie-fails
Я поразмыслил над этим случаем и установил, что следует:
1. Избегать работать поздно ночью
Как я вас понимаю… У самого после ночных бдений порой случаются «провалы», но отучить себя от этого не выходит…
Ночью вообще самое продуктивное время, никто не тревожит… коллеги, семья, клиенты…
и на хабре почти никто не пишет, потому что все программят или спят.
6 утра — самое продуктивное время. Проснулся свежим, голова варит на отлично. Никто не мешает. За окном рассвет.

При этом, с 13 до 14 отличный дневной сон.
Если живешь не один, заснуть в 10 вечера проблема.
Ох, я думал я один такой. Тоже считаю, что работать утром — самое то. И при этом тоже днем тянет поспать. Но зато после дневного сна голова опять вежая и опять готов работать
:)
Это статья-перевод, так что это не к автору.
Насчёт дат — нужно не изобретать колесо и использовать возможности базы.
Для MySQL выборка за прошедшую неделю выглядет так: SELECT * FROM `table` WHERE `datetime_field` >= NOW() — INTERVAL 1 WEEK
И.т.д., у MySQL весьма обширный список функций по работе с датами и такие вещи как летнее время уже обрабатываются за нас.
BETWEEN кстати с датами тоже работает прозрачно — главное что бы тип столбца был date, time или datetime
В связи с грядущим «недоперехором» на зимнее время 2011 нам еще долгое время придется отлавливать многие вещи, которые совсем не факт, что корректно обработаются за нас.
Поле типа datetime хранится с учётом текущей временной зоны — т.е. с текущей серверной часовой зоной. Если вам нужно показать пользователю другой временной зоны данные, то при установке соединения просто сделайте вот так:
SET time_zone = timezone;


Так что большинство проблем давно имеют решения, просто часто никто их не ищет.
Я после аналогичной ошибки с временем, перешел на ранение времени в GMT, но не отказался от секундного его представления.
Действительно, зачем нам отладчик с брекпоинтами как у всех нормальных людей, мы лучше трейсов наделаем.
на сервере тоже отладчик?
Из одной крайности в другую. А почему бы не хранить и передавать данные в зашифрованном виде? (с ключами достаточной для будущих мощностей криптостойкости)
Статья поучительная, хотя бы тем, что напоминает о некоторых действительно распространенных ошибках, большинство из которых совершаются из-за невнимательности и спешки.

Но перевод хромает… Местами очень напоминает гугл, подвергшийся рерайту. Например:

«Для третьего пункта я осуществил несколько функций, чтобы обеспечить показ сообщений о дебаггинге только мне самому».

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

Помню, нас учили стараться передать именно смысл, а не структуру предложения. Конечно, если ситуация не требует максимальной точности. Переведите предложение дословно, а потом напишите его так, будто вы излагаете заложенный в него смысл самостоятельно, не опираясь на текст оригинала. Я думаю, это даст хороший результат.
я может чего не понимаю…
а почему для дебага нельзя использовать site.com/page.aspx?debug=1?
Лучше тогда уж в куки. Потому, что для POST-форм придётся каждый раз менять action, для ajax-запросов вообще какие-то хаки придумывать.
Было бы еще хорошо узнать, как работать с деньгами правильно.
Сейчас есть один проектик, в котором деньги приодят в рублях, переводятся в доллары и кладутся флоатом в базу…

Я теряюсь — что с этим делать?
ну в базе точно нужно использовать DECIMAL — вроде как специально для хранения денег придумали этот тип.
В mssql для этого есть типы decimal и money
Лучше всего не работать с деньгами, если возникают такие вопросы.
Если следовать такой логике — то вообще не стоит задавать вопросы, чтобы получать на них ответы.
Жить в счастливом неведении. Что может быть лучше?
В банковских продуктах деньги хранятся в самых мелких единицах измерения, которые существуют в валюте. Например, тунисский динар состоит из 1000 милльем. Для каждой валюты составляется карта трансформаций, которая подготавливает данные для вывода. Карта — это набор коэффициентов, на которые умножается сумма, чтобы получить денежные единицы другого порядка
Откуда информация? Я думал что в банках понятие «валюта счета» отвечает в том числе и за то, в какой валюте хранятся данные. Ведь иначе тунисский доллар может вырасти или упасть?
Информация из содержимого таблиц, которые используются АБС. Валюта счета — информационное поле. Хоть и пишут USD, RUR, EUR, и так далее, реально деньги хранятся в центах, копейках и прочих мелких единицах.

Простой пример. Человек взял кредит 1 тунисский динар. Заплатил обязательный платеж по телу кредита 1 милльем. Если вы храните в базе 1 динар, то вы сначала должны узнать из какого количества боллее мелких денег состоит динар, потому что вы должны вычитать не 0.01, а 0.001. Это на каждую операцию вы должны лезть в справочник и что-то там мудрить. Бездумная трата машинных ресурсов, не находите?

Теперь вариант с хранением в милльемах. Человек взял в кредит 1000 милльем, заплатил 1, осталось заплатить 999. Такие операции как вычитание, сложение, умножение, деление, можно делать без справочников. А на момент отображения данных уже лезть в справочники и узнавать, какое количество динаров ему еще осталось платить.
А как насчет дробных частей? Наверняка есть какое-то устойчивое мнение, начиная с какого разряда можно отбрасывать цифры. В бухгалтерии до какого разряда идет расчёт процентов? И в какую сторону округляются суммы?
Поясняю еще раз. Данные хранятся в целочисленном виде. Не в float. Если попадается бухгалтер-задрот, который любит считать все до десятых копеек, то водите еще одну размерность — десятая копейки, тогда копейка будет 10 десятых копейки, рубль — 1000 десятых копеек. Все эти размерности будут играть роль на момент вывода единиц на экран пользователя, но ни в коем случае не на момент математических рассчетов.
Храните в БД в flloat, при расчетах в php используйте только функции BCMath, дабы избежать неточностей в арифметических операциях с float'ами.
Всегда писать что-либо вежливое в тексте письма, например, «Пожалуйста, проигнорируйте это тестовое сообщение». Нежелательно писать что-то вроде «Мой клиент — дурень» — мало ли это прочитают 20 тысяч ничего не подозревающих инвесторов.

Взял за правило быть вежливым даже в комментариях. Их может никто и не видит, но мало ли…
А может просто не стоит вести разработку и тестирование на продакшн сервере, не? Я с php не работаю, это там так принято разрабатывать/дебажить? белый список ip дебагеров очень мило :)
Вроде про разработку на продакшене нигде не было. Или я пропустила?
Пропустили, глава «Невыключенный режим отладки» :)
Там не про разработку на продакшене, а о том, что с продакшена загрузили на лив код с включенным режимом дебага.
а если ошибка вылезет как раз на продакшене
стараюсь использовать 2 конфига (production и development) в которых храню все настройки
и далее примерно так:
switch ($_SERVER['SERVER_NAME']) {
case 'www.site.com':
case 'site.com':
case 'aliasOfsite.com':
define('MODE', "production");
break;
default:
define('MODE', "development");
break;
}
Вот изменится у вас имя сервера, а обновить конфиг забудете…
В условии по дефолту я бы предложил кидать ошибку, потому что запустить production конфигурацию локально тоже может быть нежелательно.
посмотрите как работает Zend Framework — там устанавливается переменная окружения и в зависимости от ее значения разбираются различные секции конфига
НЛО прилетело и опубликовало эту надпись здесь
Строил собаке будку, сделал огромное количество ошибок:
  • сначала сделал крышу, в конце обнаружил, что она не подходит для будки
  • собрав будку, понял, что забыл сделать дверь
  • переделав будку понял, что она мала для моей собаки...


Выходит все строители г…
НЛО прилетело и опубликовало эту надпись здесь
Это не я ;)

Пробуйте сами:

function GetMoney (amount) {
  var pounds = Math.floor (amount);
  var pence = Math.floor (amount * 100) % 100;
  return pounds + '.' + (pence < 10 ? '0' : '') + pence;
}
alert (GetMoney (4.9995) + ' ' + GetMoney (0.1 * 0.7));
НЛО прилетело и опубликовало эту надпись здесь
Кстати говоря, при работе с деньгами как раз таки округление чаще всего идет до меньшего целого, как ни странно. Ну а математическое округление пригодится именно в математических рассчетах.
НЛО прилетело и опубликовало эту надпись здесь
1) « 0.6999999999999999, что затем будет уменьшено до 69 пенсов вместо округления до 70» мы о них и говорим, вроде как
2) конечно, а до этого и нет необходимости округлять.
НЛО прилетело и опубликовало эту надпись здесь
> … угадайте, что будет возвращаться, если вы запустите следующее?
>
> SELECT * FROM products WHERE category='retro clothing';
>
> Ответ – ничего, поскольку колонка категории длиной всего в 10 символов, так что категория последнего продукта урезана до retro clot.

Если проверять warnings, то подобное можно заметить после первого же INSERT-а или хотя бы сразу понять почему SELECT возвращает неверный результат.

> Перевод часов
>
> Я бы не назвал эту ошибку «погрешностью». Она появляется при особых редких обстоятельствах,…

Вызвало улыбку, потому что по bogus-ам «перестали работать timestamp/даты в MySQL» я определяю приход весны и осени: редкие обстоятельства на миллионах инсталляций дают эффект =)

Статья в целом хорошая и полезная.
Дебажу всегда в error_log с названием класса и номером строки, очень удобно
А после случая, когда админы напортачили и файл index.php отдался как текст, я стал писать в нём только одну строчку => require '../index.php' // который, естественно, не виден снаружи
А вот это действительно ценный совет. Как-то никогда не думал о такой ситуации, а ведь она более чем реальна!
А что в индексе обычно такого важного?
Вот если бы был доступен конфиг — это да :)
3. Избегайте представления цен с помощью переменных формата float, если это возможно. Вместо этого для пенсов и центов используйте целые числа, а в базах данных используйте тип переменных с фиксированной запятой — DECIMAL.
Удивительно, но эта ошибка встречается очень часто (слишком часто!) и приводит к очень неприятным последствиям.
Добавлю, что в некоторых языках программирования и СУБД аналогичные типы могут называться Numeric, Currency или Money (а также smallmoney).

Я бы распечатал такой плакат и дал каждому разработчику, имеющему дело с денежными суммами.
Теперь у меня было четыре строчки весьма сложного кода, чтобы сделать одну очень простую вещь. Сегодня, пока я писал эту статью, я обнаружил встроенную в Javascript функцию, которая справится со всем этим:
<script type="text/javascript">
function GetMoney (amount) {return amount.toFixed (2);}
alert (GetMoney (4.9995) + ' ' + GetMoney (0.1 * 0.7));
</script>
Автор (оригинала) явно неполноценно тестировал то, что написал и не знает про баг с функцией toFixed() :)

Тестовый «эксплойт»:
alert([1.1255.toFixed(3), 0.1255.toFixed(3)]) // 1.125,0.126 - FF5, Chrome12, Opera 11.5
</script>
— на данный момент даёт ошибку в FF5, Chrome12, Opera 11.5. Не даёт ошибки в IE8, Safari5.

Или с использованием функции автора:
<script>
function GetMoney (amount) {return amount.toFixed(2);}
alert([GetMoney(1.155), GetMoney(0.155)]) // 1.16,0.15 - FF5, Chrome12
</script>

Такую ошибку даёт в FF5 и Хроме, но не факт, что Опера застрахована от ошибок для .toFixed(2).
Вот и баг для Оперы: alert([GetMoney(1.255), GetMoney(0.255)])
это больше похоже на округление к ближайшему чётному, а не на баг.
Ближайшее чётное — 6 (на 2-м месте после точки). 1.255 округляется до 1.26, а 0.255 округляется до 0.25, хотя должно тоже до 0.26 (и в IE8, Safari так и есть).
Так, чего-бы такого прикупить в Лондоне на £327.68, или больше. :)
Большинство описанных ошибок лечатся грамотными тестами (которые лучше писать до реализации), а режим отладки лучше включать через переменные среды — тогда на целевой машине ничего ненужного выводиться не будет.

И да, PHP таки говно. Любой современный язык (Python, Ruby) и Perl делают его как щенка по удобству пользования и выразительности синтаксиса. Я уж молчу про такие приятные штуки как CPAN — там есть практически все.
Вот же ж любовь компьютерщиков свести все к холивару :) Как удобство пользования и выразительность синтаксиса влияют на вышеуказанные ошибки??
Чем более выразителен синтаксис языка, тем меньше кода надо писать, и тем меньше ошибок в итоге вылезет.

Чем более удобен язык для решения задачи, тем меньше времени и усилий займет «натянуть» задачу на язык, и соответственно меньше ошибок будет совершено.

Называть PHP удобным может только человек, который ничего больше не видел: в нем даже модулей до сих пор нет, я уж не говорю про активно внедряемые в другие языки функциональные фичи.
А ктоего таким называет?
Просто в данном топике разбираются абсолютно другие ошибки. По-моему, они никак не связаны с удобством языка. Это более высокий уровень логики.
Насчет рассылок. Тут надежнее всего таки не позволить письму отправиться куда не надо.
Для этого достаточно двух вещей:
1. тестировать рассылки только на dev-сервере
2. отправлять письма только по какому-то фильтру. У нас на работе, например, используется RoundCube с фильтром по нашим рабочим адресам. Остальные письма просто складываются на сервер и их можно просмотреть.
по поводу отладки: я использую несколько расширенную схему, причём пришёл к ней почти сам даже не допустив косяка:

define(DEVELOPER_IP, '212.121.212.121'); // assign office IP
define(SHOWDEBUG, $_SERVER['REMOTE_ADDR'] == DEVELOPER_IP); // show DEBUG only for office IP

// настройка ini-переменных
ini_set('error_reporting', 'E_ALL & ~E_NOTICE');
error_reporting(E_ALL & ~E_NOTICE);
# /doc/root/../logs/errors.log, файл необходимо предварительно создать!
ini_set('error_log', implode(DIRECTORY_SEPARATOR, array($_SERVER['DOCUMENT_ROOT'], '..', 'logs', 'errors.log')));
if (SHOWDEBUG):
// show errors and warnings
ini_set('display_errors', 'On');
ini_set('display_startup_errors', 'On');
ini_set('log_errors', 'Off');
ini_set('html_errors', 'On');
ini_set('track_errors', 'On'); # If enabled, the last error message will always be present in the variable $php_errormsg
else:
// disable errors and warnings
ini_set('display_errors', 'Off');
ini_set('display_startup_errors', 'Off');
ini_set('log_errors', 'On');
ini_set('html_errors', 'Off');
ini_set('ignore_repeated_errors', 'On');
ini_set('ignore_repeated_source', 'On');
ini_set('track_errors', 'Off'); # If enabled, the last error message will always be present in the variable $php_errormsg
endif;
Да, с часами прикольно получилось, очень немногие знают все силу *nix'овой date.
Только полноправные пользователи могут оставлять комментарии. Войдите, пожалуйста.