Monday, February 27. 2006The no-framework PHP MVC frameworkComments
Display comments as
(Linear | Threaded)
It is downright scary how much we think alike. Even your code looks so much like mine you'd think I stole everything I do from you--which in a way is partially true. Great article, I never understood why so many programmers want to force layer after layer of complexity onto a simple Web application.
On a side note, I'm curious to see how developers will take to Yahoo! REST requests being returned as serialized PHP.
I can confirm the ideas of this article and the comments of those who agree with the objects of the article. I am living proof.
I am a PHP noob, an OOP noob and an MVC noob. You may already be thinking about dismissing my opinion before I can explain my position, pls bear with me. I have been building websites (small ones), over the past four years using Dreamweaver, for both static and dynamic projects, (this is an instance where size DOESN'T matter, trust me). It was only recently when I have been involved in the creation of one of my own projects, that I decided I would have to, do things as I did when I first became interested in computers over twenty five years ago, that is, get my hands dirty in some heavy code. I needed a site that would through up articles and video/audio that was related to the article. I needed to create a tutorial website, that makes heavy use of tracking users actions, article use over time etc. I first looked at the two major open source frameworks, but I soon ran into obstacles when I wanted to do something specific. I spent over three months becoming familiar with both of them before realising a simple truth. Then I spent another month researching PHP frameworks, having been sold the marketing mantra of, access to libraries, cleaner and better, more organised code. Again after trying to wrap my head around MVC and OOP, I realised that same simple truth. What is this truth I speak of? I spent so much time learning these CMSes and frameworks, that I believe I could have competed the the whole project within the same time period, using PHP5 classes and straight HTML/CSS. As for cleaner organised code that you can come back to in a year? I don't understand the argument. If you split your code down into manageble block, as in the example of this article, managability is not an issue. As for code re-use? again, I don't understand. Do people not build up a library of common classes that are well commented? can you simply not include ir call these classes in your future projects or the same project? Enough of this nonsense. It seems people against this Rasmus' comments are simply wishing to defend their particular way of working. I realise I am a guy developing on his own and the needs of a team might be different, but I doubt it. OK, I'm off to do what I should have done three months ago. Thanks Rasmus. PS I found CodeIgniter the lightest framework out there and it doesn't impose too many restrictions.
But there are so many things that you find yourself doing over and over again that you start to make sense of multilayered frameworks. They don't have to be necessarily complex, but I find extremely useful to work with simple interfaces to objects that do trivial things - things that I don't really need to reimplement.
I can always override the default model or controller if I want more complex functionality...Caching takes care of that extra performance hit. I've made my own multi layered framework and up until now it's made me happy, and I don't see why I shouldn't use some other people's framework if it is well designed and solves the common problems I don't need to go over - again.
I think you are confusing component re-use with frameworks here. If you always build exactly the same style of application and you have a framework tuned perfectly for that task, then you are in luck. Finding a "well-designed" framework as you say, that fits your problem space perfectly is easier said than done. My contention is that you time is better spent building your own ideal base infrastructure for any sizable project and then use whatever discrete components you are used to on top of that.
That's all great if all you need to do is build the web's next best guestbook, but if you work on a project with 7 developers and 1 webdesigner this is not going to work very well.
A framework isn't ment to just add layers of complexity, it also enforces a certain way of coding (ok I realize you could just as well write coding specs). Your statement about keeping it procedural as much as possible means losing ALL the benefits of OOP in the first place. Next please compare your controller to (for example) this: class ItemController { function ItemController() { $this->model = new ItemModel(); $this->view = new ItemView($this->model); } function run() { $action = isset($_POST['itemAction']) ? $_POST['itemAction'] : 'listItems'; switch($action) { case 'listItems': $this->view->renderList(); break; case 'addItem': $this->model->addItem(); $this->view->renderList(); break; } } $controller = new ItemController(); $controller->run(); Which one do you find easier to come back to after 1 year? All that's left to say is : globals? SQL Injection? I can't believe what you posted, I'm downright shocked to the bones. Which one do you find easier to come back to after 1 year? All that's left to say is : globals? SQL Injection? I can't believe what you posted, I'm downright shocked to the bones. This is very effective and maintainable. In fact, I think it'd be even more maintainable than some object oriented mess of code, especially when that object oriented mess of code, is just a mess.
I fully agree with You Jurgen,
@Andrew: We assume that OO and procedural code is correct of course... So no mess.. This way of working is excellent for small websites with just one maintainer, and maybe one developer sitting close to each other, simple as that. But when things start to grow you can't do it like that anymore. Code will be repeated all over and will be un-maintainable anymore. Not to mention security problems later on, when things change... Also doing direct SQL calls from an application is without a layer is 'not-that-nice'.....
Did you read the code? There is no SQL injection attack possible here. And the idea that because something is procedural it is automatically spaghetti while OOP is not is pretty funny. A template is inherently procedural to me. I have nothing against OOP when used correctly, but I see a lot of things approaching HTML classes where you end up doing $html->br() just to spit out a break tag. That makes absolutely no sense to me.
Hi!
Indeed I overlooked the fact you're using PDO. My bad ;) I agree that your code isn't really spaghetti code (and we all know how capable you are, let that be clear), and I certainly agree 100% about your comment in regards to extremely bad designed and totally besides the point written frameworks. So how's Pear doing these days then? I'd say it is a PRIME example of how NOT to design an OO framework, so there you have it. People download pear code, learn from it, and think it's OKAY to have a Date class which in total uses nearly 250kb of code... I rest my case ;) I think you are doing a lot of damage with this posting. Do you realize what's going to happen if ONE of the 30 programmers in the building I work in find's your post? For years I have struggled convincing fellow programmer's that PHP is NOT a simple scripting language for the gamers and what not, that it actually CAN compete with J2EE and ASP.NET and C# if used where appropiate. To read this from the creator of the language....I'm still shocked Besides, how this example is supposed to show that using a monolithic controller is bad is beyond me. Greetings, Jьrgen
This has nothing to do with Pear. You will notice I am not using any Pear components here. And I am not trying to illustrate that a monolithic controller is bad. I am simply stating that as fact and showing how you can build something without one.
I still think you are hung up on OOP vs. Procedural. Both the controller and the DB layer could easily have been OOP and it wouldn't change the point of example nor does it increase readability. I guess your biggest beef is that I used a global for my database connection handle instead of making it a property of a database wrapper class? It's a minor point as far as I am concerned, and yes for namespace-related concerns you may want to wrap it like that, but again, this was not the focus of this article. The focus was the separation and where to put what, not the line-by-line details of the actual implementation. You also wouldn't use sqlite for a huge project, but it is perfectly fine as a way to illustrate the concepts here.
I have had great luck with http://phpsavant.com which I would characterize as the anti-template templating system. No special syntax required, just create a new template, assign data to it from your controller, and display it. The way you access assigned data from the template is with the object prefix "$this->" instead of any new special syntax.
Rasmus this really isn't meant to be a flame but I'm dumbstruck. That is spaghetti code you're advocating pure and simple.
In the anarchic and often anti-intellectual world of php there needs to be some leadership. Anyone who seriously wants to learn how to program is badly served by articles such as above. Most people churn out code exactly like this but there must be clear goals for those who want to go on to learn more - OOP & testing basically. I don't doubt that you found some bad examples of OOP frameworks. That's not surprising given the lack of an object culture (http://www.procata.com/blog/archives/2006/01/13/building-a-culture-of-objects-in-php/) in php but it doesn't mean that OOP is a bad choice. OOP doesn't add complexity: it's a way to tame the complexity which already exists but which might not have been understood.
I think you guys are missing the point. It isn't about OOP vs. Procedural. I could just as easily have written the controller code as a series of objects. The important point is not the style of the code, the important point is that you don't have a single monolithic controller that becomes your bottleneck and forces all your controller logic into one place because it turns what is supposed to be a discrete and modular architecture into a monolithic one.
You could also use OOP without "one monolithic controller".
I've rewritten this application using Ruby on Rails. DISCLAIMER: I'm fan of rails. Make sure you have some salt to take. Rails is one of the frameworks which fit more or less in this description: "Most likely in the form of a big complex MVC framework with plenty of layers that abstracts away your database, your HTML, your Javascript and in the end your application itself. If it is a really good framework it will provide a dozen things you'll never need." Rails is not big, some things are complex, but simpler than the same thing in PHP. There is only one layer of abstraction for the database (ActiveRecord). It abstracts html to some degree, but you still have "code" templates (like vanilla php), not a separate template language. (like smarty). It abstracts javascript (I did not write a line of JS for this application). I'm not sure what you mean with "abstracts [...] the application itself". "If it is a really good framework it will provide a dozen things you'll never need." Ehh, how many functions does PHP have? How many do you use? Providing these is still a good idea, because others need them. Well, back to the rails version. It is less than 100 lines (excluding CSS). Yours is 400 lines (excluding CSS again). You may formulate a conclusion. Rails uses the shared-nothing architecture, like PHP, so both are perfectly scalable. And, in my opinion, the rails version is better designed. You have validation code in the controller. It should really be in the model. Plus, there are 0 lines of sql in my application. This means that you can use any database, mysql, pgsql, sqlite, etc. without rewriting your sql. I agree that your code is not spaghetti. It doesn't mix controller, html and data code (if you don't count the data validation, which is data-code, so that means model) If I find some time, I will write a more in-depth reply to this. (with code comparison)
It's only 400 if you include the Javascript. Otherwise it is 200. Without writing a line of JS, you are not going to get the extra candy effects this app has. The fades, overlays and field manipulation stuff has to come from somewhere.
But Rails happen to have some JS niceties build in. I think there is fades and field manipulation but there might be more.
Regarding the actual framework I like your idea that we should write a good base and use that, and there are a lot of framworks to choose from, but given that you could choose one that you like and use in every project you will probably not have much problem going back to the code a year later. The naming in your models made me nervous about building larger apps where you need more than one model/table for a view. The can't all have load_items() and be included at the same time. Therefore some grouping is needed and I think objects could help a lot. But namespaces might do the trick if someone gets them into PHP...
By the way, I agree that data validation should be in the model, but it is called from the controller, and in this simple example all it has is a check to see if all the fields have been filled in. If you need to apply any actual business rules to validate he data, those business rules should of course be in the model.
Scriptaculous is a component of Rails, and includes the javascript effects. No external libraries needed, just a fresh rails installation.
The javascript effects are created using ruby code that gets compiled to javascript. There is a feature called rjs (ruby-javascript) templates for these things. Example: page.visual_effect(:highlight, 'the_id_of_a_div_on _the_page') Gets compiled to something like: new Effect.highlight('the_id_of_a_div_on _the_page'); And this javascript code is executed in the browser. Rails is consistent: all validation in the model: class Product < ActiveRecord::Base validates_presence_of :description, :category end If you try to save a product with an empty category/description, you'll get an errormessage. I've studied your php example, and I see that I can strip some more lines off the ruby code: your script just refreshes if the input data is good, my version updated the products table, and highlighted the succesfully saved product. But I really like your approach overall. This mvc 'framework' could even be used for really big applications. You would probably create a few folders (views, controllers, models), but you don't need objects to do mvc. And I agree that you don't need a template language. PHP was originally intended as a template language, and it is really good for html generation. You have to keep attention not to mix the m, v and c if you are used to spaghetti code though.
What about a link?
Sure, JS stuff is built in, but you still need to control it. Whether you do that with Ruby code that generates JS or just with straight JS, you still need to write it. It's not like I wrote reams of code to fade and unfade. It was just a 3-line function for each:
function fade(o, dur, fnc) { var oAnim = new YAHOO.util.Anim(o, {opacity: {from: 1, to: 0}}, dur); if(fnc) oAnim.onComplete.subscribe(fnc); oAnim.animate(); } function unfade(o, dur, fnc) { var oAnim = new YAHOO.util.Anim(o, {opacity: {from: 0, to: 1}}, dur); if(fnc) oAnim.onComplete.subscribe(fnc); oAnim.animate(); } where I can pass in a function pointer to be called when the animation completes. I don't really see how Rails can abstract that away. How do you tell Rails the starting and ending opacity levels on a fade and the fact that you want a certain function to be called at the end of the fade unless you actually specify this somewhere?
I am not sure where you needed a callback, but this is my "javascript" code:
visual_effect :fade, 'modified', :duration => 2
Perhaps this comes down to a question of control. In your case, where is this Modified element? Is it relatively or absolutely positioned? And the callback is there to reload the form and possibly reset it if that was asked for. I don't see how that one line of yours replaces:
div = document.createElement("div"); div.className='status'; div.innerHTML = resp['status']; pos = YAHOO.util.Dom.getXY(resp['elem']); div.style.visibility = 'hidden' document.body.appendChild(div); YAHOO.util.Dom.setXY(div,[pos[0],pos[1]+40]); div.style.visibility = 'visible' fnc = function() { if(resp['reset']) { document.forms[resp['formName']].reset(); } window.location.reload(false); } fade(div,2,fnc); unless something is reading your mind somewhere.
The code would look something like this (still Ruby on Rails):
{ :action => "add" }, :update => "modified", :complete => visual_effect( :fade, 'modified', :duration => 2) ) %> That's all the JS/AJAX code necessary to update a given element and to add a visual effect such as a fade-in or an animation of some sort. Much easier to read IMHO.
I see no mention of a div there, so the two bits of code obviously don't do the same thing. Mine creates a div, fills it with something, positions it absolutely, appends it to the document, then fades it and after it fades the page is reloaded which clears out the element and the form fields and updates the form.
What that code does is makes an ajax call to an action called "add". That action returns a html-snippet, which the element with the id "modified" is updated to contain (replacing any previous content inside it). Then the same element is faded in.
Another way to do it would be to just add a html snippet to the bottom or top of an element container (instead of replacing the contents entirely), simply by adding :position => "bottom" to the code. Except for some insignificant differences, the code does what your code does (in about 200 lines less).
Well, you could argue that it replaces the 13 lines of Javascript, but it isn't 200. The 200 lines of Javascript does all sorts of other stuff. And I would argue that the differences aren't insignificant and in this case probably adds another round trip?
No, that's not correct. I know PHP very well, and I know Ruby on Rails quite well. For you to have the complete perspective, you'd have to learn Rails as well.
This particular point has little to do with PHP. It's a Javascript thing. My additional roundtrip comment had to do with the fact that you only did the Modified message there, but not any of the other actions, so you'd have to make another trip, or do something different from that one-liner.
But this is getting a bit semantic. If you prefer writing Javascript in Ruby and that works for you, great. I'll stick to writing my Javascript in javascript.
{ :action => "add" },
:update => "modified", :complete => visual_effect( :fade, 'modified', :duration => 2) ) %> Rasmus, The :update => "modified" portion is basically telling the page to replace the contents of any element on the page that has an id attribute of "modified" and replace its contents with what is returned from the AJAX call. There are other options you can provide that would allow you to add the new stuff either at the top, bottom, before or after the specified element. I might suggest reading the documentation[1] before arguing that it can't be done. [1] http://api.rubyonrails.org/classes/ActionView/Helpers/JavaScriptHelper.html
I didn't say it couldn't be done. I said the example shown doesn't do the same thing as the code it supposedly replaces. I have no doubt that you can do the same thing, but the 1 or 2 liner shown doesn't give me the same level of control.
Their point is it does - they chose to update an existing div, but you could aslo create divs.
I do agree with you that writing Javascript in Ruby like this is much easier to read. Javascript is an annoying language to use. But I lump it into the same category as HTML. Writing HTML is annoying too, but trying to abstract away the annoyance has never worked for me. HTML should look like HTML and Javascript should look like Javascript. For very expressive things like HTML and Javascript you end up inventing an entirely new language to try to represent everything that can be expressed in those.
Great, now I know how to do a fade!! Thanks guys!
you should try phpontrax.com if you like RoR's but want to use php. It has all the scriptaculus stuff built in same function calls as RoR. Syntax is almost identical to RoR.
Hi
OK, apologies. You seemed to be rather sceptical about OOP frameworks. I'd go along with that for the most part. Just because it's object-oriented doesn't automatically make it good. It's hard to find well-written examples in php. I'd agree with your point about templates (and html classes which emit br tags...) although I'd definitely have a whole pile of objects doing all the validating, data gathering, business logic etc prior to throwing a few vars at some simple php presentation code in the template. I find I'm not sure exactly what you mean by "monolithic" controllers though. To an OOP bigot like myself, there's a choice between FrontController (single point of entry) or PageController (multiple points of entry) but I can't see any compelling reason to choose one over the other. FrontControllers can hand over to any number of objects to carry out the application controller logic for a given request (that's their only unique role otherwise carried out by apache) and PageControllers can extend a superclass which provides a single location for common processing tasks. Six of one, half a dozen of the other. I tend to prefer PageControllers but I think you can write a flexible FrontController design - and you can have more than one FC if need be.
My problem with monolithic controllers is that I don't like centralized presentation-level logic. Views and their associated controller logic should be as discrete as possible. If you start lumping all your controller logic into one big pile it becomes very hard to swap out individual views or change the flow slightly in just one part of the application without affecting other parts.
So the gist here was small discrete controllers, clean HTML templates where the HTML looks like HTML and a clean and separate data model layer. The point wasn't so much to say all frameworks out there are bad or that OOP is bad, more to say that it isn't hard to build your own base that does just enough for your particular problem and uses whatever style of programming you are comfortable with instead of having to try to fit your problem into someone else's idea of how you should structure your code. I was also hoping people would pick up on how the Javascript code manages to connect events to the various form elements without having all sorts of onclick/onmouseover stuff in the templates along with the various performance hints related to opcode caching and storing lists in shared memory.
Maybe I'm out of the loop, but I thought using.inc files was out in the days when ASP just came out. With a .inc file, you can browse to that file from the web an view the contents as text. Let's say you happen to have some password in the code, say for accessing a DB, then that password is out in the open for anywho who cares to find it. All you would have to do is call it 'file.inc.php' and it wouldn't have the inherent problems the .inc file does.
Just a thought.
My standard production server Apache config always has:
[Files *.inc] deny from all [/Files] Replace []'s with angle-brackets. Silly comment system here doesn't let me put them in. Naming them .php instead and letting people browse them directly can be a much bigger problem since they are now being executed out of context. So you need to either put your include files outside your docroot tree, or you need to block direct access to them with an Apache rule as above. (and no, this rule is not in place on the talks server where this app is hosted, because the whole point here is to actually show the code ;)
Not necessarily. You can use .htaccess or the webserver's ini file to either deny access to .inc (and .db files, in this case) or have them parsed by the php parser.
But I agree, I also always name my incluse files .inc.php, just to make sure.
It is quite common for knoweledgeable web admins to have .inc files parsed by the php interpreter (unless they use server-side-includes on the same webserver as php).
It is true that if every php coder had used inluded_file.inc.php from the beginning, this would not ever have been a problem...
You still need to be careful about that. Executing a .inc file out of context can be a security problem. You are better off placing them outside your docroot or turning off direct access to them in your Apache config.
Still, I find frameworks much easier to work with (specially with more than one developer) just because they comply to a known structure. In most MVC frameworks the Front Controller or whatever you wanna call it just delegates the request to other more specific controllers so you don't really have one single controller doing all the work. At the individual controller / model level you still have loads of chances to do whatever you want (for example writing your own helper classes and using them however you see fit in your models or controllers) so it is not accurate to say, as it is often said, that frameworks limit flexibility (ok, bad ones might!). They just structure the workflow and allow for flexibility for the things that really need flexibility (like specific bussiness logic operations). If only to my personal experience, this has proven to be true. I also think that PHP is perfectly suitable for good MVC framework design and that it should be encouraged.
How about Ruby on Rails instead? I've been studying it for two weeks and love it. Admitedly, I've haven't done PHP, but it is definitely easier to use than J2EE. Worth a look.
I actually thought this was very refreshing.
Sadly, I feel confident in saying that the PHP frameworks that are here today, probably wont be in 2 years. That's what I'm getting burnt out on. One thing that I'd love to be able to do is come back to an application in 6 months, and know what the hellz is going on. I can say for sure that I wouldn't want to read about how the "framework" works. Ugh. I've been trying out PHP frameworks for at least 3 years and now... I love to see all of the oop/framework purists squirm! PHP does a great job when used simply. Nice work.
I learned my lessons about monolithic controllers the hard way by having to maintain my mistakes. It's not even Legacy code and it's a pain in my a$$.
Hope you post more articles, more often. The PHP community could use someone pushing simple, small and fast.
How did I know this would turn into an OOP vs. Procedural war? Okay, maybe war is a strong word, but the new disclaimer at the top from Rasmus speaks volumes.
Well said Buddha. If the Java vs. PHP argument means you have to turn your code into something that looks like Java, then you might as well use Java.
Your article just confirmed the impression that I had when trying to make one of those monolitic controller. I was jailed in that controller and could not event do what I wanted to do.
Now I changed my way of coding, puting the controller away and now I'm free to do more in less time. Maybe I'm not a super MVC guru but I'm free. (If you find my comment quite unreadable, it's normal: I'm from Quebec)
"It is downright scary how much we think alike. Even your code looks so much like mine you'd think I stole everything I do from you--which in a way is partially true"
I think I can fully subscribe to the above post. Hire me! ;) I know OOP and MVC purists will frown at the code, but I really have a hard time 'getting' the benefit of turning all (and I mean all) functions into objects and adding layer upon layer of abstraction for the sake of 'architectural style'. I my own experience, when a new coder is brought on the project 2 years after the initial one left, most of the time it will in fact be easier for him to grasp what a single function does and what it should not do than fully understand the delicacy of object manipulation - especially if the object coded by guy nr. 1 is poorly documented and makes a lot of assumptions about its usage patterns. As for the framework craze, they generally have a very steep learning curve. The main benefit arises from the fact that you can expect the next-programmer-in-the-row to know the chosen framework and understand it better than the code you have developed in house. Unfortunately, they come and go so quickly that it is more than likely that this will not happen. My 2c. gaetano
I find your article somewhat refreshing in the fact that if you want to seperate your code along the "MVC" lines you can do it simply without using complicated frameworks. And if you don't want to seperate it out (leaving your controller code in the view itself) then that is fine too.
That is what makes PHP a joy to code in. You are not hog-tied into doing things a certain way. If you want to make your application complicated by developing your own or using an existing framework, go ahead. More power to you. But I like to keep things as simple as possible. And I totally agree with Rasmus. HTML should look like HTML, Javascript like Javascript. All I know is that, when I go back to work on code I wrote years ago and all I did was page-based development with the controller at the top of each view, it is fair easier to debug and maintain than the complicated mess you can get into by abstracting your application and splitting up all the elements that make up a request across a billion different files. In my book, simplicity always wins out versus complicated.
"Monolithic controller" sounds as if you were doing something wrong. As I said, controllers should be focalized and simple, and you achieve that by separating responsibilities with the correct use of objects.
True, the learning curve to most of frameworks may be steep, but once you really understand their structure (which is similar to most) it gets much easier to take someone else's work, just because you know where to find things. You know what to expect from the framework. It is not about piling up layer after layer for the sake of it. It is about a scalable structure. When everybody knows the structure it can only be a good thing, and that's what patterns are all about.
Sorry to comment again, but I was wondering if along with your example of simplifying MVC, you could throw at us any certain type of directory structure that you use. I see how structured the directories have to be with Rails, and other frameworks, but using your approach, do you have any certain directory structure for your files that you like to use?
Again, nice article, great way to break MVC down simply without all the objects.
I think that's really personal preference. I like to have any code that has HTML and CSS in it in one place and the rest elsewhere. In my example I did that by moving the model code into a model/ directory. In some of my full applications I put all the backend business logic (model) code outside of the docroot on my include_path.
Lee - Here's the (Rails-like) directory structure I use for framework-less PHP: http://jonaquino.blogspot.com/2006/03/what-makes-rails-great-its-directory.html
Rasmus, I was hoping you could answer a question. In your article you say "I tend to use separate include files for each table in my database." In your example with 1 database that works out very well. But what if you have to be able to manipulate some more tables. Say for example an webshoplike application. After posting a form, several tables like items_in_cart, items_in_stock, orders, etc etc must be updated. Would you include a seperate db.inc for each of those? Is there a point when you would take a different aproach? What is the advantage of using seperate files for each table, compared to one common database class with methods to select, add, delete etc?
Ok, this turned out to be more then one question, but I hope you get my point and shed some light on this.
Well, I should say a separate file for each set of related tables instead I guess. If the same set of tables is always used together, lump the calls to manipulate them into the same file, but separate things that are logically separate. From a performance perspective you are better off with less files that are larger than more files that are smaller.
"From a performance perspective you are better off with less files that are larger than more files that are smaller," on a shared server, all file operation seem costly.
Trying to keep file operations small and few has lead me to build the PHP files with only data and functions needed (I use a perl script to do this). This results in PHP files optimized on a per request basis but with the drawback of lots of code duplication on the production server. There other benefits when it comes testing, maintenance and code reuse. It has developed into metaprogramming.
I've nearly finished the explanation of the Ruby code. Because I wanted to get Railsish coding style, I haven't translated your code line-by-line. I've looked at the example application, and used that as a goal, so there might be things I overlooked. It is very possible that my application doesn't do the same as yours, but from the user's perspective, they are functionally equivalent. When the user enters incorrect data, the missing fields will be highlighted. If the data is good (all the fields are filled in), the user will see the updated list, and a fading "modified" text. I've positioned this text relatively, but it could easily be positioned absolutely with CSS.
Port to Rails, with code + explanation (no ruby course though ;-)):
http://www.web-site-build.com/no-framework-application-on-rails/
After reading chapter 14 of the PHP5 Power Programming book, in particular pages 467 and 470, I got the impression that an opcode cache like APC would "tuck away" the require_once and include_once. You seem to say here that require_once are slow under an opcode cache, hence contradicting what I had understood. Can you please clarify this point?
The opcodes for the included file will be "tucked away" in shared memory. But we still need to identify which opcode array to pull out of shared memory on an include. When running under an opcode cache include_once and require_once do an extra open() syscall compared to their include/require counterparts. Of course they end up not actually reading from the file, but because the functions are geared towards a non-opcode cache environment there is a bit of a mismatch. I will eventually come up with a workaround for this. Maybe by adding an extra hook, but for now you will take a slight hit if you use include_once instead of include everywhere.
Don't get too depressed though, it's not a big hit, but if you are trying to squeeze every last bit of performance out of a system, this is one of the places where you can save a syscall. Have a read through this for some more APC optimization hints: http://news.php.net/php.general/231433
Sometimes I use defined like in C headers to avoid the use of include_once in situations like this.
If the file filex.php may be included more than once and there's seems to be no way to rewrite the code to avoid include_once then I use define('INC_FILE_X',true) at the top of filex.php and instead of include_once if(!defined('INC_FILE_X)) { include 'filex.php'; } Quicker than an open() syscall right?
There is already a PHP implementation for an MVC Framework that works like RoR and already has the basic functionalities that RoR does like, ActiveRecord, Ajax, Html objects, JS Effects.
There is a sample blog application along with it, to let you experiment with the feature. Though this is still in its pre-alpha release, but early evaluation will determine if it looks promising or not. You might be interested in taking a look at phptarsier (http://www.sourceforge.net/projects/phptarsier/).
If you're looking for RoR inspired frameworks you might want to check out http://www.codeigniter.com as well.
- very easy installation ( No PEAR, just unzip, update config and ready to get coding ) - source code easy to understand - clear and concise documentation
Rasmus, have you had a chance to play with the Zend Framework (0.1.2)?
I'm very curious to know whether you will stick with your current approach to building php apps (which I very much like by the way), or if you'll adopt the Zend Framework once it becomes more stable.
Looks like all member functions of class item could be static. Any particular reason why they are not?
|
In his famous pragmatic style, Rasmus Lerdorf has shared an article on his Toys blog that will walk you through what he calls a "no-framework PHP MVC framework." The task is a simple rich Web application, with SQLite and PDO for data abstraction, Ajax an
Tracked: Feb 28, 14:25
Rasmus Lerdorf, Benevolent Dictator for Life, posted on his blog an entry The no-framework PHP MVC framework: So you want to build the next fancy Web 2.0 site? You'll need some gear. Most likely in the form of a big...
Tracked: Mar 01, 01:34
In the end, the no-framework framework that Rasmus proposes isn’t so much of a framework as a coding style / approach, and he basically advocates rolling your own instead of refactoring someone else’s complicated framework. Still, some go...
Tracked: Mar 01, 09:50
«The no-framework PHP MVC framework» — это достаточная спорная статья, опубликованная Расмусом Лердорфом на его блоге (Rasmus’ Toys Page). Вначале автор рассказывает о том, что все эти многоуровневые фреймворки ...
Tracked: Mar 03, 07:30
Tracked: Mar 09, 18:41
Rasmus Lerdorf, the giant pulsating brain behind PHP, has posted a very interesting article about a “No-framework PHP MVC framework” which, frankly, breaks my brains. I’ve posted this here for my own purposes, but it looks like a grea...
Tracked: Mar 14, 06:20