如果日期字符串为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']));

让我们将其分解为两部分:

(1) 找出它是否与模式匹配

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

(2) 分配给您的变量

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

上面的正则表达式"捕获"了3个不同的组(括号中的部分),然后分别作为$m[1]$m[2]$m[3]提供。您可以交换它们,并根据自己的意愿设置它们的格式。

使用PHP日期函数

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

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

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

关于在DATE类型数据上使用LIKE(我不知道你的表结构),请阅读这篇文章。这是使用YEAR/MONTH/DAY重新设计查询构建的合理论据。

我冒昧地让你的搜索功能"更具包容性"。我的查询不仅使用LIKE搜索您想要的四列,当提交的字符串可以解释为日期(通过strtotime())时,WHERE子句中还添加了两个条件,使用两个日期列上的格式化数据。

实际上,如果用户键入:yesterday,则将返回患者名称包含yesterdayin_date2018-04-21discharge_date完全匹配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']
        }
    }
}