php:类延迟加载?
我这里有个问题,这几天我一直在想。 在php应用程序中,要对对象执行某些操作,您需要:php:类延迟加载?,php,Php,我这里有个问题,这几天我一直在想。 在php应用程序中,要对对象执行某些操作,您需要: 定义它 使用它运行函数 像这样: (带自动加载和注册表对象) $registry->obj=newmathclass($var1,$var2)//例如,创建一个对象,其中$var1保存数据库对象的值,而$var2保存值1 $registry->obj->calculate('value')//获取产品行并返回其总值。 这样,在脚本中的任何时候,我都可以简单地运行预先定义的计算函数(或其他函数) 想象一下,一个
$obj->calculate('price');
不创建对象,例如
mathclass::calculate('price');
然后根据需要自动加载mathclass,而不会产生主要开销,这里的问题是,我不能再在开始时为mathclass提供任何变量
($var1,$var2).
我想要的是能够在不自动加载类的情况下伪创建对象,这样就不会增加开销,而是对象使用变量创建自己,但仅当我实际需要使用它时
我的意思是,php真的希望我在一开始就定义每个类,以便以后使用它们吗?
这是延迟加载吗?急装
我可能解释得很糟糕,所以请给我指出正确的方向
编辑2015:简单伪代码示例解决方案:
如果您使用自动加载功能,它将仅在实例化数学类时加载它,1个选项是在需要时实例化它,另一个选项是使用某种包装类,该类将包含并调用该类。在PHP中可以使用的是静态类。虽然这是你可能不考虑的高流量网站所做的事情。 这样声明一个类:
class Something
{
private static $var = "something";
public static function PrintVar()
{
echo self::$var;
}
}
现在,您可以包含该类并在任何地方执行代码,而无需初始化对象
像这样:
Something::PrintVar();
印刷品
something
祝你好运 类对象需要使用
new()
定义的部分原因是它们消耗内存。通常情况下,如果您还没有这样做,PHP将在脚本末尾执行内存清理,但通常在构造函数/析构函数面向对象的环境中,您希望unset()
该类对象以释放内存。由于这些原因,PHP的早期版本(在php4之前)存在内存泄漏问题
如果要避免整个初始化过程,您可能只想尝试一个简单的包含库,例如:
<?
if (!function_exists("calculate"))
{
function calculate($var1={default},$var2={default})
{
...routine...
}
}
?>
这样,您就不必为一个简单的例程定义一个完整的类了。它允许您从配置文件配置类,当您需要一个类时,只需通过service builder调用它。您可以使用延迟加载工厂,即
class Registry
{
private $registeredClasses;
private $loadedClasses;
private $objects;
public function RegisterClass($className, array $parameters)
{
// ... store class ...
}
private function Load($className)
{
// Load the class via some sort of autoloader
}
private function CreateInstance($className)
{
$parameters = $this->GetParametersFor($className);
$this->CreateNewInstanceWithParameters($className, $parameters);
}
public function GetObject($className)
{
if (!$this->IsAvailable($className))
{
$this->Load($className);
$this->CreateInstance($className);
}
return $this->GetInstanceOf($className);
}
}
在以后的代码中,您可以这样使用它:
$registry = new Registry();
$registry->RegisterClass("math", array("var1" => $var1, "var2" => $var2));
...
$registry->GetObject("math")->calculate($x1, $x2);
...
Ofc您需要添加我懒得添加的部分,即自动加载。您能给出一个更好的示例吗。您的
calculate()
只是添加了输入参数,因此它没有说明类中实际需要$var1
和$var2
的原因。好的,我编辑了它,很抱歉我的解释不准确,但通常我的问题是因为我不能正确定义问题。如何在加载其他类之前预定义该类加载其他类的方式?您必须专门为该类(或某个可扩展类)创建一个包装类。检查类是否实例化为成员变量,如果不需要,则需要一次_并实例化。注意这个解决方案对我来说是次优。同意,这也是我遇到的问题之一。这更像是一个注册,不是吗?它主要是两者的混合。我之所以称之为Registry,是因为这个问题似乎使用了注册表,而且(取决于实现和使用情况)注册表和ServiceLocator是非常相关的。只是觉得服务定位器模式将是一个更合适的类名,因为它“不仅仅”是一个注册表。这是最接近解决方案的,我仍然在思考我的问题,所以请容忍我。这基本上与Gordon的答案相同,但没有解释如何使用它。最后,我将使用的是A.加载主配置文件B.配置文件导入类开始选项C.我调用类并根据需要加载,可惜没有2个最佳答案按钮。优秀的阅读,你一直在哪里找到这些选项。但它怎么也解决不了我的问题!(我的解释可能要怪我)@Yuri你可以在网站上找到这些文章的大部分。很抱歉,我没有得到你剩下的评论。你是说,它帮助解决了问题还是没有?如果没有,你需要什么帮助?谢谢戈登的帮助,我真的很感激。这里更好地描述了我遇到的问题:问题是:如何延迟加载依赖类。@Yuri如果使用DI容器,则需要配置类的实例化方式。当您需要它们时,您只需告诉容器获取一个特定的类,然后容器就会为您实例化它。这是相当懒惰的加载。这与@dbemerlin的解决方案非常相似。对不起,Gordon,我真的很想了解依赖项注入如何帮助延迟加载,以及如何配置类的实例化方式,你能更详细地解释一下吗?谢谢你的运气,但是静态类不是我想要的,因为即使不打算使用它们,也必须事先加载它们。
$registry = new Registry();
$registry->RegisterClass("math", array("var1" => $var1, "var2" => $var2));
...
$registry->GetObject("math")->calculate($x1, $x2);
...