【问题标题】:Replacing {{string}} within php file在 php 文件中替换 {{string}}
【发布时间】:2013-07-26 01:13:44
【问题描述】:

我在我的一个类方法中包含一个文件,并且该文件中有 html + php 代码。我在该代码中返回一个字符串。我明确写了{{newsletter}},然后在我的方法中我做了以下事情:

$contactStr = include 'templates/contact.php';
$contactStr = str_replace("{{newsletter}}",$newsletterStr,$contactStr);

但是,它不会替换字符串。我这样做的唯一原因是,当我尝试将变量传递给包含的文件时,它似乎无法识别它。

$newsletterStr = 'some value';
$contactStr = include 'templates/contact.php';

那么,如何实现字符串替换方法呢?

【问题讨论】:

标签: php variables replace


【解决方案1】:

不,不包括在内。 include 正在执行 php 代码。它的返回值是包含文件返回的值 - 或者如果没有返回:1.

你要的是file_get_contents():

// Here it is safe to use eval(), but it IS NOT a good practice.
$contactStr = file_get_contents('templates/contact.php');
eval(str_replace("{{newsletter}}", $newsletterStr, $contactStr));

【讨论】:

  • 使用eval 非常不安全,在某些安装中是不允许的。
  • 其实我只是reading the docsinclude 语句的默认返回值为1,如果包含失败则为false(我不确定为什么它不是布尔值true,但这就是文档所说的)。
  • @Gustav 它与在此上下文中包含文件一样安全。您没有根据用户输入进行操作。 (并且 eval 不能用 vanilla php 禁用,它需要一个额外的扩展......)
  • @Gustav 他正在使用 eval 来...评估他从外部加载的脚本。不涉及用户输入,脚本将与包含中的 eval'd 一样。这些用例是 eval 首先存在的原因。运行自己的代码没有什么不安全的。当人们告诉你 eval 不好时,这根本不是他们的意思。
  • @IMSoP 在他的示例中,它不是用户输入,而是来自文件的原始字符串……
【解决方案2】:

这是我用于模板的代码,应该可以解决问题

  if (preg_match_all("/{{(.*?)}}/", $template, $m)) {
      foreach ($m[1] as $i => $varname) {
        $template = str_replace($m[0][$i], sprintf('%s', $varname), $template);
      }
    }

【讨论】:

  • 你是说 sprintf('$%s', $$varname) 吗?
  • 其实看起来应该是 sprintf('%s', $$varname)
【解决方案3】:

您可以使用 PHP 作为模板引擎。不需要{{newsletter}} 构造。

假设你在模板文件中输出了一个变量$newsletter

// templates/contact.php

<?php echo $newsletter; ?>

要替换变量,请执行以下操作:

$newsletter = 'Your content to replace';

ob_start();        
include('templates/contact.php');
$contactStr = ob_get_clean();

echo $contactStr;

// $newsletter should be replaces by `Your content to replace`

通过这种方式,您可以构建自己的模板引擎。

class Template
{
    protected $_file;
    protected $_data = array();

    public function __construct($file = null)
    {
        $this->_file = $file;
    }

    public function set($key, $value)
    {
        $this->_data[$key] = $value;
        return $this;
    }

    public function render()
    {
        extract($this->_data);
        ob_start();
        include($this->_file);
        return ob_get_clean();
    }
}

// use it
$template = new Template('templates/contact.php');
$template->set('newsletter', 'Your content to replace');
echo $template->render();

最好的一点是:您可以立即在模板中使用条件语句和循环(完整的 PHP)。

使用它以获得更好的可读性:https://www.php.net/manual/en/control-structures.alternative-syntax.php

【讨论】:

  • 如果您想保护包含的文件免受变量污染($this),您可以将其包装在反弹封包中:call_user_func(Closure::bind(function () { include func_get_arg(0); }, null ), $path);
  • 也许我错了,但据我了解,这个例子你只是用相同的值覆盖了你之前声明的变量$newsletter。由于之后您仍然必须回显变量,因此该示例对我来说似乎无效,相当于$x = 'foo'; echo $x;
  • @LeonKramer 不,$newsletter 不会被覆盖。在模板文件中,它只是回显。它之所以有效,是因为模板外部和内部的 $newsletter 在同一范围内。 Variable scope
  • 好的,现在知道了。这堂小课很甜!
  • 这太美了,我想知道很久了!谢谢你。
【解决方案4】:

将 output_buffers 与 PHP 变量一起使用。它更加安全、兼容和可重复使用。

function template($file, $vars=array()) {
    if(file_exists($file)){
        // Make variables from the array easily accessible in the view
        extract($vars);
        // Start collecting output in a buffer
        ob_start();
        require($file);
        // Get the contents of the buffer
        $applied_template = ob_get_contents();
        // Flush the buffer
        ob_end_clean();
        return $applied_template;
    }
}

$final_newsletter = template('letter.php', array('newsletter'=>'The letter...'));

【讨论】:

    【解决方案5】:

    可能有点晚了,但我看起来像这样。

    问题是 include 不返回文件内容,更简单的解决方案是使用 file_get_contents 函数。

    $template = file_get_contents('test.html', FILE_USE_INCLUDE_PATH);
    
    $page = str_replace("{{nombre}}","Alvaro",$template);
    
    echo $page;
    

    【讨论】:

      【解决方案6】:

      基于@da-hype

      <?php
      $template = "hello {{name}} world! {{abc}}\n";
      $data = ['name' => 'php', 'abc' => 'asodhausdhasudh'];
      
      if (preg_match_all("/{{(.*?)}}/", $template, $m)) {
          foreach ($m[1] as $i => $varname) {
              $template = str_replace($m[0][$i], sprintf('%s', $data[$varname]), $template);
          }
      }
      
      
      echo $template;
      ?>
      

      【讨论】:

        猜你喜欢
        • 2011-04-04
        • 2012-10-26
        • 2014-06-01
        • 2013-10-09
        • 1970-01-01
        • 2023-03-28
        • 1970-01-01
        • 2017-08-01
        • 1970-01-01
        相关资源
        最近更新 更多