将PHP变量注入HTML代码
以前可能有人问过这个问题,但我在一些初步搜索中找不到问题的答案,所以这里是: 我当前将PHP变量注入HTML的方法的一个非常简单的示例如下: HTML(file.php): 这很好地实现了正确的结果,但每次我必须复制并粘贴这三行以将变量注入HTML文件时,我都会感到恼火。我可能希望在以后更改此注入功能的详细信息,而它目前分散在我代码中的几百个位置 在理想情况下,我会将这三行移到一个单独的函数中,该函数将文件路径作为输入,并返回“编译”结果。但是,该函数将不再具有对调用范围的访问权限,我必须将变量作为另一个输入传入。我唯一能想到的就是:将PHP变量注入HTML代码,php,Php,以前可能有人问过这个问题,但我在一些初步搜索中找不到问题的答案,所以这里是: 我当前将PHP变量注入HTML的方法的一个非常简单的示例如下: HTML(file.php): 这很好地实现了正确的结果,但每次我必须复制并粘贴这三行以将变量注入HTML文件时,我都会感到恼火。我可能希望在以后更改此注入功能的详细信息,而它目前分散在我代码中的几百个位置 在理想情况下,我会将这三行移到一个单独的函数中,该函数将文件路径作为输入,并返回“编译”结果。但是,该函数将不再具有对调用范围的访问权限,我必须将变量
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();
}
这当然可以完成工作,如果没有更好的解决方案,我也会实施,但对我来说似乎不太理想。它包括每次运行时创建一个数组,只是在其中循环并提取所有变量,我觉得这有点不对
有人知道其他可能有效的方法吗?不太清楚你在问什么,但这是我的答案
我不知道代码的结构,但我希望您使用的是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 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' );
Inside template.php
<header>
<?= $view->render( 'header.php' ) ?>
</header>
<h1><?= $view->dataOne ?></h1>
<p><?= $view->dataTwo ?></p>
您的injectVariables()
函数没有问题,实际上这是个好主意
- 无论如何,您不应该对性能产生影响(如果这是您的主要问题,那么您正在进行过早的优化!)
- 您的视图(HTML)不应该知道应用程序的内部。(你分担责任——这是一个巨大的话题,我不会深入谈论)
您知道,如果某个内容最终变成$variables,那么它已经被构建/格式化,或者与显示
$filePath
在复杂的系统中,您可能会得到一个带有pdf生成器的变量,为什么HTML会需要它呢?HTML的唯一用途是显示HTML数据 您的逻辑中的一些变量几乎每次都以$variables结尾,例如会话信息(当前记录的用户),对于您的情况,这是正常的 在理想情况下,如果您将一个类放入$variables中,那么它应该仅为HTML的目的而设计,即使它与您的逻辑几乎是同一个对象。
作为一个例子,我在我的逻辑中设计了一个会话类。它确实有方法,如
和Logout()
以及字段,如EnsureIsAlive()
<代码>全名将被我的HTML使用,因为我想在我的页面标题中显示它。FullName
我应该有一个HTML会话类,它只包含一个
字段,因为HTML只有一个作业,用于显示数据FullName
和Login()
是特定于逻辑的,与显示数据完全无关。 在现实中,时间总是一个约束条件,因为您是从头开始自己编写的,所以最终可能只将逻辑会话类发送到$variables中EnsureIsAlive()
- 设计说明:我是一名C#程序员,我们总是使用数组上的类来传递参数,这是一个很好的实践,它确实影响了有关如何将
传递到HTML的示例。在您的情况下,您可以创建一个简单的数组,而不是创建一个专门用于HTML的类:全名
$variables['Session'] = array('FullName' => $mySession->fullName).
- 设计说明:我是一名C#程序员,我们总是使用数组上的类来传递参数,这是一个很好的实践,它确实影响了有关如何将
- 保持上下文变量干净
如果多次调用injectVariables()(对于不同的
),则可能不需要相同的变量。$PathFile
一个
可以用于小部件,另一个用于完整页面。injectionVariables()
为什么TimeWidget需要您的
变量 您还可以同时准备多个$variables,因为每个totalInvoice
都有自己的参数injectVariables()
injectVariables()
)完全相同
您写道,您的每个页面都会调用injectVariables()
,您也可以(但可能很复杂)只在一个类似文件的文件中进行调用
框架将HTTP请求处理到一个特定文件中(例如,或会打电话给(内部)和)。
然后,这个页面(在我的示例中是index.php)将根据他的GET参数包括一个特定的文件(控制器)(
$\u GET['page']
和$\u GET['subpage']
)。控制器的任务是获取数据,应用逻辑,然后填充$variables。
然后index.php将使用相关的HTML调用injectVariables()。如果没有ob_start(),它似乎可以正常工作;如果省略它,您会看到什么?如果您直接回显您的
ob\u get\u clean
调用(或者,等效地回显results变量),您将得到相同的结果。有或没有鳕鱼
// 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' );
<header>
<?= $view->render( 'header.php' ) ?>
</header>
<h1><?= $view->dataOne ?></h1>
<p><?= $view->dataTwo ?></p>
$variables['Session'] = array('FullName' => $mySession->fullName).