我在代码的可读性方面苦苦挣扎了一段时间,之后,我试图获得尽可能多的见解(针对我的标准)。在我的水平上,我认为我完全可以理解并使用它。

但是我在演示中仍然有很多混合的html / css。通常,我有一个中等水平的复杂多维数组作为返回值,在实际的演示页面上,我会对其进行迭代,但是仍然会用它做很多事情。

所以我现在正在寻找进入诸如Smarty之类的模板引擎,但我无法理解,如何在下面的示例中迭代和使用演示文稿中的数组的示例中保存一些实际代码:

$courseinfo = new courseinfo($_SESSION['course_short']);
$row = $courseinfo->get_all(); 
$default = $courseinfo->get_default();
$prices = $courseinfo->get_prices();
$month_min_show = 5;

//color settings for prices
$colorlow = '#6F6'; 
$colormid = '#09F'; 
$colorhigh = '#F90'; 
$colorspecial = '#F0F';
$colorfull = 'rgba(255,0,0,0.3)';


/* CONTENT CALENDAR
-----------------
-----------------
*/

echo '<div id="calendar">';
$count['month'] = 0;
foreach($row as $month)
{
    $lastcourse = end($month['course']);
    $laststart = $lastcourse['date'];
    $enddate = new DateTime($laststart);
    $enddate->modify('+ '.($lastcourse['length']-1).' days');
    $iterate = new DateTime('01-'.date('m',strtotime($laststart)).'-'.$month['year']);
    if (!isset($stored['year']) || isset($stored['year']) && $stored['year'] != $month['year'])
    {

        if($count['month'] > $month_min_show) { break;}     // don't show next year if $month_min_show months already displayed
        if(isset($stored['year'])) { echo '<br /><br /><br /><div style="margin-top:-10px"></div>';}
        echo '<span class="year" style="float:left;">'.$month['year'].'</span>';
        echo '<div style="float:right;margin-top:-20px;padding-right:5px;">';
        echo '<div style="float:left;font-size:12px;font-weight:bold;">PRICES '.$month['year'].'</div>';

        echo '<div class="pricelegend" style="background-color:'.$colorfull.'">fully booked</div>';
        if (in_array('low',$prices[$month['year']])) { echo '<div class="pricelegend" style="background-color:'.$colorlow.'">'.$default['price_low'].' &euro;</div>'; }
        if (in_array('mid',$prices[$month['year']])) { echo '<div class="pricelegend" style="background-color:'.$colormid.'">'.$default['price_mid'].' &euro;</div>'; }
        if (in_array('high',$prices[$month['year']])) { echo '<div class="pricelegend" style="background-color:'.$colorhigh.'">'.$default['price_high'].' &euro;</div>'; }
        if (in_array('custom',$prices[$month['year']])) { echo '<div class="pricelegend" style="background-color:'.$colorspecial.'">Special Offer</div>';}


        echo '</div><div style="clear:both;"></div><hr width="800px;" align="left"/>';
    }


    echo '<div class="m_start">'.mb_strtoupper($month['monthname'],'UTF-8').'<br />';
        echo '<span class="yearsmall">'.$month['year'].'</span>';
    echo '</div>';
    echo '<div class="courses">';
    echo '<div style="float:left;width:10px;">&nbsp;</div>';
    while($iterate<=$enddate)
    {
        $dayname = strftime('%a',$iterate->format('U'));
        if ($dayname == "So" OR $dayname == "Sa") { $daycolor = "#999"; } else { $daycolor = "#FFF";}

        echo '<div class="dayname" id="'.$iterate->format('dmY').'" style="color:'.$daycolor.'">'.$dayname.'</div>';

        $iterate->modify('+ 1 days');
    }
        echo '<br />';

    $lineswitch = 0;
    foreach($month['course'] as $course) 
    { 
        $date = $course['date'];
        $date = new DateTime("$date");
        $coursewidth = $course['length']*20-2;
        if($course['class'] == 'low') { $pricecolor = $colorlow; }
        elseif($course['class'] == 'mid') { $pricecolor = $colormid; }
        elseif($course['class'] == 'high') { $pricecolor = $colorhigh; }
        else {$pricecolor = $colorspecial;}
        if($course['user'] >= $course['usermax']) { $pricecolor = $colorfull;  }
        if(isset($_SESSION['course_id']) && $_SESSION['course_id'] == $course['id']) { $bordercolor = 'border-color:#FFF';} else {$bordercolor = '';}

        if($course['user'] < $course['usermax']) { echo '<a class="clink" id="'.$course['id'].'" href="'.$_SESSION['book_url'].'?course='.$course['id'].'" target="_self">'; }
        echo '<div class="course" style="background-color:'.$pricecolor.';'.$bordercolor.';width:'.$coursewidth.'px;margin-top:'.$lineswitch*17 .'px;margin-left:'.(10+($date->format('d')-1)*20).'px">';

        if($course['user'] < $course['usermax'])
        {
            echo '<span class="coursestart">&nbsp;'.$date->format('d').'</span>';


            if($course['length'] > 1) 
            {
                echo '-';
                $date->modify('+ '.($course['length']-1).' days');
                echo '<span class="courseend">'.$date->format('d').'&nbsp;</span>';
            }
        }
        else { echo '<span style="color:#000;">x</span>'; }

        echo '</div>';
        if($course['user'] < $course['usermax']) {echo '</a>';}
        unset($date);
        if ($lineswitch == 0) { $lineswitch = 1;} else {$lineswitch = 0;}
    }
    echo '</div>';

    echo '<div class="m_end"></div>';
    echo '<div style="clear:both;"></div><br />';
    $stored['year'] = $month['year'];
    $count['month']++;

}       
echo '</div>';


