4

私はColdFusionでアプリケーションを作成していますが、ほとんど安定していますが、エラーが頻繁に発生します。すでに古いアプリケーションに取って代わっているため、私ではなくユーザーがエラーを受け取ることがあります。

エラー、リファラー、どのページのエラー、行番号などの情報を送信するエラーが発生したときに表示される、すばらしいページを作成しました。

私がうまくいかないように見える唯一のことは、フォームデータがある場合はそれを送信することです。事前にどのページでエラーが発生したのかわからないので、「#form.field#」だけを出力することはできません。

たとえば、次の場合です。

form.abc = 1
form.def = 2

事前に知らなくても、「form」から変数名と値を取得するにはどうすればよいですか?

このドキュメントは、正しいパスに沿った構造のループに関するものですか?

また、そのデータをデータベースに保存するための良い方法を探しています。これは、エラーに関するその他の情報が保存される場所であり、メールで送信する必要がないためです。

4

5 に答える 5

7

Form スコープには、FieldNames送信されたフィールドを示す変数があります。

StructKeyList(Form)スコープ内の現在の変数のリストを取得することもできます。これには、その後 Form スコープに追加された FieldNames およびその他の変数も含まれます。

これらのいずれも a 内で使用できます<cfloop index="CurField" list="#StructKeyList(Form)#">が、もっと簡単な方法があります...


CF8 を使用している場合は、関数を使用してスコープを簡単に文字列に変換serializeJson()deserializeJson()、適切なデータベース フィールドに格納することができます。

CF6..7 を使用している場合は、これらの機能を模倣するriaforgeからcfjsonと呼ばれる CFC をダウンロードできます。


最後に、以前のバージョンの CF を使用している場合、またはストレージに JSON を使用することに奇妙な嫌悪感を抱いている場合は、上記のヒントにあるさらに単純なループを使用して独自のループを作成できます。コレクション ループを使用すると、構造体または構造体を直接ループできます。スコープ - これらの属性として「インデックス」ではなく「アイテム」を選んだ迷惑な人がいることに注意してください。

フォーム変数はすべて単純なオブジェクト (つまり文字列) であることを知ってkey=value[newline]key=value[newline]...いるので、元に戻すのも簡単な基本的な形式を選択しました。

エンコーディング:

<cfset Output = '' />
<cfloop item="CurField" collection="#Form#">
    <cfset Output = Output & CurField & '=' & Form[CurField] & Chr(10) />
</cfloop>

<cfoutput>#Output#</cfoutput>

デコード:

<cfset FormData = StructNew()/>
<cfloop index="CurLine" list="#Output#" delimiters="#Chr(10)#">
    <cfset FormData[ListFirst(CurLine,'=')] = ListRest(CurLine,'=') />
</cfloop>

<cfdump var="#FormData#"/>


最後の重要な注意事項: すべてのユーザー指定の変数 (Form、Url、Cookie スコープ) と同様に、セキュリティ ホールを防ぐためにそれらを正しく処理する必要があります。具体的には、すべてのデータベース クエリに cfqueryparam を使用していることを確認して ください。脱線しすぎましたが、cfqueryparam について何か助けが必要な場合は、遠慮なく別の質問をしてください。


お役に立てれば。:)

于 2009-02-03T08:14:47.913 に答える
4

すべてのフォーム フィールドを手動で繰り返し処理する場合、最も簡単な方法は次のような cfloop です。

<cfloop collection="#form#" item="variables.name">
  #variables.name#=(#form[variables.name]#)<br/>
</cfloop>

とはいえ、エラー メールの場合は、次のようにフォーム スコープ (特殊な構造にすぎません) を "ダンプ" する方が簡単であることがわかるでしょう。

<cfmail
  from="errors@#cgi.server_name#"
  to="you@yourdomain.com"
  subject="Error Occurred in such and such a place"
  type="html">
    <cfdump var="#form#"/>
</cfmail>

エラー メールを送信するときは、CGI スコープ (これも特殊な構造体) を 2 つ含めるのが好きcfdumpです。これは、リクエストに関するその他の役立つ情報を提供できるからです。

CF 8 を使用している場合は、次のようにテキスト形式でダンプすることもできます。これにより、メッセージのサイズが小さくなります (そして、私の意見では、メッセージが読みやすくなります)。

<cfdump var="#form#" format="text">

注: formatCFDump タグの属性は CF 8 用に追加されたため、以前のバージョンの ColdFusion では使用できません。

これらのエラーをデータベースに保存する方法を探しているとおっしゃいましたが、それは良い考えです。そのための独自のカスタム ソリューションを作成する代わりに、BugLogHQを確認することをお勧めします。それはしばらく前から出回っていて、私を含む他の人にもうまく機能しています。何よりも、無料でオープンソースです. 古くて広く使用されているということは、それ自体のコードにエラーが発生する可能性が低くなり、おそらくあなたが書くよりも多くの優れた機能を備えていることを意味します.

BugLogHQ を使用すると、エラーの表示について心配する必要はありません。データをバグ ロガーに送信するだけで、あとはバグ ロガーが処理します。

于 2009-02-05T13:33:12.900 に答える
3

Formは単なるハッシュ/構造であるため、キーを反復処理するだけです。

