openSUSE:Packaging PHP

Jump to: navigation, search


This page is a introduction on how to package PHP projects for openSUSE and others using the openSUSE Build Service. All global guidelines for packaging are also valid for PHP projects.
Icon-warning.png
Warning: This page is currently under development. Please test and suggest improvements.
Icon-warning.png
Warning: The PHP packagers are starting to provide packages which matches different PHP versions at the same time, therefore the development repository may currently be inconsistent.

General Notes

To simplify reviewing, please follow all openSUSE packaging guidelines.

  • Use spec-cleaner to verify your spec-file and to bring them into easily readable formats.
  • Check the package's license and ensure it's LICENSE file is included: [1]
  • Check the group. Web applications will typically be installed into

There are some useful macros for packaging PHP available:

Macro Typical value explanation
%__php /usr/bin/php PHP binary
%__phpize /usr/bin/phpize PHP-ize binary
%__php_config /usr/bin/php-config PHP-config binary
%php_version ? PHP's version

Packaging Applications

PHP applications which bases on PEAR packages must require the virtual provides php-pear(channelname/packagename) instead of the real package names.

PHP applications should put PHP files under /usr/share/php/{<Vendor Name> or <Application Name>}. So, for example:

  • /usr/share/php/roundcubemail for the roundcubemail package
  • /usr/share/php/nextcloud for the nextcloud package

If you expect multiple versions being installed at the same host and the same time, consider to add the version number (with dots replaced by underscores, if needed). Examples:

  • /usr/share/php/nextcloud13
  • /usr/share/php/nextcloud14_0

Supporting different web servers

Providing configuration snipplets for web servers like apache or nginx is very welcome and a big plus for any package. But please consider to create sub-packages if you support different web servers:

  • moodle <- main package. This package should neither recommend of suggest any of the sub-packages specific for the web server.
  • moodle-config-nginx
    • package containing configuration files for nginx and matching requires/recommends
    • this package should have a
      Requires: moodle
      line, so it is automatically removed if the user uninstalls moodle
    • this package should have a
      Supplements: (nginx and moodle)
      line, so it get's automatically selected if the user installs nginx
  • moodle-config-apache
    • package containing configuration files for apache(2) and matching requires/provides
    • this package should have a
      Requires: moodle
      line, so it is automatically removed if the user uninstalls moodle
    • this package should have a
      Supplements: (apache2 and moodle)
      line, so it get's automatically selected if the user installs apache2

composer files

A composer.json file is not used, and should be installed as %doc as it provides useful information about the package and its dependencies.

PEAR Packaging

To package pear-projects several macros can be used. Therefore the php-devel as well as the php-pear package must be required at devel-time and the php-pear package must be required for installation purposes.

Icon-warning.png
Warning: With PHP 8 it is planned to move the /usr/share/php7/PEAR locations to /usr/share/php/PEAR
Macro Typical value explanation
%__pear /usr/bin/pear PEAR binary
%php_pearxmldir /var/lib/pear PEAR's XML directory
%pear_phpdir /usr/share/php7/PEAR PEAR's main directory
%pear_docdir /usr/share/php7/PEAR/doc PEAR documentation directory
%pear_testdir /usr/share/php7/PEAR/test PEAR documentation directory
%pear_datadir /usr/share/php7/PEAR/data PEAR data directory
%pear_cfgdir /usr/share/php7/PEAR/cfg PEAR configuration directory
%pear_wwwdir /usr/share/php7/PEAR/htdocs PEAR htdocs directory
%pear_metadir /usr/share/php7/PEAR PEAR meta directory

Packaging a PEAR channel

PEAR Packages which do not come from the official PEAR repository must provide a channel to allow installation. Package names for channels should be lower-case and must follow this naming schema: php-pear-channel-{channel-name}.

Every pear-channel must contain:

BuildRequires:  php-devel
BuildRequires:  php-pear
Requires:       php-pear
Provides:       php-channel(channel-name)
BuildRequires:  php-devel
BuildArch:      noarch

From PHP5 and PHP7 to the new packaging schema

The old naming-scema for channels included PHP's version number in the package name. As we dropped that, new channels should be include the following obsoletes sections in it's spec:

Obsoletes:      php5-pear-channel-oldchannelname
Obsoletes:      php7-pear-channel-oldchannelname

SPEC file Example

Name:           php-pear-channel-htmlpurifier
Version:        1.1
Release:        0
Summary:        Adds HTML Purifier channel to PEAR
License:        LGPL-3.0
Group:          Development/Libraries/Other
Url:            http://htmlpurifier.org/
Source0:        http://htmlpurifier.org/channel.xml
BuildRequires:  php-devel
BuildRequires:  php-pear
Requires:       php-pear
Provides:       php-channel(htmlpurifier)
Obsoletes:      php5-pear-channel-htmlpurifier
Obsoletes:      php7-pear-channel-htmlpurifier

