(Created page with "= PHP Packaging Tips = we need content ;) Category:PHP") |
|||
Line 1: | Line 1: | ||
= PHP Packaging Tips = | = PHP Packaging Tips = | ||
we need | == Autoloader == | ||
=== Explanation === | |||
'''Composer''': most library and lot of applications are now "composer" aware. Which means composer is used to install dependencies and create a suitable autoloader. Composer is mostly a "Bundled every library in every project", not something we want in Fedora. | |||
'''Consumer Autoloader''': in some case, we can add an autoloader for an application and all its dependencies. It seems this is not the best solution, if the dependency tree change, the autoloader need to be fixed. | |||
'''Provider Autoloader''': if each library provides an autoloader for its classes and its dependencies, a consumer just have to include this autoloader. This seems the best solution, so recommended here. | |||
Providing an autoloader is not mandatory (so not in the Guidelines), but seems a good practice. | |||
=== Implementation === | |||
There are various way to create an autoloader | |||
'''classmap''' : when "composer.json" describe a library to autoload a classmap, e.g. | |||
<pre> | |||
"autoload": { | |||
"classmap": ["lib/"] | |||
} | |||
</pre> | |||
the simple solution is to generate an simple classmap autoloader, using the '''phpab''' command, e.g. | |||
<pre> | |||
BuildRequires: %{_bindir}/phpab | |||
%build | |||
%{_bindir}/phpab --output src/autoload.php src | |||
</pre> | |||
'''symfony''': recommended when your package already pull some symfony components, e.g. | |||
<pre> | |||
BuildRequires: php-composer(symfony/class-loader) | |||
Requires: php-composer(symfony/class-loader) | |||
(cat <<'AUTOLOAD' | |||
<?php | |||
if (!isset($fedoraClassLoader) || !($fedoraClassLoader instanceof \Symfony\Component\ClassLoader\ClassLoader)) { | |||
if (!class_exists('Symfony\\Component\\ClassLoader\\ClassLoader', false)) { | |||
require_once '%{phpdir}/Symfony/Component/ClassLoader/ClassLoader.php'; | |||
} | |||
$fedoraClassLoader = new \Symfony\Component\ClassLoader\ClassLoader(); | |||
$fedoraClassLoader->register(); | |||
} | |||
$fedoraClassLoader->addPrefix('Foo\\Bar', dirname(dirname(__DIR__))); | |||
AUTOLOAD | |||
) | tee src/autoload.php | |||
</pre> | |||
'''Notice''': in this implementation proposal, ''$fedoraClassLoader'' can be shared between libraries when various autoloader are stacked. | |||
'''ZendFramework''': recommended when your package already pull some ZF components. | |||
<pre> | |||
TODO and example | |||
</pre> | |||
[[Category:PHP]] | [[Category:PHP]] |
Revision as of 11:34, 26 June 2015
PHP Packaging Tips
Autoloader
Explanation
Composer: most library and lot of applications are now "composer" aware. Which means composer is used to install dependencies and create a suitable autoloader. Composer is mostly a "Bundled every library in every project", not something we want in Fedora.
Consumer Autoloader: in some case, we can add an autoloader for an application and all its dependencies. It seems this is not the best solution, if the dependency tree change, the autoloader need to be fixed.
Provider Autoloader: if each library provides an autoloader for its classes and its dependencies, a consumer just have to include this autoloader. This seems the best solution, so recommended here.
Providing an autoloader is not mandatory (so not in the Guidelines), but seems a good practice.
Implementation
There are various way to create an autoloader
classmap : when "composer.json" describe a library to autoload a classmap, e.g.
"autoload": { "classmap": ["lib/"] }
the simple solution is to generate an simple classmap autoloader, using the phpab command, e.g.
BuildRequires: %{_bindir}/phpab %build %{_bindir}/phpab --output src/autoload.php src
symfony: recommended when your package already pull some symfony components, e.g.
BuildRequires: php-composer(symfony/class-loader) Requires: php-composer(symfony/class-loader) (cat <<'AUTOLOAD' <?php if (!isset($fedoraClassLoader) || !($fedoraClassLoader instanceof \Symfony\Component\ClassLoader\ClassLoader)) { if (!class_exists('Symfony\\Component\\ClassLoader\\ClassLoader', false)) { require_once '%{phpdir}/Symfony/Component/ClassLoader/ClassLoader.php'; } $fedoraClassLoader = new \Symfony\Component\ClassLoader\ClassLoader(); $fedoraClassLoader->register(); } $fedoraClassLoader->addPrefix('Foo\\Bar', dirname(dirname(__DIR__))); AUTOLOAD ) | tee src/autoload.php
Notice: in this implementation proposal, $fedoraClassLoader can be shared between libraries when various autoloader are stacked.
ZendFramework: recommended when your package already pull some ZF components.
TODO and example