这是我要遍历的数组的一个示例:

Array ( [04.2012] => 
    Array ( [monthname] => April [year] => 2012 [course] => 
        Array ( 
           [0] => Array ( [id] => 106 [date] => 2012-04-02 14:00:00 [length] => 3 [class] => mid [price] => 110 [user] => 0 [usermax] => 20 [day] => 02 [week] => 14 [dayname] => Mo [hours] => 3 ) 
           [1] => Array ( [id] => 107 [date] => 2012-04-03 10:00:00 [length] => 3 [class] => mid [price] => 110 [user] => 0 [usermax] => 20 [day] => 03 [week] => 14 [dayname] => Di [hours] => 3 ) 
           [2] => Array ( [id] => 108 [date] => 2012-04-05 14:00:00 [length] => 3 [class] => mid [price] => 110 [user] => 0 [usermax] => 20 [day] => 05 [week] => 14 [dayname] => Do [hours] => 3 )   
          ) 
       ) 


您可以看到很多代码,这样您就可以了解如何仍然需要对数组进行很多工作。


那么,如何将其拆分成较小的块,或者使其更易读易用?

希望我可以在这里弄清楚我想要的东西...并且确定如果您发现此代码中完全愚蠢的其他内容,请给我一个字!那里的动态变化。

旁注:我一个人工作,总是会的,所以分开只是我一个人。

评论

我建议使用PHP框架,例如cakePHP。这些框架使用MVC(模型视图控制器)体系结构,将帮助您将业务逻辑与表示代码分开。

#1 楼

感谢您提供真实的表示逻辑部分的完美示例。
大多数推销一些原始模板解决方案的人都不知道存在如此复杂的情况。

让您正确使用的三个规则:


使用PHP作为模板引擎。
不使用PHP回声输出HTML标记或文本常量,而仅使用纯HTML。
将所有数据准备移至业务逻辑部分。

在业务逻辑中格式化所有数据。
仅将标量传递给模板。没有日期时间对象!
没有复杂的逻辑-模板中仅使用基本的PHP语法。

因此,两次遍历数据:做所有的数据准备和格式化。
下一次在模板中进行实际输出。

因此,PHP代码变成这样

$count['month'] = 0;
foreach($row as $i => $month)
{
    $month['lastcourse'] = end($month['course']);
    $month['laststart']  = $month['lastcourse']['date'];
    $month['enddate']    = new DateTime($month['laststart']);
    $month['enddate']->modify('+ '.($month['lastcourse']['length']-1).' days');
    $month['iterate']    = new DateTime('01-'.date('m',strtotime($month['laststart'])).'-'.$month['year']);
    $month['showyear']   = (!isset($stored['year']) || isset($stored['year']) && $stored['year'] != $month['year']);
    $month['monthname']  = mb_strtoupper($month['monthname'],'UTF-8');
    $row[$i]             = $month;
}   


而模板却像这样干净

<div id="calendar">
<? foreach($row as $month): ?>
  <? if ($month['showyear']): ?>
    <? if ($stored['year']): ?>
        <br /><br /><br /><div style="margin-top:-10px"></div>
    <? endif ?>
        <span class="year" style="float:left;"><?=$month['year']?></span>
        <div style="float:right;margin-top:-20px;padding-right:5px;">
        <div style="float:left;font-size:12px;font-weight:bold;">PRICES <?=$month['year']?></div>
        <div class="pricelegend" style="background-color:<?=$colorfull?>">fully booked</div>
        some code removed
        </div><div style="clear:both;"></div><hr width="800px;" align="left"/>
  <? endif ?>
        <div class="m_start"><?=$month['monthname']?><br />
        <span class="yearsmall"><?=$month['year']?></span>
        </div>
    <div class="courses">
    <div style="float:left;width:10px;">&nbsp;</div>
<? endforeach ?>
</div>


我不会重新格式化所有代码,而只是给您一个想法。

评论


\ $ \ begingroup \ $
在阅读了几次之后,我完全把它挖了!这是一种轻巧简单的方法来解决我的问题。现在,我将尝试重新编写自己的代码,看看它如何进行-可能会再次提出进一步的问题。如果其他人还有话要说,我将保留问题。非常感谢!!
\ $ \ endgroup \ $
–匿名
2011-11-28 11:36

\ $ \ begingroup \ $
随便问。我多年来一直在开发这种方法,并希望从我的经验中分享一些东西。
\ $ \ endgroup \ $
–颜色弹片
11-11-28在11:40

\ $ \ begingroup \ $
内联样式和速记PHP标记通常是不行的。除了做得好。 :)
\ $ \ endgroup \ $
– Daveo
2011年11月28日在12:11

