Directory structure in MVC PHP Frameworks - php

At this moment, my framework's directory structure looks like this:
framework/
libraries/
autoload/
autoload.class.php
resource.namespaces.php
router/
tests/
router.test.php
router.class.php
resource.routes.php
configuration/
framework.configuration.php
router.configuration.php
controllers/
index.controller.php
models/
index.model.php
views/
default/
index/
index.view.php
header.view.php
footer.view.php
assets/
css/
javascript/
images/
index.php
When my framework was smaller, it was a lot cleaner. I have give a look at other popular frameworks. They have two main folders:
framework/
app/
web/
Actually, this structure is very clean and nice because we separate the front-end and the back-end. But I wonder what should I put in each of these.
Logically, libraries folder should be inside the app folder, but it is not really a part of the application. For me, an application has models, controller and views. I think libraries should be put outside. Where should I put my libraries?
I has a lot of PHPUnit tests in my libraries. Should I add a folder named tests inside each library, or should I put it inside/outside the app folder?
If I want to implement a template feature, where I could choose which template I want to use for my website, how could I organise it? Every template has differents elements, so header.view.php will not be the same, etc. Now, I'm creating a folder in views which is the template folder. But I think it is a bad idea, 'cause now, for every template I must recreate all the views.
In a lot of applications, there is a vendor folder that contains all the main classes. Is this the same as my libraries folder? Does it have the same role?
I also have some 'resources' files (eg.: resources.routes.php). They are used to add some routes/namespaces. It's a bit like a configuration file. Should I create another direcotry for these files, or put them inside the class which they refers to?

I'll try to cover all your questions.
The vendors folder that you see in many apps is from composer. In that folder are all the dependencies of your application/framework (often libraries from other people).
Composer allows you to pull in some good components for your framework so that you don't have to write everything from scratch. Say for example I want to use FastRoute because it is much better than any router I am capable of writing myself. So I just add the following to my composer.json, run composer update and I can use it in my framework.
{
"require": {
"nikic/fast-route": "dev-master"
}
}
You can also use composer to autoload your classes so that you don't have to write your own autoloader (and cache that for production).
I really dislike your current file names. adding .class to a filename makes absolutely no sense to me. The dots also just complicate Autoloading. I recommend you have a look at PSR-0 for some inspiration on how to handle file names/namespaces (This is supported by the composer autoloader).
For the tests you could create a Tests folder in the root folder of your project and in there recreate the directory structure of your project and add the test classes in the matching folders. You can also put your mock objects in there. This makes it easy to just run tests for a certain part of your application.
I also recommend that you move your application out of your public folder and instead have a public folder with only an index.php and your assets. That index.php does nothing other than requiring your front controller that bootstraps your app. Doing it that way adds another layer of security if for some reason your webserver stops processing PHP. Otherwise a visitor would be able to see your whole source code.
To get some inspiration for your folder structure questions, I recommend that you have a look at how other people solved this issue. Arya and PitchBlade would be a good starting point because they are way smaller than a framework like symfony.
I hope this helps. In the future I recommend that you split up your questions into different SO questions, that makes answering easier and you will get better answers because people who know the answer to one of your questions don't also have to answer all of them.

Related

Folder structure for modular development with PHP and vuejs (or angular)

