CiviCRM Community Forums (archive)

*

News:

Have a question about CiviCRM?
Get it answered quickly at the new
CiviCRM Stack Exchange Q+A site

This forum was archived on 25 November 2017. Learn more.
How to get involved.
What to do if you think you've found a bug.



  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Discussion (deprecated) »
  • Feature Requests and Suggestions (Moderator: Dave Greenberg) »
  • autoload for civicrm libraries
Pages: [1]

Author Topic: autoload for civicrm libraries  (Read 2021 times)

donquixote

  • I post occasionally
  • **
  • Posts: 42
  • Karma: 3
  • CiviCRM version: none
  • CMS version: Drupal
  • MySQL version: 5
  • PHP version: 5.2
autoload for civicrm libraries
February 26, 2012, 08:21:50 am
Hi,
I imagined this must have already been mentioned or suggested, but I have not found it anywhere else.

The codebase of CiviCRM looks like a perfect candidate for PHP class autoloading.
We do not even have to move classes and files around, they are all decently arranged in a directory tree!

The require_once statements all over the place are not just additional code weight, they also need to be carefully kept up to date, old dependencies removed, etc.

------

What I would suggest:
1. Write a custom autoloader for CiviCRM, inspired by existing ones.
2. Add an alternative autoload mechanic, that can hook into existing Drupal or Joomla autoloaders. This way, we can let those existing tools deal with stuff like caching.
3. Slowly remove the require_once statements.

--------------

Autoloading in general

The function spl_autoload_register() is available since PHP 5.1.2
http://php.net/manual/de/function.spl-autoload-register.php

Looking at existing autoloaders, I can identify three aspects:
- Direct lookup: Determine the file location only by looking at the fragments of the class name. The only additional information we use is a list of possible base directories (which might depend on the prefix or top namespace of the class name).
- Direct lookup + lazy cache: Every successful lookup is stored in a cache, so next time we don't have to analyse the string fragments.
- Using a pre-generated map: We look for the class name in a big pre-generated array. To generate the map, we have to scan a bunch of directories. The challenge is not the lookup itself, but generating the map, and knowing what to scan.

Usually, a good autoload mechanic does come with a

------------

Existing autoloaders in Drupal

Drupal 6 and 7 (map-based)

D6 contrib ("autoload" module) and D7 core provide a map-based autoload mechanic that is based on scanning files and looking for a string like "class xyz".
This is not how it should be done. Why?
- It does not imply any standards about where to put your classes, and how to name them. It does not even imply a one-class-per-file rule, or to prefix them by the module name.
- Any file that does contain a class, has to be listed in the module's info file, like this: "files[] = somefile.inc". This list can get quite long.
- You have to clear caches, before Drupal will recognize a new class file, or before it recognizes that an old class file has been removed.

Drupal 8 (PSR-0)

D8 is going to have an autoloader based on PHP 5.3 namespaces and PSR-0.
https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
It is going to use the symfony class loader, which implements this pattern:
http://drupalcode.org/project/drupal.git/blob/87e5ffc3b5e47aaa1273935988c2e6956f6ce529:/core/vendor/Symfony/Component/ClassLoader/UniversalClassLoader.php#l213
In addition, the Symfony class loader does implement the PEAR naming convention for classes, which is very close to what CiviCRM is doing.

To be honest, I am not really happy about PSR-0 for Drupal modules.
W/o PSR-0, we could have something like
Drupal\foo\SomeClass -> sites/all/modules/foo/lib/SomeClass.php
With PSR-0, it has to be
Drupal\foo\SomeClass -> sites/all/modules/foo/Drupal/foo/SomeClass.php, or
Drupal\foo\SomeClass -> sites/all/modules/foo/lib/Drupal/foo/SomeClass.php

But anyway, that's what a majority of people want, so be it.

"X Autoload" module (D6, D7, D8 ?)

http://drupal.org/project/xautoload
This is a module that I am writing, which aims to bring a reasonable autoloading to D6 and D8. The module wants to support everything that is being discussed for D8, and more. That is,
- PSR-0, PEAR (prefix-based), and some variation of these.
- direct lookup, lazy cache, pregenerated map.
- pluggable, easily testable, and hopefully performing just as good as the Symfony one, or better.
- an interface that does make it easy to compare with the Symfony class loader.
- a standard for prefixing every module-provided class with the module name, and putting it inside $module_dir/lib. (but easily pluggable for other patterns)

The code (not what you see now, but what is waiting in my local repo) is adapted from the Symfony class loader, with a few modifications.

I think, for D6 and D7, this is going to be preferable to the existing map-based autoloading. For CiviCRM, this would mean that we just have to register the CRM folder for the CRM_ prefix, and it would just work.
For Drupal 8, we will see.

-----------

Autoload in Joomla

Honestly, I have no idea :)
If Joomla does not provide anything by itself, we could still register a custom autoloader.

donquixote

  • I post occasionally
  • **
  • Posts: 42
  • Karma: 3
  • CiviCRM version: none
  • CMS version: Drupal
  • MySQL version: 5
  • PHP version: 5.2
Re: autoload for civicrm libraries
February 26, 2012, 08:51:32 am
Oh, great, it looks like I am totally out of date once again :)
http://issues.civicrm.org/jira/browse/CRM-9544

Anyway, maybe my comments here do help.

donquixote

  • I post occasionally
  • **
  • Posts: 42
  • Karma: 3
  • CiviCRM version: none
  • CMS version: Drupal
  • MySQL version: 5
  • PHP version: 5.2
Re: autoload for civicrm libraries
February 26, 2012, 09:15:30 am
Btw, while I did disagree with PSR-0 for Drupal 8 (and having no chance vs a majority of people who support it), I have absolutely no problem with PSR-0 for CiviCRM.
The issue I have with PSR-0 is explained quite nicely here:
https://groups.google.com/forum/#!topic/php-standards/PhgdC7djii8
Quote
- It's unclear from the PSR-0 spec if it's allowed to register a
namespace fragment.  That is, if we could say that:

Drupal\Module\$module\MyClass => somedir/$module/src/MyClass.php
which unfortunately is not allowed with PSR-0.

Ironically, this is the person (Larry Garfield / Crell) who does now strongly support PSR-0 for Drupal modules ..
Anyway, following a standard does have a value, and if a majority of people wants that, so be it.

The above deep subdir mapping would allow more shallow directory trees in modules. For CiviCRM this is not an issue, because CiviCRM is more like a standalone library than a Drupal module, and the CiviCRM namespace doesn't need to be nested within the Drupal namespace.

---------

xautoload does (or will) support PSR-0 and PEAR (which is the equivalent to PSR-0 with "_" instead of "\"), but it does also support what Larry Garfield suggested above. If you think about it, PSR-0 and PEAR are just special cases of this namespace/prefix to subdir mapping.

Adam Wight

  • I’m new here
  • *
  • Posts: 9
  • Karma: 3
  • CiviCRM version: 4.2.x
  • CMS version: Drupal
  • MySQL version: 5
  • PHP version: 5.3
Re: autoload for civicrm libraries
February 27, 2012, 02:11:38 pm
Cool!  Thanks for doing the work to research what the Drupal project is up to.  I agree with your criticisms of PSR-0, plus the backslash notation trickling down from the Php Internals group is like kryptonite to developers. \\\\adam

Pages: [1]
  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Discussion (deprecated) »
  • Feature Requests and Suggestions (Moderator: Dave Greenberg) »
  • autoload for civicrm libraries

This forum was archived on 2017-11-26.