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 :)
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.
Does CakePHP's bootstrap.php file have to do anything with the Bootstrap.js framework?
Is there any specific reason behind this file being named as such?
Bootstraps refer to a configuration file that includes the autoloader ( if present ) and any credential parsing/loading for a specific project.
The concept allows you to use a library in many projects only having to customize one file for each database/setup/modules to include/exclude.
Bootstrap framework was nicely named to suggest that using it will be synonymous to the bootstrap concept? ;)
No, it is unrelated to the bootstrap framework.
The point is to provide a single point which, by design, allows the core app/configuration to be extended in a variety of ways, as suggested by:
http://book.cakephp.org/2.0/en/development/configuration.html#bootstrapping-cakephp
Code + comments in the bootstrap.php file maintained with the release provide guidance on specific uses. FWIW I find it convenient to include bootstrap.php in my version control repository, while excluding core, database & email configurations so they can be maintained separately on my development & production server(s).
No, the two things are completely separate in all ways, other than their name.
Bootstrap.js
Bootstrap.js is a project, originally created by Twitter, to be a client-side development framework that encapsulates the workflow of HTML, CSS and JavaScript into an easy-to-use API. The project's tagline:
Bootstrap is the most popular HTML, CSS, and JS framework for developing responsive, mobile first projects on the web.
I am not, personally, aware of the reasons why they named it 'Bootstrap' (it was originally named 'Twitter Blueprint', blueprint making a little more sense since it defines the structure and outline of your application).
CakePHP's bootstrap.php
CakePHP's bootstrap.php file, on the other hand, represents the actual term "bootstrap". Rather, the process of "bootstrapping". Because of this, the name bootstrap.php fits really well!
In general, bootstrapping is:
the starting of a self-sustaining process that is supposed to proceed without external input
A better summary, keeping CakePHP in mind, is to say that the bootstrapping process in MVC applications (e.g. CakePHP) initializes "core" (i.e. used and available by everything in the application) configurations such as global constants, model / view / controller paths, or even loading other configuration files.
The Configuration documentation for CakePHP has several examples of how the application itself leverages bootstrap.php in this way (just search for "bootstrap.php" while on the page and you can jump through the examples). At the very bottom of that same page, you'll find a section on Bootstrapping CakePHP which outlines several reasons you'd want to extend it yourself (a few of which I mention above) =]
So my login check I have split into two sections that I tried putting in two different files and including them. First I will show the original code then the split code. I think my problem is with the link to the include. I try to use an absolute path. But it seems to be failing. My whole App is modular so I have global files set up outside of the rest of the App structure and I call the files as needed. I have also thought of just loading the functions through _autoload() but I don't know that this would solve my issue.
<?
//Inventory index.php
include$_SERVER['DOCUMENT_ROOT'].'/Globals/db_connect.php';
include$_SERVER['DOCUMENT_ROOT'].'/Globals/functions.php';
sec_session_start();if(login_check($mysqli)==true){?>
/////Html and or more php code to be executed. Usualy a mix of both.
<?}else{
echo ("You are not authorized to access this page, please login. <br/>");}?>
here is what I am trying to do....P.S. I know my code is kinda hard to read I am trying to format it for easier reading but I can process clumps better than I can spaced code. Not sure why.
<?
//Inventory index.php
include$_SERVER['DOCUMENT_ROOT'].'/Globals/auth1.php';?>
/////Html and or more php code to be executed. Usualy a mix of both.
<?}else{include$_SERVER['DOCUMENT_ROOT'].'/Globals/auth2.php';?>
What I think is happening is the includes in Auth1 are failing. are my absolute paths failing? Am I better off using _autoload().
You should always choose "autoloading" in favor of manual includes for multiple reasons.
Readable structure -- one class for each file and one folder for each namespace segment allows you to find anything in the directory structure of your project very fast.
Easy maintenance -- if you change the folder structure/position of your files (as well as their namespaces) you're done, no paths to be rewritten and verified.
Compatibility with other projects for example using PSR-0 or PSR-4. PSR-0 is meant for covering legacy code, PSR-4 should be used for new libraries.
Compatibility with package management software -- which expect some kind of predictable conventions to be respected. For example Composer expects either PSR-0 or PSR-4 and it enables autoloads for you.
On the subject of coding standards and formatting the same applies:
familiar structures are easier to recognize.
The decision is perfectly arbitrary; it's always your (or your team') choice. Either will work fine -- you will get used to any one of them.
Consistence is important, PSR-1 and PSR-2 are the lingua franca of both Symfony & friends as well as many other projects which use composer as their package management (and others).
I can suggest to use composer and it's autoloader which support different types of files loading. For production you can use --optimize option to make autoloading works better (as I remember composer scan all folders and build array of existing files)
I'm working on releasing a PHP framework I have been using for a few years
on github. Been trying to read up on the most correct way a project
should be structured, what extra files such as readme's etc should be
added. Been coming up with blanks on google. Can anyone point me to a
project that's a good example or any good write ups.
Some PHP projects hosted on Git(hub) include:
CakePHP
Gallery3
Garden
PHPUnit
Kohana
I'd just make sure that no temporary files, etc. get in the repository by creating a .gitignore file, and add some readme's etc. to the root of the repository.
Any configuration files should also be ignored, and sample configuration files should be created in the repository.
I'd recommend writing the readme file in a format that Github supports, like Markdown. It'll make your repository front page look better.
You might want to follow some kind of class naming guideline to make things like autoloading easier to implement. For example, the class MyFramework_Controller should be located at directory /lib/MyFramework/Controller.php.
You should just create some kind of basic layout for now - it'll be easier to give suggestions when we can see what you have right now.
What is the best way to integrate an external script into the Zend Framework? Let me explain because I may be asking this the wrong way. I have a script that downloads and parses an XML file. This script, which runs as a daily cron job, needs to dump its data into the database.
I am using Zend Framework for the site which uses this script and it seems to me that it would be best to use my subclassed model of Zend_Db_Abstract to do the adding and updating of the database. How does one go about doing this? Does my script go in the library next to the Zend Components (i.e. library/Mine/Xmlparse.php) and thus have access to the various ZF components? Do I simply need to include the correct model files and the Zend DB component in the file itself? What is the best way to handle this sort of integration?
Yes, you should put your own classes that maybe inherit Zend Framework classes or add further classes into your own folder next to the Zend Framework folder in library.
When you have Zend_Loader s auto-loading enabled, the class names will automatically map to the class you created, e.g.:
My_Db_Abstract will map to My/Db/Abstract.php .
In your library directory you should have your own library next to the Zend library folder. Whatever you call it (Mylib, Project, ...) you should include it into the Zend Autoloader and that's done as follows:
require_once 'Zend/Loader/Autoloader.php';
$loader = Zend_Loader_Autoloader::getInstance();
$loader->registerNamespace('Project_');
$loader->setFallbackAutoloader(true);
if ($configSection == 'development')
{
$loader->suppressNotFoundWarnings(false);
}
In order for you library to integrate nicely with ZF and the Autoloader you should stick to the ZF naming conventions. This means two things:
if you extend an existing ZF class, replicate the ZF folder structure so that your file has the same path and name except for the library name. E.g. /library/Zend/Db/Abstract.php => /library/Project/Db/Abstract.php.
if you write your own classes, still stick to the ZF naming conventions for the autoloader to find them.
I just came across something that may be germane to this question. This IBM developerWorks article.
The author recommends simply creating a scripts folder in the ZF hierarchy and the using it as one normally would within ZF (though he does set the ini path and call autoload). Is it that simple? Does simply being in the hierarchy of the framework and including the path and autoloader grant your script access to all of the goodies?
I'm not 100% sure what you're trying to ask but I will try to help. If at any point you add a reference to "/path/to/zend/framework" into your php include path then you have in essence enabled the Zend Framework. From there if you do:
require_once('Zend/Loader.php');
Zend_Loader::registerAutoload();
Then at any point in your script you can pretty much just create new Zend Framework objects and Zend_Loader will handle the rest.
One of the big things about the Zend Framework though is not forcing you to do things a certain way. That's why sometimes there are several ways to accomplish the same thing. So, if you feel you need to make your script use the Zend Framework just for the sake of doing so this is not really necessary. But if you think it may improve your script in some way then go for it.
I usually put custom stuff that I think could be used across projects in a custom folder in the library. So I have a library/Ak33m folder that has scripts that may be outside of the framework.
As a ZF noob myself, I think I understand some of what the OP is trying to figure out. So, I'll just explain a bit of what I understand in the hope that it is helpful either to the OP (or more likely, to a future reader, since the original question is so old and I imagine that OP is now a ZF guru).
I understand that ZF claims to be largely "use at will", so that you need no buy into an entire structure, like the Zend_Application, the Zend_Bootstrap class, the entire MVC approach, etc.
Further, I understand conventions for class naming and file locations that enable easy autoloading. Ex: class App_Model_User resides in a folder App/Model/User.php
I think what can be potentially confusing is that in the script context, where you have not yet
done the .htaccess magic that pushes all request to public/index.php
set your APPLICATION_PATH and include paths in public/index.php
created your Application or Bootstrap object tied to a config file
it can be a little bit unclear how best to avail yourself of most of the ZF goodness we get in that context and want in another context.
I guess my answer to the original question would be that the usual entry point sequence of
http request -> .htaccess -> index.php -> config
sets up much of our environment for us, we would need to duplicate some of that for different entry path.
So, for your script, my first instinct would be to create a common include file that mirrors much of what happens in index.php - set the include paths, the APPLICATION_PATH, instantiates and calls a bootstrap, and then does your script-specific processing.
Even better, it might be desirable to create a single entry point for all your scripts, like we do in the http/web context. Extend Zend_Application for your own script purposes so that $application->run(); no longer starts up the MVC router-controller-dispatch processing, but rather does your own stuff. In that way, this single script entry point would look almost identical to the web entry point, the only difference being which application object gets instantiated. Then pass the name of your desired Application class as a command line parameter to the script.
But here I confess to being less confident and just throwing out ideas.
Hope all this helps someone. It actually helped me to write it all down. Thanks and cheers!
Update 2009-09-29: Just ran across this article: Using Zend Framework from the Command Line
Update 2009-11-20: And another article: Cron jobs in Zend Framework | GS Design
Update 2010-02-25: Easy command line scripts with Zend Application - David Caunt