之前可能已经提出过这个问题,但我无法通过一些初步搜索找到问题的答案,所以这里是:
我当前将PHP变量注入HTML的方法的一个非常简单的示例如下:
HTML(file.php):
<tag><?php echo $variable; ?></tag>
PHP:
$variable = "value";
ob_start();
include "file.php";
$results = ob_get_clean();
这样可以很好地达到正确的结果,但每次我必须复制并粘贴这三行以将变量注入我的HTML文件时,它会让我很烦。我可能希望在以后更改此注入功能的详细信息,并且它目前分散在我的代码中的几百个位置。
在一个完美的世界中,我会将这三行移动到一个单独的函数中,该函数将文件路径作为输入,并返回&#34;编译的&#34;结果。但是,该函数将不再具有对调用范围的访问权限,并且我必须将变量作为另一个输入传递。我唯一能想到的就是:
function injectVariables($filePath, array $variables)
{
//Built-in PHP function, extracts array key => value pairs into variable $key = value pairs in the current scope
extract($variables);
ob_start();
include $filePath;
return ob_get_clean();
}
这肯定会完成工作,如果没有更好的解决方案,那将是我实施的,但对我来说似乎不太理想。它涉及每次运行时创建一个数组,只是为了遍历它并提取所有变量,这对我来说感觉有点不对。
有没有人知道其他可能有效的方法吗?
答案 0 :(得分:1)
不确定你在问什么,但这是我的回答
我不知道您的代码的结构,但我希望您使用MVC方法(或者至少是处理类的方法),以便您可以执行以下操作:
在主控制器中,您创建一个类变量,如viewData
,它将是一个数组。你把所有你想要的东西都放进去了
$this->viewData['username'] = $username;
$this->viewData['myArray'] = array('foo' => 'bar');
$this->viewData['menuSubview'] = 'path_to_menu_subview.php';
然后,您创建一个渲染函数。
public function render()
{
extract($this->viewData);
ob_start();
include("myfile.php");
return ob_get_clean();
}
在myfile.php(使用HTML)中,您可以简单地执行到目前为止使用的内容
<div id="menu"><?php include($menuSubview);?></div>
<p><?=$username;?></p>
<p><?=$myArray['foo'];?></p>
整个代码可以是这样的。
class Something {
protected $viewData;
protected $viewFile;
public function logic()
{
$this->userProfile();
echo $this->render();
}
public function userProfile()
{
$this->viewData['username'] = 'John The Ripper';
$this->viewFile = 'myFile.php';
}
public function render()
{
extract($this->viewData);
ob_start();
include($this->viewFile);
return ob_get_clean();
}
}
答案 1 :(得分:1)
这是一个简化的类,它存储数据并允许递归呈现所有可以从初始实例访问保存数据的文件。
class View {
// view data
protected $_data = [];
/**
* Set view data
*/
public function __set( $key, $value )
{
$this->_data[ $key ] = $value;
}
/**
* Get view data
*/
public function __get( $key )
{
if( array_key_exists( $key, $this->_data ) )
{
return $this->_data[ $key ];
}
return null;
}
/**
* Render view file
*/
public function render( $file )
{
if( is_file( $file ) )
{
$view = $this;
ob_start();
include( $file );
return ob_get_clean();
}
return 'File not found: '.$file;
}
}
只需在包含的文件中使用变量$ view来访问类中的数据,或者使用render()另一个可以执行相同操作的部分文件,依此类推。
// Bootstrap a View instance and add some data
$view = new View;
$view->dataOne = 'valueOne';
$view->dataTwo = 'valueTwo';
// Render main template
echo $view->render( 'template.php' );
在template.php里面
<header>
<?= $view->render( 'header.php' ) ?>
</header>
<h1><?= $view->dataOne ?></h1>
<p><?= $view->dataTwo ?></p>
答案 2 :(得分:1)
您的injectVariables()
功能没有任何问题,实际上这是一个好主意。
您的观点(HTML)不应该了解您的应用程序的内部。 (你分担责任 - 这是一个很重要的主题,我不会深入谈论)
你知道,如果某些内容最终变成了$变量,那么它已被构建/格式化,或者显示为$filePath
是很有意义的。
在复杂的系统中,你最终可能会得到一个带有pdf生成器的变量,HTML为什么会这样? HTML的唯一目的是显示HTML数据。
你的逻辑中的一些变量几乎每次都会在$变量中结束,例如会话信息(当前记录的是谁),对于你的情况,这是正常的。
在完美的世界中,如果你把一个类放入$ variables中,它应该只是为了HTML的目的而设计,即使它与你的逻辑几乎是同一个对象。
作为一个例子,我在我的逻辑中设计了一个Session类。它确实有Logout()
和EnsureIsAlive()
等方法以及FullName
等字段。 FullName
将由我的HTML使用,因为我想在页面的标题中显示它
我应该有一个只包含FullName
字段的HTML的Session类,因为HTML只有一个作业,它是显示数据的。 Login()
和EnsureIsAlive()
特定于逻辑,并且与显示数据完全无关。
在reallity中,时间总是一个约束,因为你是从头开始编写所有的,你可能最终只需将逻辑Session类发送到$ variables。
设计说明:我是C#程序员,我们总是使用类数组来传递参数作为一个好的实践,它确实影响了如何传递{{1你的HTML。在您的情况下,您可以创建一个简单的数组,而不是创建专用于HTML的类:
FullName
这样,您仍然可以避免HTML访问特定于您的逻辑的无关方法。我不确定它在php中是否是一个很好的实践...
保持上下文变量清洁
如果您多次调用injectVariables()(对于不同的$variables['Session'] = array('FullName' => $mySession->fullName).
),您可能不需要相同的变量。
一个$PathFile
可以用于小部件,另一个用于完整的完整页面
为什么TimeWidget需要您的injectionVariables()
变量?
您还可以同时准备多个$变量,因为每个totalInvoice
都有自己的参数。
我不是最新的,但我知道phpBB模板系统使用(回到2000附近)与injectVariables()
完全相同的模式。
您写道,您的每个网页都会调用injectVariables()
,您也可以(但可能很复杂)仅在一个文件中执行此操作 - 例如php frameworks。
框架将HTTP请求处理到一个特定文件中
(例如。http://yoursite.com/hello/world或http://yoursite.com/login会调用(internaly)http://yoursite.com/index.php?page=hello&subpage=world和http://yoursite.com?page=login)。
然后这个页面(我的例子中的index.php)将根据他的GET参数(injectVariables()
和$_GET['page']
)包含一个特定的文件(控制器)。
控制器作业将获取数据,应用逻辑然后填充$变量
然后index.php将使用相关的HTML调用injectVariables()。