Распространенные ошибки программирования, которых следует избегать программисту ColdFusion?

В духе моих других вопросов, касающихся "распространенных ошибок программирования... которых следует избегать"

Каких ошибок программисту ColdFusion следует избегать?


person Community    schedule 27.07.2009    source источник
comment
Задавать слишком широкие вопросы о SO. ;)   -  person Byron Whitlock    schedule 28.07.2009
comment
Забавные вопросы... информативные вопросы... не просто слишком широкие! Некоторые из этих вопросов об ошибках получают хорошие ответы в них! Хорошее чтение.   -  person Andrew Siemer    schedule 28.07.2009
comment
@Greg Beech +1 - хотя я должен признать, что я программировал с помощью ColdFusion от CF 3 до 6.1 ... как только человек находит язык / платформу, такую ​​​​как C # и .NET, очень трудно поддерживать интерес к миру ColdFusion. Но, оглядываясь назад, нужно признать, что ColdFusion 2.0 предложил классическим разработчикам ASP то, что .NET смог предложить только МНОГО лет спустя. Я бы даже сказал, что ASP.NET был вдохновлен ColdFusion точно так же, как C# был вдохновлен Java.   -  person Andrew Siemer    schedule 28.07.2009
comment
Забавно, как один и тот же вопрос получает отрицательную оценку и закрывается, потому что платформа не популярна. Тема «Распространенные ошибки javascript» (прямо под этим банкоматом) имеет несколько голосов «за».   -  person Ed S.    schedule 28.07.2009
comment
Могу поспорить, что ряд отрицательных голосов был сгенерирован людьми, которые либо никогда не слышали о ColdFusion, либо никогда не использовали ColdFusion. Скорее всего, за это проголосовали не потому, что это ColdFusion, а потому, что сегодня я опубликовал несколько из этих вопросов ... и любители чистоты устали от вопросов такого типа. Не беспокойся!   -  person Andrew Siemer    schedule 28.07.2009
comment
‹GRIN› Вопрос о том, что вас больше всего расстраивает на работе, приемлем, но вопрос, связанный с ColdFusion, получает меньше голосов и голосов, чтобы закрыть его! Мы, программисты, непостоянный народ!   -  person Andrew Siemer    schedule 28.07.2009
comment
... или просто не люблю, когда люди играют в репутационную систему.   -  person Dour High Arch    schedule 28.07.2009
comment
Таким образом, задавать один хороший вопрос можно... но задавать 5 разных, хотя и одинаково хороших вопросов в том же духе, что и первый хороший вопрос, нельзя? Слишком смешно.   -  person Andrew Siemer    schedule 28.07.2009
comment
@ Эндрю - если бы вы сделали эти вопросы вики сообщества, вы бы не получили столько критики. Как бы то ни было, вы делаете их CW только после того, как многие люди потребуют этого, и вы в основном выбираете все языки, которые можете найти, и пишете копию того, что было популярным вопросом. Это репутационный фарм, чистый и простой. Похоже, вы даже перестали менять их на CW.   -  person zombat    schedule 28.07.2009
comment
Я задавал вопросы только по интересующим меня языкам/темам. Я не задавал вопросов о Perl, XAML, HTML, Lingo, Lisp и т. д., но мог бы. Спасибо за вашу преданность. Это сделало мой день приятным! :П   -  person Andrew Siemer    schedule 28.07.2009
comment
@zombat - Я сделал это CW специально для тебя!   -  person Andrew Siemer    schedule 28.07.2009
comment
Я отзываю свою предыдущую защиту этой темы, заметив, сколько их там...   -  person Ed S.    schedule 28.07.2009
comment
Я никогда не понимаю, для чего используется CW   -  person Henry    schedule 28.07.2009
comment
CW используется, чтобы уменьшить нытье от людей, которые хотели бы сначала подумать о том, чтобы задать вопрос о репутации. ;)   -  person Peter Boughton    schedule 29.07.2009
comment
@zombat называет акт задавания хорошего вопроса, который побуждает многих людей ответить и проголосовать за вопрос, репутационным фермерством. Мне нравится этот термин, независимо от того, уничижительный он или нет. И если задавать много хороших вопросов, которые действительно заслуживают вопроса, репутация владельца вопроса - это репутационное фермерство ... тогда во что бы то ни стало называйте меня репутационным фермером !!! Я люблю задавать вопросы и отвечать на вопросы ..репутация или нет. Забавно видеть всю интерактивность, созданную им.   -  person Andrew Siemer    schedule 29.07.2009
comment
@ Питер Боутон: Нет, его следует использовать, когда нет единственного правильного ответа на вопрос (например, этот). FAQ содержит больше информации   -  person Ed S.    schedule 31.07.2009
comment
Всегда существует вероятность единственного правильного ответа — даже вопросы, которые являются бессрочным голосованием, могут иметь сводку ответов в качестве принятого ответа. Конечно, отсутствие представителя CW помогает в вопросах, основанных на голосовании, так что первый человек, который даст общий ответ, не получит незаслуженную репутацию. Но в противном случае это просто обходной путь, когда есть несколько участников (на вопрос или ответ), устраняющий сложность расчета стоимости модификаций и деления rep.   -  person Peter Boughton    schedule 31.07.2009
comment
Для такого вопроса, как этот, Генри заслуживает репутации как за то, что поднял вопрос, так и за то, что составил подробный подробный ответ.   -  person Peter Boughton    schedule 31.07.2009
comment
Эндрю Симер задал вопрос. Имя Генри появляется просто потому, что он редактировал его.   -  person Patrick McElhaney    schedule 31.07.2009


