将PHP变量注入HTML代码

将PHP变量注入HTML代码,php,Php,以前可能有人问过这个问题,但我在一些初步搜索中找不到问题的答案,所以这里是: 我当前将PHP变量注入HTML的方法的一个非常简单的示例如下: HTML(file.php): 这很好地实现了正确的结果,但每次我必须复制并粘贴这三行以将变量注入HTML文件时,我都会感到恼火。我可能希望在以后更改此注入功能的详细信息,而它目前分散在我代码中的几百个位置 在理想情况下,我会将这三行移到一个单独的函数中,该函数将文件路径作为输入,并返回“编译”结果。但是,该函数将不再具有对调用范围的访问权限,我必须将变量

以前可能有人问过这个问题,但我在一些初步搜索中找不到问题的答案,所以这里是:

我当前将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()
    以及字段,如
    FullName
    <代码>全名将被我的HTML使用,因为我想在我的页面标题中显示它。
    我应该有一个HTML会话类,它只包含一个
    FullName
    字段,因为HTML只有一个作业,用于显示数据
    Login()
    EnsureIsAlive()
    是特定于逻辑的,与显示数据完全无关。 在现实中,时间总是一个约束条件,因为您是从头开始自己编写的,所以最终可能只将逻辑会话类发送到$variables中

    • 设计说明:我是一名C#程序员,我们总是使用数组上的类来传递参数,这是一个很好的实践,它确实影响了有关如何将
      全名
      传递到HTML的示例。在您的情况下,您可以创建一个简单的数组,而不是创建一个专门用于HTML的类:

      $variables['Session'] = array('FullName' => $mySession->fullName).
      
    这样,您仍然可以避免HTML访问特定于逻辑的不相关方法。我不确定这在php中是否是一个好的实践

  • 保持上下文变量干净
    如果多次调用injectVariables()(对于不同的
    $PathFile
    ),则可能不需要相同的变量。
    一个
    injectionVariables()
    可以用于小部件,另一个用于完整页面。
    为什么TimeWidget需要您的
    totalInvoice
    变量

    您还可以同时准备多个$variables,因为每个
    injectVariables()
    都有自己的参数

我不是最新的,但我知道phpBB模板系统使用的模式(早在2000年左右)与您的
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).