我有一个具体的问题,可以使用一般性答案...在 PHP 中构建多层应用程序时,是否必须在业务逻辑层完成所有操作,或者任何层都可以工作...例如,假设我正在构建一个在表示层上显示用户信息(来自数据库)的应用程序。我应该使用业务层简单地将数据传递给表示层,还是直接在表示层内从数据库中获取信息。是否应该将表示层仅用于呈现数据,访问层仅用于获取数据,而所有工作都在业务层完成?
另外,说到不同的层,最好是按程序做事,还是使用 OOP(比如使用 include 来显示模板 vs 使用类来包含模板,程序验证数据 vs 使用类,或者函数 vs从数据库等获取数据的类)
如您所见,我正在努力了解事物的运作方式,以及做事的最佳方式。话虽这么说,如果您有任何建议或关于该主题的任何一般提示...请留下...
谢谢
最佳答案
Web 应用程序和 N 层很有趣,主要是因为 N 层的概念随着 JSON 和 AJAX,或 Flash 和 XMLRPC 的广泛采用而扩展。这chart on Webopedia显示一条交错的蓝线,很好地表达了这一点。总结一下:您的业务、访问器和表示逻辑不仅可以存在于服务器上——而且在某些情况下,就在浏览器中。然而,N 层的意图是可分离性。如果您需要更改 UI 或数据库,或添加其他 UI,则不应影响您的业务逻辑。这就是决定您的 API 的因素——预计有一天您的 HTML 和 CSS 会被 Flex 抛弃,而 MySQL 会被 Oracle 取代。
这是由需求决定的,在我使用的一些 Web 应用程序中,同时使用了 N 层的变体。以 LyrisHQ(电子邮件 ASP)为例。他们有一个客户网络应用程序。最近,他们开始着手推广他们基于 Flash 的应用程序。这显然是将大量数据直接传送到浏览器,并且可能在 Flash UI 中复制了一些业务逻辑。但是,他们必须维护这两个应用程序,因为对于不同的(和重叠的)需求,其中任何一个都是必需的。
大多数常见的 PHP 应用程序都没有考虑将大量未格式化的数据传送到浏览器。但如果你是,这会很快告诉你你想如何设计你的 API。很可能,除了您的 PHP 演示模板使用的类似内部 Controller 类之外,您还需要可以与 XMLRPC、REST 或 SOAP 通信的 Controller 。这将严格意味着对于一个简单的 Web 登录页面,您将拥有一个用于与 LoginController 类对话的登录表单的 PHP 模板。 XML 接口(interface)同样会使用相同的 LoginController 类。正如您假设您会疯狂地将 SQL 写入 Ajax 请求一样……您将严格避免将查询写入您的演示模板。
业务层可以或多或少严格,因为通常不需要切换品牌的数据库后端。在严格的 N 层设计中,您的业务对象如何与您的数据库对话,就像您可以从 MySQL 切换到 MS SQL 而无需重写业务层一样。有时这是通过为每个表(表网关)、每一行(事件记录)、每个连接或每个事务建模对象来完成的。这是 PDO 或 PHP-ADO 之类的东西有用的地方,但不足以完全隔离。 Java 中的 ORM/持久层(如 Hibernate)通常通过提供对象查询语言 (OQL) 更好地展示了这种隔离。
我本人目前正在从基于 MySQL 的 PHP 应用程序过渡到 MS-SQL 应用程序。该应用程序只使用过直接 SQL 查询。想象一下,选择如何在一个类中进行一系列查询,然后将它们抽象化或子类化,并希望不改变业务逻辑。最起码,您需要使所有 SQL 调用都是间接的。 ( S.O. post on PHP ORM .)
最后,关于您关于 OOP 的问题:如何使用它来满足您的要求。我个人的技术是从 PHP 演示模板中的逻辑开始,花几分钟时间开始工作,很快我就会将其重构为一个类和一个模板。如果我有共同的想法,我会将例程分解为共享类,努力保持 DNRY 原则。 (S.O. post on that here. OOP 不是 N 层设计的基本要求。DNRY 对于保持代码的可维护性非常重要,不过。截止日期和范围转移通常会破坏 API。重构它,直到获得继续前进所需的内容. 我敢打赌 OOP 会帮助你实现目标。
关于php - PHP 中的多层......正确的方法?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1694894/
我正在学习如何使用Nokogiri,根据这段代码我遇到了一些问题:require'rubygems'require'mechanize'post_agent=WWW::Mechanize.newpost_page=post_agent.get('http://www.vbulletin.org/forum/showthread.php?t=230708')puts"\nabsolutepathwithtbodygivesnil"putspost_page.parser.xpath('/html/body/div/div/div/div/div/table/tbody/tr/td/div
总的来说,我对ruby还比较陌生,我正在为我正在创建的对象编写一些rspec测试用例。许多测试用例都非常基础,我只是想确保正确填充和返回值。我想知道是否有办法使用循环结构来执行此操作。不必为我要测试的每个方法都设置一个assertEquals。例如:describeitem,"TestingtheItem"doit"willhaveanullvaluetostart"doitem=Item.new#HereIcoulddotheitem.name.shouldbe_nil#thenIcoulddoitem.category.shouldbe_nilendend但我想要一些方法来使用
类classAprivatedeffooputs:fooendpublicdefbarputs:barendprivatedefzimputs:zimendprotecteddefdibputs:dibendendA的实例a=A.new测试a.foorescueputs:faila.barrescueputs:faila.zimrescueputs:faila.dibrescueputs:faila.gazrescueputs:fail测试输出failbarfailfailfail.发送测试[:foo,:bar,:zim,:dib,:gaz].each{|m|a.send(m)resc
我试图在一个项目中使用rake,如果我把所有东西都放到Rakefile中,它会很大并且很难读取/找到东西,所以我试着将每个命名空间放在lib/rake中它自己的文件中,我添加了这个到我的rake文件的顶部:Dir['#{File.dirname(__FILE__)}/lib/rake/*.rake'].map{|f|requiref}它加载文件没问题,但没有任务。我现在只有一个.rake文件作为测试,名为“servers.rake”,它看起来像这样:namespace:serverdotask:testdoputs"test"endend所以当我运行rakeserver:testid时
作为我的Rails应用程序的一部分,我编写了一个小导入程序,它从我们的LDAP系统中吸取数据并将其塞入一个用户表中。不幸的是,与LDAP相关的代码在遍历我们的32K用户时泄漏了大量内存,我一直无法弄清楚如何解决这个问题。这个问题似乎在某种程度上与LDAP库有关,因为当我删除对LDAP内容的调用时,内存使用情况会很好地稳定下来。此外,不断增加的对象是Net::BER::BerIdentifiedString和Net::BER::BerIdentifiedArray,它们都是LDAP库的一部分。当我运行导入时,内存使用量最终达到超过1GB的峰值。如果问题存在,我需要找到一些方法来更正我的代
我正在尝试设置一个puppet节点,但rubygems似乎不正常。如果我通过它自己的二进制文件(/usr/lib/ruby/gems/1.8/gems/facter-1.5.8/bin/facter)在cli上运行facter,它工作正常,但如果我通过由rubygems(/usr/bin/facter)安装的二进制文件,它抛出:/usr/lib/ruby/1.8/facter/uptime.rb:11:undefinedmethod`get_uptime'forFacter::Util::Uptime:Module(NoMethodError)from/usr/lib/ruby
Rails2.3可以选择随时使用RouteSet#add_configuration_file添加更多路由。是否可以在Rails3项目中做同样的事情? 最佳答案 在config/application.rb中:config.paths.config.routes在Rails3.2(也可能是Rails3.1)中,使用:config.paths["config/routes"] 关于ruby-on-rails-Rails3中的多个路由文件,我们在StackOverflow上找到一个类似的问题
我想了解Ruby方法methods()是如何工作的。我尝试使用“ruby方法”在Google上搜索,但这不是我需要的。我也看过ruby-doc.org,但我没有找到这种方法。你能详细解释一下它是如何工作的或者给我一个链接吗?更新我用methods()方法做了实验,得到了这样的结果:'labrat'代码classFirstdeffirst_instance_mymethodenddefself.first_class_mymethodendendclassSecond使用类#returnsavailablemethodslistforclassandancestorsputsSeco
我需要从一个View访问多个模型。以前,我的links_controller仅用于提供以不同方式排序的链接资源。现在我想包括一个部分(我假设)显示按分数排序的顶级用户(@users=User.all.sort_by(&:score))我知道我可以将此代码插入每个链接操作并从View访问它,但这似乎不是“ruby方式”,我将需要在不久的将来访问更多模型。这可能会变得很脏,是否有针对这种情况的任何技术?注意事项:我认为我的应用程序正朝着单一格式和动态页面内容的方向发展,本质上是一个典型的网络应用程序。我知道before_filter但考虑到我希望应用程序进入的方向,这似乎很麻烦。最终从任何
我在我的项目中添加了一个系统来重置用户密码并通过电子邮件将密码发送给他,以防他忘记密码。昨天它运行良好(当我实现它时)。当我今天尝试启动服务器时,出现以下错误。=>BootingWEBrick=>Rails3.2.1applicationstartingindevelopmentonhttp://0.0.0.0:3000=>Callwith-dtodetach=>Ctrl-CtoshutdownserverExiting/Users/vinayshenoy/.rvm/gems/ruby-1.9.3-p0/gems/actionmailer-3.2.1/lib/action_mailer