Ответы (9)


  • установить <cffile> путь загрузки в доступный через Интернет каталог с поддержкой CF!!!

  • isStruct() перед isObject() в серии <cfif>, ожидающих isStruct, ловит только struct (компонент cfc также возвращает True из isStruct())

  • нет HtmlEditFormat() при отображении пользовательского контента (XSS)

  • забыл добавить output=false для методов CFC

  • не используя <cfqueryparam> внутри <cfquery>

  • не охватывая не столь очевидные переменные, такие как имя cfquery или индекс цикла в методе

  • используйте <cfform>, когда все, что им нужно, это простой ванильный HTML <form>

  • забыл UrlEncodedFormat() пользовательский URL

  • использовать <cffeed> без очистки содержимого

  • слишком доверяйте isDate() (любое число вернет true)

  • ожидать, что сравнение строк будет чувствительным к регистру (операторы IS и EQ не чувствительны к регистру)

  • отправка строк «да» или «нет» в SerializeJSON() без добавления пробела для сохранения строки (иначе SerializeJSON() или DeserializeJSON() преобразует их в «истина» и «ложь»)

  • не помещая службы singletons в область приложения

  • слепо создавайте столько CFC, сколько хотите, как в JAVA

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

  • написание функций, которые принимают массив в качестве аргумента и изменяют этот массив, ожидая, что этот массив будет изменен (массив в CFML передается по значению)

  • слепо изменяет access="remote" в методе и ожидает, что он сработает (когда удаленный прокси обычно более уместен)

  • используйте много WriteOutput() в cfscript, когда CFML более подходит

  • слепо использует IsDefined(), когда StructKeyExists() обычно может делать это более эффективно

  • слепо использует Iif() и De(), не зная, что они такие же неприятные, как Evaluate()

  • обновите некоторый код в onApplicationStart() и не увидите разницы при обновлении (перезапустите приложение!)

  • <cfloop> или '' за пределами <cfquery>, что приводит к открытию нескольких новых соединений запроса. В 99% случаев лучше иметь несколько операторов внутри одного cfquery для выполнения нескольких действий или для объединения данных вместе.

  • абсолютный путь жесткого кодирования, когда ExpandPath() обычно лучше

  • забыл включить поддержку Unicode в DSN (Unicode становится '????')

  • не обновляться до последней версии JRE и исправлений

  • неправильное использование области клиента и взорвать реестр Windows...

  • использует устаревшие/устаревшие функции/функции (т. е. флэш-форму, также известную как flex 1.x alpha, cftable, полнотекстовый поиск Verity и т. д.)

  • передача CFCATCH функции в качестве аргумента типа Struct (CFCATCH ведет себя как Struct, но это не так. Просто передайте его как тип 'Any').

  • Не читать Лучшие практики CFC из вики ColdBox.

  • покупка в духе .ASP(X), .JSP или [вставьте веб-технологию] всегда лучше.. ;)

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