Essentially, I'm looking to have a PHP development workflow that needs to be modular, but using a Single Page Application technology.
I understand it is recommended to separate the back-end from the front-end. Develop them separately. But is there a way to group all related code into one module (or folder), meaning all backend code with its own views presentation inside the same folder?
It's like MVC, but the "V" contains fragments of vuejs (or angular) files, which extends from a master file somewhere in your project.
For example
Assume we are building a modular CMS, where you can upload "plugins" (really, PHP modules), extending the CMS' functionality:
-project[root-folder]
----core[folder] # contains all infrastracture code, api routes, master view file, magic, etc.
----modules[folder] # uploadable modules goes here
--------User[folder] # sample module; follows the MVC pattern
------------Controllers[folder] # contains files, e.g. UserController.php
------------Models[folder] # contains User.php
------------views[folder] # where vue components is housed
----------------users/index.php # contains vue code
----------------users/create.php # etc...
----------------users/js/user.js
----------------users/css/user.css
--------Blog[folder] # another module
----index.php # the master view or just the bootstrap file
----gulpfile.js
Then inside the core/ folder, there is a master layout that binds all views together.
Will a folder structure like this be viable?
Obvious problem there is you can't use .vue files (as that would mean, every time you upload a new module, you need to run gulp or re-compile).
Hoping for your feedback. Thanks.
This question will strike a lot of folk as bizarre and twisted. That's the reaction I got when I asked it in the context of .net mvc. I'm with you 100%.
I'm too new to js frontend development (and too ignorant of PHP) to have much advice. It's going to be tricky. Ajax calls to PHP code will need to go to paths below the src directory. But then you want to stop your frontend resources being served from these same paths. Both PHP and gulp will want to use file paths for urls, but at least for Gulp this can be controlled.
I'll follow this with interest. My ambition is to keep in the same folder things you're likely to want to delete together, and for those things to be able to call each other with short, relative paths. The ideal would be to be able to specify the module route independently of the path on disk, and to have this route work for both frontend bundled resources and services. Good luck !
I came across this question whilst searching for an approach for exactly the same problem. I'm building a "platform" rather than an application with a plugin system along the lines of Wordpress. I have the additional issue of the platform itself being a 'multitenancy' environment, too - so any plugins cannot interfere with the core "Dashboard" that holds these things together.
So; posting for a few reasons, two years on...
Did you get anywhere and would you care to share any thoughts?
I came across a quite extensive article for PHP Phalcon that has certainly given me a few ideas. Sharing incase it helps you/others:
https://blog.antsand.com/singlepost/index/5619/How-to-integrate-php-(Phalcon)-and-Vue.js-components
There's a line buried in the series that says "As a rule of thumb. Structure your code, based on the application and NOT on the programming language and frameworks." I'm not sure how wise or not this is, but it certainly gave me something to crack on with.
So right now, I have a module folder a bit like:
/mymodule
/Controller
/Model/
/Template
thing.vue
/Assets
/js
/css
MyModule.php
Assets are handled via a framework route (i.e, /assets/{path:.*} )
Templates are handled via the (PHP) module install script to make sure webpack knows where they live.
Still at proof-of-concept stage but rightly or wrongly, it seems to work well enough!

What is the correct way to break a larger Laravel 5 project into modules?

I'm working on a PHP project with Laravel 5 and I'm thinking of setting up a different folder structure for it.
The standard Laravel folder structure is something like this:
/app
/commands
/Http
/Controllers
/Middleware
Kernel.php
routes.php
/Providers
Model.php
/config
/resources
etc...
However, when the project grows larger and you have a lot of Controllers/Repositories/Models and such. This structure is gonna break.
For example: it's not very easy to find a bug in your admin panel if you have to dig through your routes, find which controller is responsible, find that controller amongst a large set of controllers, find out what that does, find out other possibly responsible classes in other large folders, and so on. In short: it's a mess.
I've been looking at ways to break the structure into modules. I've come up with a way to do it, but I'm not sure if it's a good way.
I would make a folder each functionality and put all the related code together. For example:
/app
/Admin
/Controllers
/Requests
/Models
routes.php
/Products
/Controllers
/Requests
/Models
routes.php
etc. (you get the point)
Instead of initializing 1 router from the standard RouteServiceProvider.php, I would have to write a ServiceProvider for each module and start all individual routes from there. So in this case I would have an AdminServiceProvider and a ProductServiceProvider which each require the routes.php file in their own subdirectory (and with that their own controller namespace).
This seems to solve my case for now, but I'm wondering if I'm gonna run into trouble with this setup. All the examples I can find on the web just stick to the standard structure. Can anyone tell me if this is a decent way to do it? Or does anyone have an alternate way of doing this?
This is a good way you proposed but there is no need to do it on your own. At the moment I'm working on a L5 project that uses modules - each of them have directories for repositories, models, own route file etc. I'm using Caffeinated module for that
I also believe the structure looks good. I would also add on an additional, core or base folder which will contain base classes and reusable componets, to ensure you do not have duplications of code in the separate "modules"
You can also checkout this interesting presentation at a Laracon, September 2014: Laracon 2014: Dayle Rees - Breaking
The Mold
Also have a look at the source for October CMS and Doptor
CMS(claims to be moduler), you may glean a thing or two. (Have
used neither, by the way).
Otherwise, do what I did and Google Opensource Laravel projects.
You get good insight from them. Especially those that a featured or
are organised, with growing communities.

Project structure for PHP

