如果日期字符串 dd/mm/yyyy 为 yyyy-mm-dd,如何有条件地重新格式化用户输入?

How to conditionally reformat user input if a date string of dd/mm/yyyy to yyyy-mm-dd?

我在表单中添加了搜索功能。当用户输入日期 18/03/2015 时,我想重新格式化日期。我需要将 $_GET['searchKeyword']'18/03/2015' 更改为 '2015-03-18' 并另存为 $searchKeyword.

我想要这个用于我的 sql LIKE 子句。 我是这样写的,但是不起作用:

$where_clause = ''; 
$searchKeyword =  $_GET['search_keyword'];

if ($_GET['search_keyword'] != '')
{   
    if (preg_match('/^(\d\d)\/(\d\d)\/(\d\d\d\d)$/', $_GET['searchKeyword'], $m)) 
    {
        $searchKeyword = "$m[3]-$m[2]-$m[1]";
        $where_clause = " where patient_id  like '%" .$searchKeyword . "%'
                          or patient_name like '%" .$searchKeyword . "%'
                          or in_date like '%" . $searchKeyword . "%'
                          or discharge_date like '%" . $searchKeyword ."%'";    
    } else {
        $where_clause = " where patient_id  like '%" .$searchKeyword . "%'
                          or patient_name like '%" .$searchKeyword . "%'
                          or in_date like '%" . $searchKeyword . "%'
                          or discharge_date like '%" . $searchKeyword . "%'";
    }
}

您可以使用 php 的 date 函数作为

$get_date = date('Y-m-d',strtotime($_GET['searchKeyword']));

使用PHP Date function

date('Y-m-d',strtotime($_GET['searchKeyword']))

让我们把它分成两部分:

(1) 判断是否匹配模式

if (preg_match('/^(\d\d)\/(\d\d)\/(\d\d\d\d)$/', $_GET['searchKeyword'], $m)) {

(2) 分配给您的变量

    $searchKeyword = "$m[3]-$m[2]-$m[1]";
}

上面的正则表达式 "captured" 3 个不同的组(括号中的部分)然后分别作为 $m[1]$m[2]$m[3] 提供。您可以交换它们并根据需要格式化它们。

您的代码目前不安全(容易受到注入攻击),因为您在查询中使用了未经过滤的用户提供的数据。使用带有占位符的 mysqli 准备好的语句将很好地解决这个问题。

我假设您的 patient_id 列是 INT 类型(但我不知道您的 table 结构)。如果不是,你可以撤消我的 CAST().

至于在DATE类型数据上使用LIKE(我不知道你的table结构),请阅读this post。这是使用 YEAR/MONTH/DAY.

重新设计查询构建的合理论据

我冒昧地为您提供了搜索功能 "more inclusive"。我的查询不仅使用 LIKE 搜索您想要的四个列,当提交的字符串 可以 被解释为日期(按 strtotime())时,还有两个条件是添加到在两个日期列上使用格式化数据的 WHERE 子句。

实际上,如果用户键入:yesterday,那么任何患者姓名包含 yesterdayin_date 完全匹配 2018-04-21 或 [=26] 的行=] 完全匹配 2018-04-21 将被返回。 (发布时是 2018 年 4 月 22 日)同样,输入 March 31 将在日期列中搜索 2018-03-31 的匹配项。没有丢失;只是更安全和更灵活,但可能返回的行太多(由您决定)。

if (!$conn = new mysqli("localhost", "username", "password", "database")) {  // use your own details obviously
    echo "Connect failed: " , $conn->connect_error);  // never display errors to the public
} elseif (empty($_GET['search_keyword'])) {
    if (!$result = $conn->query("SELECT * FROM `table`")) {
        echo "Syntax error on query with no keyword";
    } else {
        while ($row = $result->fetch_assoc()) {
            // do what you wish with $row['columnname']
        }
    }
} else {
    $query = "SELECT * FROM `table` WHERE";
    $query .= " CAST(`patient_id` AS CHAR) LIKE ? OR `patient_name` LIKE ?";
    $query .= " OR `in_date` LIKE ? OR `discharge_date` LIKE ?";
    $wrapped = "%" . $_GET['search_keyword'] . "%";  // wrap the values with % for binding downscript
    if (($unix = strtotime($_GET['search_keyword'])) !== false) {
        $query .= " OR `in_date` = ? OR `discharge_date` = ?";
        $reformatted = date('Y-m-d', $unix);
    }
    if(!$stmt=$conn->prepare($query)) {
        echo "Error on prepare: " , $conn->error;
    } elseif (isset($reformatted) && !$stmt->bind_param("ssssss", $wrapped,  $wrapped, $wrapped, $wrapped, $reformatted, $reformatted)) {
        echo "Error on bind (x6 params): " , $stmt->error;
    } elseif (!isset($reformatted) && !$stmt->bind_param("ssss", $wrapped, $wrapped, $wrapped, $wrapped)) {
        echo "Error on bind (x4 params): " , $stmt->error;
    } elseif (!$stmt->execute()) {
        echo "Error on execute: " , $stmt->error;
    } elseif (!$result = $stmt->get_result()) {
        echo "Error on get result: " , $stmt->error;
    } else {
        while ($row = $result->fetch_array(MYSQLI_ASSOC)){
            // do what you wish with $row['columnname']
        }
    }
}