person Community    schedule 27.07.2009
comment
@ Генри - это настоящий список, чувак! Спасибо. - person Andrew Siemer; 28.07.2009
comment
все еще думаю, что добавить в список... :) - person Henry; 28.07.2009
comment
@ Генри: небольшая опечатка - это HTMLEditFormat(). (Одна из причин распространенности XSS-уязвимостей заключается в том, что имена escape-функций HTML повсюду такие подробные: htmlspecialchars(), Server.HTMLEncode(), как хотите. Обычно я создаю функцию-оболочку для HTMLEditFormat() и называю ее h(), что очень удобно. оболочка для URLEncodedFormat с именем u().) - person Tomalak; 28.07.2009
comment
О, и +1. Очень хорошая подборка того, что можно сделать неправильно в CF. - person Tomalak; 28.07.2009
comment
Я все еще вижу это в устаревшем коде: execute(form.counted#i#) вместо form['counted#i#']. - person Ben Doom; 28.07.2009
comment
надеюсь, вы не возражаете, я добавил пробелы и отредактировал орфографию, отличный список! - person ethyreal; 31.07.2009
comment
@ethyreal, с чего бы мне возражать? :) Спасибо за редактирование. Я также добавил 2 дополнительных пункта в пост. - person Henry; 31.07.2009

Неуместное использование #

ВЫБРАТЬ *

Не очищать ввод URL/форм

Отладка в производственной среде (даже если вывод подавлен)

person ale    schedule 27.07.2009

