我有一个问题,这是我过去几天一直在考虑的问题。 在php应用程序中,您需要对对象执行某些操作:
想象一下,这个特定页面加载可能需要或可能不需要数百个类的Web应用程序,但只能在应用程序的开头定义。 理想的解决方案是我只需运行
$obj->calculate('price');
不创建对象,例如像
mathclass::calculate('price');
然后根据需要自动加载数学类而不需要主要开销,这里的问题是我不能再在开始时给mathclass任何变量
($var1,$var2).
我想要的是能够伪造对象而不需要对类发生任何自动加载,因为不添加开销,但是对象用变量创建自己,但只有当我实际需要做什么时才它
我的意思是php真的希望我在开始时定义每个类,以便以后可以使用它们吗? 这是懒人装吗?急切加载?
我可能会解释这个问题,所以请指出我正确的方向。
class Service {
private $cb, $instance;
public function __construct($cb){
$this->cb = $cb;
}
public function __invoke() {
if(!$this->instance){
$this->instance = call_user_func($this->cb);
}
return $this->instance;
}
}
// setup autoloading
set_include_path(__DIR__.'/vendor'. PATH_SEPARATOR .get_include_path()); // optional
spl_autoload_register(function($c){
include preg_replace('#\\\|_(?!.+\\\)#','/',$c).'.php';
});
// simple dependency injection
$service['db'] = new Service(function(){
return new Database('sqlite::filename.sqlite');
});
$service['config'] = function() use(&$service){
return new Config($service['db']());
};
$service['math'] = function() use(&$service){
return new Math($service['config']());
};
// usage
$service['math']()->calculate('price');
答案 0 :(得分:4)
使用Dependency Injection Framework。它允许您从配置文件配置类,当您需要类时,只需通过服务构建器调用它。
答案 1 :(得分:3)
您可以使用延迟加载工厂,即
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你需要添加我懒得添加的部分,即自动加载。
答案 2 :(得分:2)
如果使用自动加载功能,它只会在实例化时加载数学类,1选项是在需要时实例化它,另一种选择是使用某种包含并调用类的包装类。
答案 3 :(得分:0)
您可以使用的是PHP中的静态类。虽然您可能认为这不适用于高流量网站。
声明一个类似的类:
class Something
{
private static $var = "something";
public static function PrintVar()
{
echo self::$var;
}
}
现在,您可以包含此类并在任何您喜欢的位置执行代码,而无需初始化对象。
像这样:
Something::PrintVar();
打印
something
祝你好运!
答案 4 :(得分:0)
类对象需要使用new()
进行定义的部分原因是因为它们消耗内存。通常情况下,如果您没有这样做,PHP将在脚本结束时执行内存清理,但通常在构造函数/析构函数面向对象的环境中,您希望unset()
该类对象释放内存。早期版本的PHP(在php4之前)由于这些原因而出现内存泄漏问题。
如果你想避免整个初始化过程,你可能只想尝试一个简单的包含库,例如:
<?
if (!function_exists("calculate"))
{
function calculate($var1={default},$var2={default})
{
...routine...
}
}
?>
然后你不必处理为一个简单例程定义一个完整类的全部痛苦。