I am quite a new Zend Framework user but I am not new to PHP or Programming. I have been going through the code to try and get to grips with how everything slots together. One of the parts I have been looking at is how classes are Autoloaded in the system. I can see that:
Zend_Application_Bootstrap references Zend/Application/Bootstrap.php
Zend_Controller_Action references Zend/Controller/Action.php
... etc etc
Essentially _ get converted to the directory sepearator and get autoloaded.
What I don't understand (although im sure there is a good reason) is why this convention isn't followed for action controllers?
IndexController references Application/controllers/IndexController.php
Why not:
Application_Controllers_Index -> /Application/Controllers/Index.php
or
Controllers_Index -> /Application/Controllers/Index.php
?
I am guessing giving the class a suffix reduces some complexity in the system somewhere, from first looks at the zend framework everything is very well thought out - I cannot imagine conventions are introduced without good reason.
Can anyone explain why controllers are prefixed, or even better point me to some code in the core showing why they have to be prefixed?
Thanks :)
To be honest, I'm not entirely certain as to why the conventions were originally developed. I suspect they had to do with how other frameworks were evolving at the time -- in particular, RoR was spiking in popularity, and this was how they defined application resources. (At the time of the original MVC iteration, I was just starting at Zend; I did a rewrite in fall of 2006, but the goal of that was to keep it as consistent with what had been developed previously, while simultaneously offering better and more flexibility.)
We've continued along the paragigm as it reinforces the idea that all items under the application/ hierarchy are resources, and not your library code. This is particularly important due to the fact that you may have non-class code within this tree (view scripts, layouts, etc.).
However, this has certainly made for a few headaches -- the introduction of the resource loader shows that we had a problem we needed to resolve. The resource loader basically addresses the symptoms, but not necessarily the root cause (poor conventions). As we work on ZF2, this is something we will be revisiting. If you're interested in posting your thoughts, I invite you to do so on the zf-contributors mailing list.
File names and classes names of Controllers should has a postfix Controller. Zend see a postfix in class name, and understand, that it is a controller. He finds this class in controllers folder.
I'm only fairly new to Zend Framework myself, but from what I can tell, given the way the Zend Framework currently stands there is no good reason for this. I'm not sure if it's a hangover from the way things started out, or just the preference of people involved, but I've heard this will be changed for ZF 2.0.
Related
I started using and testing Symfony 4 for main project migration. I was used to getting told by Symfony on how files should be structured, but now when there are no more bundles, I wonder, how to structure huge monolith application.
Scale now: ~300 routes, ~70 controllers, ~90 entities, ~20 bundles
How services.yaml should look like? - should I stay on App namespace or maybe I could simulate bundles? Where to put service configuration for each component?
How services and controllers should be separated in directories? - Should I go for src/Service/{Something}/{Something}Manager.php or stay on src/{Something}/Service/{Something}Manager.php and just don't use Bundle keyword? Why?
Where would you put UserAuthenticationProvider and/or WebSocketServer?
I've made a new set of REST APIs for a legacy monolith application and faced the same questions.
I will answer this question first:
How services and controllers should be separated in directories?
I went down the src/Service/{Something}/{Something}Manager.php path as I thought that that was the way. As the project has grown, I regret that and will be moving to src/{Something}/Service/{Something}Manager.php
Why?
I find the separation in namespacing much easier to read and much
harder to accidentally use the wrong class.
I now have files split out across the application and it's much harder to abstract it into a library that can be re-used by other applications.
I can't refactor functionality as easily - everything is spread out an
intertwined. If I were converting a monolith, I would prefer to have
code to refactor that was bound by some function so I could work on
that, before moving to the next.
There are other reasons but feel the need to separate this back out before the application gets any larger.
How services.yaml should look like? Well, the autowiring is amazing. I would keep your service yamls in the various functional splits (as above) and start refactoring them out. With the default autowiring config, you'll find that very little needs explicit definitions.
Where would you put UserAuthenticationProvider and/or WebSocketServer?
For the provider, probably something like, src/Security/Authentication/Provider/UserAuthenticationProvider.php.
For the WS server, I'm not really sure - it depends where it sits in the app and how it's used.
To start with, S4 still supports bundles pretty much as before. The config section has been reorganized a bit but if you already have a huge app working under bundles then you might just consider keeping it more or less as is. It should still work just fine with minimal tweaking.
There are a couple of approaches for a bundle-less app. Typically you would group files by functions using feature sub-directories to keep things organized.
Assume you have three existing bundles called FooBundle, BarBundle, JarBundle
config
services
foo.yaml
bar.yaml
jar.yaml
routes:
foo.yaml
bar.yaml
jar.yaml
src
Controller
Foo
Foo1Controller
Foo2Controller
Bar
etc
Entity
Foo
foo entities
Bar
bar entities
Form
etc
templates
foo
bar
jar
You get the idea. Might be worth modeling this all out in advance especially to see where the odds and ends might fit. And probably use the App namespace for everything. This approach pretty much follows the Symfony 4 best practices. Can't really go to far wrong with it.
There is at least one other approach in which you group files by features. I won't go into much detail as it's definitely not the normal Symfony approach and will take some tweaking. But you could do:
src
Blog
routes.yaml
services.yaml
BlogEntity.php
BlogVoter.php
Edit
BlogEditController.php
BlogEditForm.php
BlogEditTemplate.html.twig
etc
Show
BlogShowController.php
etc
What I'm looking for is a way to remove the model from a set of PHP files that make up a website. It's difficult (for me) to explain.
By models I mean models in an MVC sense.
As an example say I have this website:
index.php
about.php
shop.php
checkout.php
All of the above PHP files use the same database. I have separated the views by adding templates using a view.php file that renders the correct template with values passed to it.
I am not looking to use a framework that's already out there. I'm looking at writing my own in some senses, with only the bits I need to use in it.
If anyone would like to explain why this is not necessary, or a better way of doing things, then I'm open to that too.
Thanks in advance.
Writing you own MVC framework will take time, but you will learn a lot in the process. So, if you have the time/resources to do it I definitely encourage you to do so.
In this context here are some small pieces of advise that may help you:
Create your domain model first. I'm assuming that you are going in the OO way, so think about your domain problem and create the abstractions that best represent your problem. Try to keep it decoupled from cross-cutting concerns, like persistence.
Test a lot, test often. Try to test (and run your tests) as you create your domain model. This will be specially valuable when in 6 months you add a new feature and want to make sure that you haven't break anything. If you can separate your domain model from anything external (like the persistence layer or third party web services) the testing it is going to be a lot simpler. Today PHPUnit is pretty much the de-facto standard for unit testing in PHP.
You don't have to write everything from scratch. There are a lot of libraries that can help you to ease the development of an MVC framework, so that you can concentrate on what you really want to develop. For example, you could use Slim to handle the page routing or you could delegate the persistence stuff to Doctrine 2.
It is always nice to analyze how other frameworks solve things. You may want to look at products like Symfony or Kohana or even check how Elgg handles its views system. Also, if you want to check out something radically different you can take a look at Seaside's architecture.
Coming back to your original question, for me the key is to keep things from different layers as decoupled as possible. While I have only used the version 1, Doctrine 2 seems like a good candidate for persistence, since it allows you to create a domain model that is quite independent from the DB. This is a huge step. The second thing is how handle the view system. This is quite developer-taste dependent. For example, I like to model everything with objects, so I like Seaside's approach. On the other hand, Elgg's way of handling views is quite nice and maybe fits better with the way things are handled in PHP. Here is when you may benefit on doing some research before deciding on a route to go.
HTH
As someone who has written his own PHP framework, and with the same sensibility as yours, I can tell you that using a framework is a fine thing to do. That said, start by writing your own - you'll gain greater appreciation for the true structure and utility of a framework.
You'll want to learn about the Singleton object pattern. It is a major differentiator in the kinds of objects you can develop in your framework.
When you have written a few models that your files/controllers (presuming MVC) include, you will begin to see where to abstract a 'base mode' from which others extend (hint: the DB singleton).
When you start pulling in configs and the like, then you'll have your first framework object from which all other bases do their extension.
I have almost completed a PHP project, using MVC, jQuery and Ajax. It is pure PHP project. I don't use any frameworks in the code right know. I would like to change that.
Doing some research, I found, that Yii turns out to be one of the best frameworks out there.
Is it possible to somehow migrate pure PHP project to Yii?
If so, then how to do this? Which steps should I follow in order to reduce the workload and enjoy the benefits the Yii framework presents?
I'm a total Yii newbie, any insights appreciated.
TL;DR : Don't do it. It's a really horrible idea.
The Rant ..
"Framework" is not a magic sauce, that you add to a project, to make it better and shinier.
Doing some research i found Yii turns out to be one of the best frameworks out there.
What a strange research you have done .. I would love to see the materials. Especially, since I would rank it as 3rd worst PHP framework. Only surpassed in it's awfulness by CodeIgniter and CakePHP.
And the reason for it is the extremely bad quality of code, that this framework displays, combined with the bad practices, that it perpetuates.
Why avoid migration?
From your description is obvious, that you are NOT familiar with this framework and have no previous experience with it.
In management of projects there a subject: risk management. And in this case, adding a previously unused framework in final stages of project would constitute a high probability an high impact risk which also, due to the sage of project, is completely unmitigated.
It means that there is a really good chance that something will go wrong. And when it does, it most likely will sink the project. Or at least push back the release data by significant length of time.
In a perfect world frameworks are used to simplify the repetitive tasks of development, at the cost of some performance. Those are the tasks you do at the start of the project. You are not at the start of a project. This means that you will gain no benefits from this "maneuver".
Why not Yii?
As I noted before, there are also reasons not only for avoiding adding framework to an existing project, but also reasons why to avoid Yii in particular.
The inheritance nightmare
All your controller will extend class CController, which extends CBaseController, which extends CComponent
All your "models" will extend ether CActiveRecord or CFormModel, which extends CModel, which extends CComponent.
Both of there chains contain static variables and execute static methods on multitude of different other classes. Combination of these factors will make debugging extremely difficult and tedious.
Global state
There are several forms of global state. One that people in PHP usually know are global variables. But that is not the only form. Every time you have a class that contains a static variable, it also creates a global state, that can (and almost always - will) cause seemingly unrelated instance mysteriously interact.
Use of global state is a core mechanic. You will see static calls all over the codebase, and the Yii's configuration file would not function without global state.
And every time you call Yii::app() you are accessing and/or changing it.
This makes unittesting impossible for Yii applications. And debugging turns into exercise of using grep on your whole project.
Tight coupling
When you create an application in Yii. It becomes bound to it. You cannot execute parts of your application without launching the full framework. Mostly it is due to the static call, that you end up adding to your code.
Every time you add a static call in your own code, that piece of code becomes tied to the name of the class. That essentially is tight coupling.
As you might have noticed (hopefully), there is another way how to achieve the same effect - the use of new operator. That is another way of coupling some code of yours to a specific name of a class.
No interfaces .. none .. whatsoever
No matter how horrible the configuration of a Yii project is, the configuration file was a well intended gesture. The least harmful way to introduce external code and replace existing components in so messed up codebase.
But unfortunately it brings in the focus the problems caused by lack of interfaces and the existing coupling.
One of the component that developers will try to replace is the CUrlManager. Mostly due to way how you can pass additional parameters.
An interface in OOP specifies the contract between two instances. It lets you define the capabilities of an instance, the methods that can be used by others. When it's not there, in a large codebase, you are left guessing, which methods are required and which are not.
In case of Yii components the problem is compounded even further due to static call and deep inheritance. The above mentioned CUrlManager extends CApplicationComponent, which extends CComponent. Also the same file defines CUrlRule and CBaseUrlRule classes.
When you are writing a replacement, you have to write some code, plug it in the configuration and then test it by running your applications. That way you know which method (or parameter) next you need to add.
Basically, it's the "save-an-see-what-blows-up" method of development.
That's not MVC!
Yii does not implement MVC or any of MVC-inspired design patterns. What it calls "MVC" could be described as ActiveRecord-Template-Logic pattern.
Instead of having proper model layer (yes, it should be a layer), the creator(s) of Yii opted for collection of active record and form wrappers. This forces the application logic to be forced in the "controllers".
On the other hand you have glorified templates, instead of proper view instances for containing presentation logic. It is somewhat mitigated by use of widgets, but those instead suffer from SRP violations, because widgets are forced to contain bits of presentation logic and perform partial rendering. The rest of presentation logic ends up again in the controllers.
And to make it all worse, the "controllers" also have to deal with authorization. This usually will mean, that whenever you change the access scheme, you will have to go through every single instance of CController to check whether it needs to be changed too.
It's not MVC. It's a mess with names taken from MVC design pattern and slapped on some components.
All the small things ..
The framework also comes with few minor issue, that do not deserve a separate section:
Defining more then one class per file:
This will get annoying quite fast, because there will be classes that are shoehorned at the class files with completely unrelated filenames. This will mean, that debugging will quite often require use of search.
Slapped on "modules":
By the looks of it, the modules where added to the framework after the fact. Which is why, when you need to set default module, you will have to set it in the configuration files parameter, that is called 'defaultController'.
I actually recently converted a MVC pattern website I had built from the ground up into Yii. It did take some time to set it all up but in all honesty it was well worth it. I was able to throw away a lot of code because there were already Yii extensions doing what I needed. I would also suggest that you keep your database because you can create the controllers and Models using Gii which will save you a ton of time.
I don't know of any quick solutions to this. It depends upon how the code was written. You have the database and your views so it is not really a complete new project when you take into yii. Yii will generate the database models for you. You already have the views from the existing project. Write the controller and actions and modify the views if necessary.
try these links as they refer to the same problem.
How do you convert an old oop project into Yii
tips on migrating an existing site to Yii
Drupal to Yii Migration
Since you already have a code in mvc, things will be much easier for you to migrate. However, while migrating to Yii, since it can generate controller and model very easily using gii, you can take the advantage of it.
So, first generate controller and model using gii, then you can replace your existing code (by replace I mean, substitute your code to the specific function in the controller and model) to the built in controller and model so that the functionality of your site still works. You can modify your view accordingly. But that won't be much of a work.
You can simply register your script for ajax, jquery and css. Those will work as well.
And yes, Yii is the best framework out there so take as much benefit as you can.
Thanks,
Ujjwal
In this project you converted php to yii framework. Its really easy for you if you do following step.
Since you already have a code in mvc, things will be much easier for you to migrate. However, while migrating to Yii, since it can generate controller and model very easily using gii, you can take the advantage of it.
second, If your database is accurate then 50% work complete.when you create CRUD operation using gii then automatically model-view-controller create.if you create mvc in php then it benifit for you.
third,You can simply include your script for ajax, jquery and css. Those will work as well you create a folder in themes(CSS,JS,AZAX,BOOTSTRAP).
four-Protected->view->layout, where you can change your theme..thats all
you also help www.yiiframework.com/doc-2.0/guide-intro-yii.html
if you think my answer is help you then rating me...thank you.
Blockquote
Edited:
http://blog.fedecarg.com/2008/06/28/a-modular-approach-to-web-development/
The above approach is what I'm looking for. So are there php frameworks available which will allow me to create modular structure like above for my code ?
Edited:
Blockquote
I would like to know which is the current best php framework which is 100% modular like joomla component architecture.
In joomla all you have to do is upload a set of files under the "components" directory and you can add "any" kind of complex functionality to joomla.
I want to develop php applications from scratch and I want all of my applications to have the same ease of joomla's component architecture. So Im currently looking for a php framework.
So which is the best way to go about if I want to do the above ?
Should I choose a php framework like codeignitor or zend etc ? but you see, even if is use them, Suppose if I have to create a new function I have to upload files to atleast 3 directories i.e controller, model and view. But you see in joomla all I have to do is upload all the files of course suitably structured into just a single directory called "components" and the rest is taken care of automatically
So what is the best way to go forward ?
Shanthi
Joomla is a CMS system AFAIK so you cant really compare a PHP framework to it.
In terms of modularity Zend Framework has an excellent excellent, simple to implement module structure.
You sat that to add complex functionality to joomla you upload files in the correct structure and joomla does it for you, well as long as you create your module files in the right structure for ZF it will work too......
Your question is same as my question. but it was for 4 months ago.
I tried to find out how can i create such modular system. After some searching I understood that we should have a single directory like 'components' as you said, and put every data of modules in it. but how we should use them ?. Easy !. just create an handler (php file) that control your installation, uninstalling, positioning, settings. In fact i just solve 3 of them. positioning is so hard i think so, i never do it till now.
if you want an example of my explanation, just tell me to create it. I'll send it for you. :)
well i think you are comparing apples to exotic devil fruits or something.
you are adding modules to a cms and exepct the same from a famework.
it doesnt work like this.
the mvc structure you are talking about (model - view - controller) makes a lot of sense and helps you to keep your code organised and to keep up good class coherency.
its a design pattern which has evolved to a de facto standard and has been adopted by almost every framework.
zend framework is probably the best way to go for you.
its layouting engine and stuff is not as fast as one could wish, but it features execellent modularity. you can even partly overload core classes to suit your needs in your "module".
only abstract classes dont work (how should they?), thats why they are almonst never used.
if you really really wanna go with a very flexible excellent system and performance is not the most important point for you, you should get going with magento, which takes the modularity and flexibility even to a higher level by adding an xml structure to zend framework that allows you to organice all your pages, manage your dependencies, rewrite your model componenents etc.
but be a aware that the more you want the more performance you will loose. my personal fav from the frameworks out there is codeigniter, but i designed my own for my needs...
I agree that there is a difference as Joomla et al as CMS's and therefore come in at a higher level of functionality than a framework, but of course with less flexibility.
However you might want to explore Symfony 2 and Lithium (Cake 3?). Both are designed to only use PHP 5.3 and greater and both use the namespace functionality in PHP. I have done less with Lithium but certainly in Symfony 2 everything (well nearly everything is a plugin making the framework modular and much easier to manage.
However you will never be able to compare the two Framework/CMS in exactly the same way as they are both built and designed for different purposes and with varying constraints.
N.B. Neither Symfony 2 or Lithium are production ready at present. Symfony is aiming at March 2011, not clear on Lithium's 1 dot oh date
[edit]
A number of answers here plump for Zend. What needs to be clear is that there are two types of framework (yes ok lot's and lot's) but being simplistic there are Full Stack and Glue.
Glue frameworks like Zend tend to be free and easy allowing you to use some parts and not others as you wish. So although nominally MVC you can easily implement Zend with V and C but not use M. You can write all your database calls manually in the controller etc.
Full Stack such as Symfony mean you pretty well use all of whether you like it or not. On the data side you use and ORM, Doctrine or Propel and a large amount of the framework is controlled from configuration files in YAML/XML. In this respect Symfony is very like Ruby et al. Please note this is not a recommendation or criticism of either.
Joomla in my opinion is gluey (but not a framework) but hey why use something that is 90% built and then rewrite 75% of it? Oh yes because the customer asks and your boss is unaware of the problems, i remember now.
I've asked this question on the zfforums as well, but I maybe I'll get a response here.
So the Zend Framework is a general purpose, flexible, loosly coupled, high quality framework. However, I find some of the MVC parts inconsistent and overly complex. Hopefully some of you can justify some of the zf design decisions and answer some questions:
General Questions/Comments
Why doesn't zend mvc follow the same naming conventions as other zend components? For example, mvc uses lower case, plural directory names and class names aren't prefixed with directory info so they can't be easily autoloaded.
I'd like the option to add a module root directory. That way, I wouldn't have to explicitly configure the dispatcher by adding controller/module directories. I'd be able to drop in a module and have it accessible immediately.
Why is there a distinction between view and action helpers? Currently, the helpers aren't designed to be shared throughout the code and there are inconsistent methods of loading and accessing the helpers. Other frameworks allow you to share the same helpers anywhere in your code. I don't see the need to specialize and violate DRY.
Zend View Questions
Why do views use "$this" to access resources? I don't see the need for the extra typing. Some other frameworks extract() an array of view variables and allow loading global functions or autoloading static helpers from within the view: myHelper::someMethod();
Why do view helpers only allow one function per class? That results in a lot of classes and associated maintenance. I'd prefer static classes with any number of methods as already mentioned.
I´m using the Zend Framework in a huge intranet site, since it´s early stages, 0.3 or 0.4 I think, and I followed the most of decisions regarding your questions. I´ll try to explain them a bit:
In most cases you don´t need to use modules. You can drop all your controllers in your application/default directory, name them IndexController or HelpController and you´re done, just access http://www.domain.com/ or http://www.domain.com/help.
If your project starts go grow you can add modules as you wish, prefixing them with the name of the module (directory name) Admin_IndexController or Forum_PostController, acessing them by http://www.domain.com/admin (you´re in admin module, index controller; not in default module/admin controller).
You can set your modules directory at applicatoin/modules, for example, and configure the FrontController to look at this directory for modules. Using addModuleDictory Whenever you create a new directory and put your view/controllers there, they´re auto-discovered by the dispatcher. Here is an example.
As I see they serve clearly distinct purposes. ViewHelpers are used to generate markup and render other actions directly in the view, abstracting menu creation, sidebar, etc. OTOH ActionHelpers interact with the dispatch process, allowing you to redirect to another action, as an example.
Views
In the beggining I too felt it a little awkward, but I got used to. I think the main reason is not to pollute the namespace, but I can be wrong with this. By the way I´m not very fond of the use of extract(), but it´s just my personal preference.
For the main reason that it´s not allowed to have more than one controller per file: autoloading. When you use $this->someViewHelper() the underlying engine looks for a class named *_SomeViewHelper_Helper in your plugin paths. Another reason is that static classes are very hard to unit test against. There´s even a proposal to rewrite the FrontController as an instance class, not a Singleton.
You´re right about the overly complex part that you say in your second paragraph and the developers and community knows about it. It just has to be this way to accomodate all requiriments and variations.
In the end I think that ZF is a very robust framework, giving us the freedom to do what we want.
I hope I could help you clearing your questions.
I don't know all the answers to these but they're interesting questions so I'll have a stab and hopefully someone can fill in the blanks.
General
Classes not in the default module are prefixed with the module name, e.g. Admin_IndexController and would reside in /admin/controllers. I think the reason for the separation, and inconsistent naming (vs. library classes) is that there would be little benefit having them in a nested folder structure. Controllers are part of your implementation so I think it makes sense, personally. Traversing the folders does get a little tiresome, however.
You could modify the dispatcher, or write a plugin to scan for directories and add them.
There is definitely overlap here - the URL helpers are a good example of this. Generally a view helper generates markup so I think there's a big enough distinction.
View
I don't know the exact reason but I'd guess it allows other helpers and view functionality to work together more easily. For example, if you've used the doctype helper to set the doctype, the form element helpers can generate XHTML or HTML as appropriate.
It definitely results in a lot of classes, but I'm not sure about maintenance. I've not run in to any problems. I can see the use in static classes, but remember that Zend_View won't stop you using them. If you have your static classes in your include path (and use Zend_Loader or similar), you can use them instead of or in addition to View Helpers.