I have always wanted to play with Symfony since I heard many cool things about the framework. Finally got some time and started studying the framework. I would save the experience for another blog post. However I am going to share how easy it is to load external libraries.
Libraries supporting PSR-0 standard
If the library was written according to the PSR-0 standard, it is already well structured with the proper implimentation of namespace. For such libraries, just open up “app/autoload.php” and add the namespace to the array which is passed to the $loader->registerNamespaces() method. Your codes should look something similar to:
1 2 3 4 5 6 |
<?php // [snip] $loader->registerNamespaces(array( //[snip] 'MyLib' => __DIR__.'/../vendor/mylib/src', // the directory to contain the root namespace )); |
Libraries supporting PEAR Conventions
Libraries with support for PEAR conventions could be easily loaded as well. Just pass the autoloader prefix (the first part of the class name or the root directory name followed by underscore) to the $loader->registerPrefixes() method.
Something like:
1 2 3 4 |
<?php $loader->registerPrefixes(array( 'MyLib_' => __DIR__.'/../vendor/mylib/src', )); |
In such scenarios the class MyLib_MyClass should reside inside __DIR__.’/../vendor/mylib/src/MyLib/MyClass.php – as the PEAR standard suggests.
The Old and Incompatible ones
PHP has a very long history of evolution and there are plenty of community maintained codes which haven’t yet been updated to reflect the modern development standards. There are many 3rd party libraries out there which are old (was written before PHP 5.3) but useful. While there is no direct way to load them into Symfony, thanks to the nifty autoloader, we can easily use them with Symfony2.
Say, we have a class like this:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
<?php // kill.php /** * KillingCurse is one of the 3 unforgivable curses * and its use earns you a one way ticket to Azkaban! * * @author He-Who-Must-Not-Be-Named */ class KillingCurse { public function getIncantation() { return "Avada Kedavra!"; } } |
It is a single file library – no namespace, no PEAR naming. What do we do? We make it PEAR compatible 🙂
# First rename the file according to the class name – KillingCurse.php
# Now create a vendor and source directory under the “vendor” directory of the app. Say, we name “voldemort” as the vendor and name the source directory “src”. The file structure would be- “/vendor/voldemort/src”. This is not a requirement, we could just create any directory under the “/vendor” directory but follwing the Symfony naming convention is a good practice.
# We need to create a prefix, so we create a directory named “Spells” (/vendor/voldemort/src/Spells)
# We put the KillingCurse.php under the Spells directory and define a Spells_KillingCurse class in the same file like this:
1 2 3 4 5 6 7 8 9 10 |
<?php class Spells_KillingCurse { public static function load() { return TRUE; } } |
The full file now looks like:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 |
<?php /** * KillingCurse is one of the 3 unforgivable curses * and its use earns you a one way ticket to Azkaban! * * @author He-Who-Must-Not-Be-Named */ class KillingCurse { public function getIncantation() { return "Avada Kedavra!"; } } class Spells_KillingCurse { public static function load() { return TRUE; } } ?> |
# Now we register the “Spells_” prefix to the “app/autoload.php”:
1 2 3 4 5 |
<?php $loader->registerPrefixes(array( //[snip] 'Spells_' => __DIR__.'/../vendor/voldemort/src', )); |
# We use the following codes in the controller:
1 2 3 |
\\Spells_KillingCurse::load(); $killingCurse = new \\KillingCurse(); $inc = $killingCurse->getIncantation(); |
Points to be Noted:
— \Spells_KillingCurse::load(); We are using a static call which does nothing. But this makes the autoloader load the file in which the bare KillingCurse lives. We used a static call instead of having to initiate an object.
— An extra class without any functionality is added just so that entire file is loaded. Any functions, classes or constants will get imported into the global namespace.
— Be sure to use the “\” before the classes, functions etc. You’re inside a namespace and you must refer to the global namespace to use items in the global scope.
— There could be many other ways to do this. Like I mentioned at the top of this post, I am just beginning Symfony2. I would love to hear new ideas or suggestions to improve the codes.