Tekrarlanmasını önlemek için bu koşullu refactor nasıl?

4 Cevap php

Bu (önceden tanımlanmış tarih aralıkları veya tarih seçici kullanarak) tarihe göre filtre edilebilir bir etkinlik sayfası parçasıdır.

Ben bütün her durum için foreach ($days as $day_number)... vb döngü tekrarlamaktan kaçınmak istiyorum.

Ben bütün döngü bir fonksiyona hareket olabilir sanırım, ama bunu uygulamak için nasıl emin değilim.

<?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;
}
?>

4 Cevap

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';                            
        }
    }
}

Bu gibi diyoruz:

generateEventsTable($today);

İlk olarak, göreli tarihler için strtotime kullanmak isteyebilirsiniz:

$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)

İkinci olarak, başlamadan iki değişkenlerini ayarlamak & yapabilirsiniz O, tarih sona:

$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 tarihleri ​​ile çalışan zaman, strtotime kontrol etmelisiniz.

Aksine, her gün için bir kez veritabanı sorgulama yerine, ben istediğiniz tarih aralığı için tüm olayları getirilen bir WHERE açıklama yapmak istiyorum, ve sonra sonuç kümesindeki her satır ile döngüler render işlevi olduğunu göndermek ve Günün çağırmadan önce bir önceki, aramaların render_day() farklıdır render_event(). ise

switch (/* input from user */) {
    // Build a date range here.
    // Resulting statement would be something like:
    // WHERE event_date >= '2009-06-10' AND event_date < '2009-06-17'
}

$events = get_events($filter);
$prev_date = null;
foreach ($events as $event) {
    if ($event->date != $prev_date) render_day($event->date);
    render_event($event);
    $prev_date = $event->date;
}

Wow! Ben bunu okudum!

İlk (smarty gibi) tüm kullanım şablon motoru veya kodu ve HTML bölmek için başka bir şekilde. Bu fonksiyonların içindeki HTML yankı kötü bir fikir.

Emin değilim ama DB unix-damgalarını kullanarak veri yapısını basitleştirmek olabileceğini düşünüyorum. Aynı php kodu ile ilgili. date/time functions php kılavuzunu dikkatle okuyun, sanırım, ilginç bir çok şey bulacaksınız ...

Aslında, zaman damgaları ve şablonları kullanarak kodu gördüğünüz gibi veri alma ve motor şablon atamak için bazı hattına kodunuzu azaltacaktır. PHP'nin "date ()" fonksiyonu zaten hafta numbe, bir hafta içinde ya da vb bir yıl içinde gün sayısını döndürmek için bir seçenek vardır ..

Bu kod neye benzeyeceğini kukla Exaple olduğunu:

$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);

Tabii, sizin kod buna benzer olabilir, bu bir hazır-to-go çözüm değil, ama bana öyle geliyor.