1

所以我一直在使用内联(正确的术语?)ColdFusion 代码来运行我的所有页面,并且已经达到了我认为我对基础知识有相当了解的地步,并且想要采取下一步行动。经过大量的交叉引用、研究和反复试验,我想出了以下 4 个页面,其目的是能够在表单页面 (crud.cfm) 中输入用户名和密码,然后,提交后,将用户重定向到一个页面,该页面显示新输入的数据以及任何过去的条目。

我可以使用简单的内联代码和 Application.CFM 来完成所有这些工作,但我希望在未来转向更多的 OOP/模块化方法,因为目前我发现自己在几个不同的页面上重写/复制粘贴大量代码。我从“crud.cfm”提交时得到的错误是:

“cfinvoke 标记中的组件属性值无效。”

我已经尝试过没有哈希并且没有大写“A”无济于事。这是我的非工作代码:

应用程序.cfc

<cfcomponent output="false">
<cffunction name="insertrecord" access="public" output="false">
    <cfargument name="data" type="struct" required="true">
    <cfquery name="create" datasource="test">
        INSERT INTO logins(
            username,
            password)
        VALUES(
            'trim(form.username)',
            'trim(form.password)')
    </cfquery>
</cffunction>
</cfcomponent>

crud.cfm

<h3> Enter new user/password </h3>

<cfform name="thisform" method="post" action="procpage.cfm">
    Username:<cfinput type="text" name="username" value="">
    Password:<cfinput type="password" name="password" value="">
    <input type="submit" value="submit">
</cfform>

procpage.cfm

<cfif !StructIsEmpty(form)>
<cfinvoke component="#Application#" method="insertrecord">
    <cfinvokeargument name="data" value="#form#">
</cfinvoke>
</cfif>

<cflocation url="resultpage.cfm" addtoken="no">

结果页面.cfm

<cfquery name="read" datasource="test">
SELECT * FROM logins
</cfquery>

<table>
<tr>
    <th>LOGIN</th>
    <th>USERNAME</th>
    <th>PASSWORD</th>
</tr>
<cfloop query="read">
<tr>
    <td>#read.login#</td>
    <td>#read.username#</td>
    <td>#read.password#</td>
</tr>
</cfloop>   
</table>

ColdFusion 版本 8,MSSQL 2005 数据库。提前感谢大家的帮助,期待您的回复!

4

2 回答 2

2

Application.cfc 是 ColdFusion 中的一个特殊文件。

http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=AppEvents_01.html

您需要将组件命名为其他名称。Application.cfc 是您放置应用程序事件、设置代码等的地方。

于 2013-03-04T21:44:23.207 回答
1

在回答你对米格尔的问题时,是的。每次调用 cfm 时都会调用 application.cfc。因此,当您点击 crud.cfm 时,application.cfc 会运行。当您点击 procpage.cfm application.cfc 运行等时。

所以你希望你的 procpage.cfm 看起来更像

<cfif !StructIsEmpty(form)>
<cfinvoke component="functions" method="insertrecord">
    <cfinvokeargument name="data" value="#form#">
</cfinvoke>
</cfif>

你的functions.cfc看起来更像

<cfcomponent output="false">
<cffunction name="insertrecord" access="public" output="false" returntype="void">
    <cfargument name="data" type="struct" required="true">
    <cfquery name="create" datasource="test">
        INSERT INTO logins(
            username,
            password)
        VALUES(
            <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(form.username)#">,
            <cfqueryparam cfsqltype="cf_sql_varchar" value="#trim(form.password)#">
              )
    </cfquery>
</cffunction>

<cffunction name="readRecord" access="public" returntype="query">
    <cfargument name="loginID" type="numeric" required="false" default="0">
        <cfquery name="read" datasource="test">
            SELECT * FROM logins 
            where loginID = <cfqueryparam cfsqltype="cf_sql_varchar" value="#arguments.loginID#">
        </cfquery>
        <cfreturn read/>
</cffunction>
</cfcomponent>

结果页面.cfm

<cfscript>
  f = createObject('component','functions');
  r= f.readRecord(theIdToPass);
</cfscript>
<table>
<tr>
    <th>LOGIN</th>
    <th>USERNAME</th>
    <th>PASSWORD</th>
</tr>
<cfloop query="r">
<tr>
    <td>#r.login#</td>
    <td>#r.username#</td>
    <td>#r.password#</td>
</tr>
</cfloop>   
</table>

您会发现 cfqueryparam 不仅性能提升很小,而且可以保护您免受 sql 攻击等,使用它!总是。

您还可以考虑为每个期望做参数而不是使用结构变量,因为在不知道您期望传递什么的情况下为结构编写错误捕获可能非常令人沮丧。

希望这可以让您对 CF 有一个积极的开始!

于 2013-03-05T03:09:42.860 回答