<cfoutput>
 <cfloop collection=#form# item="field">
  #htmleditformat(field)=#htmleditformat(form[field])#<br/>
 </cfloop>
</cfoutput>

データをデータベースに入れますか?それをどのように行うかは、後でそれをどうするかによって異なります。最も柔軟な解決策は、form(およびurl)全体をWDDXオブジェクトに変換し、それをblobフィールドに格納することです。

<cfwddx action="cfml2wddx" input=#url# output="encodedURL"/>
<cfwddx action="cfml2wddx" input=#form# output="encodedForm"/>
<cfquery datasource="yourDSN">
 INSERT INTO errorlog (datestamp, event, script_name, path_info, url, form)
 VALUES
  (<cfqueryparam value=#now()# cfsqltype="CF_SQL_TIMESTANP"/>,
   <cfqueryparam value="your error string or cfcatch data" cfsqltype="CF_SQL_VARCHAR"/>,
   <cfqueryparam value=#cgi.script_name# cfsqltype="CF_SQL_VARCHAR"/>,
   <cfqueryparam value=#cgi.path_info# cfsqltype="CF_SQL_VARCHAR"/>,
   <cfqueryparam value=#encodedURL# cfsqltype="CF_SQL_BLOB"/>,
   <cfqueryparam value=#encodedForm# cfsqltype="CF_SQL_BLOB"/>)
</cfquery>

そうすれば、自由に分析するためにすべての生データにアクセスできます。もちろん、他にもたくさんの方法があります。

于 2009-02-03T08:47:54.023 に答える
3

アプリケーションで Application.cfc を使用している場合は、onError メソッドを以下のものに置き換えてください。注: application.settings.mode は、次のいずれかの値 (dev、test、prod) にすることができます。application.settings.webmasteremail は、エラー情報の送信先の電子メール アドレスに設定する必要があります。これらの変数は両方とも onApplicationStart メソッドで設定する必要があります。

この関数は何をしますか? アプリが "dev" モードに設定されている場合 (application.settings.mode = "dev" を設定)、エラー情報が画面に表示されます。アプリが他のモード (テストや本番など) に設定されている場合は、電子メールが送信され、情報がデータベースに保存されます。

<cffunction name="onError" returnType="void" output="true">
    <cfargument name="exception" required="true">
    <cfargument name="eventname" type="string" required="true">
    <!--- corrects bug where <cfabort> throw an error --->
    <cfif arguments.exception.rootCause eq "coldfusion.runtime.AbortException">
        <cfreturn>
    </cfif>
    <cfsavecontent variable="errordata">
        <p>#eventname#</p>
        <cfdump var="#exception#" label="Exception Information" format="text">
        <cfdump var="#url#" label="URL Information" format="text">
        <cfdump var="#form#" label="FORM Information" format="text">
        <cfdump var="#application#" label="Application Scope" format="text">
        <cfif isdefined("session")>
            <cfdump var="#session#" label="Session Scope" format="text">
        </cfif>
        <cfif isdefined("client")>
            <cfdump var="#client#" label="Client Scope" format="text">
        </cfif>
        <cfdump var="#cgi#" label="URL Information" format="text">
    </cfsavecontent>

    <!--- will email the error inforation and display the error page --->
    <cfif application.settings.mode eq "dev">
        <p>#eventname#</p>
        #errordata#
    <cfelse>
        <cfmail to="#application.settings.webmasteremail#" from="error@#cgi.http_host#" subject="Error has occured on #cgi.http_host#" type="HTML" charset="windows-1252">
        <p>#eventname#</p>
        #errordata#
        </cfmail>

        <cfquery datasource="yourDSN">
        insert into errorlog
        (
            creationdate
            ,event
            ,info
        )
        values
        (
            <cfqueryparam value="#now()#" cfsqltype="CF_SQL_TIMESTAMP"/>
            ,<cfqueryparam value="#eventname#" cfsqltype="CF_SQL_VARCHAR"/>
            ,<cfqueryparam value="#errordata#" cfsqltype="CF_SQL_LONGVARCHAR"/>
        )
        </cfquery>

        <h2>A functional error has occurred.</h2>
        <p>A notification of this error has been automatically e-mailed to the development team; no action on your part is required.</p>
        <p>Please click the "back" button on your browser to return to the web site.  We apologize for this inconvenience.</p>
    </cfif>
</cffunction>
于 2009-02-03T14:20:23.633 に答える
0

フォーム変数を自分宛てに電子メールで送信する場合は、次のようにそれらをダンプします。

<cfmail type="html" ...>
    <cfdump var="#form#" label="form">
    <cfdump var="#cgi#" label="cgi">
    <cfdump var="#session#" label="session">
</cfmail>

そこに好きなスコープを捨てることができます。私が提供したものが必要な場合と不要な場合があります。

最初の問題は、アプリケーションが古いアプリケーションを置き換えていることだとおっしゃいましたか?デプロイしているのと同じサーバーで開発していますか?その場合は、開発コピーのアプリケーションの名前を変更するだけです。この問題を回避するために、名前が一意であることを確認してください(それが問題である場合)。

于 2009-02-03T18:27:19.610 に答える