views:

614

answers:

6

Hello, everyone.

What solution would you recommend for including files in a PHP project?

  1. There aren't manual calls of require/include functions - everything loads through autoload functions
  2. 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?
A: 

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, ...)

Saem
+1  A: 

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.

Bob Fanger
A: 

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().

Jeremy DeGroot
+1  A: 

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.

42
+1  A: 

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.
jonstjohn
A: 

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).

troelskn