%description
This package adds the HTML Purifier htmlpurifier.org channel which
allows PEAR packages from this channel to be installed.

%prep
%setup -q -c -T

%build
# Empty build section, nothing to build

%install
mkdir -p %{buildroot}%{php_pearxmldir}
install -pm 644 %{SOURCE0} %{buildroot}%{php_pearxmldir}/htmlpurifier.org.xml

%post
if [ $1 -eq  1 ] ; then
   %{__pear} channel-add %{php_pearxmldir}/htmlpurifier.org.xml > /dev/null || :
else
   %{__pear} channel-update %{php_pearxmldir}/htmlpurifier.org.xml > /dev/null ||:
fi

%postun
if [ $1 -eq 0 ] ; then
   %{__pear} channel-delete htmlpurifier.org > /dev/null || :
fi

%files
%{php_pearxmldir}/*

%changelog

Packaging a PEAR package

Package names for PEAR packages should be lower-case and must follow this naming schema: php-pear-{package-name}.

Every PEAR package must contain the following code:

BuildRequires:  php-channel(channel-name)
BuildRequires:  php-devel
BuildRequires:  php-pear
BuildRequires:  php-pear
Requires:       php-pear
Requires:       php-channel(channel-name)
Provides:       php-pear(channel-name/package-name) = %{version}
Obsoletes:      php5-pear-%{pear_sname}
Obsoletes:      php7-pear-%{pear_sname}
BuildArch:      noarch

For packages from the main PEAR repository the channel-name is empty. Packages which did not exist as PHP5 or PHP7 packages must not contain the "Obsoletes" parameter.

From PHP5 and PHP7 to the new packaging schema

Support automatic upgrading from PHP5 or PHP7 packaging schema needs some work. The package must provide all names foreign packages has been unused. To allow a smooth upgrading from PHP5 versions the package should contain line like the following:

Obsoletes:      php5-pear-old-package-name
Obsoletes:      php7-pear-old-package-name

Applications that consumes the package should consume the virtual provides php-pear(channel-name/package-name) instead of the real package names.

SPEC file Example

%define pear_name  Auth_SASL
Name:           php7-pear-Auth_SASL
Version:        1.1.0
Release:        0
Summary:        Abstraction of various SASL mechanism responses
License:        BSD-3-Clause
Group:          Productivity/Networking/Web/Servers
URL:            https://pear.php.net/package/%{pear_name}
Source:         https://pear.php.net/get/%{pear_name}-%{version}.tgz
BuildRequires:  php-devel
BuildRequires:  php-pear
Requires:       php-pear
Provides:       php-pear(%{pear_name}) = %{version}
Obsoletes:      php5-pear-%{pear_name}
Obsoletes:      php7-pear-%{pear_name}
BuildArch:      noarch

%description
Provides code to generate responses to common SASL mechanisms, including:
  - Digest-MD5
  - CramMD5
  - Plain
  - Anonymous
  - Login (Pseudo mechanism)

%prep
%setup -q -n %{pear_name}-%{version}
# move package.xml when needed
[ -f ../package.xml ] &&  mv ../package.xml .

%build

%install
%{__pear} install --nodeps --offline --packagingroot %{buildroot} package.xml
install -D -m 0644 package.xml %{buildroot}%{php_pearxmldir}/%{pear_name}.xml

%{php_pear_gen_filelist}

%post
if [ "$1" = "1" ]; then
  # on "rpm -ivh"
  %{__pear} install --nodeps --soft --force --register-only %{php_pearxmldir}/%{pear_name}.xml || :
fi
if [ "$1" = "2" ]; then
  # on "rpm -Uvh"
  %{__pear} upgrade --offline --register-only %{php_pearxmldir}/%{pear_name}.xml || :
fi

%postun
if [ "$1" = "0" ]; then
  # on "rpm -e"
  %{__pear} uninstall --nodeps --ignore-errors --register-only pear.php.net/%{pear_name} || :
fi

%files -f %{name}.files
%docdir %{pear_docdir}
%exclude %{pear_metadir}/.??*
%exclude %{pear_testdir}

%changelog

Run PHPUnit tests during the packaging phase

Whenever possible, PHPUnit test should be run during the packaging phase. In general, it should be easy to run those tests.

BuildRequires:  php-phpunit
...
%check
pushd %{pear_name}-%{version}/Symfony/Component/%{pear_name}
# in case you don't want packaging to fail on failing tests, append "|| true" to the next line
phpunit --bootstrap autoloader.php