我有一个面向对象的框架,它使用页面设计,每个页面都扩展了框架的视图。因此,例如,我的网站索引页实际上是一个实现框架提供的抽象类View
的类。我通过在页面顶部包含一个启动脚本来挂钩框架,经过一些处理后,框架创建了一个页面实例并处理其视图数据。为了增加系统的灵活性,我不要求类名作为文件本身的名称。这允许我创建类似支持类的东西,并使其表现为/support/
子域的索引。
我最初是通过框架的构造函数将页面的类名传递给框架,但是这又在页面的顶部或底部添加了一些步骤。我目前通过过滤的请求URI标识的数据库中的页面表获取类名。我使用此表来构建导航,并且添加额外的表列几乎是免费的。只要我有数据库连接,这就可以正常工作,但我正在尝试为状态消息和错误报告实现静态页面支持,我需要另一种方法来创建页面类的实例。如果我使用命名类的文件名的标准约定,那么我知道我有一个可靠的方法来推断类名。我不想仅仅出于演示原因而将所有类索引命名。关于面向对象框架如何初始化的一些建议或一些标准是什么?
<?php
abstract class View
{
abstract function getView();
}
?>
<?php
require_once("View.inc");
require_once("CoreController.inc");
$Framework = new CoreController();
$Framework->Initialize();
exit;
?>
<?php
require_once("Startup.inc");
class Index extends View
{
public function getView()
{
echo "<pre>View Data</pre>";
}
}
?>
在我的框架中,我有一个处理页面的TemplateController。页面类是已知的,因为它是通过另一个类映射的。但是,如果没有数据库,我想在index.php
内发现这个类,而不改变它当前设置的方式。这是TemplateController中的实际代码。
//Get the View Class from Page
$view = $page->getPageClass();
//We need to catch View creation failure
$this->Page = new $view($this->Framework);
//Initialize the Page View
$this->Page->Initialize();
//Cache the Page View
$this->cacheView($this->Page, $page->getPageName(), $this->SiteID.TCS_PAGE_SORTID);
在上面的代码段$view
中是从另一个控制器映射的类的实际名称。我将对框架的引用传递给视图的构造函数,其余的实际上是无关紧要的。我试图想出一个类似的映射技术来识别数据库关闭时的页面类。我喜欢框架启动的一个包含行,并希望保持简单。
在TemplateController的顶部,我还必须重新包含实际页面,因为我的启动脚本位于顶部,即使它是请求的页面,也不包括实际的类。
include($_SERVER['SCRIPT_FILENAME']);
请查看Stack Overflow问题 Identifying class names from $_SERVER['SCRIPT_FILENAME'] ,了解我正在尝试做的更多信息。
答案 0 :(得分:3)
这是我的页面路由清单:
最重要的是 - 停止复制,考虑最好的方法。
我在PHP UI framework - Agile Toolkit中使用的所有建议都是我的贡献者。
相关来源: Agile Toolkit - a PHP Framework with jQuery , Agile Toolkit - PageManager.php , Agile Toolkit - URL.php 和 {{ 3}}
我们希望让开发人员变得非常简单。也是安全的。而且灵活。因此,基于URL选择“页面”类。怎么样?很简单:
/hello.html -> page_hello
/hello/world.html -> page_hello_world
然后将类映射到文件名。 page/hello/world.php
然后我们也想要使用动态网址,例如:/article/234
许多框架在这里实现了复杂的技术(数组,正则表达式,前端控制器)。我们没有。这有mod_rewrite
。只需将其重写为page=article&id=234
即可。和鳞片。
除了页面之外,还有其他类,但无法直接访问这些类。因此页面位于/ page /文件夹下,区分它们并保持安全。
然后设计师说 - “我不会写PHP ”。所以我们介绍静态页面。如果未定义课程page_hello_world
,我们会调查template/skin/page/hello/world.html
。这是设计师和非开发人员添加新页面的简便快捷方式。
如果找不到页面怎么办?调用Api->pageNotFound()
。您可以随意从SQL重新定义和加载页面,或使用粉红色大象的图片显示404页面。
然后有一些页面来自附加组件 。我们不希望默认启用它们,而是让用户在某处将它们添加到应用程序中。怎么样?
class page_hello_world extends Page_MegaPage
接下来的问题是,我们如何处理该页面的子页面,因为有时所有功能都不适合单页面。好吧,让我们添加对page_edit()
方法(或任何page_XX)的支持,作为这些类中子页面的别名。现在,附加组件开发人员可以包含一个多功能页面,可以扩展,自定义并放置在应用程序的任何位置。
最后有黑客,他们想要快速做点什么。对于他们,我们将相同的技术应用于API。您可以在API中定义函数page_hello_world
,而不需要类。
有些人可能会说有太多方法可以做一件简单的事情。哦,好吧。
我希望这有用。
答案 1 :(得分:2)
使用__autoload()
。大多数主要的PHP框架都使用自动加载来简化类加载。
答案 2 :(得分:1)
您需要某种方法将URL映射到对象,这通常由大多数框架中的路由组件处理。可能想看看https://github.com/chriso/klein.php等库,或主要框架的路由组件(Zend,Symfony等)。
答案 3 :(得分:1)
为什么不使用URL中的信息来检测正确的类?由于您不会将数据库用于静态页面,因此您必须以某种方式存储URL和文件中的类之间的映射。即你将有一个文件mapping.php
:
return array(
'about' => 'AboutView',
'copyright' => 'CopyrightView',
);
此处,about
和copyright
是网址组件,值代表View
的相应子类。您可以使用http://example.com/index.php?page=about之类的URL,并使用网络服务器的重写功能使其看起来很好。
您将更改Page::getPageClass()
的实现,以便返回正确的视图类。根据URL,它将使用上面文件中的静态映射或使用数据库。
这种方法有什么问题?