给PHP包含()'d文件父变量范围

时间:2010-02-06 03:18:52

标签: php function include scope

是否有一个包含文件在父作用域中用于它所调用的文件?以下示例已简化,但执行相同的工作。

本质上,函数会包含一个文件,但是希望包含文件的范围是调用包含它的函数的范围。

main.php:

<?php
  if(!function_exists('myPlugin'))
  {
    function myPlugin($file)
      {
        if(file_exists($file)
        {
          require $file;
          return true;
        }
        return false;
      }
  }

  $myVar = 'something bar foo';

  $success = myPlugin('included.php');

  if($success)
  {
    echo $myResult;
  }

included.php:

<?php
  $myResult = strlen($myVar);

提前致谢,
亚历山大。

编辑:解决方案

嗯,有点,谢谢Chacha102的贡献 现在也可以从课堂内调用!

main.php

<?php
  class front_controller extends controller
  {
    public function index_page()
    {
      $myVar = 'hello!';

      // This is the bit that makes it work.
      // I know, wrapping it in an extract() is ugly,
      // and the amount of parameters that you can't change...
      extract(load_file('included.php', get_defined_vars(), $this));

      var_dump($myResult);
    }
    public function get_something()
    {
      return 'foo bar';
    }
  }

  function load_file($_file, $vars = array(), &$c = null)
  {
    if(!file_exists($_file))
    {
      return false;
    }
    if(is_array($vars))
    {
      unset($vars['c'], $vars['_file']);
      extract($vars);
    }
    require $_file;
    return get_defined_vars();
  }

included.php:

<?php
  $myResult = array(
    $myVar,
    $c->get_something()
  );

如果你想引用一个方法,它必须是公共的,但结果是预期的:

array(2) {
  [0]=>
  string(6) "hello!"
  [1]=>
  string(7) "foo bar"
}

现在,这没有任何实际用途,我想知道如何做到的唯一原因是因为我很固执。这个想法进入了我的脑海,不会让它打败我:D

<rant>
感谢所有贡献者。除了嘘我的人。这是一个简单的问题,现在已经发现存在(复杂的)解决方案 搞砸它是否“符合PHP的做事方式”。曾告诉客户“哦不,我们不应该这样做,这不是正确的做事方式!”?没想到。
</rant>

再次感谢Chacha102:)

2 个答案:

答案 0 :(得分:4)

function include_use_scope($file, $defined_variables)
{
    extract($defined_variables);
    include($file);
}

include_use_scope("file.php", get_defined_vars());

get_defined_vars()获取在调用它的范围内定义的所有变量。extract()接受一个数组并将它们定义为局部变量。

extract(array("test"=>"hello"));
echo $test; // hello

$vars = get_defined_vars();
echo $vars['test']; //hello

因此,实现了期望的结果。你可能想要从变量中删除超全局和东西,因为覆盖它们可能是坏事。

查看此comment以删除不良内容。

为了反过来,你可以这样做:

function include_use_scope($file, $defined_variables)
{
    extract($defined_variables);
    return include($file);
}

extract(include_use_scope("file.php", get_defined_vars()));

include.php

// do stuff
return get_defined_vars();

但总而言之,我认为你不会得到预期的效果,因为这不是PHP的构建方式。

答案 1 :(得分:-1)

我知道如何使用超全球数组的唯一方法。

main.php:       

  $GLOBALS['myVar'] = 'something bar foo';

  $success = myPlugin('included.php');

  if($success)
  {
    echo $GLOBALS['myResult'];
  }

included.php:

<?php
  $GLOBALS['myResult'] = strlen($GLOBALS['myVar']);