2009-02-09 84 views
4

我有很多PHP视图文件,我曾经使用简单的包含语句在我的控制器中包含这些文件。他们都使用在视图类中声明的方法,他们像$ view-> method();不过,我最近决定,如果包含也将由这个视图类来完成会更好。但是,这会改变包含文件的范围,以便不再定义$ view。 这里是一个代码示例:PHP为包含文件定义范围

in someViewFile.php (BOTH siuations) 
    <html> 
    <head><title><?php echo $view->getAppTitle(); ?></title> 
    etc. 
OLD SITUATION in controller: 
    $view = new view; 
    include('someViewFile.php'); //$view is defined in someViewFile.php 
NEW SITUATION in controller: 
    $view = new view; 
    $view->show('someViewFile'); //$view is not defined in someViewFile.php 

现在我在视图类使用这种攻击我的方式解决该问题:

public function show($file){ 
    $view = &$this; 
    include($file.".php"); 
} 

反正是有申报inluded文件的范围或者是这是解决问题的最好方法吗?

这些例子都是粗略简化的。

回答

1

您不能更改include()范围,否则您的方法可能与您描述的情况一样好。虽然我会跳过丑陋的PHP4兼容符号,我自己。

11

这是一个简化但功能强大的视图类,我已经看到了很多,并且使用了很多。
正如你可以在下面的代码中看到的:你用模板文件的文件名实例化一个视图。
客户端代码,可能是一个控制器,可以发送数据到视图中。这些数据可以是您需要的任何类型,甚至其他视图。
嵌套视图将在呈现父代时自动呈现。
希望这会有所帮助。

// simple view class 
class View { 
    protected $filename; 
    protected $data; 

    function __construct($filename) { 
     $this->filename = $filename; 
    } 

    function escape($str) { 
     return htmlspecialchars($str); //for example 
    } 

    function __get($name) { 
     if(isset($this->data[$name]) { 
      return $this->data[$name]; 
     } 
     return false; 
    } 

    function __set($name, $value) { 
     $this->data[$name] = $value; 
    } 

    function render($print = true) { 
     ob_start(); 
     include($this->filename); 
     $rendered = ob_get_clean(); 
     if($print) { 
      echo $rendered; 
      return; 
     } 
     return $rendered; 
    } 

    function __toString() { 
     return $this->render(); 
    } 
} 

使用

// usage 
$view = new View('template.phtml'); 
$view->title = 'My Title'; 
$view->text = 'Some text'; 

$nav = new View('nav.phtml'); 
$nav->links = array('http://www.google.com' => 'Google', 'http://www.yahoo.com' => 'Yahoo'); 

$view->nav = $nav; 

echo $view; 

模板

//template.phtml 
<html> 
    <head> 
     <title><?php echo $this->title ?></title> 
    </head> 
    <body> 
     <?php echo $this->nav ?> 
     <?php echo $this->escape($this->text) ?> 
    </body> 
</html> 

//nav.phtml 
<?php foreach($this->links as $url => $link): ?> 
    <a href="<?php echo $url ?>"><?php echo $link ?></a> 
<?php endforeach ?> 
+1

我认为有一个小错字,它说“filname”? – noio 2010-10-28 19:38:23

+0

事实上,该成员及其用法是`filname`,其中赋值是`filename`。我试图编辑它,但编辑需要6个字符的变化。 _roll eyes_ – Travis 2013-02-24 20:14:46

+0

固定的错字 - 感谢您指出 – meouw 2013-02-25 09:35:45

1

我该怎么办,(我不知道它是怎么行)仅仅是

extract($GLOBALS); 
include $view.".php"; 

当然作为地狱作品

干杯!

0

也许这与我的php设置或什么有关,但如果我在一个函数中包含一个文件,那包含文件将只包含该函数变量的范围。

$a = 1; // This variable isn't visible for the included file 

function render() 
{ 
    $b = 2; // This variable is 
    include('template.php'); 
} 


// ---------------------------------------- 
// template.php 

<html> 
<body> 
<?=$a?> // wont show 
<?=$b?> // will show 
</body> 
</html> 

我想我会像这样的东西去:

function render($template, $variables) 
{ 
    extract($variables); 
    include($template); 
} 

用法:

render('templates/mytemplate.php', array(a=>1, b=>2)); 
0

什么Quano所提供的扩展:

把它一步并且在全局执行范围内包含变量(否则这些变量必须在公司的内部全局调用路得)。这个想法是,你希望包含在你的主应用程序范围内,或者你的定义范围内工作。

考虑这个类:

class PHPInclude { 
    private static $globalsList = array(
      'GLOBALS','_SERVER','_GET','_POST','_FILES', 
      '_REQUEST','_SESSION','_ENV','_COOKIE' 
     ); 
    public static function phpInclude($file,$variables=array()) { 
     if (file_exists($file)) { 
      $globs = array(); 
      foreach ($GLOBALS as $key => $value) { 
       if (!in_array($key,sefl::$globalsList)) { 
        array_push($globs,$key); 
       } 
      } 
      foreach ($globs as $key) { 
       global $$key; 
      } 
      foreach ($variables as $variable) { 
       global $$variable; 
      } 
      unset($globs,$key,$value); 
      ob_start(); 
      include $file; 
      return ob_get_clean(); 
     } 
     return ''; 
    } 
} 

如下使用它:

$foo = 'bar'; 
function testScope() { 
    $woo = 'sah'; 
    PHPInclude::phpInclude('file.phtml',array($woo)); 
} 

的例子将自动包括$foo,因为它是在全球范围内,并$woo加入,因为它是在局部范围。

我还没有测试$this作为一个任意变量,但我的蜘蛛感官告诉我it won't work (warning)

1

一个更简化的版本视图类:

Class View { 

    protected $filename; 

    function __construct($filename){ 
     $this->filename = $filename; 
    } 

    function display(){ 
     global $session; //put global variables here 

     include Cfg::ROOT . '/views/' . $this->filename;  
    } 

    function assign($key, $val){ 
     $this->$key = $val; 
    } 

} 

在控制器:

$view = new View('homepage.php'); 
$view->assign('page_title',$page_title); //assign all needed variables from controller 
$view->display(); 

在模板/视图文件:

echo $this->page_title; 
-1

您可以发送get_defined_vars( )作为视图函数的参数。这会生成一个包含当前作用域中所有已定义变量的数组。在你的“视图”方法中,你将调用PHP的“提取”在接收的数组上。