所以我有一个输入字段用于搜索我的数据库。我希望能够只搜索day
,day
+ month
或day
+ month
+ year
,就像这样:
仅限18日 18-1 //天+月 18-1-2018 //日+月+年
我首先需要做的是使用explode分割结果:
$date = explode("-", $this->string); // $this->string is set in the constructor
这会给我一个1,2或3个结果的数组(我们假设输入是正确的)。
问题在于我的方法中有太多if/else
语句:
搜索():
public function search()
{
$date = explode("-", $this->string);
if (array_key_exists(2, $date))
{
if (!is_numeric($date[0]) || !is_numeric($date[1]) || !is_numeric($date[2]))
{
return false;
}
return $this->dateCheck($date[0], $date[1], $date[2]);
}
if (array_key_exists(1, $date))
{
if (!is_numeric($date[0]) || !is_numeric($date[1]))
{
return false;
}
return $this->dateCheck($date[0], $date[1]);
}
if (array_key_exists(0, $date))
{
if (!is_numeric($date[0]))
{
return false;
}
return $this->dateCheck($date[0]);
}
return false;
}
dateCheck():
private function dateCheck($day = null, $month = null, $year = null)
{
if ($year == null)
{
$year = Carbon::now()->format('Y');
}
if ($month == null)
{
$month = Carbon::now()->format('m');
}
if ($day == null)
{
$day = Carbon::now()->format('d');
}
return (bool) checkdate($month, $day, $year);
}
我的问题是,任何人都有更好的解决方案来减少任何数量的if/else
陈述吗?
PS。如果在任何地方返回false,将会有一个重定向返回到输入页面,并显示一条消息,指出没有结果。
答案 0 :(得分:2)
假设您使用PHP> = 5.6,则可以使用splat运算符(...
),也称为参数解包。您可以在PHP manual here。
splat运算符将获取数组中的元素并将它们作为单独的参数传递。
public function search()
{
$date = explode("-", $this->string);
// If any items are not numeric, this will evaluate to false.
$numeric = array_reduce($date, function ($carry, $item) {
return $carry && is_numeric($item);
}, true);
if (empty($date) || !$numeric) {
return false;
}
return $this->dateCheck(...$date);
}
如果您还没有使用PHP 5.6,那么您的最后几行将需要有所不同。您可以使用call_user_func_array()
函数,该函数使用数组项作为参数调用函数。
return call_user_func_array([$this, 'datecheck'], $date);
或者,您可以设计数组,以便索引始终存在:
$date = array_replace([null, null, null], $date);
return $this->dateCheck($date[0], $date[1], $date[2]);
您还可以使用三元快捷键操作符(?:
)将dateCheck
函数缩减为:
private function dateCheck($day = null, $month = null, $year = null)
{
return (bool) checkdate(
$month ?: Carbon::now()->format('m'),
$day ?: Carbon::now()->format('d'),
$year ?: Carbon::now()->format('Y')
);
}
这基本上表示如果变量为false-y(null,0,'',false等),则将其替换为Carbon输出。如果你想对null检查严格,并且你在PHP 7上,你可以使用null coalesce运算符(??
)而不是三元快捷运算符。然后,只有在变量为null
时才会使用Carbon值。
答案 1 :(得分:1)
$date = explode('-', $x);
$date = array_replace([date('d'), date('m'), date('Y')], $date);
答案 2 :(得分:1)
您可以大量简化代码。 dateCheck
函数在逻辑上不能减少那么多,但我们可以写得更漂亮:
$year = $year === null ? Carbon::now()->format('Y') : $year;
$month = $month === null ? Carbon::now()->format('m') : $month;
$day = $day === null ? Carbon::now()->format('d') : $day;
return (bool) checkdate($month, $day, $year);
search
函数可以使用实用程序函数来减少确定日期是否有效所需的开销量。像这样:
$date = explode("-", $this->string);
if (count($date) === 3 and static::isValidDate($date)) {
return $this->dateCheck($date[0], $date[1], $date[2]);
}
if (count($date) === 2 and static::isValidDate($date)) {
return $this->dateCheck($date[0], $date[1]);
}
if (count($date) === 1 and static::isValidDate($date)) {
return $this->dateCheck($date[0]);
}
return false;
最后,新的(静态)方法isValidDate
:
private static function isValidDate(array $date) {
foreach ($date as $field) {
if (!is_numeric($field)) {
return false;
}
}
return true;
}
您还可以将编码器重写为更简单,重用相同的isValidDate
方法,并将search
函数更改为:
$date = explode("-", $this->string);
if (static::isValidDate($date)) {
return $this->dateCheck($date);
}
return false;
并且dateCheck
到(请注意,此函数的参数现在是一个数组的date
变量):
$year = !isset($date[0]) ? Carbon::now()->format('Y') : $date[0];
$month = !isset($date[1]) ? Carbon::now()->format('m') : $date[1];
$day = !isset($date[2]) ? Carbon::now()->format('d') : $date[2];
return (bool) checkdate($month, $day, $year);
答案 3 :(得分:1)
在搜索功能中,您只需将日期字符串转换为数组
即可 $date = explode("-", $this->string);
过滤掉非数值(不应该在那里)
$valid = array_filter($date, 'is_numeric');
并检查是否所有有效的Il有效(评估的短路)返回实际计算的结果
return (count($date) === count($valid)) &&
call_user_func_array(array($this, 'dateCheck'), $valid);
public function search()
{
$date = explode("-", $this->string);
$valid = array_filter($date, 'is_numeric');
return (count($date) === count($valid)) &&
call_user_func_array(array($this, 'dateCheck'), $valid);
}
对于datecheck函数:我们只需在传递的参数末尾添加默认值,只需使用前三个值,不需要ifs或三元操作。
private function dateCheck($day = null, $month = null, $year = null)
{
$date = array_filter(func_get_args(), 'is_int');
array_push($date, Carbon::now()->format('m'), Carbon::now()->format('Y');
list($day, $month, $year) = array_slice($date, 0,3);
return (bool) checkdate($month, $day, $year);
}