【问题标题】:PHP function use variable from outsidePHP函数使用外部变量
【发布时间】:2012-06-18 16:09:55
【问题描述】:
function parts($part) { 
    $structure = 'http://' . $site_url . 'content/'; 
    echo($tructure . $part . '.php'); 
}

此函数使用在此页面顶部定义的变量$site_url,但此变量未传递给函数。

我们如何让它在函数中返回?

【问题讨论】:

    标签: php function variables


    【解决方案1】:

    添加第二个参数

    你需要向你的函数传递额外的参数:

    function parts($site_url, $part) { 
        $structure = 'http://' . $site_url . 'content/'; 
        echo $structure . $part . '.php'; 
    }
    

    如果关闭

    如果您更愿意使用闭包,那么您可以将变量导入当前范围(use 关键字):

    $parts = function($part) use ($site_url) { 
        $structure = 'http://' . $site_url . 'content/'; 
        echo $structure . $part . '.php'; 
    };
    

    global - 不好的做法

    这篇文章经常被阅读,所以需要澄清一下global。使用它被认为是一种不好的做法(请参阅 thisthis)。

    为了完整起见,这里是使用global的解决方案:

    function parts($part) { 
        global $site_url;
        $structure = 'http://' . $site_url . 'content/'; 
        echo($structure . $part . '.php'); 
    }
    

    之所以有效,是因为您必须告诉解释器您要使用全局变量,现在它认为这是一个局部变量(在您的函数中)。

    推荐阅读:

    【讨论】:

    • 添加第二个或更多参数并不总是最实用的。它只是增加了我们每次调用函数时必须传递的参数数量,在我的情况下,我正在构建一个适用于字符串并在整个页面中重复多次的函数,很难做到这一点,
    • 另外添加第二个参数可能并不总是可行的,例如使用 array_filter() 或您无法影响调用者的类似情况。
    【解决方案2】:

    或者,您可以使用带有 use 关键字的闭包从外部范围引入变量。

    $myVar = "foo";
    $myFunction = function($arg1, $arg2) use ($myVar)
    {
     return $arg1 . $myVar . $arg2;
    };
    

    【讨论】:

    • 这种方式有点难,例如如果你有 10 个变量,这种方式会很难。
    • php 显示错误,为什么?解析错误:语法错误,意外“使用”(T_USE),期待“{”
    • @Kermani 您可能使用的是旧版本的 PHP,它没有 use 语法。这种语法是在 PHP5.3 中引入的。见wiki.php.net/rfc/closures
    • @JoeGreen,这个被称为能够使用在函数之外定义的变量的功能是什么。
    • @thiout_p 我认为现在回答为时已晚。但也许其他人正在寻找答案:闭包在变量中定义并且没有名称 $myFunction = function myFunction() 这是错误的语法。并且无法使用词法变量。正确的语法是 $myFunction = function() 然后允许词法变量。调用闭包 $myFunction()
    【解决方案3】:

    不要忘记,您也可以通过引用传递这些use 变量。

    用例是当您需要从回调内部更改 use'd 变量时(例如,从某些源对象数组生成不同对象的新数组)。

    $sourcearray = [ (object) ['a' => 1], (object) ['a' => 2]];
    $newarray = [];
    array_walk($sourcearray, function ($item) use (&$newarray) {
        $newarray[] = (object) ['times2' => $item->a * 2];
    });
    var_dump($newarray);
    

    现在$newarray 将包含(为简洁起见,此处为伪代码) [{times2:2},{times2:4}]

    相反,使用不带& 修饰符的$newarray 会使外部$newarray 变量在闭包范围内只读访问。但是闭包范围内的$newarray 将是一个完全不同的新创建的变量,仅存在于闭包范围内。

    尽管两个变量的名称相同,但它们将是两个不同的变量。在这种情况下,外部$newarray 变量将在代码完成后包含[]

    【讨论】:

    • 此方法解决了我的(不同的)问题,即从外部范围更新正在使用的变量不会反映在函数中。通过引用引用它可以让我从外部范围获取该时间点的值。
    【解决方案4】:

    我想这取决于您的架构以及您可能需要考虑的其他任何因素,但您也可以采用面向对象的方法并使用class

    class ClassName {
    
        private $site_url;
    
        function __construct( $url ) {
            $this->site_url = $url;
        }
    
        public function parts( string $part ) {
            echo 'http://' . $this->site_url . 'content/' . $part . '.php';
        }
    
        # You could build a bunch of other things here
        # too and still have access to $this->site_url.
    }
    

    然后你可以在任何你喜欢的地方创建和使用对象。

    $obj = new ClassName($site_url);
    $obj->parts('part_argument');
    

    对于 OP 想要实现的目标来说,这可能有点矫枉过正,但至少我想为新手提供一个选项,因为还没有人提到它。

    这里的优势是可扩展性和包容性。例如,如果您发现自己需要将相同的变量作为对多个函数的引用来传递一个共同的任务,这可能表明一个类是有序的。

    【讨论】:

      【解决方案5】:

      我有类似的问题。答:使用全局。还有其他选择。 但是,如果您需要使用外部范围的命名函数,这里我有:

      global $myNamedFunctionWidelyAccessibleCallableWithScope;
      $myNamedFunctionWidelyAccessibleCallableWithScope =
          function ($argument) use ($part, $orWhatYouWant) {
              echo($argument . $part . '.php');
              // do something here
              return $orWhatYouWant;
          };
      function myNamedFunctionWidelyAccessible(string $argument)
      {
          global $myNamedFunctionWidelyAccessibleCallableWithScope;
          return $myNamedFunctionWidelyAccessibleCallableWithScope($argument);
      }
      

      这对于使函数 myNamedFunctionWidelyAccessible 可从任何地方访问很有用,但也将它与范围绑定。而且我故意给了很长的名字,全球的东西都是邪恶的:(

      这里是documentation with a good example

      【讨论】:

        【解决方案6】:

        只需使用 GLOBAL 关键字输入函数即可:

         global $site_url;
        

        【讨论】:

        • 我不推荐,这是不好的做法。
        猜你喜欢
        • 2014-03-01
        • 1970-01-01
        • 2012-07-14
        • 1970-01-01
        • 1970-01-01
        • 2022-08-19
        • 2012-08-27
        • 1970-01-01
        • 2013-11-10
        相关资源
        最近更新 更多