PHP函数内使用Include

11

我正在尝试创建一个函数,可以按以下方式调用:

view( 'archive', 'post.php' );

而函数真正做的事情是这样的。

include( 'view/archive/post.php' );
这样做的原因是,如果将来我将目录扩展为 view/archive/another_level/post.php,我不想回到代码中的所有位置并更改所有包含路径。
目前,这是我为自己的函数所拥有的,但似乎 include 是在函数内部调用的,并且没有在调用函数时调用...
function view( $view, $file )
    {
        switch ( $view )
        {
            case 'archive'  : $view = 'archive/temp';   break;
            case 'single'   : $view = 'single';     break;
        }

        include( TEMPLATEPATH . "/view/{$view}/{$file}" );
    }

如何使此函数正确地包含文件?

编辑:

没有显示任何错误。感谢@Ramesh提供的错误检查代码,ini_set('display_errors','On'),我能够看到包含文件中还有其他“未显示”的错误,这似乎导致该文件未显示出来...


4
没问题,这应该按预期工作...你遇到了什么具体的问题? - scibuff
我没有收到错误信息,只是什么也没有被打印出来... - cnotethegr8
1
你是否已经设置了错误显示?如果没有,请加入以下代码 ini_set('display_errors','On');,这样你就可以得到错误报告了。 - GoSmash
@Ramesh 谢谢你的代码,我以前不知道这个。这帮助我调试问题。 - cnotethegr8
5个回答

12

这个使用案例被明确地记录了:

如果include出现在调用文件内的函数中,则调用文件中包含的所有代码将表现为其已定义在该函数内。所以,它将遵循该函数的变量作用域。唯一的例外是魔术常量,它们会在include发生之前由解析器进行求值。

我的看法是,保持基本路径在常量中(您似乎已经在某种程度上这样做)甚至进行全站搜索和替换(在任何体面的编辑器中都可以完成30秒任务),比重写所有包含的文件来使用全局变量要简单得多。


10

以下是解决该问题的一种方法:

更改您调用函数的方式,使其看起来像这样:

include( view('archive','post') );

你的函数应该长成这样:

<?php
function view( $view, $file )
{
    switch ( $view )
    {
        case 'archive': $view = 'archive/temp'; break;
        case 'single' : $view = 'single';       break;
    }

    return TEMPLATEPATH . "/view/{$view}/{$file}";
}
?>

3

虽然您并没有明确说明您遇到的确切问题是什么,但我怀疑问题在于您的变量无法传递到您的包含文件中。解决此问题的一种相对可行的方法是在您的include语句之前添加以下代码:

extract($GLOBALS);

这将会把全局作用域中的所有变量导入到你的函数中。然而,这并不会使函数完全按照你的意愿执行。考虑下面的代码:

function some_func () {
  $x = 2;
  view('archive', 'post.php');
}

$x = 1;

some_func();

在这个包含文件中,$x的值将会是1,而不是您期望的2。这是因为$GLOBALS仅包含从全局范围内获取的数据,它不包含some_func()范围内的变量。在PHP中,没有机制可以访问“父级”范围内的变量。
简单来说,您想要使用的方法(将其封装在函数中)将不起作用。

2

我认为你应该了解变量作用域

http://php.net/manual/zh/language.variables.scope.php

变量的作用域是指其定义的上下文环境。

因此,如果你在函数内部包含一个文件,那么文件中的内容只能在该函数的上下文中使用。


1
function view( $view, $file )
{
    switch ( $view )
    {
        case 'archive'  : $view = 'archive/temp';   break;
        case 'single'   : $view = 'single';     break;
    }

    include( TEMPLATEPATH . "/view/".$view."/".$file );
}

这对我很有效。此外,您可以在case内部使用include,甚至更好的方法是每次构建整个要包含的URL。


它能运行,但如果你想要使用父文件的全局作用域,这不是一个解决方案。 但是@sean9999 的解决方案非常简单而且有用。 - Mephiztopheles

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接