\ $ \ begingroup \ $
@Daveo导致麻烦的速记PHP标记(当前)是<?和<%。使用<?=很好。
\ $ \ endgroup \ $
–莱维·莫里森(Levi Morrison)
2011年11月28日在19:17

#2 楼

处理此批次:

//color settings for prices
$colorlow = '#6F6'; 
$colormid = '#09F'; 
$colorhigh = '#F90'; 
$colorspecial = '#F0F';
$colorfull = 'rgba(255,0,0,0.3)';

// ...
// ...
// ...

if (in_array('low',$prices[$month['year']])) { echo '<div class="pricelegend" style="background-color:'.$colorlow.'">'.$default['price_low'].' &euro;</div>'; }
if (in_array('mid',$prices[$month['year']])) { echo '<div class="pricelegend" style="background-color:'.$colormid.'">'.$default['price_mid'].' &euro;</div>'; }
if (in_array('high',$prices[$month['year']])) { echo '<div class="pricelegend" style="background-color:'.$colorhigh.'">'.$default['price_high'].' &euro;</div>'; }
if (in_array('custom',$prices[$month['year']])) { echo '<div class="pricelegend" style="background-color:'.$colorspecial.'">Special Offer</div>';}


一种方法是使用类似以下内容的方法:

# place your colors into an array instead
$colors = array();
$colors['low'] = '#6F6'; 
$colors['mid'] = '#09F'; 
$colors['high'] = '#F90'; 
$colors['special'] = '#F0F';
$colors['full'] = rgba(255,0,0,0.3);

