I run multiple websites all running off of a single installation of CodeIgniter on my server (separate application directories and a single system directory). This has been working fabulously and I don't see any reason to change it at this point.
I find myself writing library classes to extend/override CI all of the time and many times if I find a bug or improve effeciency I have to go back to several websites to make the same adjustments at risk of a typo that breaks one of the websites. Because of this it requires that I change each file and then test that site for bugs.
I have been pondering a solution of using a single libraries directory in a central location and symlinking all of my websites to that central directory. Then when I make a file change it will immediately propagate to all of the downstream websites. It will still require that I test each one for errors, but I won't have to make the changes multiple times. Anything that is specific to a single website will either be a non-shared file (still in the linked directory just not used elsewhere) or can be put in a local helper.
Also, I keep separate 'system' directories by CI version so I can migrate my websites independently if necessary--this central libraries file would be attached to a specific version to reduce possible breaks.
Does anyone see potential issues or pitfalls from taking this approach? Has anyone accomplished this in another direction that I should consider?
Thanks in advance!
I think this actually makes sense :] Go for it. Even on official CodeIgniter page, they mention it's possible.
Also, I don't see one reason why there should be any problem.
Edit: they touch the problem of multiple sites here: http://codeigniter.com/user_guide/general/managing_apps.html
also:
http://codeigniter.com/wiki/Multiple_Applications/
http://www.exclusivetutorials.com/setting-multiple-websites-in-codeigniter-installation/
How to Handle Multiple Projects in CodeIgniter?
http://codeigniter.com/forums/viewthread/56436/
I have a single system directory and separate application directories for my CI apps. In order to share libraries and some view templates between my apps, I have created a "Common" directory, in the same folder as the CI system and with the same structure as a regular app folder and used symlinks, but you can modify the Loader class so that it looks in the Common folder too. My setup looks something like this:
/var/CodeIgniter/
/var/Common/
/var/Common/config/
/var/Common/controllers/
...
/var/Common/libraries/
...
/var/www/someapp/
/var/www/someotherapp/
...
I'm not sure how you handle publishing your sites (assuming you actually do any of that), but I'd look into version control. For example, in SVN you can make external to another svn directory (or file) and then just update the current svn directory which grabs the external file. This approach gains one benefit from the others, which is when you modify the common library, the others aren't immediately affected. This prevents unwanted breaks before you have time to go test all the sites using the common library. You can then just update each site's folder whenever you are ready to test the changes. This is "more work", but it prevents code duplication AND unwanted breaks.
I wrote a MY_Loader to do exactly that.
http://ellislab.com/forums/viewthread/136321/
Related
I have 3 PHP projects using the CodeIgniter framework which share some exact same files such as models libraries and controllers. What's the best way I could share these files across without having to keep in sync and update the same files across?
In linux I thought of using dynamic links and extract these files to a central place but that kind of breaks our version control and would create portability issues.
Another way perhaps to use unison on these files across projects
I'm assuming that's a common problem, what are common approaches?
Separate them into a module, and use something like composer.
http://getcomposer.org/
Or just put them in a separate SCM.
One thing you can do:
Put all the shared code in libraries, helpers and models and place this in a separate folder. Then use:
$this->load->add_package_path('shared location');
Also take a look here: http://codeigniter.com/user_guide/libraries/loader.html , under application packages.
This works for most of the stuff, except controllers.
Use version control! In svn you can use externals, git has submodules or subtrees.
You don't want to use hardlinks, you'll run into weird issues like updating one project influences another project ("that I haven't touched in weeks").
The code can be in two physical places but shared under version control. There will always be only one authorative copy, namely the one in your version system. All physical copies are derivatives. It's important to see that you have control over when you update the code of a specific project, so a change at one point doesn't immediately break another project in case you made a mistake.
If you do want to catch these kinds of errors, set up a proper regression testing environment.
Sharing a development environment with another developer is also a big no. You don't want to have to wait till your colleague fixes a parse error that breaks the entire program. Each developer should have their own copy (checkout!) of a project and similarly each project should have their own copy (externaled) of shared code.
Seperate them into folders outside your project, then configure or include them in your projects.
Usually we will rewrite "autoloader" method for the project to find files in our new folders.
I'm interested in cleaning up my codeigniter applications folder (just to clean up the clutter). I've seen a few applications that only include the important folder (ex. controllers, models, views, config) and do away with alot of the other stuff (like logs, hooks etc.)
Does someone know which folders can be deleted and which are required?
Thanks
Consider that this "clean up" won't bring you this great advantages, apart from your personal feelings. Since Codeigniter tries to look into application folders which are named like the system ones (libraries, core..) before going to search for those folders inside the "system", I don't think it will be painless to remove them; you might try, though, and just keep those which, very likely, contain somethin: config,controllers,errors,models,views.
Another thing you could do, and which will free more "space" (are you worried about file count?), is deleting unused/unwanted helpers and libraries (from the system folder); the ones you are damn sure you don't use and never will in the future (like the javascript library, for ex, plainly useless, or the smiley helper...You got the point).
All in all, apart from the feeling of "having cleaned up your workspace", I don't really see what benefit this will bring you. But, if you really, really feel so strongly inclined to, make a back-up copy and start deleting, you can always put them back if CI yells at you.
Each file and folder in the CodeIgniter Application folder is an extension of the whole CodeIgniter framework in one form or another, and should not be tampered with. CodeIgniter is a light, fast framework, and should not need any other "modifications". If you'd like to play around with CodeIgniter though to try out any "improvements"; I'd check out their page on GitHub, view some commits that may be related to your question, and play around with it yourself on your own machine.
The framework is setup so you can develop your applications and update to new versions of code igniter without breaking said applications. You don't want to start messing with the actual framework that's just asking for random errors.
if you are trying to make it as lite as possible just auto load the libraries and helpers that you require directly into the controller where they are needed.
-L
I'm having a bit of an application structure design dilemma.
I have created a web app that creates online surveys. It all works fine, but I would now like to create a new site that does different types of online surveys. This new site will be pretty much 95% similar in terms of layout, logic, functions, etc.
Rather than duplicate all the code from the current web app, I'd like the new app to share in the "fountain of knowledge" created by the current app - so to speak.
Can anyone enlighten me with their experiences of doing this sort of thing? Their best practices?
As a rough guide, I'm currently thinking of using symlinks for all the major logic files (library.php, functions.php, etc), and then deciding which logic to use based on which URL the user logged-in from.
Does that sound like a good or bad idea?
Would it be any better or worse to divide the whole system in to 3 sites, with the site in the middle containing all the common elements and logic? This middle site would have no independent use - it would be used from either of the 2 applications looking for functionality and assets, etc.
Any help and experience on this matter is very much appreciated indeed.
I'm very wary of going down a dead-end solution.
Kind Regards,
Seb
Good solution if:
you host your website yourself and creating symlinks between differents virtual hosts is not a problem
you won't have to make significative changes between the 2 websites
But instead of using symlinks, I could take advantage of PHP's include_path directive and put the common libraries in this path. This way, just write your includes relative to this path, the files will be accessible from any site you want on the same server.
The second advantage of using include_path is you can bypass any open_basedir directives which wouldn't allow you to include files which are not in the same virtual host base dir.
This is how I'd do it...
Create a core library.
Create you 2 site directories.
Create site specific code folders in
each site.
Create core library folders in each
site that simlink to the main core
library created.
Basically, lets say i have a webserver and i resell hosting specifically for local churches.
i have 5 churches as clients, i have a simple CMS made for them they are equal copies of the same files, for each website i install the CMS , database and the website, i think it's a waste of resources.
i would like to know if i can do the following, afaik most webhosts have the following structure:
A main directory (home)
www.church1.com (church1)
www.church2.com (church2)
www.church3.com (church3)
www.church4.com (church4)
www.church5.com (church5)
basically i want the CMS to be on the Home directory, and each one of the Churches (clients) would only have a Config file, a Database ant the template regarding their websites.
so the system source code would be shared, but the website design and the database files would be completelly separated.
i'm not a webhosting or a development expert, but i know my way around, i'm sorry if the question is too basic, i'm having a hard time finding if this is possible.
EDIT: I Think Rudu's reference pretty much solved my problem!
Since you are building it yourself, put the include files (application logic) in a folder or include path that is accessible to all the domains. Then you can put your template files, images and stylesheets in the individual domain folders. If you are database driven you can check the domain $_SERVER['HTTP_HOST'] and load results from a certain table or database based off of that. You really can go a lot of different directions here if you are building it yourself.
It is possible - the answer. Exactly - there are some settings ( and now i dont remember them ) that can block it - but set up in all sites that libraries are there and be happy
We have a custom PHP/MySQL CMS running on Linux/Apache thats rolled out to multiple sites (20+) on the same server. Each site uses exactly the same CMS files with a few files for each site being customised.
The customised files for each site are:
/library/mysql_connect.php
/public_html/css/*
/public_html/ftparea/*
/public_html/images/*
There's also a couple of other random files inside /public_html/includes/ that are unique to each site. Other than this each site on the server uses the exact same files. Each site sitting within /home/username/. There is obviously a massive amount of replication here as each time we want to deploy a system update we need to update to each user account. Given the common site files are all stored in SVN it would make far more sense if we were able to simply commit to SVN and deploy to a single location direct from there. Unfortunately, making a major architecture change at this stage could be problematic. In my mind the ideal scenario would mean creating an account like /home/commonfiles/ and each site using these common files unless an account specific file exists, for example a request is made to /home/user/public_html/index.php but as this file doesnt exist the request is then redirected to /home/commonfiles/public_html/index.php. I know that generally this approach is possible, similar to how Zend Framework (and probably others) redirect all requests that dont match a specific file to index.php. I'm just not sure about how exactly to go about implementing it and whether its actually advisable. Would really welcome any input/ideas people have got.
EDIT AllenJB's comment reminded me that we have previously explored AliasMatch as a potential solution to this, we ended up with an general.conf file for a user that looked something like this:
php_admin_value open_basedir "/home/commonfi:/home/usertes:/usr/lib/php:/usr/local/lib/php:/tmp"
php_admin_value include_path "/home/commonfi"
AliasMatch (.*).php /home/commonfi/public_html/$1.php
AliasMatch (.*).html /home/commonfi/public_html/$1.html
You can set this up via the Apache configuration - you probably want Alias, but there are several options:
http://httpd.apache.org/docs/2.2/urlmapping.html
You certainly can build a "cascading" system as you describe (load local file, if that doesn't exist, load global file). The complexity is that the files are loaded in different ways (using include() in PHP, through the web, ... maybe even more ways?)
Filesystem includes
If the includes/ consist of files containing one PHP class each, you could use an autoloader like Zend Framework does. The autoloader would look first for a custom version of the include file, and if it doesn't find one, include the global version instead. I happen to have such an autoloader handy if you need code to start with.
If the includes don't match the one-class-per-file structure, you would have to build a custom include() function that fetches the local version of the file or, failing that, the global one.
Pseudo-code:
function fetch_path($name)
{
if (file_exists(LOCAL_DIRECTORY."/$name")) return LOCAL_DIRECTORY."/$name";
if (file_exists(GLOBAL_DIRECTORY."/$name")) return GLOBAL_DIRECTORY."/$name";
return false;
}
Web resources
The second part is going to be the web part (i.e. Web URLs with local or global files). I think this should be pretty easily solvable using the -f switch in a .htaccess file. You would build a rule that rewrites failed requests (!-f) to the local web resources directory (example.com/css/main_stylesheet.css) to the global one /home/commonfiles/public_html/main_stylesheet.css). You would need to fiddle around with Apache's server config to be able to rewrite local requests to the commonfiles directory, but it should be possible.
That is maybe worth a separate question.