PHP静态变量和旧数据

时间:2018-08-16 10:39:12

标签: php static static-methods

我正在研究一个由其他开发人员启动的项目。该项目有一个帮助程序类,它将接受输入并从一些异地注册表中获取数据。

该类很简单,它唯一要做的就是获取数据。 我的老板要求我使用此帮助程序类来创建另一个界面。

所以我做到了。我得到了该类,围绕它建立了我的界面并处理了结果。只要我给出单个输入,例如“用户”,一切都可以。当我通过循环放置辅助函数时,一切都会皱缩。

我必须通知您,帮助器类中的函数是静态函数,该函数具有某些注册表的循环。每个注册表的返回值都通过注册表函数写入通用静态变量。调用每个注册表后,静态变量将返回到接口。

结果是,在循环的某些迭代中,我得到了错误的数据,更具体地说,我得到了先前用户的数据。

如果每次迭代我都将静态变量预设为“ []”,则一切正常。

例如:

class Helper {
    private static $results = [];

    public static askRegistries ($userId) {
        $registries = ['registry1','registry2','registry3'];

        foreach($registries as $registry) {
            self::callRegistry($userId, $registry);
        }

        return self::$results;
    }

    private static callRegistry($userId, $registry) {
        self::$results[] = getData($userId)
    }
}

在上面的示例中,我试图向您解释如何将数据设置为静态变量并返回给接口。

问题#1

  

此静态函数的每次调用是否正常?   保留旧数据?

问题2

  

如果正常,你能向我解释为什么吗?

问题3

  

再次正常,解决此问题的正确方法是什么   无需对代码进行任何重大更改,因为这是被禁止的   我的老板?

编辑#1

问题#4 如果我将对静态方法 callRegistry 的调用更改为附加到static变量的注册表类,还有什么我需要记住的吗?

例如

class Helper {
    public static $results = [];

    public static askRegistries ($userId) {
        $registries = ['Registry1','Registry2','Registry3'];

        foreach($registries as $registry) {
            $registryClass = new {$registry}();
            $registryClass->query($userId);
        }

        return self::$results;
    }
}

class Registry1{   
    public query($userId) {
        Helper::results = doSomething();
    }
}

在此示例中,静态变量是公共变量。

2 个答案:

答案 0 :(得分:1)

首先,静态函数和静态变量属于Class而不是Class对象。

以上语句得出的结论是,静态变量和方法始终应直接从类中调用,例如MyClass :: function()和MyClass :: $ var

类中的静态变量从不打算处理状态。因此,您绝不能为类更改静态变量。改用常量。

如果要将数据存储在变量中,只需在类中定义一个普通(私有,受保护或公共)变量,然后通过类的对象对其进行更新。

如果您在循环中调用callRegistry(),则将您的帮助程序::: $ results重置为空数组的明智做法是,您在循环中传递的每个用户都将添加到Helper :: $ results。这反过来会影响您的RAM,因为所有这些数据都作为状态存储,直到脚本结束。 https://alanstorm.com/php-meminfo-and-memory-leaks/

我认为这应该可以解决您的问题

class Helper {
    private $results = [];

    public static askRegistries ($userId) {
        $registries = ['registry1','registry2','registry3'];

        foreach($registries as $registry) {
            self::callRegistry($userId, $registry);
        }

        return self::$results;
    }

    private callRegistry($userId, $registry) {
        $this->results[] = getData($userId)
    }
}

$helper = new Helper();

foreach($userIds as $userId){
    $helper->callRegistry($userId, $registry);
}

答案 1 :(得分:1)

  

每次调用此静态函数使用静态变量来保留旧数据是否正常?

  

如果正常,你能向我解释为什么吗?

这是正常的。静态变量存储在类中,而不存储在类的特定实例中。使用1个实例更新静态变量将对所有实例进行更新。

由于此帮助程序类与静态变量的唯一交互是追加到它的后面,因此每次使用它时,它都会构建并构建和构建此静态变量。

  

还是正常情况,如老板所禁止的那样,在不做任何重大更改的情况下解决此问题的正确方法是什么?

我个人会将private属性和方法的范围更改为protected

我将callRegistry的行为更改为:

  1. 将响应从getData($ userId)分配给本地变量
  2. 将此本地变量附加到self::$results
  3. 返回局部变量

然后,我将编写一个类来扩展Helper,并使用一个函数来覆盖askRegistries的行为以返回本地数组。像这样:

// Give the class a real name of course
class ExtendedHelper extends Helper {

    public static function askRegistries ($userId) {
        $output = array();
        $registries = ['registry1','registry2','registry3'];

        foreach($registries as $registry) {
            $output[] = self::callRegistry($userId, $registry);
        }

        return $output;
    }

}

您可能还希望将$registries作为静态变量存储在父类中,因此您不必在子类中重新定义它。