用于过滤记录的PHP PDO语句

我正在使用 PHP PDO通过JSON将对象检索到iOS应用程序.
一个包含事件对象的数据库表.它有三个字段来存储日,月和年.数据库的所有者不希望在日期字段中存储日期,这意味着我必须处理它.

该应用程序发送带有参数的URL,如下所示:

http://..hidden domain./myfile.PHP?dia_inicio=16&dia_final=15&mes_inicio=11&mes_final=12&ano_inicio=2014&ano_final=2015

这意味着我正在寻找从16Nov2014到15Dec2015的活动.

这是我的PHP代码

$sql = 'SELECT * FROM tbagenda  WHERE  (dia_evento => :di AND mes_evento = :mi AND ano_evento = :ai) OR (dia_evento <= :df AND mes_evento = :mf AND ano_evento = :af) ';

    // use prepared statements,even if not strictly required is good practice
    $stmt = $dbh->prepare( $sql );
    $stmt->bindParam(':di',$dia_inicio,PDO::ParaM_INT);
    $stmt->bindParam(':df',$dia_final,PDO::ParaM_INT);
    $stmt->bindParam(':mi',$mes_inicio,PDO::ParaM_INT);
    $stmt->bindParam(':mf',$mes_final,PDO::ParaM_INT);
    $stmt->bindParam(':ai',$ano_inicio,PDO::ParaM_INT); 
    $stmt->bindParam(':af',$ano_final,PDO::ParaM_INT);
    // execute the query
    $stmt->execute();

    // fetch the results into an array
    $result = $stmt->fetchAll( PDO::FETCH_ASSOC );

    // convert to json
    $json = json_encode( $result );

    // echo the json string
    echo $json

我应该如何更改我的声明以使其适用于以下日期:16Nov2014至28Nov2014(同月),16Nov2014至5Dec2014(不同月份,同年)和16Nov2014至02May2015(不同年份)?

稍后再加:

iOS日志显示发送到PHP文件的URL:

recuperar_eventos_dia.PHP?dia_inicio=11&dia_final=26&mes_inicio=11&mes_final=11&ano_inicio=2014&ano_final=2014

PHP部分:

$start = "$ano_inicio-$mes_inicio-$dia_inicio";
$end = "$ano_final-$mes_final-$dia_final";

// In the sql,concatenate the columns to make a YYYY-MM-DD date string
// and cast it to a MysqL DATE type.
// That makes it possible to use BETWEEN
$sql = 'SELECT 
  *
FROM tbagenda  
WHERE STR_TO_DATE(CONCAT_WS('-',ano_evento,mes_evento,dia_evento),"%Y-%m-%d") 
     BETWEEN :start AND :end';

// Bind and execute the statement with 2 parameters:
$stmt = $dbh->prepare( $sql );
$stmt->bindParam(':start',$start,PDO::ParaM_STR);
$stmt->bindParam(':end',$end,PDO::ParaM_STR);
$stmt->execute();

// fetch,etc...
$result = $stmt->fetchAll( PDO::FETCH_ASSOC );

        // convert to json
        $json = json_encode( $result );

        // echo the json string
        echo $json;

现在来自表tbagenda的截图:

解决方法

对不起,你被这个不幸的桌子结构困住了.

我建议连接表的列以形成可用的日期字符串,并通过MysqL的内置函数STR_TO_DATE()将它们转换为日期值.对查询字符串输入值执行相同操作,以便与BETWEEN运算符进行正确的日期比较.

// Begin by concatenating the input values into single date strings YYYY-MM-DD
$start = "$ano_inicio-$mes_inicio-$dia_inicio";
$end = "$ano_final-$mes_final-$dia_final";

// In the sql,concatenate the columns to make a YYYY-MM-DD date string
// and cast it to a MysqL DATE type.
// That makes it possible to use BETWEEN
$sql = "SELECT * 
        FROM tbagenda  
        WHERE STR_TO_DATE(CONCAT_WS('-','%Y-%m-%d') 
          BETWEEN :start AND :end";

// Bind and execute the statement with 2 parameters:
$stmt = $dbh->prepare( $sql );
$stmt->bindParam(':start',etc...
$result = $stmt->fetchAll( PDO::FETCH_ASSOC );

字符串操作将影响此查询性能.如你所知,如果将日期存储为正确的DATE会更好,因此MysqL不需要将它们转换为比较.然后他们也可以被编入索引.

另请注意,我没有包含日期​​字符串的验证.在执行查询之前,您可以考虑检查它们以确保它们生成有效日期.

// strtotime() would return false for invalid date strings...
if (strtotime($start) && strtotime($end)) {
  // The dates are valid,and so you can proceed with the query
  $sql = 'SELECT.....';
}

相关文章

统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...
前言 之前做了微信登录,所以总结一下微信授权登录并获取用户...
FastAdmin是我第一个接触的后台管理系统框架。FastAdmin是一...
之前公司需要一个内部的通讯软件,就叫我做一个。通讯软件嘛...
统一支付是JSAPI/NATIVE/APP各种支付场景下生成支付订单,返...