Hey all, kind of new at Kohana and I have a quick question.
I have a site where there will be three subsections, organized by subdomain (i.e. admin.site.com, community.site.com, www.site.com) but each of the subsections will be pulling from the same database so should be sharing the same models. Is there a way to organize it so that I can use the same Kohana model/system/module files for each of the subdomains, but keep the application folder separate? Something like:
/home/user/admin/
application/
bootstrap.php
cache/
...
index.php
/home/user/community/
application/
bootstrap.php
cache/
...
index.php
/home/user/public_html/
application/
bootstrap.php
cache/
...
index.php
/home/user/kohana/
modules/
...
models/
...
system/
That way I can keep Kohana up-to-date across three sites with only one update, plus I can use the same modules and model classes. Is there any way I can make this happen? Or is there some other method I should be using?
Thanks!
I figured out how to do this, so I thought I would answer it in case someone else needs to know.
I moved my system and modules folders out of the webroot (to /home/user/kohana/) and created a folder there called sites. Then I created three separate folders in /home/user/kohana/sites/ for each of my three subdomains (admin, community, and www). I copied the contents of the application folder to each of these folders, then copied the index.php and .htaccess files to the webroots for each subdomain.
In each of the index.php files, at the top, I added:
$install_dir = '../kohana/';
and edited the following directory variables to include the new path:
...
$application = $install_dir.'sites/admin';
...
$modules = $install_dir.'modules';
...
$system = $install_dir.'system';
And it worked! I feel kind of stupid for not realizing how easy it was to move the directories around. Hopefully my explanation is coherent and assists someone else in the future.
Related
Currently I am developing a small headless CMS. If anyone wants to use it he should just copy the root folder of my CMS and put it into his public_html folder. So for any requests to the CMS the URL looks like this:
example.com/my-cms-name/subfolder/...
To better organize third-party libraries I decided to use composer. But now I have the composer.json file and the vendor file in my CMS folder which is going to be in the public_html folder. So everything from composer will be available for everybody which is obviously not a good practice.
How can I overcome this problem? Should I do all composer things separately in a different folder? But then the user of my CMS has to include multiple folders into multiple directories which makes everything more complicated...
I agree to Half Crazed. Probably people will have to upload your CMS files via FTP anyway and set a root path. So you might as well divide your scripts in private and public ones. So a directory structure like this might be a good idea.
-config
-public_html (root path that people must point their domain to)
-css
-javascript
-images
-index.php
-.htaccess (optional)
-src (where your namespaced script should reside )
--MyApp
-vendor
-composer.json
-composer.lock
Update composer.json and add your own src, run update command. Then include the vendor autoload.php in your index.php and go the router/controller way.
I am trying to integrate some new Symfony3 apps into an existing web space. At my webroot /html, each app has it's own directory. Each of these apps could be anything- cakePHP, custom PHP, whatever. And each are accessed by a URL like localhost/appname. This structure is not flexible and I am not able to add anymore URL patterns to vhosts or anything like that.
Therefore, I have my Symfony3 install at /symfony which is a sibling directory of /html. Inside of /html I have a landing directory for my Symfony app: /html/symfonyapp.
In /html/symfonyapp/index.php I have one sole line of code:
require_once DIR.'/../../symfony/web/app.php';
In my Symfony set up, I have a bundle called SymfonyappBundle. I have a route configured in src/SymfonyappBundle/Resources/config/routing.yml to redirect calls to /symfonyapp to this particular Bundle.
The routing is not working. Calls to http://localhost/symfonyapp always end up going to the routing for "/" Why? I feel that it has nothing to do with my Symfony setup, but instead something to do with the request coming in through that /html/Symfonyapp/index.php file.
Any help is greatly appreciated!
Edit: I see it's helpful to list out the directory structure so here it is:
- /var/www/html <-- this is your (global) web root
|- cake-app
|- custom-php-app
|-symfonyapp
|—index.php (which contains only a require for app.php)
-/var/www/symfony <—symphony standard install here
|- app/
|- vendor/
|- src/
|- web/ <-- the web root for your symfony-app
|- .htaccess
|- app.php <-- the "boot"-script similar to index.php
I hope I got this right. Your directory structure looks something like this:
- /var/www/html <-- this is your (global) web root
|- cake-app
|- custom-php-app
|- symfony <-- the project root for you symfony-app
|- app/
|- vendor/
|- src/
|- web/ <-- the web root for your symfony-app
|- .htaccess
|- app.php <-- the "boot"-script similar to index.php
So basically you have a typical Symfony-application, but it sits inside a shared web root. So when accessing it you don't go to http://example.com/, but instead to http://example.com/symfony/web/
This might be the first problem you are having. Your application must be accessed from the web folder, not from the symfony-folder. Depending on for example some rewrite rules in /var/www/html/.htaccess you might not be able to look through files in the symfony-subfolder and there is no entry script, so it will not work. Dependening on your setup you might not even have permission to rewrite the url per .htaccess or in your server's config, this would complicate things a bit further. For now let's assume the .htaccess-file in web/ does work and it's just a matter of the wrong folder your url is pointing at.
There are multiple options you have if you want the url to be accessible at http://example.com/symfony/ (without the web/-part). Symfony's project structure is actually pretty flexible and you could get rid of the symfony/web/-folder and instead use symfony/ as your web root. There might be some gotchas for example with some install scripts that copy resources like css and js into your web-root. You could also run into issues when bundles point to the web-directory, e.g. for storing uploads. You probably have to make a few adjustments but a basic setup should be doable in no time by moving all files from web to the parent folder (including the .htaccess which might be hidden).
Another option might be to create a new .htaccess in symfony's project root that points to web/app.php instead of just app.php. You could take the existing file as a reference. I try to avoid using htaccess-files and don't have a setup right now were I could try it, but it might be worth a shot before moving lots of files around. Although you still might run into issues with assets where the path is not matched correctly.
edit: another option that's probably more work, but might be useful if you want to migrate away from the other existing web apps to just a Symfony app is, to move symfony to the same level as html/ and move all the stuff from web/ into html/. Now your server's web root is also symfony's web root (again you might have to fiddle around with assets expecting to be in a folder called web/). Now you just need to make sure that whenever Symfony does not find a route it will pass the request to your other apps. There are several things to look out for and it's a lot more work than the 2 approaches above, but in can be useful. There was a pretty good talk about it at last year's SymfonyCon in Berlin on how to do this if you are interested in this route:
https://github.com/SymfonyCon/2016-talks#modernizing-with-symfony
https://slidr.io/derrabus/modernizing-with-symfony
Unfortunately the video of the talk is not out yet.
The solution that I found was to add a custom Kernel for each web application. So for each folder I have under my webroot /var/www/html, I added a new Kernel in Symfony. Each Kernel has it's own routing and config files, which solved my routing issues! I followed this symfony doc to set up the kernels: http://symfony.com/doc/current/configuration/multiple_kernels.html
App1:
webroot: /var/www/html/app1/index.php has the typical app.php code in it which initializes App1 Kernel as such: $kernel = new App1Kernel('dev', true);
symfony details: in app/config I added one directory per Kernel , so this would be app/config/app1. I copied all config, routing, service files into this directory and reference the custom Bundle for the app.
App2:
webroot: /var/www/html/app2/index.php has the typical app.php code in it which initializes App1 Kernel as such: $kernel = new App2Kernel('dev', true);
symfony details: in app/config I added one directory per Kernel , so this would be app/config/app2. I copied all config, routing, service files into this directory and reference the custom Bundle for the app and changed any references to Bundles to the appropriate bundle.
I'm looking for a clear explanation of how to use CodeIgniter for multiple domains. I want a single set of models and config files, with the ability to call different controllers depending on the domain the request is coming from. After doing some research, I am fairly certain the way I currently have this set up is not ideal, and I would like to fix it before I get too far into building. Here's the current set up:
I have three domains that I'm managing:
domainA.com
domainB.com
domainC.com
Each domain points to a different folder on my server:
/domains
/global
/models
/model1.php
/model2.php
/domainA.com <--- domainA.com points here
/application
/controllers
/domainAController1.php
/domainAController2.php
/assets
/system
/index.php
/domainB.com <--- domainB.com points here
/application
/controllers
/domainBController1.php
/domainBController2.php
/assets
/system
/index.php
/domainC.com <--- domainC.com points here
/application
/controllers
/domainCController1.php
/domainCController2.php
/assets
/system
/index.php
Then, in each controller, I add a package path in the constructor function so that the controllers have access to my global models:
$this->load->add_package_path(APPPATH.'../../global/');
This allows me to load models from the controllers as normal with something like:
$this->load->model('model1');
The folder hierarchy I'm showing above is not complete. Inside each of the domain folders, there is a full CI installation. So if I want to define constants or configuration parameters for the entire "app", I essentially have to do it three times. Also, the more I develop, the more I am coming across needs for more advanced features like base models and controllers and I have a feeling this "package path" solution I"m using now is not going to work.
This clearly is not the right way to go about it, and I was hoping someone could offer me a better way to implement this.
I am running CodeIgniter version 2.1.4.
***************************UPDATE***************************
Here's what I ended up doing to get this working. I would love someone's advice on if this is a good or bad idea, meaning, do you foresee any obvious issues using this method?
I used routes and controller subfolders to accomplish what I needed. I now have a single installation of CI, and within my controllers folder I have subfolders for domainA.com, domainB.com and domainC.com.
Then, in my routes.php file, I added this after the reserved routes:
switch($_SERVER['SERVER_NAME']){
case 'domainA.com':
$controllerSubDirectory = 'domainA.com';
break;
case 'domainB.com':
$controllerSubDirectory = 'domainB.com';
break;
case 'domainC.com':
$controllerSubDirectory = 'domainC.com';
break;
default:
$controllerSubDirectory = '';
break;
}
route['(.*)'] = "{$controllerSubDirectory}/$1";
In other words, I just take the incoming request and route it as if it were actually coming in with the appropriate subfolder as it's first URI segment.
Are there any issues with this I am not thinking of? Maybe some sort of security risks?
The short answer: take advantage of CodeIgniter "Third Party Packages" feature.
Your directory structure is not very well organized. It is not necessary to store multiple copies of the CodeIgniter System files, assuming of course that all applications are using the same system (version and no/same modifications to core files).
Check CodeIgniter Docs for more detail.
As mentioned above, you could take advantage of CI's packages to package your common code as a 3rd party package. Then you can just load models and other resources as you normally would, and CI will know how to find them on it's own.
I'm working on multi-website CMS in Zend Framework.
I've came to a point where I need to override module from application/ folder in my website/application folder.
A bit better explanation of my issue:
Here's tree of my application (important part):
library/
application/
module1/
controllers/
models/
....
module2/
controllers/
models/
....
websites/
website1.com/
application/
module1/
controllers/
models/
....
So what I need to do is that module1/ in websites/website1.com/application/ override module1/ in application, IF it exists. I want everything in module1/ in websites folder to override everything in main application folder.
I'd also like if there are 2 controllers in this module1 (for example IndexController and TestController) and if I put only TestController in websites folder under module1/controllers to override ONLY TestController from Application folder and to get IndexController from main folder.
Sorry if I failed to explain exactly what I'm trying to achieve. If there's something unclear, please ask.
Thank you.
Edit:
Okey, first of all - thanks for your comments.
Reason for having websites/ folder is, mostly because of vhost as I prefer that all of my websites have separate (public?) folders, and reason for having one library with application folder is because, obviously, upgrade reasons (so when I, for example, upgrade Zend - I don't need to upgrade it for every website).
I'll most likely rarely use overriding option for controllers, and yes, I'd even prefer if I could, for example, extend main Controller (for example - IndexController) and override some functions, but I thought that's way harder then override whole class.
Here's full structure of my application:
library/ - Library folder contains Zend and many other classes that I'll use in my application.
Zend - Zend Framework
MyCMS - Classes from my old CMS.
sites/ - Folder that contains websties.
website_1 - Website one.
application/ - Application folder for website one. If I need to redefine module or something. So, if I need to override module: main_module, I'll create folder main_module here with files that I want to override.
config/ - Configuration for website_1 - if I need to override, for example, application.ini
lang/ - Language files for this specific website.
templates/ - Templates folder for website (layouts and templates). By the way, I'm using smarty.
default/ - Main template.
layout/ - Layouts for Zend View.
css/
js/
images/
modules/
files/ - Place to upload files in, for this website. This will contain user avatars and stuff.
index.php - Main file that runs bootstrap and application.
Bootstrap.php - Inherited bootstrap. In case I need to override some functions from default bootstrap.
application/ - Main folder that contains application modules and stuff.
main_module/
configs/ - Module configuration.
config.ini
controllers/ - Controllers for this module.
modules/ - Submodules. There are like boxes that I display on website. For example, if my main module is "news", here, I'll make new sub-module to display box with statistics.
submodule/
services/ - XML/JSON/whatever service. If someone targets controller in services with specific parametars, it'll return response in requested format.
controllers/ - Services will only have controllers.
configs/ - Configuration for this submodule.
controllers/ - Controllers for this submodule.
models/ - Models for this submodule.
lang/ - Language files for this submodule.
template/ - Templates for this submodule.
helpers/
css/
js/
images/
index.html
models/ - Models for main module.
lang/
services/ - Main module will also have services. See submodule services for explanation.
controllers/
template/
helpers/
css/
js/
images/
index.html
Bootstrap.php - This is main bootstrap file that every website's bootstrap file will extend (and override some methods - if needed).
Update
Even though I highly discourage your directory structure, it's your application and you should structure it however you like.
To load multiple controllers, you should create a Front Controller Plugin to add paths to the controller directories stack
class My_Controller_Plugin_Paths extends Zend_Controller_Plugin_Abstract
{
public function preDispatch()
{
// Something like this...
// Would be best to load paths via config/database or somewhere
$dispatcher = Zend_Controller_Front::getInstance()->getDispatcher();
$dispatcher->addControllerDirectory('/path/to/website1.com/controllers')
->addControllerDirectory('/path/to/website2.com/controllers');
}
}
This is entirely untested, but you get the idea. Just make sure you register the plugin with the Front Controller in you bootstrap
I'd agree with #Laykes. This is a badly structured application.
I'm not sure of your exact requirements, but if it were my application, I would try to structure it like this:
/application
/modules
/default
/controllers
/IntexController.php // Default_IndexController
/Website1com
/IndexController.php // Default_Website1com_IndexController (possibly extends Default_IndexController)
Here you can see a properly structured class inheritance without creating totally separate, and probably duplicate, application folder.
Autoloading anything like this though totally depends on you and your priorities. You could do a number of things, each with their own +ve's and -ve's.
You could throw all paths into your include_paths in the order you want
Check files exist and load from a front controller plugin
To name a couple.
I am creating a very large PHP MVC-based site that will have a large library of php classes, javascripts, and many css files (not to mention a large amount of files for the MVC).
For the first time ever, I am actually taking the time to plan out a clean and organized directory structure.
What directory structures do you typically use, and which will be easiest to manuever when there are thousands of files?
This is my setup. It's worked great for me for small - very large projects (including a social network).
These folders would all live within my main application folder:
config - contains custom PHP config files
css - contains the project's CSS files
helpers - contains 'helper' files (each file is a collection of functions)
images - contains the project's images
js - contains the project's Javascript files
lib - contains PHP classes specific to the project
modules - My MVC framework allows packaging site sections as modules
blog - An example module
controllers - contains the controllers for the module
models - contains the models for the module
views - contains the views for the module
views - contains views that should be globally accessible (page header, footer, etc)
All the directories could obviously contain sub-folders that would further organize your files. For example, the 'css' folder could have sub-folders named 'web' and 'mobile'. The 'images' folder could contain a 'user_uploaded' folder which could then contain`'profile'. And of course you can add folders as you see fit, in one project I have a folder called 'uploaders' which just contains stand-alone upload scripts.
I also use convenience methods which help construct the filenames of what I want to load. For example, my loadView() will look for the view file in the current module directory, or if you pass an optional $module argument, it will look specifically within that module's folder.
I hope this helps.
You should have one directory as web root, where only files you want exposed to the whole internet should reside.
project/
web/
index.php
css/
js/
images/
config/
lib/
web/ is the root shown to visitors
lib/ is here the library folder, and where autoload look for files.
You can add more subfolders to project/ like controller, modules, view, helper, etc. This depends on your framework.
EDIT:
If you use composer (which I recommend) and maybe npm with grunt and less your file structure would be the following:
project/
web/
js/
css/
images/
index.php
cli/
config/
config.php
node_modules/
src/
test/
vendor/
composer.json
composer.lock
packages.json
web/ has all your public files
cli/ scripts and programs to be run from command line NOT the web
config/ has all your config files (in git you ignore config.php and instead have config.dist.php without usernames, passwords, validation codes and table prefixes/suffixes and other "secrets")
node_modules/ has all your library files from npm (in git I suggest you put this in a submodule)
src has all your local PHP files in psr4 structure, set up to autoload in composer.json
test/ has all your unit tests for your src classes, set up in autload-dev in composer.json (remember to use composer install --no-dev on live, maybe add -o if you don't have too many classes)
vendor has all your library files from composer and the ONE AND ONLY autoload.php to be included in web/index.php and any cli scripts (in git I suggest you ignore this vendor folder)
Add other folders and files as required for your project.
For deployment use this structure:
/sites/project/ (project is your projectname)
current (alias to current release folder releases/v1.1.0)
previous (optional alias to previous release folder releases/v1.0.1)
releases/
v1.0.0/ (git checkout of tag v1.0.0)
v1.0.1/ (git checkout of tag v1.0.1)
v1.1.0/ (git checkout of tag v1.1.0)
shared/ (has all your shared files and folders to be aliased in all releases - maybe something like GlusterFS)
Make a deployment script. Something like this:
First take backup of db or to copy it to a new database, checkout git repo to new folder with release tag, get all git submodules, run composer install --no-dev, setup any aliases for shared folders and files like uploaded images and configuration files, generate js/css with grunt and less or equivalent, point current alias to the new folder with the tag, run update database script, restart nginx/apache/fpm-php services, run tests to check the website is up.
Have a script to go back to previous version (or a guide so you know what to do).
For core files which are included:
approot/inc/
For data access functions and classes are in:
approot/dao/
For javascripts:
approot/scripts/
For CSS:
approot/styles/
For images:
approot/img/
For static content (normally for user profile pictures or uploaded images):
approot/static/
For caches:
approot/caches/
For templates or View files:
approot/templates/
All pages file:
approot/
Structure from Samstyle PHP Framework
The answer I posted here was from 2009. Over the years more standards were published, including PSR-0 which covers the topic on folder structure. I also have a new (and I feel that it's better) folder structure with Packfire Framework.
In my experience, you can never plan for this. You can try to follow what frameworks do, but I find I never quite fit exactly into their mold.
I recommend to just keep a good rule of thumb for 20 files in a directory maximum. If you find you need more, just create a few sub directories and move common components in there.
This is mostly a matter of preference, a quick Google search would reveal many different project structures. But it would be really nice if there were an agreed upon standard. I think this initiative by the PHP Package Development Standards is a good candidate.
This is the directory structure they propose:
bin/: command-line executables
config/: configuration files
docs/: documentation files
public/: web server files
resources/: other resource files
src/: PHP source code
tests/: test code
EDIT:
This is also mentioned in the PHP The Right Way under the section Common Directory structure.
I use codeigniter for small and big projects.
It's MVC feature is moderately good.
codeIgniter\system\application\config : contain all kind of configuration files like DB,Payment gateway, ftp config, routes and ...
codeIgniter\system\application\models: contain all kinds of database classes, you should create sub folders according to your need, I used customers, mailData, paymentModel, report, web-service and ....
codeIgniter\system\application\views: contain all kinds of files that will work as output for clients, you should think of reuse these files if possible. Like the models you had to create sub folder like administration, reports, email, email_template .....
codeIgniter\system\application\controllers : this is the most important part. This will help to create SEO url, so you should be more careful about sub folders this time. You can create like administration, products, reports, orders..... and consider a good name for the functions of the controller class.
These were for the PHP/HTML file.
Now about the other files:
codeIgniter\images: for the images
codeIgniter\scripts: for the Java scripts and their framework
codeIgniter\styles: for the CSS
codeIgniter\uploads: for the uploaded files, if you don't want to put files in the DB
For the detail see codeIgniter framework in detail.
Here "codeIgniter\" is the approot
This is the structure i'm using currently,
public/
assets/ /* js, css, imgs, ... */
index.php
src/
config/ /* for config files */
helpers/ /* for functions */
libraries/ /* for free classes that are not MVC classes */
models/ /* for M in MVC */
views/ /* for V in MVC */
controllers/ /* for C in MVC */
vendor/ /* for vendors files */
uploads/ /* for uploaded images, docs, ... */
Have a look at symfony 1.4 or symfony 2 dir structure. Choose what's most intuitive to you.
I believe this depends on how large the project will become. This is what I used mostly:
project/
index.php
img/
css/
js/
views/
functions/
As long as all the project files are organised...
Even though the question is abit old, I still think it is wise to suggest the latest scaleable application structure which I have been working in my SOA based application and working absolutely fine.
myApplication/
app/
config/
+ this can include custom MVC structure
cli/
docker/
lib/ - most commonly reusable components
logs/
public/ - should contain all publicly exposable web contains
sql/ - db migration stuffs
tests/ - compulsory test
tools/ - application addon tools like any kinds of rulset etc
vendor/