我正在使用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至2015年5月2日(不同年份)?
后来添加:
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的截图:
答案 0 :(得分:3)
对不起,您已经陷入了这种不幸的桌面结构。
我建议连接表的列以形成可用的日期字符串,并通过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('-', 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 );
字符串操作将影响此查询的性能。如你所知,如果将日期存储为正确的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.....';
}