我正在研究一个由其他开发人员启动的项目。该项目有一个帮助程序类,它将接受输入并从一些异地注册表中获取数据。
该类很简单,它唯一要做的就是获取数据。 我的老板要求我使用此帮助程序类来创建另一个界面。
所以我做到了。我得到了该类,围绕它建立了我的界面并处理了结果。只要我给出单个输入,例如“用户”,一切都可以。当我通过循环放置辅助函数时,一切都会皱缩。
我必须通知您,帮助器类中的函数是静态函数,该函数具有某些注册表的循环。每个注册表的返回值都通过注册表函数写入通用静态变量。调用每个注册表后,静态变量将返回到接口。
结果是,在循环的某些迭代中,我得到了错误的数据,更具体地说,我得到了先前用户的数据。
如果每次迭代我都将静态变量预设为“ []”,则一切正常。
例如:
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();
}
}
在此示例中,静态变量是公共变量。
答案 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
的行为更改为:
self::$results
然后,我将编写一个类来扩展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
作为静态变量存储在父类中,因此您不必在子类中重新定义它。