我想在PHP中创建一个100%面向对象的框架,根本没有程序编程,一切都是对象。很像Java,除了它将在PHP中完成。
如果它使用任何现有的设计模式(如MVC),那么这个东西应该有什么功能的指针?如何为数据库中的每个表创建对象,以及如何显示HTML模板等?
请不要链接到现有的框架,因为我想自己做这个主要是作为一个学习练习。您 会被投票,以便链接到现有框架作为您的答案并说“这可以满足您的需求”。
我想要的一些功能是:
答案 0 :(得分:30)
我在你的清单上遇到了很多问题,所以让我指出我是如何处理它的。我也是OOP上瘾者,并且发现对象技术非常灵活,强大而优雅(如果正确的话)。
MVC - 是的,请放手,MVC是Web应用程序的标准。它是一个记录良好且易于理解的模型。此外,它在应用程序级别上做了OOP在类级别上所做的事情,也就是说,它将事物分开。 MVC的好处是Intercepting Filter模式。它有助于为处理前和处理后的请求和响应附加过滤器。常见的用途是记录请求,基准测试,访问检查,缓存等。
数据库表/行的 OOP表示也是可能的。我每天都使用DAO或ActiveRecord。 ORM问题的另一种方法是Row Data Gateway和Table Data Gateway。这是使用ArrayAccess
界面的TDG的example implementation。
HTML模板也可以表示为对象。我将View对象与Smarty模板引擎结合使用。我发现这种技术极其灵活,快速且易于使用。表示视图的对象应该实现__set
方法,以便每个属性都传播到Smarty模板中。此外,应实现__toString
方法以支持视图嵌套。见例:
$s = new View();
$s->template = 'view/status-bar.tpl';
$s->username = "John Doe";
$page = new View();
$page->template = 'view/page.tpl';
$page->statusBar = $s;
echo $page;
view/status-bar.tpl
的内容:
<div id="status-bar"> Hello {$username} </div>
view/page.tpl
的内容:
<html>
<head>....</head>
<body>
<ul id="main-menu">.....</ul>
{$statusBar}
... rest of the page ...
</body>
</html>
这样您只需要echo $page
并且内部视图(状态栏)将自动转换为HTML。看看complete implementation here。顺便说一句,使用拦截过滤器之一,您可以使用HTML页脚和标题包装返回的视图,因此您不必担心从控制器返回完整页面。
在设计时,是否使用Ajax的问题不应该是重要的。该框架应该足够灵活,可以本地支持Ajax。
表单验证绝对是以OO方式完成的事情。使用Composite pattern构建复杂的验证程序对象。复合验证器应遍历表单字段并分配简单的验证器,并给出是/否答案。它还应该返回错误消息,以便您可以更新表单(通过Ajax或页面重新加载)。
另一个方便的元素是自动转换类,用于在db中更改数据以适合用户界面。例如,如果db中的INT(1)字段表示布尔状态,并且在HTML中使用复选框导致空字符串或_POST或_GET数组中的"on"
,则不能只将一个分配给另一个。拥有改变数据以适合View或db的翻译服务是一种清理数据清理的方法。此外,即使在非常复杂的转换过程中(例如the one converting Wiki syntax转换为HTML),转换类的复杂性也不会使控制器代码丢失。
使用面向对象技术也可以解决 i18n 问题。我喜欢使用__
函数(双下划线)来获取本地化消息。函数而不是执行查找和返回消息给了我一个Proxy对象和预注册消息以供以后查找。一旦将Proxy对象推入View并将View转换为HTML,i18n后端会查找所有预先注册的消息。这样,只运行一个返回所有请求消息的查询。
访问控制问题。我在我的other Stackoverflow answer中描述了它。
最后,如果您想使用完全面向对象的现有代码,请查看Tigermouse framework。页面上有一些UML图表可以帮助您了解工作原理。请随意接管这个项目的进一步发展,因为我没有时间去研究它。
有一个很好的黑客!
答案 1 :(得分:17)
现在冒着被投票的风险,同时又是一个正在开发自己框架的人,我觉得有必要告诉你至少要有一些使用现有框架的经验。它不需要大量的经验,也许可以为每个流行的教程做一些初学者教程。
考虑到构建一个好框架所需的时间,花时间去研究你喜欢什么和讨厌现有的解决方案会比较苍白。你甚至不需要只看php框架。 Rails,Django等都很受欢迎。
建立一个框架是有益的,但你需要一个明确的计划和对手头任务的理解,这是研究的结果。
您的问题的一些答案:
答案 2 :(得分:6)
创建自己的框架是一种很好的方式,可以了解其他框架可能会发生的一些事情。如果你是一个像我一样的完美主义者,它会给你一个很好的借口来痛苦地对每一个细节进行痛苦(例如,如果该对象被称为X或Y,我应该使用静态方法还是实例方法)。
我自己写了(几乎完全是OO框架),所以这是我的建议:
最终,除非您的需求特殊,否则如果采用现有框架,大多数人的工作效率会更高。但是Ruby on Rails philosophy
答案 3 :(得分:5)
冒着听起来很滑稽的风险,在我看来,这就像任何其他软件项目一样:
您需要明确定义您的要求,包括动机和优先级:
为什么这样做?您希望实现的主要好处是什么?如果答案是“速度”你可以做一件事,如果它是“易于编码”你可能会做另一件事,如果它是“学习经验”你可能会做一件事
您要解决的主要问题是什么?哪个最重要?安全?简单的UI生成?伸缩性?
“它应具备哪些功能”的答案实际上取决于上述问题的答案。
答案 4 :(得分:4)
以下是我的建议:
现在,我的理由:
...如果你曾经和开发人员合作过,那么你就和喜欢重新发明轮子的开发人员一起工作了。这是一种非常非常常见的故障模式。
......他们会写下成千上万种你能想象到的最疯狂的语言......
......“哦,我要创造自己的框架,创造我自己的一切,”这一切都会比你刚出去的东西更加糟糕......
所以,节省一些时间,并为一些人解决问题的工作,比如一个网络应用程序,让人们在猫的猫砂盆需要清洁时自动更新Twitter。完成了“面向对象的PHP框架”的问题。无论您使用哪种框架都不会像任何可用的,完全支持的框架那样可靠或有用或功能丰富今天。
这并不意味着你无法获得学习经验,但为什么在黑暗中做到这一点,创建一个框架,它将成长为无用的代码blob,让你没有任何东西显示你的时间?开发一个网络应用程序,供人们使用和享受,我认为你会发现这种体验非常有益,并且教育。
答案 5 :(得分:2)
我为你的朋友提供了完美的链接:http://nettuts.com/tutorials/php/creating-a-php5-framework-part-1/。这是我看过的一个很棒的教程,而且它不是太强大了。再看看那个网站的PHP部分,我看到了一篇关于CRUD的文章。至于其他地方的AJAX外观,但你必须从某个地方开始,本教程非常棒。
注意:本教程有3个部分,我认为它会在第二部分中介绍MVC,但是使用其他方法启动第一部分。
答案 6 :(得分:2)
就像Jim OHalloran所说,编写自己的框架可以让您深入了解其他框架的工作方式。
也就是说,我之前编写了一个数据访问层,几乎完全抽象出任何SQL。应用程序代码可以请求相关对象,抽象层只需要在需要时获取数据,不需要不必要地重新获取,仅在更改时保存,并支持将一些对象放在不同的数据库上。它还支持复制数据库和受尊重的复制延迟,并具有智能收集对象。它也是高度可扩展的:核心是参数驱动的,我可以用大约15行代码添加一个全新的对象 - 并且免费获得所有的魔力。
我还编写了一个CRUD布局引擎,该引擎用于相当大比例的网站。核心是参数驱动的,因此一旦你编写了参数列表,就可以运行列表和编辑任何内容的页面。它自动进行分页,保存 - 新删除支持等,利用上面的对象层。它本身并不是面向对象的,但本来可以这样做。
换句话说,PHP中的面向对象框架不仅可行,而且效率非常高。这完全是在PHP 4,BTW中,我遇到了几次PHP 4对象的可能性。 : - )
我从来没有达到一个称为物体的中央调度,但我并不遥远。不过,我已经使用了几个这样做的框架,并且文件布局很快就会变得毛茸茸。出于这个原因,我会选择一个只需要复杂的调度系统,而不是更多。一个简单的动作/视图(无论如何几乎都是MVC)应该可以让你获得足够的远远。
答案 7 :(得分:2)
我最初开始创建自己的框架,其理念类似于您自己的框架。然而,几个月后,我意识到我正在重新创作已多次完成的工作。最后,我找到了一个易于扩展的开源框架,并将其作为我自己开发的基础。
我自己实现的功能:
我看到和思考的功能,忘了它!我将建立在别人之上:
当然,编写一个优于开源选项的框架是可能的,但你为什么要打扰呢?
答案 8 :(得分:2)
确实有些开发商没有充分理由重新发明轮子。但是因为已经存在好的框架并不意味着浪费时间自己做一个。我刚刚开始使用它,并不打算将它用于锻炼之外。我强烈建议你这样做。
答案 9 :(得分:1)
我在新框架中寻找的一个巨大卖点是,它可以轻松编写可测试的代码。
我们通常使用Zend Framework,而且它非常棒,但尝试单元测试/测试驱动基于ZF的代码并不是完全没有受虐狂。
如果你能提供一个框架,用一些允许我们编写可测试代码的东西替换ZF的MVC部分,同时仍然允许我们使用ZF的库部分,我会 - 实际上 - 给你买啤酒。 / p> 如果你抛弃AJAX,我会给你买两瓶啤酒。 OO PHP框架和JavaScript框架之间存在巨大差距。
答案 10 :(得分:1)
请勿链接到现有框架
我不会,我开始编写自己的学习目的,并看一些主流框架,即使我的知识有限,也会看到很多错误和不好的想法。
它们是由核心开发人员而不是最终用户构建的。
我绝对不会说我能比#34;大男孩写得更好&#34;但是我(以及我想象中的大多数人)可以指出为什么他们做的事情很糟糕,即使只是因为他们不是最终用户/非开发人员友好...
我想知道你的框架是如何做的,大约6年了? 你还在努力吗?你停止了吗?
对你来说这可能有点晚了,但对于其他任何人来说,编写自己的框架对于学习目的来说是一件很棒的事情。
但是,如果你想要写一个非学习目的,因为你无法找到你正在使用的那个,或者因为它太臃肿了,那就不要了! 相信我,不要受到侮辱,如果你是一个知识渊博的开发者,你就不会在这里考虑它成功!
去年我想学习OOP /课程,以及更高级的PHP 编写自己的框架是我做过的最好的事情(实际上还在做),因为我学到的东西比我预想的要多得多。
在我学习的过程中(仅举几例):
还有许多其他基本的PHP内容,你总是会偶然地看到它们。
所有这些不仅极大地提高了我对PHP及其附带的东西的掌握程度,达到了更高级别,而且还有一些商业/广泛使用的方法和原则。 这一切都增强了我对使用PHP的信心,这反过来又使学习变得更容易。
当你开始学习时,你将学习基础知识 - A(变量),然后是B(如何编写基本功能)等。
但是,当你尝试学习更高级的东西,学习和使用D和E,你也必须学习和理解F,G,H和J,并且知道它并不需要很长时间。那些你必须知道K,L和M,并且要了解L和M的部分,首先需要了解N和O ......
它变成了一个雷区,因为试图学习一件东西需要先学习其他一些东西,而其他东西往往需要了解其他各种事物。
你最终离你开始的地方一英里远,你的思绪刺痛和射击火花,大约20个标签打开所有高级PHP的东西,没有一个你100%舒适。
但是随着时间的推移,通过练习和最肯定的奉献精神,它将全部适合到位,您将回顾代码,甚至是文件/类的集合,并且思考&#34;我是否写过..&#34 ;?
写一个框架对这个&#34;雷区&#34;有很大的帮助。因为:
你可以按照自己的方式去做。这可能不是最佳实践,但只要您尝试学习最佳实践,随着时间的推移,您将会改进,并且可能比阅读教程更容易,因为您可以控制什么以及如何做点什么。
嗯,首先,你不能重新发明轮子,这是不可能的,因为你只会制造一个轮子。
当人们说&#34;不要重新发明轮子时,他们当然意味着&#34;那里已经有框架&#34;,公平地说,他们是由技术熟练的人写的开发人员。
这并不是说框架没有问题或问题,但总的来说它们非常可靠,安全且写得很好。
但是这个陈述在编写自己的框架方面是荒谬的!
为学习目的编写自己的框架非常有用。
即使您计划在商业上使用它,也不打算在您自己的网站上使用它,您还没有“重新发明轮子”,您已经做了其他事情。
您的框架不会像其他框架一样,它不具备许多特性和功能,这可能是您的主要优势!
只要您了解最佳安全实践等,因为您可以认为您正在编写一个超级快速的系统,并且没有其他框架所具有的所有膨胀,但事实上您已经拥有有人可以爬进去的地方的洞...
但是,一个你不能在互联网上使用的学习项目是理想的 - 或者最终使用它,当你足够高级以便知道它是安全的!
尽管如此,你应该编写自己的框架IF:
如果没有以前的经验或PHP的高级知识,您可能会花一些时间编写一个框架,进一步的阅读和知识将向您显示您的方法存在偏差,因此您可能会删除所有内容并重新开始。
不要为此感到沮丧
我做到了这一点,因为我在第一个月学到了很多先进的模式和做事方式,我最终在重构不好的地方,并且采用全新方法的空白画布是唯一的选择。
然而,这是非常令人愉快的,因为我看到了一个更好的结构形式,我不仅可以看到更好的框架基础开始发生,但意识到这是因为我对高级PHP有了更好的理解。
做吧!在你编写一些代码之前,确保你有一个你想要它做的计划 说真的,记下你将如何加载错误检查,是否要自动加载,或者在需要时包含文件?您是否打算使用集中式加载机制,在需要时实例化类或其他方法?
无论你做什么,无论你处于什么阶段,如果你要进入新领域,先做好计划。当你碰到砖墙,可以回到你的计划,并意识到你的计划的轻微偏差会解决它时,你会很高兴。
否则你最终会陷入混乱,没有任何计划或方法来重新设计它以解决当前的问题或要求。
答案 11 :(得分:0)
您希望构建我已经使用了几年的完全相同的东西,结果是Agile Toolkit。
$page->add('CRUD')->setModel('User');
所有分页和许多其他内容都是通过对AJAX和Object Reloading的本机支持实现的。下面的代码显示了一个带有随机标签的主题按钮。如果点击显示新号码,则重新加载按钮。
$b=$page->add('Button')->setLabel(rand(1,50));
$b->js('click')->reload();
所有表单验证都是基于AJAX的。来自服务器的响应是一个JavaScript链,它指示浏览器突出显示错误消息或重定向到下一页或执行任何其他javascript操作。
当您真正进行对象重新加载时,表格排序和分页具有非常直观和简单的实现。
这似乎不合适而且做错了。模板在VCS中更好。