PHP MVC(无框架),我应该在控制器或模型中调用很多方法吗?
我一直致力于用 PHP 创建我自己的 MVC 应用程序,并且我在网上看到了很多关于应该如何设置的不同意见。当然,我知道似乎有一种普遍的“这就是 MVC,这就是你如何创造它”的方法,但我遇到了两个看似相互冲突的观点。
我的应用程序的一些背景知识:我使用 smarty 作为我的演示者和面向对象的方法。看起来很简单,但我试图找出普遍存在的“什么是模型”问题。
如果我看一下一些教程和框架,他们似乎将模型严格视为一个从抽象类继承 DAL 方法的类,并且在类本身中定义了一些额外的内容,因为您的数据需求因对象而异。例如,我可能会看到类似 $productModel->get(5) 的内容,它从数据库返回 5 个产品的数组。那么如果我需要查询多个模型怎么办?我是否将所有数据存储在控制器或数组中并将其传递给视图?那么,如果我动态调用我的控制器,如何保留呈现视图所需的控制器特有的数据?这看起来很糟糕,特别是因为我必须传入“controllerName”、“controllerData”等内容,并且我的 View::render() 方法会因参数而变得非常臃肿,除非我传入控制器本身。也许我在这里遗漏了一些东西。
假设我想创建一个查询用户表的登录。登录是一个模型还是一个控制器,取决于我在网上看到的某些实现。一些实现(我将调用此方法 1)使用方法 login() 创建一个 LoginController,该方法可能会比较 $_POST 和从用户模型实例 $user->get(1) 返回的内容,以查看用户是否是已验证。或者,login() 可能是默认控制器中的一个方法。另一方面,更类似于 Joomla 方法的实现(实现方法 2)将创建一个登录模型并声明其中的所有操作。然后,任何需要分配给视图的数据都将从这些方法返回。因此,login->login() 实际上会检查帖子,看看是否有匹配等。此外,用户模型可能会在该模型方法内实例化。
我的感受1:控制器很胖。此外,控制器还存储从模型中提取的数据或传递一万个变量。这似乎与模型应该将数据传递到控制器应该不知道的视图的想法不符。另外,假设我想将特定控制器处理的特定模型中的所有内容包装在外部模板中。我必须在与该模型交互的控制器函数中复制此模板设置代码。看起来效率极低。
我对 2 的感受:它不适合采取非模型方法的操作。如果我想访问我的站点根目录,我必须创建一个索引模型或一些看起来有点过分的东西,以便拥有一个将数据传递到视图的模型。此外,这似乎不是一种很受欢迎的方法。但是,我确实更喜欢它,因为我可以执行 View::render(mymodel->func()) 并确保数据将按照我喜欢的方式传回,而不必用以下方式搞砸我的控制器将一千个查询结果合并在一起的代码。
我已经对此进行了太多的宗教争论,想知道你们的想法。
I've been working on creating my own MVC app in PHP and I've seen a lot of differing opinions online about how exactly this should be set up. Sure, I understand there seems to be a general "It's MVC, it is what you make of it" approach, but I'm running into 2 seemingly conflicting viewpoints.
A little background on my app: I'm using smarty as my presenter and an object-oriented approach. Seems simple enough, but I'm trying to figure out the ubiquitous "what is a model" question.
If I take a look at some tutorials and frameworks, they seem to view the model as strictly a class that inherits DAL methods from an abstract class, with a little bit extra defined in the class itself as your data needs differ from object to object. For example, I might see something like $productModel->get(5) that returns an array of 5 products from the database. So what if I need to query multiple models? Do I store all of the data in the controller or an array and pass that to the view? Then if I'm dynamically calling my controller, how can I persist the data unique to the controller necessary to render the view? This seems bad, especially because I then have to pass in things like "controllerName", "controllerData", and my View::render() method gets hugely bloated with parameters, unless I pass in the controller itself. Maybe I'm missing something here.
Let's say I want to make a login that queries a users table. Login is a model or a controller, depending on certain implementations I've seen online. Some implementations (I'll call this method 1) make a LoginController with method login() that might do a comparison of $_POST and what's returned from the user model instance $user->get(1) to see if a user is validated. Or maybe login() might be a method in a default controller. On the flipside, an implementation (implementation method 2) that resembles more of a Joomla approach would make a Login model and declare all of the actions inside of that. Then any data that needs to get assigned to the view would get returned from those methods. So login->login() would actually check post, see if there's a match, etc. Also the User model would probably be instantiated inside that model method.
My feelings about 1: The controller is fat. Additionally the controller is storing data pulled from models or passing in ten thousand variables. It doesn't seem to jibe with the idea that the model should be passing data to the view that the controller should be blind to. Also, let's say I want to wrap everything that is in a specific model handled by a specific controller in an outer template. I'd have to copy this template-setting code all across my controller functions that interface with this model. It seems grossly inefficient.
My feelings about 2: It doesn't make for having actions that aren't model methods. If I want to go to my site root, I have to make an index model or something that seems like overkill in order to have a model that passes data to the view. Also, this doesn't seem to be a very popular approach. However, I do like it more because I can just do View::render(mymodel->func()) and ensure that the data is going to be passed back just the way I like it without having to crap up my controller with code merging a thousand query results together.
I've waded through far too many religious arguments about this and want to know what you guys think.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
我过去也构建过自己的框架,所以我知道您正在经历什么。我听说过“构建胖模型”这句话,我同意这一点——只要主要目标是返回数据。我认为控制器是“霸主”,因为它操纵数据并指示它应该去的地方。
对于登录控制器,我可能会创建类似的东西...
发布 URI: http://example.com/login/authenticate
在我看来,数据应该始终从模型中流出 ->控制器->查看最有意义的内容(数据、操作、输出)。视图应该只能访问控制器为其提供的内容。
至于这个……
好吧,我想象您正在构建一个“基础”或“父”控制器,该控制器由动态调用的控制器扩展。这些子控制器可以具有视图呈现所需的属性——老实说,我需要一个示例来进一步说明。
希望这会有所帮助。如果您提出更具体的问题,我也许能够给出更经过深思熟虑的意见。
I've built my own framework in the past too so I know what you're going through. I've heard the saying "build fat models" and I agree with that -- as long as the main goal is to return data. I considered the controller to be "The Overlord" as it manipulated data and directed where it should go.
For a login controller i might create something it like...
Post URI: http://example.com/login/authenticate
In my opinion data should always flow from the model -> controller -> view as it makes the most sense (data, manipulation, output). The View should only have access to what it has been given by the controller.
As for this...
Well I would imagine you're building a 'base' or 'parent' controller that gets extended off of by your dynamically called controllers. Those child controllers can have properties that are needed for for the view to render -- honestly I'd need an example to go further.
Hopefully this helps a bit. If you ask more specific questions I might be able to give a better thought out opinion.
如果您正在编写自己的应用程序,我认为最好的解决方案是自己动手并找出答案。
最终,无论对您来说最有意义,还是让您更容易概念化您的应用程序并快速添加或更改它,都将是您的最佳选择。
如果一种方法是“错误的”,那么你会通过经验发现,而不是别人告诉你。你会更好地了解整个情况,并确切地知道为什么一种方法更好。
奇怪的是,当我用 PHP 编写自己的框架时,对我有帮助的是 CherryPy。它使面向对象的 Web 应用程序的概念变得如此简单明了,我非常喜欢使用它,以至于我模仿 CherryPy 建模了 PHP 框架的基本结构。
我并不是暗示你应该学习 CherryPy。我的意思是,简单、清晰和享受使用自己的网络应用程序进行开发会大有帮助。
如果我要给出一条具体建议,我会说尽量避免重新输入代码;编写可在尽可能多的情况下重用的代码。这不仅有利于您的应用程序,而且有利于您将来可能编写或处理的应用程序。
您可以查看 Eric S. Raymond 的Unix 编程规则。我认为它们绝对适用于此。
If you're writing your own app, I think the best solution is to do it yourself and find out.
Ultimately, whatever makes the most sense to you, and whatever makes it easier for you to conceptualize your app and quickly add to or change it, is going to be your best option.
If one way is "wrong", then you'll find out through experience, rather than someone else telling you. And you'll know the entire situation that much better, and know EXACTLY why one way is better.
What helped me when I was writing my own framework in PHP was, strangely enough, CherryPy. It made the concept of an object-oriented web app so simple and obvious, and I enjoyed using it so much, that I modeled the basic structure of my PHP framework to imitate CherryPy.
I don't mean to imply you should learn CherryPy. I mean that simplicity, clarity, and enjoying developing with your own web app go a LONG way.
If I were to give one piece of specific advice, I'd say try to avoid retyping code; write your code to be reusable in as many situations as possible. This will not only be good for your app, but for future apps you may write or work on.
You might check out Eric S. Raymond's Rules for Unix Programming. I think they're definitely applicable here.