I was disbanded here at the request of Dean, and I decided to benefit society. Since I am a fool and I do not know how, let me think I will write about ZF - an awesome thing that for some reason everyone sincerely hates. It is necessary to have time, however, until Pelevin was shown on NTV (unfortunately not real).The main problem with all kinds of QS is that they are really quick and really start, but if you do everything there, you’ll end up with a not-so-scalable application that’s not very clear what to do. Compared to the official quickstart of the previous version of Zend Framework, the
new one is just great, but not without flaws. I will go from the other end: instead of explaining how to do something meaningless and typical, I will try (!) To tell you how to write an application in general, using Zend Framework in various ways. And it is time to do habrakat.
Zend Framework is a magical and happy PHP framework for real men (;-)). For me, ZF is the only opportunity to write a easily-written, scalable and quite accompanying web application in a very short time (6 hours is easily done without much effort authorization set + registration + posts + tape + tree comments + tea + coffee + dance), favorably differing from solutions, where in general almost nothing needs to be done (Wordpress, Drupal, ...) because the programmer does not impose anything at all: ZF, in principle, is a set of interrelated classes: you can use only those that you want, keeping that style razra bots that you like best. You do not want to use Zend_Auth for authorization? And who forbids you to write your something? ;) At the same time, it is beautifully and very logically built (all sorts of classes, parentes, interfaces, all garbage): it is convenient to rewrite it, for example, simply by inheriting some of your own class from the standard Zendovsky and adding what you want to finish writing (just not arrange in the comments of the holivars "ZF against something. Please, do not arrange at all).
Aha So, what we will have will be (I hope) difficult, but logical and more or less beautiful: it will be easy to finalize and easy to understand where we have what. I am an idiot and amateur, and therefore I can’t claim that all my moves are really reasonable, correct and that I use all the possibilities: I will say “thank you” for valuable advice, additions, refutations and so on. Oh yeah, and I think that one article here is not limited to. Moreover, the first may seem rather trivial, then wait for the second 8) Specifically, in this one I will talk about working with Zend's MVC implementation, later I will stick to it, but I hope not to forget about the workers who don’t like it.
')
I decided to repeat: “I'm not a hacker, I'm just learning.” Do you know better? Let's rewrite this / write the following article together so that it is even cooler ;-)
And yes, I love you very much, but in the comments you will point out grammatical or punctuation errors or typos in the code - Nasru into karma. Write in habraposhta. No one needs these temporary fixes looming under the article that cannot be removed.Go!
The first step is to
download the ZF, and then run through the
quikstart , at least until “Create a Configuration and Registry”. Then some kind of garbage comes with SQLite (I’ll never understand the sense of skylight), and then Zend_Form is used in general (I’m against this kind of entertainment, bitch - we’ll write all html with pens or ask the web designers, if you want, nothing complicated there). From the skeleton that you succeed, we will dance.
So, we have something like the following (which is not - leave it, if something extra - well, figure out what to do with it):
+ application /
+ config /
* app.ini
+ controllers /
* IndexController.php
* ErrorController.php
+ layouts /
+ scripts /
* layout.html
+ helpers /
+ models /
+ dbtable /
* SuperModel.php
+ views /
+ scripts /
+ index /
* index.phtml
+ error /
* error.phtml
+ helpers /
* routes.php [1]
* bootstrap.php
+ library / // [2]
+ zend /
// tru la la ...
+ public / (he's htdocs / for me, but it doesn't matter)
+ static /
// [3]
* index.php
[1] - in this file are all routes. It is then included in bootstrap.php (after qs the routes should go in the bootstrap itself, but usually I get a lot of them)
[2] - I would take this folder to a higher level, that is, say, if you have it all in /home/va1en0k/coolsite.ru/, then why not keep the libraries in / home / va1en0k / library / instead of / home / va1en0k / coolsite.ru / library /: it will be easier for the rest of the programs to reach them
[3] - there will be different cool CSS, JS files, pictures - all canoe. They can be spread by styles /, images /, can be transferred to some other server, no one forces them to keep them here: HTML, we write all
Everything is quite simple, the usual MVC. The algorithm for writing a program like this (it is somewhat different from the “development through testing”, which everyone loves so much, but, in principle, you can arrange tests of the type, controller, and model before / after / during their development):
- First of all, we need something that happens during a certain user action: the designer asked us about it or something else there;
- Action is always a url challenge. We come up with an url (it can be any, but we all are very happy with urls of the form / “controller_name” / “action_name”. But, let's say, to get a post, it's better to have something like this: / post / 12321, isn't it?), We decide how it will be processed by the controller (none does not fit? We create a new one in / application / controllers /), we add an action to this controller;
- We create /views/scripts/ controller controller name / action_name.phtml, draw the html we need there;
- Where you need to display something that is not displayed on other pages, we write: <? = $ This-> shachlo?>, Write down or remember what we need;
- Where it is necessary to display something that is displayed a lot where, for example, the name of a user, we write something like <? = $ This-> printUser ($ this-> user)?>;
- Now we go and create all the helpers we need (helpers are functions that are called like this: <? = $ This-> printUser ($ this-> user)?>). We write them in / views / helpers /. It is better to make them separately so that at any time you can add an icon to the names of users or apply some other style. Or replace them all with the word SCHACO, so that all users simply ohreneli with surprise! %)
- Jumping up with happiness, we write an action. The whole action code can (why not) be divided into 3 parts:
- We deal with the arguments: get the data from the forms or from the URL there (if the URL was / user / 12345);
- We do what is required of the action: we launch a rocket into space or send a message to the taxi driver on a pager. If we need data from the database, or if we need data from some Last.fm or Twitter, or some other data — any at all — ask for a model. If the model [for now] does not know how to issue, we ask as if it can: $ this-> m-> twitter-> getUser (“va1ka”); or is there $ this-> m-> getUsersTable () -> getUser ("va1en0k"); - as you wish, request;
- We give the view all that he asked in step 3: $ this-> view-> shachlo = "popyachtsa"; etc.;
- We add to the model everything we asked for in the previous step.
This algorithm is almost universal (if we need what happens in any action of the user, we must act a little differently), and I recommend sticking to it as clearly as possible. Why first view, and then the rest? Well, for two reasons, firstly, 37signals are advised this way, and secondly, this is the most reasonable way to understand what we need and how to receive. It is important to make sure that all requests to the data go only encapsulated through the model: then, luck, we can in case of something leave the database without looking at another or add a nice cache that speeds up our program, like resetting a stepped module. It is important to ensure that all HTML, well, that is, very, very all, goes through views or layouts in folders, in helpers, or just like that.
And now specifically for the three whales MVC.
View
As I have eloquently hinted, there should be all the whole HTML in the views. Any errors, anything, that's all that happens in the controller and - even more so - in the model should be devoid of tags and be a bare line. Any output constants (I mean, for example, taglines or “Error! The user name must be up to 25 characters! Kill yourself!”) Should also be stored in view.
How to do it? Helpers rush to the rescue! Create a helper (an amazing code goes on, which is not a fact that it is worth using as is, but, in principle, there is nothing absolutely awful in it. Just think for yourself how you want to organize what is happening):
class Zend_View_Helper_Errors extends Zend_View_Helper_Abstract {
public function errors ($ err) {
if (! sizeof ($ err)) return '';
$ html = '<div class = "errors">';
foreach ($ err as $ er)
$ html. = '<p>'. AppErrors :: getErrorString ($ er). '</ P>';
$ html. = '</ div>';
return $ html;
}
}
And also a class with a static method:
class AppErrors {
static function getErrorString ($ er) {
// return the string. We take it from somewhere: an array there or a database or somewhere else, translate, if necessary, via Zend_Translate and return
}
}
The $ err itself, the helper argument, is an array of "errors." An error can be encoded simply by a number of some, and maybe even an array, say, array ('err_id' => 666, 'err_arg' => 'satan'), if the error has arguments%) Well, or even an object, whom far fantasy perverted.
Controller
The controller consists of actions. Actions are the backbone (just like in a structural-functional sociology based on an integration approach) application. This is how an ideal request from a program designer to a programmer looks like: “Come on, if you press this button, this and that will happen”. Here, “this and that” are actions (to whom do I explain this?).
Before producing packs of controllers, I suggest making a cunning move: create our own front and action controllers and inherit them from them. Then, in which case, we will be able, for example, to prohibit visiting any pages without entering the site (as in the leper colony, for example), set various variables necessary for action controllers, and so on:
class SchachloFrontController extends Zend_Front_Controller {
//
here we do not forget to overload getInstance (), as the doctor
prescribed for us
} // don't forget to change bootstrap.php!
class SchachloActionController extends Zend_Action_Controller {
// in my opinion, it’s not necessary to overload%)
} // and inherit all the action controllers from it (these are the ones in / application / controllers /
Well, then everything is more or less clear. I advise as much as possible to break the code down into small functions, shoving them into the model or leaving to the share of helpers (both view helpers and action helpers). And do not forget: any data should be received in the model, even your grandmother's middle name%) Although not, its better to be in the config if only your grandmother is needed.
Model
With the model, in fact, I have the most doubt because of inexperience. Well, I personally usually do this:
For each data type I create labels in the database. There for the post, for comments, all the cases. If the data type has an array variable (for example, tags for a post), for it, the stump is clear, a separate label. Then for each tablet I create in / application / models / DbTable / my own file. Well, the main file is SuperModel.php - in which our lovely Angelina Jolie, who returns all the labels (which are stored in static variables) by their methods. Similarly, I shove the necessary classes next to work with the file system or external data sources (I recently worked with last.fm, with the help of Zend_Rest_Client without any pressure at all), and I shove methods into the supermodel to get them.
So, if I suddenly need to find out something, I’m looking at how many data sources it is. If one label: I add a method to its own class. If there is one tablet and several more for it (like, we get a post from a posts table and tags to it from tags, etc.), then that too. And if we need 2 or more more or less equal tables, I put the method in the model, but I organize work with each of the participating tables in it.
What else to say? Oh yes. Do not forget about cash. You can add a cache snoop to each method, or you can take 2 models at once: one will be as described above, and the other will call the first through the cache, at the same time turning it off when it is not needed at all. I’ll probably write about the cache if I’m not banned again. : D
Phew Like 13 kilobytes, and not very much and told. Amateur, what could be here! Waiting for your feedback.