Php 如何重构此条件以避免重复?

Php 如何重构此条件以避免重复?,php,dry,Php,Dry,这是事件页面的一部分,可以使用预定义的日期范围或日期选择器按日期进行筛选 我想避免重复整个foreach$days作为$day\u编号。。。等等。针对每种情况循环 我猜整个循环可以移动到一个函数,但我不确定如何实现它 <?php // open the db connection $db = new wpdb('user', 'pass', 'db', 'server'); // $today = date('Y-m-d'); $today = '2009-06-21'; $tomo

这是事件页面的一部分,可以使用预定义的日期范围或日期选择器按日期进行筛选

我想避免重复整个foreach$days作为$day\u编号。。。等等。针对每种情况循环

我猜整个循环可以移动到一个函数,但我不确定如何实现它

<?php

// open the db connection
$db = new wpdb('user', 'pass', 'db', 'server');


// $today = date('Y-m-d');
$today = '2009-06-21';
$tomorrow  = date( 'Y-m-d', mktime(0, 0, 0, date('m'), date('d')+1, date('Y')) );
$seven_days_ahead = date( 'Y-m-d', mktime(0, 0, 0, date('m'), date('d')+6, date('Y')) );
$thirty_days_ahead = date( 'Y-m-d', mktime(0, 0, 0, date('m'), date('d')+29, date('Y')) );


echo '<div class="column first">';


if ( ! empty($_REQUEST['date_range']) )    
{
    // user has chosen a date/range, show matching events 


    $date_range = mysql_real_escape_string($_REQUEST['date_range']);


    switch( $date_range )
    {
        case 'all':

            // code here

            break;

        case 'next_7_days':

            // code here

            break;

        case 'next_30_days':

            // code here

            break;

        default:

            // code here

    }


}
else
{
    // no date selected, show todays events

    $days = convert_date_to_day_number( $today );

    foreach ( $days as $day_number )
    {
        $where = sprintf( 'WHERE e.day_id = %s', $day_number );

        $events = get_events( $where );

        if ($events)
        {
            echo '<table class="results">';

            render_day( $day_number );

            foreach ($events as $event)
            {
                render_event($event);
            }  

            echo '</table>';
        }
        else
        {
            echo 'No events';                            
        }
    }

}

echo '</div> <!--/column-->';





function convert_date_to_day_number($date)
{
    global $db;

    $sql = "SELECT day_number FROM days WHERE day_date = '$date'";

    $day_numbers = $db->get_results($sql);

    foreach ($day_numbers as $key => $value)
    {
        $day_number[] = $value->day_number;
    }

    return $day_number;
}


function get_events($where)
{
    global $db;

    $sql = "SELECT
                 e.id,
                 TIME_FORMAT(e.start_time, '%H:%i' ) AS start_time,
                 e.x_prod_desc AS title,
                 -- e.title_en AS title,
                 p.name_en AS place,
                 et.name_en AS type,
                 w.week_number,
                 d.day_date AS start_date
             FROM event AS e
             LEFT JOIN place AS p ON p.id = e.place_id
             LEFT JOIN event_type AS et ON et.id = e.event_type_id
             LEFT JOIN days AS d ON d.id = e.day_id
             LEFT JOIN week AS w ON w.id = d.week_id ";   

    $sql .= $where;

    $events = $db->get_results($sql);

    return $events;          
}

function render_event($event)
{
    $request_uri = $_SERVER['REQUEST_URI'];

    $output = <<<EOD

    <tr class="week-$event->week_number">
        <td class="topic"></td>
        <td class="time">$event->start_time</td>
        <td class="summary">
         <a href="$request_uri&amp;event_id=$event->id">$event->title</a>   
        </td>
        <td class="type">$event->type</td>
        <td class="location">
           <span class="addr">$event->place</span>
        </td>
    </tr>

EOD;

    echo $output;
}


function render_day( $day_number )
{
    global $db;

    $sql = "SELECT
                d.day_number,
                DATE_FORMAT( d.day_date, '%W %e %M %Y' ) AS date,
                DATE_FORMAT( d.day_date, '%b' ) AS month,
                DATE_FORMAT( d.day_date, '%e' ) AS day
            FROM days AS d
            WHERE day_number = " . $day_number;

    $day = $db->get_results($sql);

    $day = $day[0];

    $output = <<<EOD

    <tr class="day">
        <th colspan="5">
            <em class="date">
                <abbr class="dtstart" title="20090605T1806Z">
                    <span title="$day->date">
                        <span class="month">$day->month</span>
                        <span class="day">$day->day</span>
                </span>
                </abbr>
            </em>
            $day->date
            <span class="event-day">Day $day->day_number</span>
        </th>
    </tr>

EOD;

    echo $output;
}
?>

我不会每天查询一次数据库,而是使用WHERE语句获取所需日期范围内的所有事件,然后将其发送到一个渲染函数,该函数循环遍历结果集中的每一行,如果当天与前一天不同,则在调用render_事件之前调用render_day