# price legend array, since your code appears to be checking each one
$priceLegend = array();
$priceLegend[] = 'low';
$priceLegend[] = 'mid';
$priceLegend[] = 'high';
$priceLegend[] = 'custom';

// ...
// ...
// ...


然后在html输出端进行操作:在这里进行一个更改,然后其他更改将随之而来。.我的意思是,对于价格图例的(例如)div样式或其他内容。.

无论如何,这仅仅是许多更改方法之一。然后,您可以将其应用于代码的其他部分。希望更多内容会发布在这里。如果您要:

<div class="pricelegend" style="background-color:<?php echo $colors['full']; ?>">fully booked</div>
<?php
    foreach($priceLegend as $key => $value) {
    if (in_array($value,$prices_array[$months_array['year']])) {
        $priceBackclr = $colors_array[$value];
        $priceDisplay = $defaults_array['price_'.$value];
        $priceDisplay .= ($priceDisplay != 'Special Offer') ? ' &euro' : '';
        ?>
        <div class="pricelegend" style="background-color:<?php echo $priceBackclr; ?>"><?php echo $priceDisplay; ?></div>';
        <?php
    }
}
?>
</div><div style="clear:both;"></div><hr width="800px;" align="left"/>


然后在模板中,如果需要显示它,请按以下方式使用它: br />
功能can帮助DRY找出您的代码。它可以根据您设置和编码的$outputType值灵活地执行其他操作。想象一下该函数存储在某个地方,然后您的输出页面简单地调用它。然后,如果可以,请创建您自己的类,该类将包含处理这些如何输出数据的此类函数。从MVC设计模式来看,它看起来可能像controllerview,但是通过微调,您可以将其变成纯view。所以我想我想说的是..要使用设计模式,面向对象的方法,并牢记忠于Don't Repeat Yourself原理。

评论


\ $ \ begingroup \ $
为您的努力+1或更多的想法-因为我知道您想推动我。您的代码可以更加自动化。在这种特殊情况下,虽然没有任何意义,但这并没有降低想法。也谢谢你!很棒,有不同的投入!!
\ $ \ endgroup \ $
–匿名
2011-11-28 13:11

\ $ \ begingroup \ $
很高兴能提供帮助。我实际上打算发表有关创建更多具有DRY功能的类,然后使它们与CSS动态配合的文章,但是我不确定这是否有意义,因为这有点像建议重新编写许多代码。但是无论如何,谢谢!
\ $ \ endgroup \ $
–名
2011-11-28 14:16

\ $ \ begingroup \ $
在这个阶段,重新格式化整个代码对我来说可能有点过多,但是我一直渴望学习,特别是在进行结构设计时。你能举一个大概的例子吗?
\ $ \ endgroup \ $
–匿名
2011-11-28 15:01

\ $ \ begingroup \ $
@danontheline,您是否有可能已经在代码中使用了设计模式?我肯定会建议使用OOP和DRY编程,但是如果您已经使用了设计模式,我想先问一下。
\ $ \ endgroup \ $
–名
11年11月29日在11:08

\ $ \ begingroup \ $
好的,以下是我认为可以使您对OOP有所了解的两个链接:net.tutsplus.com/tutorials/php/oop-in-php和phpfreaks.com/tutorial/oo-php-part-效果一环..接下来,我个人甚至将OOP应用于小型项目,例如简单的调查或请愿页面。当我需要快速整理一些信息以查看该想法是否可行时,我会进行程序化操作。然后我对它进行OOP操作。 :D尝试将其应用于所有项目。至于DRY ..一个大概的例子是..让我更新我的答案...
\ $ \ endgroup \ $
–名
2011-11-29 21:56



#3 楼

您可能还考虑使用Twig或Smarty之类的模板引擎。

它们都提供了显示和逻辑的完全分离。