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)
Related
I am currently working as a student on php project which has grown since the beginning of time and has about 1800 php-files.
The problem is: it is completely without namespaces, or any of the PSR-4, etc. recommendations. The technical debt is strong with this one :).
We want to use composer (and twig and some libraries more) and having problems including this (especially composer). I think it's because of the overwrite of __autoload() via spl_autoload_register() in the composer-autoloader?
Is there a good and fast way to start integrating namespaces without rewriting the whole project?
You can still use Composer with PSR-0 or classmap.
I'd probably go with the classmap first. Advantages: Can deal with multiple classes per file. Can deal with arbitrary file structures.
Once you achieved using Composer's autoloading, you can start removing either the existing autoloader or those require_once/include_once that are likely spread all over the place.
Once you've got rid of all that file loading legacy and have established Composer autoloading, you can try to organize the code according to PSR-0. This will probably require you to rename files and reposition them. It might also be the case that the classes don't have any identifiable prefixes - which is bad for your PSR-0 autoloading because all these files would belong into one single folder.
Note that until this point you haven't changed the name of any class, so the code should run without any changes.
Using namespaces does not have a very noticeable advantage. You'd be forced to rename all classes, rename all usages of that class name, and all in all it won't provide any noticeable benefit if used alone.
On the other hand, you sound like you do want to refactor everything else as well, so switching to namespaces can be used as a signal for "newer" code.
You can use PSR-4 and PSR-0 at the same time, so it won't affect your renaming of classes (besides the necessary class name changes in all the places).
In composer documentation section about autoloading I found at least two means to load classes that not corresponds to psr-0/4. First one is to specify classmap property of composer.json file and second one is fill include-path property in my composer.json.
As I can see include-path is more plain feature while classmap caused scanning for classes in specified locations. Who can explain which one should I use in different cases?
Avoid using include-path. It is meant for old software that expects the include_path setting to contain some directories, so that require_once "Relative/Path/To/Class.php" works from ANY location (think of the way PEAR works). Using too many paths impacts performance, because PHP needs to scan starting from the first directory, until it finds the relative path requested.
Classmaps are an always working solution if the classes do not conform to PSR-0 or PSR-4. Autoloading works by knowing the name of the class and finding out the file this class is contained in. PSR-0/4 define a way to know the file name by using and splitting the class name. Classmaps however know every class name and their file name directly. The bad thing about classmaps is that if they grow too large, they also affect performance because loading a huge classmap and then only using about 1% of the contained classes has a big overhead.
include-path and classmap are not mutually exclusive. In fact, they might be both needed: To load the first class, you'd need the classmap (otherwise you'd be forced to explicitly use require_once), and if that file will load dependencies using relative paths inside require_once (and does not know about autoloading), a proper include path has to be set.
If you ever have the chance to change it, I highly recommend to avoid setting the include path, and only use the classmap feature to autoload classes (which means you should remove any include/require functions in that code base). It would be even better if your code can be transformed to be PSR-0 compliant, but this usually is a huge rewriting task for old code with barely any benefit. You'd have to worry about performance only if you really have a HUGE framework with many files and classes - which usually is not the case with older code bases.
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 have a directory of PHP scripts ( mainly utilities), that is located on C:\Development, whereas my Symfony application is located in D:\Development.
How to include the utility scripts into the Symfony application? I try not to use include() because I prefer a symfony-like command.
There are basically two approaches
Extend the autoloading
modify the include path
#2 can be achieved numerous ways. If you are unsure how to, let me know and I'll post some details.
You don't have to change php.ini. You can use ini_set or set_include_path. Check ricardo's comment in the User Contributed Notes section at the documentation for set_include_path().
Personally, I'd create a new folder inside the lib/vendor folder on your project, put your scripts in there, and then symfony should handle it all automatically assuming you've followed its naming conventions for files/classes. If not, you may need to alter the autoload stuff as per Peter Bailey's answer.
I prefer this way because I like to be able to deploy the project from one server to another as one atomic unit with no reliance on external dependancies. This may not be an issue for you though, in which case the existing answer will suit you better.
What solution would you recommend for including files in a PHP project?
There aren't manual calls of require/include functions - everything loads through autoload functions
Package importing, when needed.
Here is the package importing API:
import('util.html.HTMLParser');
import('template.arras.*');
In this function declaration you can explode the string with dots (package hierarchy delimeter), looping through files in particular package (folder) to include just one of them or all of them if the asterisk symbol is found at the end of the string, e.g. ('template.arras.*').
One of the benefits I can see in package importing method, is that it can force you to use better object decomposition and class grouping.
One of the drawbacks I can see in autoload method - is that autoload function can become very big and not very obvious/readable.
What do you think about it?
What benefits/drawbacks can you name in each of this methods?
How can I find the best solution for the project?
How can I know if there will be any performance problems if package management is used?
I use __autoload() extensively. The autload function that we use in our application has a few tweaks for backwards compatibility of older classes, but we generally follow a convention when creating new classes that allow the autoload() to work fairly seemlessly:
Consistent Class Naming: each class in its own file, each class is named with camel-case separated by an underscore. This maps to the class path. For example, Some_CoolClass maps to our class directory then 'Some/CoolClass.class.php'. I think some frameworks use this convention.
Explicitly Require External Classes: since we don't have control over the naming of any external libraries that we use, we load them using PHP's require_once() function.
The import method is an improvement but still loads up more than needed.
Either by using the asterisk or loading them up in the beginning of the script (because importing before every "new Classname" will become cumbersome)
I'm a fan of __autoload() or the even better spl_autoload_register()
Because it will include only the classes you're using and the extra benefit of not caring where the class is located. If your colleges moves a file to another directory you are not effected.
The downside is that it need additional logic
to make it work properly with directories.
I use require_once("../path-to-auto-load-script.php.inc") with auto load
I have a standard naming convention for all classes and inc files which makes it easier to programaticaly determine what class name is currently being requested.
for example, all classes have a certain extension like inc.php (so I know that they'll be in the /cls directory)
and
all inc files start with .ht (so they'll be in the /inc directory)
auto load accepts one parameter: className, which I then use to determine where the file is actually located. looping once I know what my target directory is, each time adding "../" to account for sub sub pages, (which seemed to break auto load for me) and finally require_once'ing the actual code file once found.
I strongly suggest doing the following instead:
Throw all your classes into a static array, className => filepath/classFile. The auto load function can use that to load classes.
This ensures that you always load the minimum amount of files. This also means you avoid completely silly class names, and parsing of said names.
If it's slow, you can throw on some accelerator, and that will gain you a whole lot more, if it still is slow, you can run things through a 'compile' process, where often used files are just dumped into common files, and the autoload references can be updated to point to the correct place.
If you start running into issues where your autoloading is too slow, which I find hard to believe, you can split that up according to packages, and have multiple autoloading functions, this way only subsets of the array are required, this works best if your packages are defined around modules of your software (login, admin, email, ...)
I'm not a fan of __autoload(). In a lot of libraries (some PEAR libraries, for instance), developersuse class_exists() without passing in the relatively new second parameter. Any legacy code you have could also have this issue. This can cause warnings and errors if you have an __autoload() defined.
If your libraries are clear though, and you don't have legacy code to deal with, it's a fantastic tool. I sometimes wish PHP had been a little smarter about how they managed the behavior of class_exists(), because I think the problem is with that functionality rather than __autoload().
Rolling your own packaging system is probably a bad idea. I would suggest that you go with explicit manual includes, or with autoload (or a combination for that matter).