我不会每天查询一次数据库,而是使用WHERE语句获取所需日期范围内的所有事件,然后将其发送到一个渲染函数,该函数循环遍历结果集中的每一行,如果当天与前一天不同,则在调用render_事件之前调用render_day


首先,您可能希望使用strotime作为相对日期:

$today = '2009-06-21';
$tomorrow  = date( 'Y-m-d', strtotime('+1 day') );
$seven_days_ahead = date( 'Y-m-d', strtotime('+7 days') );
$thirty_days_ahead = date( 'Y-m-d', strtotime('+30 day') );
    // or +1 month (=> calendar month)
其次,您可以设置两个具有开始和结束日期的变量,然后:

$date = $start_date; // 'Y-m-d' format
while( $date <= $end_date ) {
    //code here or fill up a table with your days
    // using $date
    $date = date( 'Y-m-d', strtotime( '+1day', strtotime($date) ) );
}

无论何时使用PHP处理日期,您都应该检查。

首先,您可能希望使用strotime作为相对日期:

$today = '2009-06-21';
$tomorrow  = date( 'Y-m-d', strtotime('+1 day') );
$seven_days_ahead = date( 'Y-m-d', strtotime('+7 days') );
$thirty_days_ahead = date( 'Y-m-d', strtotime('+30 day') );
    // or +1 month (=> calendar month)
其次,您可以设置两个具有开始和结束日期的变量,然后:

$date = $start_date; // 'Y-m-d' format
while( $date <= $end_date ) {
    //code here or fill up a table with your days
    // using $date
    $date = date( 'Y-m-d', strtotime( '+1day', strtotime($date) ) );
}
无论何时使用PHP处理日期,都应该检查。

哇!我读过了

首先,使用模板引擎或任何其他方式来分割代码和HTML。从函数内部回显HTML不是一个好主意

我不确定,但我认为在DB中使用unix时间戳可以简化数据结构。php代码也是如此。仔细阅读php手册,我想,你会发现很多有趣的东西

实际上,正如我从您的代码中看到的,使用时间戳和模板将使您的代码简化为获取数据并将其分配给模板引擎的行。PHP的date函数已经有了一个选项,可以返回周数、一周或一年中的天数等

这是一个虚拟示例,您的代码可能是什么样子的:

$begin = mktime(...);
$end = mktime(...);
$query = "
    SELECT a,b,c 
    FROM events 
    WHERE ctime >= $begin AND ctime <= $end AND ...
";
$events = array();
while ($fetch = fetch_here(...))
{
    $event = new MyEvent();
    $event->loadDBFetch($fetch);
    array_push($events, $event);
}
$tplEngine->assign('events', $events);
当然,这不是一个现成的解决方案,但在我看来,您的代码可能与此类似。

哇!我读过了

function generateEventsTable($dateStr)
{
    $days = convert_date_to_day_number( $today );
    foreach ( $days as $day_number )
    {
        $where = sprintf( 'WHERE e.day_id = %s', $day_number );
        $events = get_events( $where );
        if ($events)
        {
            echo '<table class="results">';
            render_day( $day_number );
            foreach ($events as $event)
            {
                render_event($event);
            }  
            echo '</table>';
        }
        else
        {
            echo 'No events';                            
        }
    }
}
首先,使用模板引擎或任何其他方式来分割代码和HTML。从函数内部回显HTML不是一个好主意

我不确定,但我认为在DB中使用unix时间戳可以简化数据结构。php代码也是如此。仔细阅读php手册,我想,你会发现很多有趣的东西

实际上,正如我从您的代码中看到的,使用时间戳和模板将使您的代码简化为获取数据并将其分配给模板引擎的行。PHP的date函数已经有了一个选项,可以返回周数、一周或一年中的天数等

这是一个虚拟示例,您的代码可能是什么样子的:

$begin = mktime(...);
$end = mktime(...);
$query = "
    SELECT a,b,c 
    FROM events 
    WHERE ctime >= $begin AND ctime <= $end AND ...
";
$events = array();
while ($fetch = fetch_here(...))
{
    $event = new MyEvent();
    $event->loadDBFetch($fetch);
    array_push($events, $event);
}
$tplEngine->assign('events', $events);

当然,这不是一个现成的解决方案,但在我看来,您的代码可能与此类似。

我无法使用smarty,它是Wordpress模板的一部分。你能推荐一个更好的方式来呈现HTML吗?我不能使用smarty,它是Wordpress模板的一部分。你能推荐一种更好的方式来呈现HTML吗?
function generateEventsTable($dateStr)
{
    $days = convert_date_to_day_number( $today );
    foreach ( $days as $day_number )
    {
        $where = sprintf( 'WHERE e.day_id = %s', $day_number );
        $events = get_events( $where );
        if ($events)
        {
            echo '<table class="results">';
            render_day( $day_number );
            foreach ($events as $event)
            {
                render_event($event);
            }  
            echo '</table>';
        }
        else
        {
            echo 'No events';                            
        }
    }
}