简体   繁体   English

在私有类方法中定义的php闭包中的静态变量

[英]static variable in php closure defined within a private class method

So I re-wrote this to hopefully be clearer about what I'm attempting. 因此,我重新撰写了这篇文章,希望可以更清楚地了解我的尝试。 During some parsing of data someValue(s) associated with someCode(s) are received. 在数据的某些解析期间,接收到与someCode相关联的someValue。 The intent is to capture a particularValue of a someCode having the lowest precedence, irrespective of the order the someCode/someValue (s) received. 目的是捕获具有最低优先级的someCode的specificValue,而与someCode / someValue的接收顺序无关。 The issue keeping this from working is that the closure is created every time the private function is called and the value of $precedenceOfCodeCaptured therefore is always reset to null. 使其无法正常工作的问题是,每次调用私有函数时都会创建闭包,因此$ precedenceOfCodeCaptured的值始终会重置为null。 If I could keep the closure around then things might work as intended. 如果我可以保持关闭状态,那么事情可能会按预期进行。

private function Foo($particularValue, $someValue, $someCode) {

    switch ($someCode) {
        case:
            CODE1:
        case:
            CODE2:

            $c = function () use ($someCode, $someValue) {
                static $precedenceOfCodeCaptured = null;
                $precedenceArray = array(
                    CODE2 => 1,
                    CODE1 => 2
                );

                if ((is_null($someValue))) {//first time the case statement matched because $someValue==null
                    $precedenceOfCodeCaptured = $precedenceArray[$someCode];
                    $particularValue = someValue;
                } else if ($precedenceArray[$someCode] <= $precedenceOfCodeCaptured) {
                    $particularValue = someValue;
                }

            };

            $c();
            break;
            ...
    }

}//end of private method

Every time Foo is called, you create a new function/closure, since you evaluate a function(), and that's what evaluating function() does! 每次调用Foo时,由于要评估function(),因此您将创建一个新的函数/闭包,这就是评估function()的作用!

If you'd like to have Foo() return the same function/closure each time, only evaluate it once. 如果您希望Foo()每次都返回相同的函数/闭包,则只需对其进行一次评估。 Perhaps use a singleton pattern, where you'll check if some higher-scoped variable that holds the function has been initialized, and initialize it if not. 也许使用单例模式,您将在其中检查一些包含该函数的更高范围的变量是否已初始化,如果尚未初始化,则将其初始化。

For example: 例如:

$c = null;

private function Foo(){

  if ($c == null) {
  $c = function() use ( $whatever){  
               static $x = 0;
               echo "x= $x";
               $x++; 
  ...
  };
}   

$c(); $ C(); }//end of private method } //私有方法的结尾

(but please don't use globals in your actual code!) (但请不要在您的实际代码中使用全局变量!)

Try this: 尝试这个:

static $x = 0;
private function Foo() {
  $c = function() use ( $whatever){  
    echo "x= $x";
    self::$x++;
   ...
  };
  $c();
}
<?php

class example{
    private function foo(){
        static $_closure;
        if( ! $_closure ){
            $_closure = function(){
                static $_state;
                /*  . . .  */
            };
        }
        $_closure();
    }
}

Note that the closure is static (it is created on first use, and not again), as is the variable that holds state inside the closure. 请注意,闭包是静态的(它是在第一次使用时创建的,而不是再次创建的),而保持闭包内部状态的变量也是如此。

However, as stated in other answers, this is "pointless" at best. 但是,正如其他答案所述,这充其量是“毫无意义的”。 $_closure should be another class method; $_closure 应该是另一个类方法; $_state should be a class property (there is no need for static anything in the closure, in foo() , nor in the class). $_state 应该是一个类属性(在闭包, foo()或类中都不需要静态任何东西)。 It is not "cleaner" or more readable or performant (in fact, the opposite is likely true) to use a closure like this. 像这样使用闭包并不是“更干净”或更具可读性或性能(实际上,可能相反)。

It might make sense if you were doing something like: 如果您正在执行以下操作,这可能是有道理的:

  • returning the closure for use elsewhere 将封盖退回其他地方使用
  • dynamically creating the function at runtime (ie, based on foo() args) 在运行时动态创建函数(即基于foo()args)
  • something else dynamic and interesting 其他有趣而有趣的东西

…but as it stands, this is simply the wrong approach. …但就目前情况而言,这只是错误的方法。 The tools to do this already exist. 执行此操作的工具已经存在。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM