免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
12下一页
最近访问板块 发新帖
查看: 3533 | 回复: 13
打印 上一主题 下一主题

高手解答:网页是怎么被抽象成多个层的? [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-09-22 17:35 |只看该作者 |倒序浏览
一个网站,这么多网页,大家是怎么来抽象出共性的呢?
mvc之类的是主要是讲模式,而很少怎么来抽象。

高手能否详解一下怎么来抽象呢?当然也可以配合模式。

论坛徽章:
0
2 [报告]
发表于 2008-09-22 17:38 |只看该作者
这个应该算是写php代码之前要定的大方向吧。

没有方向,很晕啊。

论坛徽章:
0
3 [报告]
发表于 2008-09-22 17:50 |只看该作者
http://www.phppatterns.com/docs/ ... er_pattern#the_view

这篇文章讲了部分view的抽象,先做个标记。

论坛徽章:
0
4 [报告]
发表于 2008-09-22 19:32 |只看该作者
路过

论坛徽章:
0
5 [报告]
发表于 2008-09-23 10:35 |只看该作者
楼主干嘛呢?
研究神学

论坛徽章:
0
6 [报告]
发表于 2008-09-23 11:29 |只看该作者
没有啊。
我想这样总是会为开发带来方便。

可能是我的话没有说清楚。

论坛徽章:
0
7 [报告]
发表于 2008-09-23 11:50 |只看该作者
或者这么说吧:

视图类具体怎么写比较可行?

论坛徽章:
0
8 [报告]
发表于 2008-09-23 16:20 |只看该作者
PHP的View层设计思路(一)收藏
一个页面,该怎样组织才最合理?
    首先就XHTML页面来说,都是由一个个的框组成的。有些框只在某个特定的页面有,
也有些框是在不同的页面间共享的。最后,有一个大框,把所有的小框包围起来,这个
大框就是<body></body>标签。再加上<head></head>段里的一些声明、CSS链接和JS链
接,一个页面就形成了。
    每个框在包含它的容器框中都需要定位,如自然定位,相对定位,绝对定位,浮
动,等等。同时每个框也需要有自身的修饰,如宽度、高度、背景、字体等等。在这种
模型中,CSS属性实际上已经被区分成了互相分离的两部分:定位和自身的修饰。这实际
上是组合模式(Composite Pattern)的一种实现,UML图为:


    很多View层设计方案都没有结合CSS一起讨论。然而如果采用上述方案,那么CSS就
应该是跟每个Block对象一一对应的。比如下面这个页面Block组织:
<body id="main">
    <div id="container_one">
        <div id="content_one">hello</div>
    </div>
    <div id="container_two">
        <div id="content_two">world</div>
    </div>
</body>
就需要main、container_one、content_one、container_two、content_two共五个CSS
文件(这里暂时先不考虑CSS文件对Web服务器性能的影响)。为什么要分开成五个CSS
文件?这是因为除<body>外的其它Block是需要在不同的<body>间复用的。要复用就必
然要松散耦合,所以每个实现上的Leaf Block(注意这是实现上的,不是UML图中的,
因为实现中一个Container Block也可以被当成一个Leaf Block使用,比如你可以把
container_two和其下的content_two合并起来当成一个整体,所谓的对象组合)都需要
一个单独的模板文件和一个单独的CSS。再举JS里的对象动态绑定做例子,就很容易理
解这种绑定。文件组织看起来大致如下,注意我没有区分各文件的逻辑层次,在现实框
架中肯定需要按照逻辑划分到不同的模块的,我只是给个例子说明下思路:
template文件:
    main.container
    container_one.container
    container_two.container
    content_one.leaf
    content_two.leaf
css文件:
    main.css
    container_one.css
    container_two.css
    content_one.css
    content_two.css
    如此一来,只需要设计一个View类,让它依此规则渲染对应的模板即可。下一篇
文章就给出该View类的一个样例实现。

<2007.07.25注:>附样例代码:

class view {
    public function __construct($layout) {
        $this->layout = $layout;
        $this->layout_target = dirname(self::$target) . '/' . $this->layout;
    }
    public function set_title($title) {
        $this->title = $title;
    }
    public function set_keywords($keywords) {
        $this->keywords = $keywords;
    }
    public function set($key, $value) {
        $this->vars[$key] = $value;
    }
    public function render($_block_token, $_block_name = '') {
        if ($_block_name === '') {
            $_block_name = $_block_token;
        }
        $_folder = $this->layout_target;
        $_go_upper_time = 3;
        extract($this->vars, EXTR_SKIP);
        ob_start();
        for ($_i = 0; $_i < $_go_upper_time; ++$_i) {
            $_block_file = self::$block_root . '/' . $_folder . '/' . $_block_name . '.tpl';
            if (!is_readable($_block_file)) {
                $_folder = dirname($_folder);
            } else {
                require $_block_file;
                $this->csses[$_block_token] = $_folder . '/' . $_block_name . '.css';
                break;
            }
        }
        if ($_folder === '.') {
            $_block_file = self::$block_root . '/' . $_block_name . '.tpl';
            if (!is_readable($_block_file)) {
                hc_api_error("Cannot find block file '{$_block_name}' for block token '{$_block_token}'");
            }
            require $_block_file;
            $this->csses[$_block_token] = $_block_name . '.css';
        }
        $this->blocks[$_block_token] = ob_get_clean();
        $this->vars = array();
    }
    public function show() {
        $blocks = $this->blocks;
        ob_start();
        require self::$layout_root . '/' . $this->layout_target . '.lyt';
        ob_end_flush();
    }
    private function render_head() {
        echo '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">' . "\n";
        echo '<html xmlns="http://www.w3.org/1999/xhtml">' . "\n";
        echo '<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />' . "\n";
        if ($this->keywords === '') {
            $keywords = config::get('system.keywords');
            echo '<meta name="keywords" content="' . $keywords . '" />' . "\n";
        } else {
            echo '<meta name="keywords" content="' . $this->keywords . '" />' . "\n";
        }
        echo '<title>' . $this->title . '</title>' . "\n";
        echo '<link rel="stylesheet" href="css/css.css" type="text/css" media="all" />' . "\n";
        echo '<link rel="stylesheet" href="css/layout/' . $this->layout_target . '.css" type="text/css" media="all" />' . "\n";
        foreach ($this->csses as $css) {
            echo '<link rel="stylesheet" href="css/block/' . $css . '" type="text/css" media="all" />' . "\n";
        }
        echo '<script type="text/javascript" src="js/jquery.js"></script>' . "\n";
    }
    private $layout        = '';
    private $layout_target = '';
    private $title         = '';
    private $keywords      = '';
    private $vars          = array();
    private $blocks        = array();
    private $csses         = array();

    public static function set_target($target) {
        self::$target = $target;
    }
    public static function set_layout_root($layout_root) {
        self::$layout_root = $layout_root;
    }
    public static function set_block_root($block_root) {
        self::$block_root = $block_root;
    }
    private static $target      = '';
    private static $layout_root = '';
    private static $block_root  = '';
}

一些初始化代码暂略(这部分代码是我目前应用中抽取出来的,所以不能直接使用),简单用例代码为:

$view = new view('index'); // 指定layout为index布局模板
$view->set_title('标题');
$view->set('name', 'diogin'); //指定一个变量
$view->render('header'); // 嵌入header块
$view->render('navigator'); // 嵌入navigator块
$view->render('content'); // 嵌入content块
$view->render('footer'); // 嵌入footer块
$view->show(); // 渲染出整个页面

以上只是一个思路,供大家参考,呵呵。


来源:http://blog.csdn.net/Diogin/archive/2007/06/06/1640214.aspx

[ 本帖最后由 oled 于 2008-9-23 16:22 编辑 ]

论坛徽章:
0
9 [报告]
发表于 2008-09-23 16:26 |只看该作者
找到一个还不错的,先贴过来放楼上再说。

论坛徽章:
0
10 [报告]
发表于 2008-09-24 10:34 |只看该作者
又一例子,至少可以提供一种思路吧。
先贴过来吧,不要怪我乱啊。

来源:http://www.baixi.org/bbs/viewthread.php?tid=7272

创建程序视图类:page.class.php
引用:
<?php
/*
ID: page.class.php, Last update: 2008/08/26, Author: Leon Lin(QQ:82756)
类名:GreatePage(创建程序视图类)
主方法:DisplayHeader、IsLogin、DisplayFooter
*/
class CreatePage
{
#主菜单数组
public $menu;
#子菜单
public $subMenu;
#主菜单当前位置
public $parentLocation;
#子菜单当前位置
public $subLocation;
#功能菜单当前位置
public $functionLocation;
#访问权限
public $purview;

//构造函数
public function __construct()
{
  session_start();
}

//顶部内容
public function DisplayHeader()
{
  echo '
  <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  <html xmlns="http://www.w3.org/1999/xhtml">
  <head>
  <meta http-equiv="Content-Type" c/>
  <meta name="keywords" c />
  <meta name="description" c />
  <meta name="generator" c />
  <meta name="author" c />
  <meta name="copyright" c />
  <meta name="robots" c>
  <title>'.$this->parentLocation.' - '.$this->subLocation.' - '.$this->functionLocation.' - '.WEBSITE_NAME.'</title>
  <link href="css/default.css" rel="stylesheet" type="text/css" />
  <script type="text/javascript">
        function displaySubMenu(li) {
   var subMenu = li.getElementsByTagName("ul")[0];
   subMenu.style.display = "block";
        }
        function hideSubMenu(li) {
   var subMenu = li.getElementsByTagName("ul")[0];
   subMenu.style.display = "none";
        }
     </script>
  </head>
  <body >
  <div class="parent">
   <div class="logo">'.SOFT_NAME.'<sup style="font-size:10px; font-weight:normal">TM</sup></div>
   <div class="menu">
   <ul>
   ';
   #一级菜单
   for($one=0; $one<count($this->menu); $one++)
   {
    #菜单权限分配
    $onecheck = explode(',', $this->menu[$one][2]);
    if ( isset($_SESSION[SOFT_KEY.'UserLevel']) && in_array($_SESSION[SOFT_KEY.'UserLevel'], $onecheck) )
    {
     echo '<li  >';
     if ($this->parentLocation==$this->menu[$one][0])
      echo "<a href=\"?action=".$this->menu[$one][1]."\" class=\"over\">".$this->menu[$one][0]."</a>";
     else
      echo "<a href=\"?action=".$this->menu[$one][1]."\">".$this->menu[$one][0]."</a>";
     #二级菜单
     if (count($this->menu[$one][3])>0)
     {
      echo '<ul>';
      for($two=0; $two<count($this->menu[$one][3]); $two++)
      {
       #菜单权限分配
       $twocheck = explode(',', $this->menu[$one][3][$two][2]);
       if ( isset($_SESSION[SOFT_KEY.'UserLevel']) && in_array($_SESSION[SOFT_KEY.'UserLevel'], $twocheck) )
       {
        echo "<li><a href=\"?action=".$this->menu[$one][3][$two][1]."\">".$this->menu[$one][3][$two][0]."</a></li>";
       }
      }
      echo '</ul>';
     }
     echo '</li>';
    }
   }
   echo '
   </ul>
   </div>
  </div>
  ';
   echo '
   <div class="sub">
    <div class="floatleft">
   ';
   foreach($this->subMenu as $name=>$module)
   {
    if ($this->functionLocation==$name)
    {
     echo "<a href=\"?action=$module\" class=\"over\">$name</a>";
    }else{
     echo "<a href=\"?action=$module\">$name</a>";
    }
   }
   echo '
    </div>
    <div class="floatright" style="padding-right:10px; color:#999999">当前位置:'.$this->parentLocation.' > '.$this->subLocation.' > '.$this->functionLocation.'</div>
   </div>
   ';
  echo '
  <div class="content">
  ';
}

//底部主内容
public function DisplayFooter()
{
  echo '
  </div>
  <div class="copyright">
   <div class="floatleft">&copy;'.date("Y").' '.WEBSITE_COPYRIGHT_COMPANY.' 版权所有</div>
   <div class="floatright">Coded by Leon Lin</div>
  </div>
  </body>
  </html>
  ';
}

//登录后提示字幕
private function DisplayTip()
{
  if (isset($_SESSION[SOFT_KEY.'UserID'])&&isset($_SESSION[SOFT_KEY.'UserLevel'])&&isset($_SESSION[SOFT_KEY.'Fullname']))
  {
   return '您好 '.$_SESSION[SOFT_KEY.'Fullname'].',欢迎登录'.WEBSITE_NAME.'!';
  }
}

//身份验证
public function IsLogin()
{
  if (!isset($_SESSION[SOFT_KEY.'UserID'])||!isset($_SESSION[SOFT_KEY.'UserLevel'])||!isset($_SESSION[SOFT_KEY.'Fullname'])) header("Location:index.php?action=logout");
  #自定义访问权限验证
  if (!empty($this->purview))
  {
   $purview = explode(',', $this->purview);
   if ( !in_array($_SESSION[SOFT_KEY.'UserLevel'], $purview) )
   {
    Warning("抱谦:权限不足!");
   }
  }
}
}
?>
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP