我正在制作一个MVC应用程序。我在我的装载程序类中创建了这个函数:
public function load_models($model)
{
if ($model) {
set_include_path($this->modelDirectoryPath);
spl_autoload_extensions('.php');
spl_autoload($model);
}
}
我正在使用我的控制器中的这个功能:
$this->load->load_models('news');
我想像这样访问这个模型类:
$this->load->news->get_article();
但除非我这样做,否则我不能:
$this->load->news = new news();
$this->load->news->get_article();
我想在不输入$this->load->news = new news();
的情况下访问它。我也想让它自动实例化。有人可以帮忙吗?
答案 0 :(得分:1)
使get_article()成为静态方法并按如下方式访问它:
$this->load->news::get_article();
如果不实例化至少一个类的实例,则无法访问非静态方法。即使使用反射,也无法实际调用和常规方法。
您可以在加载类中实现一种魔术方法,当您访问任何属性时,例如
$this->load->news->get_article();
它会检查'news'属性的名称是否也加载了一个类名,如果是,但它没有设置为该类的实例,请创建一个并将其分配给它。
这是神奇的方法:
public function __get(){ ... } ;
基本上,每次访问对象时都会调用这个魔术方法...每次访问对象的不可用属性(未声明或创建的属性)
答案 1 :(得分:1)
你似乎正在“引导”一些严重过时的CodeIgniter(如果你想了解细节,请访问PHP聊天室)。如果你想要高质量的代码,那就不是模仿的框架。
哦,你实现的模式实际上是MVP,而不是MVC ..有一个difference。
首先你应该制作自动加载器,这实际上是有效的。阅读spl_autoload_register()
..如何使用它,它实际上做了什么。如果您需要一些示例,除了注释中提供的示例之外,您还可以查找PSR-0的实现。它应该给你一些想法,如何在实践中使用它。
这一切基本上都会摆脱控制器中的$this->load->load_models('news');
行。
在MVC中,模型是一个层而不是一个对象/类。我不打算重复整个歌舞,我前段时间写了一篇answer ...这很长= /
你不应该在控制器中使用new
,但不是出于你想的相同原因。您应该避免new
,因为它会导致与类名紧密耦合。相反,您应该在构造函数中为Controller
实例提供Factory
。
$factory = new DomainFactory( new PDO(...), $cache );
$controller = new Foobar( $factory );
$controller->$command($request);
这可以在控制器方法中使用,如下所示:
public function __construct( $domain_factory )
{
$this->factory = $domain_factory
}
public function do_stuff( $request )
{
$id = $request->getQuery('id');
$articles = $this->factory->build('news')->get_article($id);
// thought i would split this line into two parts
}
哦......以及工厂会做什么,就是这样:
public function __construct( $pdo, $cache )
{
$this->pdo = $pdo;
$this->cache = $cache;
}
public function build( $name )
{
$instance = new $name;
$instance->assign_connection( $this->pdo );
$instance->assign_cache( $this->cache );
return $instance;
}
这应该会给你一些想法..
如果你想学习如何做好面向对象的代码,这里有一些你可能会发现有用的链接,这些代码遵循最佳实践: