所以我一直在使用内联(正确的术语?)ColdFusion代码来运行我的所有页面,并且已经达到了我认为我对基础知识有一个很好的理解,并希望采取下一个步。经过大量的交叉引用,研究和反复试验后,我提出了以下4页,其目的是能够在表单页面输入用户名和密码(crud.cfm)然后,在提交后,将用户重定向到显示新输入数据的页面,以及任何过去的条目。
我可以通过简单的内联代码和Application.CFM来完成所有这些工作,但是我想继续向更多的OOP / Modular方法迁移,因为目前我发现自己在几个代码中重写/复制粘贴代码不同的页面。我从&crud.cfm'提交时收到的错误是:
" cfinvoke标记中的组件属性具有无效值。"
我试过没有哈希,没有大写" A"无济于事。这是我的非工作代码:
的Application.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">
resultpage.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数据库。 提前感谢您的帮助,期待您的回复!
答案 0 :(得分:2)
Application.cfc是ColdFusion中的一个特殊文件。
http://livedocs.adobe.com/coldfusion/8/htmldocs/help.html?content=AppEvents_01.html
您需要为其他组件命名。 Application.cfc是放置应用程序事件,设置代码等的地方。
答案 1 :(得分: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>
resultsPage.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攻击等攻击,使用它!总是
你也可以考虑为每个人做一个参数而不是使用struct变量,因为在不知道你希望传递的内容的情况下为结构写入错误捕获可能会非常令人沮丧。
希望这可以让你在CF上取得积极的开始!