0

我在一家拥有大量 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 查询。我知道你可以坐在那里,相当乏味地将小字符串连接在一起来完成类似的事情。

我想问的是:

  1. 有没有一种方法可以在 PHP 中构建查询,类似于在 ColdFusion 中构建查询的方式,通过使用<cfquery></cfquery>标签作为缓冲区的边界,在两者之间使用干净的逻辑和语法,以及
  2. 不管#1的答案如何,当绑定参数的数量变化时,PHP中是否有任何直接的方法来执行数据绑定,直到运行时才知道,并且可以通过多变量逻辑确定数量?在上面的示例中执行此操作很简单——您只需<cfqueryparam>在需要的时间和地点使用它。

因为我们没有时间或资源来重新构建整个应用程序,所以我不打算通过 ORM 映射我们所有的对象。我真的只想构建查询。

提前致谢。

4

1 回答 1

1

您可以获得的最接近的是在 PHP 中使用查询生成器。这看起来像这样(不完整的示例):

$columns = [ 'nametable.uid', 'firstname', 'lastname' ];

if isset($alldata) {
    array_push($columns, 'phone', 'email');
}

$builder = new GenericBuilder(); 

$query = $builder
    ->select()
    ->setTable('nametable')
    ->setColumns($columns)
;

if isset($firstname) {
    $query
        ->where()
        ->like('firstname', $firstname)
}

etc.

习惯它需要一些时间,但我认为这比提到的字符串连接地狱更具可读性。

于 2017-11-04T03:14:32.790 回答