I’ve been writing my own general-purpose PHP library for a while and I’m thinking about how to organize the directory structure, but I wanted to get people’s ideas before I formalized the directory structure for the library.
Here is what I have so far:
I was thinking I could either do it “By Topic” or “By Category”. So far, I can only think of one example that I like of the “By Category”: Boost http://www.boost.org/doc/libs/1_46_1/?view=categorized
Also, Qt is organized by module, but I think it’s a bit messy because everything is kinda stuffed into QtCore http://qt-project.org/doc/qt-5/qtmodules.html
Thanks in advance.
I found a really great book that has shown me a number of great library design conventions to follow: http://www.apibook.com/blog/
I found an interesting article that mentions organization of code (http://highscalability.com/blog/2012/3/26/7-years-of-youtube-scalability-lessons-in-30-minutes.html). At the bottom, it says:
“What is your code tree going to look like? He wants these words to describe it: simple, pragmatic, elegant, orthogonal, composable. This is an ideal, reality is a bit different.”
First of all, the chosen structure is a compromise decision, that means that you’ll have to deal and prioritize some aspects over others depending on your purpose. There are some grouping criterias you could follow, such as:
- Functional Cohesion, I think that should be the strongest one in your design. Classes/files/resources with the same or similar functionality should be together
- Component Hierarchy, Depending on the granularity level you choose, that means if you prefer fine-grained components vs coarse-grained, you would have more or less files/resources in one folder. This can be controlled using folder hierarchy and nesting.
- Change, Some files are more likely to be changed than others, you have to keep this in mind in order to provide a folder hierarchy depending on the probability to be modified.
- Extensibility, For a framework to be useful and adaptable to almost any scenario you have to provide the possibility to extend components and functions. Adding a folder for extensions (aka plugins) is a good idea.
There are lot of criterias you should use, but always keep in mind the KISS Principle. You can search for package management in books like The Unified Software Development Process (Ivar Jacobson et al.), I hope this could be helpful.
Since it is multi-purpose library devoted to solve versatile problems or provide interfaces for common features, it is better to have structure by
subject which may be DataType/Technology/Language/Protocol etc. like so:
On top we have:
- Http which is a protocol so your
Http.requestwould be an interface to perform Http request
- Html which is markup language, so
Html.Form.UploadFilewill provide developer with features to create upload file forms
- Ajax which is technology
- XML which is markup language
- DataType which is … well, data type.
status_codes remain under
Http. Every sub-library can have its own util features like
DataType lib may need datatype_cast_lib to know how to juggle with datatypes.
This way of library organization mostly resembles organzation of PECL
Good question, BTW! I asked the same question myself frequently. I’ve been organizing and reorganizing my directories structure for years. It really depends on project. I’ve adapted structure above corresponding to structure you’ve provided here.
The core devs behind them were active (along with other major framework developers and php celebrities) in defining standard php 5.3 naming conventions so that their respective components could play with each other, Zend, and other libraries/frameworks that might follow the same conventions:
In both cases, bundles/libraries are first-class citizens, and the two follow similar patterns when it comes to organizing them.
The Lithium core, in particular, is a library in its own right. It’s organized like so:
$ ls LICENSE.txt analysis core g11n security template tests action console data net storage test util
(I tend to find Symfony 2 a bit messier/less predictive, but that’s just my own opinion.)
Please be PSR-0 compatible, whatever structure you’re going to use.
I personally suggest using the PEAR2 directory structure .
I would say a good place to start is to look at how other frameworks and/or libraries are doing it.
Personally I like the way the Zend Framework is organized, with a fairly flat namespace, having all major components in the Zend directory. When using the Zend MVC project structure, you get an added autoloader translating _ to / all classes are named like
Zend_Form and put in a file called Form.php inside the Zend directory, so that when calling
new Zend_Form – the autoloader looks for
Zend/Form.php. Only the ‘main’ class is directly inside the Zend folder, any additional class files, like exceptions and abstract are put inside a
Zend/Form folder, and classnames named like
Zend_Form_Exception – which cause the autoloader to look for
External libraries are usually treated as such, and separated from the rest of the code in a /lib, /library and/or /vendor folder to indicate that external authors are responsible for these classes.
I would say that it depends on how/if you use namepaces etc. Otherwise I would see a use for something like the ZendFramework directory layout (even though it’s ugly as sin… hehe). Then I usually have a
Corethat contains base functionality that all other parts might make use of like Array and String manipulation, Encryption/Decryption
+ Core - Array - String + Encryption - MD5 - SHA1 ...
Then I try to think of all subsequent folder as isolated parts/modules. Do I have a Jquery folder with a lot of JQuery helpers? Then that might be a good folder to add.
+ Core - Array - String + Encryption - MD5 - SHA1 ... +JQuery
Does my JQuery require some HTML specifics that other “modules” might also use? Then that should go into Core. For instance my JQuery helpers might make use of JSON.
+ Core - Array - String + Encryption - MD5 - SHA1 ... + Encoding - JSON +JQuery
If it’s JQUery specific it should recide under JQuery.
+ Core - Array - String + Encryption - MD5 - SHA1 ... + JQuery - Datepicker
By always asking the question “Is this something that oter parts of my library will make use of and/or extend?” you will get a good idea if the functionality in question should be part of your Core or part of your specific library module.
<project name>/ application/ configs/ application.ini controllers/ helpers/ forms/ layouts/ filters/ helpers/ scripts/ models/ modules/ services/ views/ filters/ helpers/ scripts/ Bootstrap.php data/ cache/ indexes/ locales/ logs/ sessions/ uploads/ docs/ library/ public/ css/ images/ js/ .htaccess index.php scripts/ jobs/ build/ temp/ tests/