Бессовестное воровство форматирования Генри...

  • быстрее и точнее проверять явное логическое значение, а не подразумеваемое; используйте ‹cfif query.recordCount GT 0› вместо ‹cfif query.recordCount›
  • не используйте Evalu(), de() или iif()... никогда. всегда есть способ обойти эти медленные функции
  • понимать структуры, ключи, значения и как обращаться к запросам и структурировать данные, используя нотацию массива. (обычно это обойдет вашу потребность в оценке())
  • не используйте знаки решетки, если вы не выводите данные или не создаете строку иным образом (не делайте этого: myFunction(arg = #myVar#))
  • прочитать и понять разницу между областью действия THIS и VARIABLES в CFC
  • избегайте чрезмерного использования ‹cfsilent>, когда вам, возможно, потребуется использовать ‹cfcontent reset="true"› непосредственно перед началом вывода (перед doctype, объявлением xml или ‹html›)
  • не перебрасывайте значения ColdFusion вслепую в блок сценария HTML (javascript) без использования jsStringFormat()
  • если вы не используете текст ‹CDATA› в своем XML, вы можете использовать xmlFormat() при создании XML-документа
  • не используйте реестр Windows для данных области клиента. Используйте базу данных.
  • если позволяет ваша ИТ-архитектура, используйте данные сеанса вместо данных клиента.
  • используйте ‹cflock> правильно и последовательно; общие данные будут просачиваться в ваше приложение.
  • если вы собираетесь использовать объекты Java, обратите внимание на сообщения об ошибках Java (например, «невозможно найти метод» может не означать, что метод вообще не существует, это означает, что метод не существует для аргументов, которые вы предоставили)
  • если вам нужно читать большие файлы, либо используйте новые функции «Файл» CF8, либо передайте задачу Java в CF6 и 7. ‹cffile> неэффективен для больших файлов.
  • понимать передачу по ссылке и по значению, а также то, как эти концепции работают в CF; особенно при использовании функций для изменения XML-документов
  • как сказал Генри, всегда используйте ‹cfqueryparam>; также убедитесь, что вы используете правильный параметр CFSQLType для вашей СУБД (для даты, времени, метки времени и т. д.)
  • не объединяйте в цепочку логические блоки ‹cfif› и ‹cfelseif›, используйте ‹cfswitch› и ‹cfcase›, если вам нужно обработать более трех условий
  • еще одно замечание по архитектуре: всегда выполняйте какую-то проверку на стороне сервера, чтобы поймать неприятные данные, которые пользователь в волчьей рубашке может передать вам
  • последнее примечание по архитектуре: пусть CF выполняет средний уровень извлечения и отображения данных, а ваш веб-сервер выполняет такие действия веб-сервера, как URL-адреса SEO (я смотрю на вас, ColdCourse)
  • person Community    schedule 07.08.2009
    comment
    не объединяйте в цепочку логические блоки ‹cfif› и ‹cfelseif›, используйте ‹cfswitch› и ‹cfcase›, если вам нужно обработать более трех условий — это довольно определенное утверждение! Я думаю, что операторы cfif/cfelseif/cfelse легче читать, потому что в них меньше тегов. - person Adrian Lynch; 09.09.2010

    Атаки путем внедрения кода SQL. Похоже, что cfquery просто создан для их разрешения. Поэтому вам следует использовать cfqueryparams.

    person JP Alioto    schedule 28.07.2009
    comment
    Не могу не подчеркнуть, насколько хороши cfqueryparams: cfqueryparam остановит внедрение sql - сервер sql никогда не выполнит значение, переданное через cfqueryparam - person Antony; 28.07.2009

    В Coldfusion все переменные по умолчанию являются глобальными, если только они не объявлены с ключевым словом var. (Несколько похоже на ситуацию в Javascript.)

    Таким образом, вы либо должны помнить var каждую переменную, используемую в функции, включая такие вещи, как имена, которые используются в cfquery name, либо вы можете просто использовать этот прием:

    <cffunction name="MyFunction">
        <cfset var Local = StructNew()>
    
        <!--- Now anything Local. is automatically local --->
        <cfset Local.x = 42>
    
        <!--- Including cfquery name="" --->
        <cfquery name="Local.Customers" datasource="some_datasource">
            SELECT C.ID, C.Name
            FROM Customers C
        </cfquery>
    </cffunction>
    

    В имени Local нет ничего волшебного, это просто условность. Хотя Coldfusion 9 добавит явный локальный область действия, поэтому, если вы используете Local, это, вероятно, облегчит обновление до CF9, когда придет время.

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

    person Jason Creighton    schedule 28.07.2009
    comment
    не так уж и опасно? На самом деле это все еще довольно опасно, поскольку код не очень потокобезопасен. - person Henry; 28.07.2009
    comment
    Что ж, да, это по-прежнему зло, и вы никогда не должны этого делать, но проблемы будут ограничены этим CFC, вместо того, чтобы потенциально влиять на какую-либо функцию верхнего уровня или страницу .CFM в вашем приложении CF. - person Jason Creighton; 28.07.2009

    Неспособность предотвратить отображение пользователями ошибок coldfusion.

    Добавьте метод onError в Application.cfc верхнего уровня, чтобы пользователи не могли видеть все эти подробные сообщения дампа, раскрывающие вашу внутреннюю работу (и сбои).

    <cffunction name="onError" returntype="void" output="true">
        <cfargument name="exception" type="any" required="true" />
        <cfargument name="eventname" type="string" required="true" />
    

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

    http://varscoper.riaforge.org/

    person Community    schedule 06.11.2009

    Чрезмерное использование «запроса запроса». То есть дальнейшая фильтрация или сортировка результатов запроса с помощью тега cfquery.

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

    person Community    schedule 30.07.2009

    Одной из самых больших ошибок будет неиспользование cfqueryparam.

    Очень плохой:

    SELECT UserName
    FROM Customers
    WHERE CustomerID = #URL.custid#
    

    Очень хороший:

    SELECT UserName
    FROM Customers
    WHERE CustomerID = <cfqueryparam value="#URL.custid#" cfsqltype="cf_sql_integer">`
    

    Эта ошибка будет стоить вам веб-сайта.

    person Community    schedule 07.08.2009

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

    Использование cfcatch без захвата и/или передачи некоторой информации об ошибке, чтобы ее можно было найти и исправить. (Трудно найти ошибку, которая не сообщает вам, что она произошла.)

    Использование listcontains(), когда вы хотите listfind(). Особенно, если в списке есть цифры. listfind() соответствует только целому элементу в списке; listcontains() соответствует части элемента. (Да, однажды мы сделали эту ошибку.)

    С правами администратора:

    • Оставьте значения по умолчанию для источника данных, настроенного на сервере. «Минимальные привилегии» применяются и на стороне CF; не давайте ему больше разрешений, чем ему конкретно нужно. (GRANT, ALTER, REVOKE, DROP... вы действительно не хотите, чтобы они проверялись.)
    • Не устанавливать флажки для извлечения всего содержимого из поля CLOB/BLOB, когда это то, что вы ожидаете. (Было действительно интересно увидеть, что это применимо к области, в которой мы хранили PDF-файлы.)
    person Community    schedule 05.10.2009