I am new to PHP and want to know the directory structure for the php projects. I have experience in Java and in java we have src contains java source files, WEB-INF contains lib, and jsp pages. Do we have any similar standard directory structure in PHP?
Also do we have layering in php like we have layers in java (e.g. Web, Service, DAO layers)
I browsed few links. But every one giving different answers.
Not sure if we can compare the two languages. I just want to stick to some standards.
Thanks in advance.
Nope. PHP is what you make of it. It can be very simple flat files, or however you want it.
That being said, there are a few agreed upon coding standards, but there is no "enforcement" of said standards. They are called PSR (PHP Standards Recommendation). There is a background on it here: http://net.tutsplus.com/tutorials/php/psr-huh/
You can view the standards one by one here: http://www.php-fig.org/psr/
Most major frameworks follow these standards, and if you are going to use one, it may be easier to go with the flow.
Again, every framework, project, plugin, program, etc, have different layouts with different project structures. A common structure is something like this:
-framework_dir
-public_html
-js
-img
-css
-index.php
-protected/private
-controllers
-models
-views
-etc
They then use the .htaccess file to block access to the protected directories. Again, this is just the common representation I have seen in several frameworks. If you are doing a personal project, just use something that is comfortable to you. Every framework is going to give you a different library or way to access the data. There are no "layers", but again every framework has objects that handle different areas (email, database, cache, http, logs, etc). Because there are dozens of popular ones, it is just up to you to find what fits with your philosophy or project. Watch a few of the 5 minute blog videos, see what jives, and then give it a test run for a couple days. If you don't like it, switch to another.
With the invention of Composer, people now have a central place to register their projects for the world to consume, and other people now can look at that code base and see similarities.
The result is this: https://github.com/php-pds/skeleton
In short:
If a package has a root-level directory for
then it MUST be named
command-line executables
bin/
configuration files
config/
documentation files
docs/
web server files
public/
other resource files
resources/
PHP source code
src/
test code
tests/
This standard does not make any further recommendations about which directories have to exist below src or public.
The task to organize your PHP source files inside any of these directories is still up to you, but there are suggestions outlined in this article that I'd agree on: Either sort by type (controller, entity, service), or sort by feature (user, login, cart, catalog, article, comment) - the latter keeping all the code that belongs to one feature in on directory (or few sub directories), which often seems to be the better file organisation.
When organizing by type, you'll find yourself jumping between directories quite often, and also you do not get a good overview about what the code is about - you'd always have "Controller", but you rarely have "StampCollection".
I tend to use a Feature-based folder structure for my backend projects.
Every feature-folder has his own controller, manager and routes file. This works well for api-backends. It looks in a way like https://blog.nikolaposa.in.rs/2017/01/16/on-structuring-php-projects/
For example, we have a Customer feature with a CustomerController, CustomerRepository, CustomerRoutes,..
My folder structure looks like this:
- build/
-- phpdox.xml
-- phpmd.xml
-- phpunit.dist.xml
- config/
- public/
-- .htaccess
-- index.php
-- assets/
- src/
-- Customer/
--- CustomerController.php
--- CustomerRepository.php
--- Customer.php
--- customer.routes.php
- tests/
- vendor/
composer.json
.gitignore
Unfortunately (or not?) you're very free with PHP. It's up to you.
Here's my structure:
framework/
controllers/
models/
configs/
files/
templates/
themes/
tmp/
index.php
init.php
.htaccess
You can control the access via .htaccess.
For a library, I am using the following structure... plus i've included recommendations I'm not using (yet)
PROJECT ROOT
|--composer.json
|--README.md
|--docs //for documentation files
|--tests //for Unit Tests
|--vendor //for external libraries (if everything isn't included through composer)
|--examples //examples of the library being used
|--config //any configuration files you may have
|--src //where the library's actual code "lives"
|--php //php source code, classes, any other scripts
|--View //html views, but actually php files that output html
|--Style //contains .css files
|--Script //contains .js files
|--Res //contains other deliverable resource files. Could be mp3 files, json etc
Currently, I'm only using composer.json,README.md, and src among the root files. But I will probably use the others as I've described, when i get to that point.
By no means do I think this is "correct". And this setup only works because I have a php router on every request. With a .htaccess, you could route a .css file to /src/Style/requested_file.css.
I wanted the project root to be cleaned up, and I have achieved that. PHP Fig does not have a PSR for directory structures... that I'm aware of. I had hoped PSR-4, autoloader would have had some standards, but... not really, in regard to directory structure.
You could look at laravel, wordpress, PHP Mailer and other php libraries to see examples and see what you might like best

Code reuse in PHP framework between multiple projects

This is my first question here. :)
I am working on a little php framework and started to think of ways to re-use the same code between multiple projects. Right now with this framework it is possible to make multiple application directories for different projects and use the same core - similar of what codeigniter 2 does.
The question about code reuse raised at work when I needed to make a website that is quite different from existing one, but would still use classes from it.
My first two ideas was either use some kind of a global "models" directory where to place files shared between multiple projects (and add option to framework to load them), or to add a possibility to load these "models" from other project(s).
I thought maybe somebody else have some better ideas and wanted to know other developer thoughts on the subject in general.
As an example this could be the current directory structure:
live/ - live site
config/
controllers/
helpers/
models/
public/
views/
admin/ - administration (same structure as "live/")
system/ - framework core
Well I don't think loading models or other classes directly from another project is a good idea. If two or more projects share the same classes, they should be located somewhere outside of both projects. This is the situation where the codeigniter packages comes in handy. It allows to have separate folder for all of your libraries, models etc. and load them in any codeigniter project very easily. Take a look at the official documentation for more details.

