我在数据库中遇到日期搜索问题。我的数据库没有(dd / mm / yyyy)31/2/1948以及其他年份(从1940年到2021年开始),但每当我提交表格以使用数据库中找不到的值进行测试时,它会自动返回结果到下个月的日期。
例如:我提交31/2/1948,它返回3/3/1948的结果。
这是我的提交表单代码:
<form method="post" action="./result" id="searchform">
<div class="container">
<span class="label">Date:</span> <input type="text" id="f1" name="day" maxlength="2" placeholder="01" /><!-- Date -->
<br /><br />
<span class="label">Month:</span> <input type="text" id="f2" name="month" maxlength="2" placeholder="01" /><!-- Month -->
<br /><br />
<span class="label">Year:</span> <input type="text" id="f3" name="year" maxlength="4" placeholder="1950" /><!-- Year -->
<br /><br />
<div class="button">
<div id="errormsg">All fields are required! Please fill it in!</div>
<input class="submit-btn" type="submit" name="submit" value="Search" /><!-- Search -->
</div>
</div>
</form>
这是result.php,它从数据库中查询。
//Check input if empty or people use the direct link and exit the script
if(empty($_POST['day']) && empty($_POST['month']) && empty($_POST['year'])) {
echo 'Please don'."'".'t try to hack!<br /><a href="./" title="Retry">Click here to <b>retry</b> again</a>';
exit;
}
// Set the test data.
$_POST_day = $_POST['day'];;
$_POST_month = $_POST['month'];;
$_POST_year = $_POST['year'];;
// Get POST data
$day = str_pad(intval($_POST_day), 2, 0, STR_PAD_LEFT);
$month = str_pad(intval($_POST_month), 2, 0, STR_PAD_LEFT);
$year = str_pad(intval($_POST_year), 4, 0, STR_PAD_LEFT);
$userDate = implode('-', array($year,$month,$day));
// Date that user keyin
$date_format = 'Y-m-d';
$dateTime = DateTime::createFromFormat($date_format, $userDate);
$myFormat = $dateTime->format($date_format);
echo $myFormat;
//Query string and put it in a variable.
$query = "SELECT * FROM $table_data WHERE dob = :date";
//Prepare data from database
$stmt = $db->prepare($query);
$stmt->execute(array('date' => $myFormat));
$data = $stmt->fetchAll(PDO::FETCH_OBJ);
if ( !$data ) {
echo 'The data <strong>'.$userDate.'</strong> wasn'."'".'t found in database!<br /><a href="./" title="Retry">Click here to <b>retry</b> again</a>';
exit;
}
MySQL数据结构和数据截图:
图片链接:http://i.imgur.com/RxjPb0d.png
我尝试了不在数据库中的日期,例如31/2/2040,它返回$data
未找到的消息,但是如果已存储在我的数据库中的年份范围(1940 - 2021) ,它总是让我回到下个月。
如果人们在31/2 / 19xx中键入不在数据库中而不是返回下个月的结果,如何强制它返回错误消息?
其他信息:
答案 0 :(得分:2)
你的问题可能很奇怪,但是会说你编写日期逻辑有些奇怪。这是我的测试代码,基于您的代码:
// Set the test data.
$_POST_day = 31;
$_POST_month = 2;
$_POST_year = 1948;
// Get POST data
$day = $_POST_day;
$month = $_POST_month;
$year = $_POST_year;
$dob = implode('/', array($day,$month,$year));
// Date that user keyin
$userDate = $dob;
$dateTime = DateTime::createFromFormat('d/m/Y', $userDate);
$myFormat = $dateTime->format('Y-m-d');
echo $myFormat;
输出以下值:
1948-03-02
当你有值时,我100%不清楚这条线的价值是什么:
$dob = implode('/', array($day,$month,$year));
我也不理解这个的价值:
$userDate = $dob;
为什么要分配一个新变量?以下是我对该代码的修改:
// Set the test data.
$_POST_day = 31;
$_POST_month = 2;
$_POST_year = 1948;
// Get POST data
$day = str_pad(intval($_POST_day), 2, 0, STR_PAD_LEFT);
$month = str_pad(intval($_POST_month), 2, 0, STR_PAD_LEFT);
$year = str_pad(intval($_POST_year), 4, 0, STR_PAD_LEFT);
$userDate = implode('-', array($year,$month,$day));
// Date that user keyin
$date_format = 'Y-m-d';
$dateTime = DateTime::createFromFormat($date_format, $userDate);
$myFormat = $dateTime->format($date_format);
echo $myFormat;
以下是我对调整的细分以简化此操作。首先,我实际使用str_pad
和intval
处理这些值。使用intval
可确保您的值实际为数字。 str_pad
使用STR_PAD_LEFT
确保将数字格式化为2位数(天和月)或4位数(年)。效果很好。
然后对于DateTime::createFromFormat
我将实际日期格式标准化为Y-m-d
。假设您将其传递给DateTime
以正确获取输入日期?这意味着如果用户一年输入9999,DateTime
应该注意到这一点?不清楚。你也可以放弃那部分进行测试和放弃。只需这样做:
// Get POST data
$day = str_pad(intval($_POST_day), 2, 0, STR_PAD_LEFT);
$month = str_pad(intval($_POST_month), 2, 0, STR_PAD_LEFT);
$year = str_pad(intval($_POST_year), 4, 0, STR_PAD_LEFT);
$myFormat = implode('-', array($year,$month,$day));
注意我是如何跳过整个DateTime::createFromFormat
逻辑的。因为你已经手动格式化它了吗?但又一次,不清楚。
还建议您查看dob
字段的数据库设置,看看这些设置是否会阻塞它。
编辑好的,看看你的编辑&amp;数据结构,我认为问题在于查询本身:
//Query string and put it in a variable.
$query = "SELECT * FROM $table_data WHERE DATE(dob) = :date";
该查询中的DATE()
函数严格用于格式化MySQL中的日期。所以你已经在数据库中正确格式化了,对吗?为什么这样?我认为查询应该是:
//Query string and put it in a variable.
$query = "SELECT * FROM $table_data WHERE dob = :date";
另一个编辑好的,看看我的代码是如何修复代码的,这是错误的:
// Set the test data.
$_POST_day = $_POST['day'];;
$_POST_month = $_POST['month'];;
$_POST_year = $_POST['year'];;
// Get POST data
$day = str_pad(intval($_POST_day), 2, 0, STR_PAD_LEFT);
$month = str_pad(intval($_POST_month), 2, 0, STR_PAD_LEFT);
$year = str_pad(intval($_POST_year), 4, 0, STR_PAD_LEFT);
$userDate = implode('-', array($year,$month,$day));
首先,为什么每个;;
值之后有两个$_POST
,如下所示:$_POST_day = $_POST['day'];;
。那就是说,你正在重复我解决的第一个问题因为 - 我会说实话 - 你似乎不明白任何代码是如何运作的。只是剪切和粘贴你找到的东西的剪辑。这是应该如何:
// Get POST data
$day = str_pad(intval($_POST['day']), 2, 0, STR_PAD_LEFT);
$month = str_pad(intval($_POST['month']), 2, 0, STR_PAD_LEFT);
$year = str_pad(intval($_POST['year']), 4, 0, STR_PAD_LEFT);
$userDate = implode('-', array($year,$month,$day));
您只需将$_POST
内容设置为该代码即可。我创建了$_POST_day
,$_POST_month
&amp; $_POST_year
变量用于测试,因为我不打算将表单发布到测试页面以获得几行代码。
另外 - 正如另一位用户指出日期31/2/1948
正在返回3/3/1948
,因为二月只有28天(月号是2)所以当你将它们设置为31时,{{1} 1}}正在做它知道怎么做的事情,并且正在从一个不合适的日期计算一个正确的日期。 31-28的剩余部分是3.而下个月将是3月。因此,它认为您尝试制作的日期为$dateTime->format
。
但是,再一次,我们意识到你正在努力学习,但只是简单地将一些代码粘贴在一起而不实际理解它是如何工作的只会导致你更多&amp;随着时间的推移,这样的头痛更加令人头痛。所以你需要借用代码,了解它的作用和做法。然后根据您的需要将其重塑为您的代码。
答案 1 :(得分:1)
2月份大多数年份为28天,闰年为29天,因此,任何一年都没有31/2这样的日期。 PHP试图给你一个有效的日期,所以它寻找一个明智的替代31/2。这是在月底之后的三天,所以你得到了3/3。
JakeGould已经为你的其余代码提供了很好的建议,所以我在此不再重复,我只是在解释你得到这个日期的原因。