I'm writing a web application and I would like to know how to initialize all constant (such as db connection data, directories etc), classes and so on.
I read about bootstrap file but I'm not sure I understand the technique ( more details here: https://stackoverflow.com/questions/9774105/htaccess-and-bootstrap-file).
A more specific case would be better. In this case, your question on settings, there are different approaches. Generally a config file is most used in projects. That way it can easily be excluded from version control systems.
Bootstrap files are not the location to store settings.
So bootstrap load the config file and following to that the bootstrap initiates the system.
Generally a config file is the most accepted choice.
For paths there are different parts. You have in-app paths. Keep them in your code, your system should be able to find the right files. Might be done with a PHP Autoloader for example.
Then you have paths to resources like images, pdf files and other data. Keep that part strongly separated from your application. Preferably via a class which handles all those files. That way you are free to move them to another server, move them to Amazon for example when your project grows etc.
So don't try to hardcode paths and keep things separated.
Related
I wish to use codeigniter NOT as a framework for building a site, but simply as a backend to handle some php stuff (eg. db in/out, image manipulation, file writing to the server).
In the default download of CodeIgniter3, there are 3 primary directories (application, system, and user_guide). Most of application is roughly empty, other than application/config; and user_guide is surely unnecessary.
So what parts of CodeIgniter3 are needed such that it is functionally complete?
TL;DR: All of it
If you want to use just a set of a framework's components, CodeIgniter is not the right pick.
Long answer:
In theory: it should be just system/core/
But most of that code assumes that you have constants defined in index.php, that you do have an "application" directory (containing "config/" and "views/errors/" subdirectories).
A lot of it also depends on language translations, for which the defaults are in system/language/, so you need that too.
Some badly written parts may also depend on a particular system/libraries/ or system/helpers/ component.
So while we started with just system/core/, you now need all of system/ and at least some of application/ (though that can be renamed to something else).
CodeIgniter has a monolithic architecture; it is simply not built in a way to allow you to do what you're asking for.
And those are only a few kylobytes of files anyway - it's not 1980 and that's not a problem; unless you actually load the extra components that you don't use, they wouldn't get in the way.
I'm trying to find a guide on PHP file/folder structure conventions.
I'm using GitHub and want to ensure I'm following a standard convention as to not confuse users.
Any help would be appreciated.
As speshak said PHP has no standards and no conventions (including its own standard library).
However:
In public directory (usually public_html) store only static resources (images/JS/CSS) and one PHP file index.php which is limited to something like this:
<?php
require '/path/to/app/outside/public/html/start.php';
$app = new App();
$app->run();
Application itself should be stored outside public directory.
File structure might reflect classes names, so: Project\Util\XML\Parser will be stored within /path/to/the/project/Project/Util/XML/Parser.php file.
Of course 3rd-party-code might be stored in separated folder, let's say vendor - that's quite common convention.
There is this:
https://github.com/php-pds/skeleton
Based on data collected from various open-source projects, this document proposes a naming convention for a number of root-level directories designated for various common purposes, as well as naming conventions for root-level documentation files.
I didn't find that this covers every imaginable scenario, but it's nice to be able to point at this and indicate you're making an effort to achieve some consistency across projects :-)
You are free to choose any directory structure. But if you would like to know about best practices, take a look at how it is done in frameworks, for example, symphony.
Take a look: http://www.flickr.com/photos/deia/402335716/
Here's few of them:
All the code that is included, should be put outside of the document root.
HTML templates should be in a separate directory.
Libraries and classes should be in 'lib' directory.
Mostly it's just a reasonable solutions, not strict conventions.
I think the most obvious one is your libraries. You should name your classes like YourCompany_Module_Class, if you want to be compatible. Using this standard, your libraries can be used along with any other similarly named libraries without clashes and problems. The new namespacing in PHP 5.3+ helps more in achieving this. You can have some guidelines for this at Zend Coding Standards - File Naming and at PSR-0 Standard Proposal.
Other than that, you'd better constantly keep the future in your mind and plan your folder structure accordingly. For example, let's say you are uploading images into user_images. Ok. But what happens when the project catches or gets bigger and now you have tens of thousands of files in a single folder. You must build some scheme that enables you to store ~1k images per directory at most like 12/56/154.jpg.
You will see many such problems and opportunities over time. But you can look at the current projects and learn from them for free :)
PHP really has no standard. If you are making use of some framework (eg CakePHP, Zend Framework, etc) it may impose some standard on you.
If you aren't using a third party library that forces a structure, just use common sense. (Put images in a images directory, included files in an includes directory, etc) People that download and install PHP apps will already be used to each app doing things differently. The fact that you're giving it some thought puts you a head of lots of the competition :)
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/
I have a folder of PHP scripts, they are mostly utility scripts. How to share those scripts among different PHP applications so that reuse and deployment are easy?
I would have to package my app into an installer, and let the user install it.
I could put the lib and hardcode the include path, but that means I haven to change the PHP code every time i deploy the web application to a new customer. This is not desirable.
Another route I consider is to copy the lib to other apps, but still, since the lib is constantly updating, that means that I need to constantly do the copying, and this will introduce a lot of problems. I want an automated way to do this.
Edit: Some of the applications are Symfony, some are not.
You could create a PEAR package.
See Easy PEAR Package Creation for more information on how to do this.
This assumes that when you say anyone, you mean outside your immediate organisation.
Updated: You do not need to upload to a website to install the PEAR package. Just extract your archive into the pear folder to use in a PHP application.
Added: Why not create a new SVN repository for your library? Lets say you create a library called FOO. Inside the repostory you could use the folder heirachy of trunk\lib\foo. Your modules could then go into trunk\lib\foo\modules and have a file called trunk\lib\foo\libfoo.php. Now libfoo.php can include once or require once all the modules as required.
PHP now supports Phar archives. There's full documentation on php.net.
There's a complete tutorial on IBM website as well.
One neat thing you can do with Phar archives is package an entire application and distribute it that way.
http://php.net/phar
http://www.ibm.com/developerworks/opensource/library/os-php-5.3new4/index.html
Ahh, libraries...
There are two conflicting purposes here:
Sanity when updating scripts (ie. not breaking 10 other apps).
Keeping things in one organized logical place for developer efficiency.
I suggest you take a close look at git and git submodules
We use git submodules extensively for this very purpose. It allows the best of both worlds because shared scripts can be upgraded at will in any project, and then that change can be moved to the other projects (deliberately) when you have time to do so and test correctly.
Of course, you need to be using git to take advantage of submodules, but if you are not using git, and you start, you'll eventually wonder how you ever lived without it.
Edit: Since the original poster is using svn, consider using SVN Externals.
UPDATED:
you just have to put the lib in some place reachable by your apps (in a place where you can reach it via http or ftp or https or something else) and include it.
If you have to update it often you can package your library in a single phar file and you can then provide your client a function to pull the library from some remote path and update a parameter in their local configuration accordingly, like:
function updateLocalLibary(){
//read the remote library in a variable
$file= file_get_content($remoteLibraryRepository.$libraryPharFile);
//give it a unique name
$newLibraryName=$libraryPharFile."_".date('Ymdhsi');
//store the library it on a local file
file_put_content($localLibraryPath.$newLibraryName,$file);
//update the configuration, letting your app point to the new library
updateLatestLibraryPathInConfig($newLibraryName);
//possibly delete the old lib
}
In your include path then you don't have necesasrily to hardcode a path, you can include a parameter based on your config, like:
include( getLatestLibraryPathFromConfig() )
(you are responsible to secure the retrieval in order to let only your clients see the library)
Your conf can be in a db, so that when you call updateLibraryPathInConfig() you can perform an atomical operation and you are sure not to have client read dirty data.
The clients can then update their library as needed. They may even schedule regular updates.
There are a lot of options:
tar + ftp/scp
PEAR (see above #Wayne)
SVN
rsync
NFS
I recommend to use a continuous integration software (Atlassian Bamboo, CruiseControl); check out your repository, build a package, and then use rsync. Automatically.
You should also look into using namespace in order to avoid conflicts with other libraries you might use. pear is probably a good idea for the delivery method, however, you can just place it in the standard path /usr/share/php/, or any other place that is set as the include path in your php settings file.
Good question, and probably one that doesn't have a definite answer. You can basically pick between two different strategies for distributing your code: Either you put commonly used code in one place and let individual applications load from the same shared place, or you use a source-control-system to synchronise between local copies. They aren't mutually exclusive, so you'll often see both patterns in use at the same time.
Using the file system to share code
You can layer the include_path to create varying scopes of inclusion. The most obvious application of this pattern is a globally maintained PEAR repository and a local application. If your it-system consists of multiple applications that share a common set of libraries, you can add a layer in between these (a framework layer). If you structure the include_path such that the local paths come before the global paths, you can use this to make local overrides of files. This is a rather crude way to extend code, since it works per-file, but it can be useful in some cases.
Use source-control
Another strategy is to make a lot of local checkouts of a single shared repository. Some benefits over the layered-include-pattern is that you can make more fine grained local changes. It can be a bit of a challenge to manage the separation between application layers (infrastructure, framework, application). svn:externals can work, but has some limitations. It's also slightly more complicated to propagate global changes to all applications. An automated deployment process can help with that.
I'm running the same php script on many domains on an apache2 server. Only some of the files change between domains, and the rest are always the same. Right now, every time I set up a new domain, I copy all the files, but I'd really like to have these common files in one place so any changes would affect all domains.
I've thought of using a bunch of symlinks to point at common files. Is this an ok approach, or are there some simple edits I can make to the php scripts or apache configuration files to make this more efficient?
Thanks!
The way I do this kind of thing is to create a "common" directory, where I place all the file that can be shared between each site. Then I simply include them wherever they are needed.
This is pretty good because allows to add features across multiple sites.
I'd suggest abstracting the common code into a set of 'library' scripts. Placing these in a common directory, and making that available by modifying PHP's include_path variable. This means you most likely won't have to modify your current scripts, while still removing the need to have more than one copy.
This path could (and probably should) be outside of your public directories. This enhances the security of your websites by not making them directly available to outside users.
This can be a bit tricky, as the application almost needs to know you're doing this. IME, it works best when you can divide the app into common code and instance code in two separate directory trees. The common code also needs to not do anything silly like include a file that has to be in the instance tree.
A single point of entry to load the common code is also a big bonus because then you can chain a few very small files: the instance code includes one in it's own directory; that file includes a file outside the instance code; that file then either loads the entry point file for the common code, or loads another that does. Now this is only one way to do it, but it means you have just one file that needs to know where the common code is (so you can move it if you have to with minimal effort), and if you do it right, all the various instance code trees load it, albeit indirectly.
You could have a library directory that sits above all of your sites, and a config file that states which library files your sites should include by default. You can then have another config file within each site that overrides the global config. These config files can be used to generate include('../../lib/*.php') statements to build the basic function toolkit needed for each site.
some_high_level_directory/
-> lib/
->*.php (library files)
-> config.php (global library includes)
-> site_1/
-> config.php (library includes that only relate to site_1)
-> www/
-> site_2/
-> config.php (library includes that only relate to site_2)
-> www/
-> etc, etc
Hopefully that makes sense... :)