What's the point of Yii's AssetManager?

I can't find much information about Yii's AssetManager for the management of JS and CSS files. My question here is what is the point of using the AssetManager? I'm not sure what value it adds to my development process, in fact, it seems like it complicates my code... every time I change my scripts or css code, I have to go in and delete my assets folder to make sure I have the latest versions.
Seems it is much simpler to just put all Javascript files under /webroot/js/ and just use the tags to load the files instead of going through the trouble of AssetManager. Plus, Yii's registerCoreScript function always places script tags inside the header tag, instead of placing them at the bottom of the code, near the closing body tag, as recommended by YSlow.
I think there must be a gap in my understanding of Yii's AssetManager. Anybody have any ideas why using the AssetManager is better than hard-coding the script tags inside the PHP code? I'm a bit confused...
Thanks!
I'm sure someone can answer this better than myself, but basically it's so that your source JS and CSS files can remain in your Protected folder.
This is a little more secure for one thing, but the main benefit to me is that you can compress and minify and otherwise process your assets with the asset publishing system, and it makes it easier to host your JS and CSS on a CDN since it's separate from your codebase.
Also, here's an official response from qiang (the guy who wrote Yii) about this.
The main benefit of Yii's asset manager is that it allows you to structure your components in a self-contained manner.
A tale of a widget
Consider a component that is a UI widget. Let's assume the distribution includes a couple of assets along with the component implementation, for example these files:
SuperWidget.php
superwidget.css
superwidget.js
image_for_css.png
Consider how you would incorporate this widget into your application if the asset manager did not exist. Typical steps might include:
Copy SuperWidget.php somewhere inside the protected/ directory
Copy superwidget.js to your js/ directory
Copy superwidget.css to your css/ directory
Copy image_for_css.png to your images/ directory or perhaps also inside css/ to help reduce the relative path dependencies
Then at runtime SuperWidget would emit appropriate tags to include the CSS and JavaScript; to do this, it would need to know where exactly you have placed these assets. In other words: some choices regarding the installation can be made arbitrarily, but then they are set in stone unless you go and edit the source.
Is the widget reusable?
If this widget were highly customized and meant to be an inseparable part of your application then this approach would work fine and there wouldn't be much need to have an asset manager. But what if it's a broadly useful component that you want to distribute?
Problems start arising.
First of all the deployment scheme we have examined requires users of the widget to copy different files into different directories, complicating the installation procedure and increasing the chance of error.
But the greater issue is that your deployment scheme could conflict with that of any other component developed independently of yours. What if someone else decided to have a superwidget.js file too?
If the installation instructions for these two components conflict then obviously one of them cannot be installed as intended, and then you resort to changing some details and hacking the source code of the component to accommodate these changes. If you later upgrade to a newer version of that component you will be forced to carefully account for your customizations, making a "copy/overwrite" upgrade impossible.
All of this is really not pretty, and while it can be unlikely to happen in practice it certainly doesn't feel right.
Asset manager, make it so
Here's where the asset manager comes in. Let's assume you decide to structure your component like this:
superwidget/
SuperWidget.php
assets/
css/
superwidget.css
js/
superwidget.js
images/
image_for_css.png
You can directly copy this somewhere inside your protected/ directory no matter what other components you have installed; the worst thing that could happen here is that you'd have to rename superwidget/ to something else if there was a conflict.
Using the asset manager, SuperWidget.php publishes the whole superwidget/assets/ directory, with the copy ending up at e.g. assets/1337c0de/ where assets/ is your application's base asset path and 1337c0de/ is a random hash created by Yii and guaranteed to not conflict with any other published asset.
This means that the assets for SuperWidget cannot possibly conflict with those of any other component, making SuperWidget truly reusable. And since the directory structure inside 1337c0de/ will be the same as in your distribution, CSS can refer to images using the relative path ../images/ without needing to refer to the value of the random hash (which is only know after publishing).
What the asset manager is not
It's not a way to increase security. Your component source would be somewhere inside protected/ anyway (so no improvement there), and the assets need to be web-accessible no matter where they end up being copied (no security for them no matter what).
It's not a catch-all solution for processing your assets (e.g. minifying CSS). While it is possible to install a custom asset manager that does this, don't forget that assets included with reusable components will a small minority among all of your "base application" assets; if you want minification across the board, you 'll have to also process everything else and the asset manager will not help you there.
TL;DR
The asset manager allows you make components that are easily distributable and can be included in applications without the fear of creating conflicts with other components.
Another perk that I like about the asset manager, is that it allows you to update your asset files without having to tell your users to clear their cache.
http://www.yiiframework.com/wiki/311/assetmanager-clearing-browser-s-cache-on-site-update/

Categories