PHP 静态变量和旧数据



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

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

所以我做到了。我得到了这个类,围绕它构建了我的界面并处理了结果。只要我给出单个输入,例如"用户",一切都很好。当我将辅助函数通过循环时,一切都会崩溃。

我必须通知您,帮助程序类中的函数是一个静态函数,它对某些注册表有一个循环。每个注册表的返回都通过注册表函数写入泛型静态变量。调用每个注册表后,静态变量将返回到接口。

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

如果每次迭代我都将静态变量预设为"[]",则一切按预期工作。

例如:

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的调用更改为附加到静态变量的注册表类,还有什么我应该记住的吗?

例如

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();
}
}

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

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

上面的语句得出结论,静态变量和方法总是意味着直接从类调用,例如 MyClass::function(( 和 MyClass::$var

类中的静态变量从来不打算处理状态。因此,切勿更改类的静态变量。 请改用常量。

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

如果你在循环中调用callRegistry((,明智的做法是将Helper::$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 个实例更新静态变量将为所有实例更新它。

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

同样,如果这是正常的,那么在不对代码进行任何重大更改的情况下解决此问题的正确方法是什么,因为我的老板禁止这样做?

我个人会将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存储为父类中的静态变量,这样您就不会在子类中重新定义它。

最新更新