doujiao7483 2014-05-25 01:44 采纳率: 0%
浏览 47
已采纳

包装后的未定义变量包含在PHP中

I'm using PHP for web development. I'm using the following function to wrap the include of a view:

<?php
function render($templateFile) {
    $templateDir = 'views/';
    if (file_exists($templateDir . $templateFile)) {
        include $templateDir . $templateFile;
    } else {
        throw new Exception("Template '{$templateFile}' couldn't be found " .
           "in '{$templateDir}'");
    }
}
?>

Although this seems right to me, there is a really unexpected behavior: when I define a variable to something (e.g. an array) and use render for including a view that uses that variable, I get an undefined variable error. But when I explicitely use include there is no error at all and things are just fine.

This is the script that calls render:

<?php
include 'lib/render.php'; // Includes the function above.

$names = array('Trevor', 'Michael', 'Franklin');

render('names.html'); // Error, but "include 'views/names.html'" works fine.
?>

And this is the file that uses the $names variable:

<html>
  <head>
    <title>Names</title>
  </head>
  <body>
    <ol>
    <?php foreach ($names as $name): ?>
      <li><?php echo $name; ?></li>
    <?php endforeach; ?>
    </ol>
  </body>
</html>

Help will be very much appreciated.

  • 写回答

2条回答 默认 最新

  • duanjianao0592 2014-05-25 01:54
    关注

    This is from the PHP documentation on the include function (c.f. http://us1.php.net/manual/en/function.include.php):

    When a file is included, the code it contains inherits the variable scope of the line on which the include occurs. Any variables available at that line in the calling file will be available within the called file, from that point forward. However, all functions and classes defined in the included file have the global scope.

    And also:

    If the include occurs inside a function within the calling file, then all of the code contained in the called file will behave as though it had been defined inside that function. So, it will follow the variable scope of that function.

    So, if your render function can't access $names, then neither can your included file.

    A possible solution would be to pass the parameters you want to be able to access in your view template, to your render function. So, something like this:

    function render($templateFile, $params=array()) {
        $templateDir = 'views/';
        if (file_exists($templateDir . $templateFile)) {
            include $templateDir . $templateFile;
        } else {
            throw new Exception("Template '{$templateFile}' couldn't be found " .
               "in '{$templateDir}'");
        }
    }
    

    Then, pass them like this:

    $names = array('Trevor', 'Michael', 'Franklin');
    
    render('names.html', array("names" => $names));
    

    And use them in your view template like this:

    <html>
      <head>
        <title>Names</title>
      </head>
      <body>
        <ol>
        <?php foreach ($params['names'] as $name): ?>
          <li><?php echo $name; ?></li>
        <?php endforeach; ?>
        </ol>
      </body>
    </html>
    

    There are probably better solutions to this, like putting your render function into a View class. Then you can call the View class function from inside your template file, and access parameters that way instead of just assuming there will be a $params variable in the view templates scope. But, this is the simplest solution.

    本回答被题主选为最佳回答 , 对您是否有帮助呢?
    评论
查看更多回答(1条)

报告相同问题?

悬赏问题

  • ¥15 求帮我调试一下freefem代码
  • ¥15 R语言Rstudio突然无法启动
  • ¥15 关于#matlab#的问题:提取2个图像的变量作为另外一个图像像元的移动量,计算新的位置创建新的图像并提取第二个图像的变量到新的图像
  • ¥15 改算法,照着压缩包里边,参考其他代码封装的格式 写到main函数里
  • ¥15 用windows做服务的同志有吗
  • ¥60 求一个简单的网页(标签-安全|关键词-上传)
  • ¥35 lstm时间序列共享单车预测,loss值优化,参数优化算法
  • ¥15 Python中的request,如何使用ssr节点,通过代理requests网页。本人在泰国,需要用大陆ip才能玩网页游戏,合法合规。
  • ¥100 为什么这个恒流源电路不能恒流?
  • ¥15 有偿求跨组件数据流路径图