我在一家拥有大量 ColdFusion Web 应用程序的大公司工作。他们要求所有这些应用程序都过渡到新的平台/语言。
其中一个应用程序非常庞大和复杂。由于资源熟悉和支持,它的目标是 PHP。
我喜欢 ColdFusion 的一大优点是能够在<cfquery>
标签之间进行“自由格式”的 SQL 查询。我想知道是否有办法在 PHP 中做到这一点。
下面是一个我可能嵌入在 ColdFusion 组件 (CFC) 中的查询示例。查询的作用并不像cfquery
标签之间查询的所有部分是如何有条件地构建一样重要:
<cfquery>
select nametable.uid, firstname, lastname
<cfif isdefined('alldata')>
,phone
,email
</cfif>
from
nametable
<cfif isdefined('alldata')>
inner join contactdata
on nametable.uid=contactdata.uid
</cfif>
where 1=1
<cfif isdefined('firstname')>
and firstname like <cfqueryparam cfsqltype="cf_sql_varchar" value="#firstname#">
</cfif>
<cfif isdefined('lastname')>
and firstname like <cfqueryparam cfsqltype="cf_sql_varchar" value="#lastname#">
</cfif>
<cfif isdefined('uidlist')>
and nametable.uid in <cfqueryparam cfsqltype="cf_sql_varchar" value="#uidlist#" list="true">
</cfif>
<cfif searchByDate>
and cast(datafield as date)
<cfelse>
and datafield
</cfif>
between
<cfqueryparam cfsqltype="cf_sql_varchar" value="#attrValue1#">
and
<cfqueryparam cfsqltype="cf_sql_varchar" value="#attrValue2#">
<cfif isdefined("attrVals")>
<cfloop from="1" to="#attrVals.length()#" index="i">
and dbo.getPersonAttr(nametable.uid,'#attrvals[i].cd()#') =
<cfqueryparam cfsqltype="cf_sql_varchar" value="#attrvals[i].val()#">
</cfloop>
</cfif>
order by
<cfif orderby eq "uid">nametable.uid<cfelse>lastname</cfif>
</cfquery>
对我来说,即使有多种逻辑路径,该代码是:
- 非常容易阅读,
- 简单易懂,并且
- 易于在语法上调试
此动态构建的查询具有的其他几个功能:
- 内联 if/else 逻辑和循环 - 跨所有 SQL 子句(Select、joins、where、order by、group 等)
- 内联,可变数据绑定:可能有 0 个绑定参数,或者 50+;直到运行时我们才会知道或关心
- 列表值的本机数据绑定(...其中 uid in ('12345','98765')...)(在coldfusion中,
<cfqueryparam ... list="true">
)
我认为我不需要学习如何构建PHP 查询。我知道你可以坐在那里,相当乏味地将小字符串连接在一起来完成类似的事情。
我想问的是:
- 有没有一种方法可以在 PHP 中构建查询,类似于在 ColdFusion 中构建查询的方式,通过使用
<cfquery></cfquery>
标签作为缓冲区的边界,在两者之间使用干净的逻辑和语法,以及 - 不管#1的答案如何,当绑定参数的数量变化时,PHP中是否有任何直接的方法来执行数据绑定,直到运行时才知道,并且可以通过多变量逻辑确定数量?在上面的示例中执行此操作很简单——您只需
<cfqueryparam>
在需要的时间和地点使用它。
因为我们没有时间或资源来重新构建整个应用程序,所以我不打算通过 ORM 映射我们所有的对象。我真的只想构建查询。
提前致谢。