Feature Wiki

Information about planned and released features

Tabs

Compatibility to PHP7

1 Requirements

ILIAS should run under PHP 7.

With the upcoming release of PHP 7, some functions will be removed which were declared as deprecated in PHP 5.x. PHP RFC: Remove deprecated functionality in PHP 7. Additionally some major changes in the behaviour of existing code constructs will come with PHP 7, see PHP7 upgrade notes.

Good

Bad

1.1 ILIAS 5.1 vs PHP7[RC2]

The following error messages are encountered when trying to get an ILIAS 5.1 installation up and running with PHP7. These are good examples for the types of problem we'll have to tackle.

Error: syntax error, unexpected 'new' (T_NEW)

Global replace:

  • =& new >>> = new
  • = &new >>> = new

session_regenerate_id(): Cannot regenerate session id - session is not active

ilInitialisation::setSessionHandler()

if(session_status() == PHP_SESSION_ACTIVE)
{
    session_regenerate_id();
}

Declaration of ilDate::get($a_format, $a_format_str = '') should be compatible with ilDateTime::get($a_format, $a_format_str = '', $a_tz = '')

ilDate

public function get($a_format,$a_format_str = '',$a_tz = '')
{
    return parent::get($a_format,$a_format_str,$a_tz);
}

Setup not completed [no real error message]

The following construct does work with PHP5.x but obviously not in PHP7. It took about 30min to debug.

MDB2_Driver_Common::_wrapResult()
$result =& new $class_name($this, $result, $limit, $offset);

MDB2_Result_Common::__construct
$this->result =& $result; >>> $this->result = $result;

Declaration of shibServerData::getInstance(array $data) should be compatible with shibConfig::getInstance()

Giving up...

1.2 Next Steps?

  • Find funding for all necessary developments (in progress)
  • Define responsibilities / Who will take care of which code? (in progress)
  • Proposal: use E_DEPRECATED [and E_NOTICES] (at least in DEVMODE)
  • Setup base PHP7 branch on ILIAS repo (based on PDO development, Fabian Schmid)
  • Make "general services" work (Leifos)
  • Setup PHP7 installation and run through test cases

2 Details of Major Issues

2.1 "=& new" produces a fatal

...=& new... 808 matches in 271 files (write ...= new... instead)

Lots of places, but search and replace should do most of the work. However the "=&" operator leads to issues in other places as well (e.g. MDB2 code that assignes objects that have been passed as references).

2.2 ereg removed

ereg 82 matches in 28 files, see stack overflow for a starting point to migration

Medium effort needed to tackle this, but locations can easily be "grepped".

2.3 Error Handling

Some fatal errors and recoverable fatal errors now throw an Error instead. As Error is a separate class from Exception, these exceptions will not be caught by existing try/catch blocks.

Not much code of ILIAS relies on try/catch, so this may be not a big issue.
Infos about "throwable"

2.4 removal of E_STRICT

2.4.1 Signature mismatch during inheritance: now E_WARNING

E.g. shibServerData::getInstance(array $data) vs. shibConfig::getInstance() (shibServerData extends shibConfig).

The effort to tackle this one is hard to estimate. We cannot simple "grep" for these issues. In easy cases we just need to "add" some optional parameters, but in other cases also the calling code may be needed to tackled, too.

2.4.2 Calling non-static methods statically: now E_DEPRECATED

myclass::nonStaticMethod() not allowed anymore.

This might not be a problem anymore because of fixes done for HHVM compatibility.

2.4.3 PHP4 constructors: now E_DEPRECATED

PHP4 constructors are now deprecated. Lots of these exist in the PEAR code, but also in native ILIAS code.

class Auth_Container_LDAP extends Auth_Container
{
/**
* Constructor of the container class
*/
function Auth_Container_LDAP($params)
{
....
}
}

It is currently planned to remove the support for PHP4-style constructors with PHP8 (no release plan yet).

2.5 Indirect Variables

Indirect variable, property and method references are now interpreted with left-to-right semantics.

// Some examples
$$foo['bar']['baz'] // interpreted as ($$foo)['bar']['baz']
$foo->$bar['baz'] // interpreted as ($foo->$bar)['baz']
$foo->$bar['baz']() // interpreted as ($foo->$bar)['baz']()
Foo::$bar['baz']() // interpreted as (Foo::$bar)['baz']()

// To restore the previous behavior add explicit curly braces:
${$foo['bar']['baz']}
$foo->{$bar['baz']}
$foo->{$bar['baz']}()
Foo::{$bar['baz']}()

We pray that these things do not exist in ILIAS code and the libs being used. None of us is currently aware of this kind of code.

2.6 foreach() array pointer

Iteration with foreach() no longer has any effect on the internal array pointer, which can be accessed through the current()/next()/etc family of functions.

These cases are hard to find, too. Additionally a "misplaced" array pointer will not cause fatals, but just "different results" than in the past.

2.7 iterating arrays by-value

When iterating arrays by-value, foreach will now always operate on a copy of the array, as such changes to the array during iteration will not influence iteration behavior.

//example
$array = [0, 1, 2];
$ref =& $array; // Necessary to trigger the old behavior
foreach ($array as $val) {
var_dump($val);
unset($array[1]);
}
// will now print all three elements (0 1 2), while previously the second element 1 was skipped (0 2).

No possible to grep for these easily. This should hopefully not lead to any problems.

3 3rd Party

3.1 PEAR MDB2

3.2 PEAR Auth / PEAR Log

Abandon SOAP Auth will be suggested.

3.3 PEAR HTMLTemplate

3.4 PEAR ExcelWriter / PEAR OLE

3.5 PEAR HTTP / PEAR Net

  • HTTP depends on Net
  • http://pear.php.net/package/HTTP
  • maintained, superseded by HTTP2 (last version Oct 2013)
  • Used by "Link Checker" and "BMF Payment"
  • 1.600 loc
  • Alternatives: Patch code (not much) or abandon lib and features

3.6 PEAR XML RPC2

3.6.1 PEAR Mail

?

3.7 PEAR, PEAR Console Getopt

3.8 MagPieRSS

3.9 SecurImage Captcha

3.10 HTMLPurifier

  • Services/Html/HtmlPurifier/library/HTMLPurifier
  • http://htmlpurifier.org/
  • Maintained, but currently (4 Sep 2015) PHP5 only
  • Will hopefully be ported to PHP7

3.11 Unsorted List of remaining PHP libs identified that are used by single components

Modules/Bibliographic/lib/LibRIS (last change: 2012)
Modules/Bibliographic/lib/PEAR_BibTex_1.0.0RC5 (unmaintained)
Modules/DataCollection/libs/ExcelReader (last change: 2009)
Modules/DataCollection/libs/SimpleExcel (last change: 2014)
Modules/Wiki/mediawiki (used to parse wiki links, actively maintained)
Services/CAS/lib, Services/CAS/phpcas/source/CAS (actively maintained)
Services/COPage/mediawikidiff (used to create page diff)
Services/COPage/syntax_highlight (syntax highlighter for code element, current source unknown [Beautifier?], alternative: GeSHi)
Services/Exceptions/lib/Whoops (actively maintained, passes Unittests in PHP7 already)
Services/Logging/lib/vendor/monolog (actively maintained)
Services/Logging/lib/vendor/psr/log/Psr/Log (actively maintained)
Services/Mail/phpmailer (HTML mails) (actively maintained)
Services/MediaObjects/getid3 (used to determine playtime of mp3 files, not "that" important)
Services/OpenId/lib/Auth/OpenID (last change: 2015)
Services/PDFGeneration/classes/tcpdf (actively maintained)
Services/SOAPAuth/include/nusoap.php, webservice/soap/lib/nusoap.php (PHP SOAP functions do not include WSDL writer, last change: 2011)
Services/WebDAV/classes/Tools (aka PEAR HTTP_WebDAV_Server, unmaintained)
Services/WebServices/Rest/lib/Slim (actively maintained)

4 Additional Information

  • Idea / concept:
  • Interest in funding: Crowdfunding, see http://www.ilias.de/docu/goto_docu_dcl_3700_747.html
  • Maintainer: all
  • Implementation of the feature is done by all maintainers
  • Testcases by: (please add your name if you want to create the testcases for this feature)

5 Discussion

, 20 Jul 2015: The bigger problem here are the 3rd party libraries used by ILIAS. The PEAR project seems dead or at least dormant and has been for years. So all the PEAR-based libraries will not work in PHP7 - this affects e.g. MDB2, Auth and probably the template engine, too. This could be a nightmare.

Erkens, Jochen [j.erkens], 2015-07-21: "Nightmare" was my first thougth as well, but unfortunately a necessary one. :-(

: @jerkens
preg_* is NOT deprecated (only ereg_*)...

Erkens, Jochen [j.erkens]  @jluetzen: You're right, I've removed the example.

, 22 Jul 2015: I tried to evaluate the work needed for the current trunk. It does not look good at all (using PHP7beta1, same PHP config as PHP5.x):

  • "=& new" is trivial to fix with a global replace to "= new"
  • I got a really weird bug in MDB2 regarding referenced variables/parameters which obviously did work in PHP 5.x. Scary stuff, because the debugging  takes ages.
  • There a tons of "declaration of ... should be compatible with ..." warnings, meaning that an extended class changed a method signature from the base class, e.g. ilObject::read() vs. ilObjUser::read(). I cannot find any information about this regarding PHP 7, but PHP 5.x seems way more forgiving. UPDATE PHP 7 removes the E_STRICT errors: as we never cared for either E_STRICT or E_DEPRECATED this for now is the real dealbreaker
    • Signature mismatch during inheritance: now E_WARNING
    • "Redefining" a constructor: see below
    • Calling non-static methods statically: now E_DEPRECATED
  • PHP4-style constructors are now deprecated (__construct() vs. class name). They will be unsupported in PHP 8 - and there is no way to do a quick fix (changing all affected classes manually instead).
    In PHP7 this seems ok for now.

JourFixe, ILIAS [jourfixe], August 03, 2015: Due to the vast use of deprecated PHP functions, ILIAS 5.1 won't run under PHP 7 (-> release notes). To get more information about the use of deprecated PHP code, the error report level should be increased at least in DEVMODE. We will discuss the necessary steps to make ILIAS PHP7 compliant at the next DevConf in Dortmund. 

Amstutz, Timon [amstutz], August 05, 2015: Since PEAR, especially MDB2 seems to generate several problems the compability to PHP7, this could be used as further point to argue for: Replace ilDB/MDB2 with PDO. Using PDO would solve does problems. Of course this can in no scenario be done for 5.1 but might be possible for 5.2. Since PHP7 runs a lot faster than previous version, this is definitely also a performance topic in which the SIG-Performance has a very strong interest in this mather. I asked therefore once again all service providers and maintainers to send me offers untill August 17. for the Feasibility Study to replace MDB2 with PDO.

Kiegel, Colin [kiegel], September 09 2015: I think it is quite important to show a simple but nice info-screen (in setup) if someone tries to use ILIAS 5.0 or 5.1 with PHP7. Otherwise it might lead to a very bad "first impression" and frustration among new ilias users trying to do a fresh install of ILIAS with PHP7 in 2016. This situation will become relevant soon and should not require much effort. A simple notice screen"please use PHP 5.x - 5.y to run ILIAS" will do.

Amstutz, Timon [amstutz], November 19. 2015: studer + raimann ag (Oskar Truffer) plublished their proposal on how to replace MDB2 with PDO: ilPDO

, 3 Dec 2015: PHP versions previous to 7.x will reach the end of their life-cycle in 2016/2017.
http://php.net/supported-versions.php

Amstutz, Timon [amstutz], 4 Dec 2015: I think it would be a good point to start to initiate the next step in the planing the migration to PHP7. As Jörg announced, versions pior to 7.x will reach end of live in 2017. ILIAS 5.2 will be released early 2017 and most major institutions will migrate to 5.2 somewhen in 2017. This means 5.2 has to be compatible with PHP 7.

Points needing discussion:

  • For the DB component the SIG-Performance financed a concept on how the replace the corresponding PEAR component: ilPDO. What about authentication and the template engine? I think this could be a good point to look for a good replacement for them as well, since we need to tackle them anyways.
  • At which point will have concrete price tag for the various todos? The SIG-Performance is happy to help looking for financing but we would need some numbers to make an estimation about the cost. What is needed to get those numbers? Is there another concept phase necessary? If yes, who will do/initiate it?

Killing, Alexander [alex], 4 Dec 2015: I put this on the agenda of the next JF. I think this topic needs priority at the beginning of next year. I agree that we need to identify all tasks first and make a prioritization. I also think there might be some conceptual work being needed for some topics (like feasibility studies for different options).

JourFixe, ILIAS [jourfixe], Dec 07, 2015: We decided that ILIAS 5.2 has to support PHP7. We will organise a developer workshop in January to discuss the next steps and the work packages to make ILIAS PHP7-compliant. Fabian Schmid will set up poll to find the best date for a workshop and notify all maintainers. We have to modify our test server configuration to support different PHP versions (and also HHVM).

Kunkel, Matthias [mkunkel], Feb 17, 2015: We started fundraising for this huge step. Every one is invitied to contribute to the funding of the feature. Please contact me (kunkel@ilias.de) for further information. The Advisory Council of the ILIAS open source e-Learning e.V. has decided to give the annual budget plus the open budget of 2013 for creating compatibility with PHP 7.

, 01 Mar 2016: To clarify: "abstract static methods" are allowed (because of late static binding) - see Reclassify E_STRICT

Abstract static methods
[...]
Proposed resolution: Remove notice.
Reason: We currently allow the use of abstract static functions in interfaces, as such it is inconsistent to not allow them as abstract methods. By using late static binding a method in the abstract class can reasonably depend on the existence of a static method in a superclass. (As far as any usage of LSB can be considered reasonable).

, 01 Mar 2016: Surprise - the signature mismatch error does not apply to constructors:

Unlike with other methods, PHP will not generate an E_STRICT level error message when __construct() is overridden with different parameters than the parent __construct() method has.

For signature matching constructors one should use interfaces:

Added support for constructors in interfaces to force constructor signature checks in implementations. Starting with PHP 5.2.0, interfaces can have constructors. However, if you choose to declare a constructor in an interface, each class implementing that interface MUST include a constructor with a signature matching that of the base interface constructor. By 'signature' we mean the parameter and return type definitions, including any type hints and including whether the data is passed by reference or by value.

see Why does PHP allow “incompatible” constructors?

, 01 Mar 2016: Signature mismatch further findings:

  • type hinting has to be exact, class hierarchies are not supported
  • the default value for optional parameters may differ
  • it is allowed to add parameters in sub-classes, only if sub-classes have less parameters than their parent(s) an error is thrown
    • the added parameters have to be optional
ILIAS currently throws a lot of
  • Only variables should be assigned by reference
  • Only variables should be passed by reference
  • Non-static method [...] should not be called statically
We are currently ignoring these as minor issues (PHP5: E_STRICT, PHP7: E_NOTICE). They might be fixed after the major problems are solved.

, 07 Mar 2016:  uncomment the following line (in php.ini) for opcache-level error logging
; OPcache error_log file name. Empty string assumes "stderr".
opcache.error_log=

, 09 Mar 2016: we decided to mark php7-relevant patches with the following syntax

  • php7-workaround: patches that make php7-migration easier, must be removed on release
  • php7-todo: code that has to be checked before release
  • correct-with-php5-removal: code that is only needed as long as PHP 5.x is still supported
Patches should have a start and end marker, a description is mandatory, as is an author signature.

Example:
// correct-with-php5-removal JL start
switch($level)
{
    // < PHP7 only
    case E_STRICT:
        // both E_NOTICE in PHP7
        if(stristr($message, "Only variables should be passed by reference") ||
            stristr($message, "Only variables should be assigned by reference")) {
            return true;
        }
        break;                                    
}
// correct-with-php5-removal end

Concerning error handling:
  • ILIAS now sets the error-level to E_ALL & ~E_NOTICE (regardless of the PHP version)
    • in DEVMODE one can activate SHOWNOTICES - don't try this at home!
  • with PHP5 the E_STRICT errors which are E_NOTICE in PHP7 are completely ignored
  • E_DEPRECATED must be fixed
    • this includes "Non-static method [...] should not be called statically" which is notE_NOTICE in PHP7 (I got confused above)
    • if DEVMODE is active E_DEPRECATED will crash and burn, without DEVMODE only a log entry is written

Killing, Alexander [alex], 10.3.2016: I spend a lot of work on the "Calling non-static methods statically: now E_DEPRECATED" issue yesterday. This is definitely not fixed by the HHVM support in 5.1, as we hoped. I got tons of these and I am not sure if we find these cases somehow automatically. Many cases can be found by simple regexp when the methods start with an underscore "_", which was a guideline in the past for static methods. Fortunately the signature mismatch issue needs less effort than originally thought, because some additional time will be needed to take care of the static calls.

, 31 Mar 2016: PEAR ExcelWriter (incl. OLE) has been removed. All components were migrated to PHPExcel.

Killing, Alexander [alex], 13 Apr 2016: We discussed this earlier but we still need a final decision of the JF, if we Abandon SOAP Auth.

Kunkel, Matthias [mkunkel], April 18, 2016: Crowdfunding completed! We have the entire funding to make ILIAS PHP7 compliant!

Killing, Alexander [alex], 2 May 2016: Our current status with topics 2.1 to 2.4: We have tackled these issues in roughly 30% of our code directories (please note that 30% of the directories does not necessarily match 30% of our code).

Killing, Alexander [alex], 17 May 2016: I have just removed all PEAR dependencies in the HTML Template IT library. The code is still in the PEAR service. I replaced lots of PEAR IT_Error usages by ILIAS exceptions. This results in a slightly stricter handling of errors in the template engine. In the past some things have been accepted that, in my experience, often resulted in bugs that have been hard to tackle. E.g. adding blocks with block names that already existed. I would prefer to get exceptions for these kind of things. I clicked through the system after my changes and did not experience many additional issues. Please make a quick check. If you do not agree with this move, please let me know what kind of exceptions you would like not to be thrown.

Schmid, Fabian [fschmid] The Database Abstraction Layer based on MDB2 has been "replaced" with PDO. The new implementation is called ilDBPdo und supports MyISAM, InnoDB and PostgreSQL. Currenttly the old implementation is still available and active when chosen "mysql" or "innodb" in the client. All used PEAR-classes are moved to (/Services/Database/lib). Additionally there are ~130 UnitTests which can be used to test witth a MySQL or PostgreSQl Database. Most of the Manager-Functionality is tested.
The following Modules are mostly ready for PHP7:

  • Datacollection
  • OrgUnits
  • Bibliographic
  • Cloud
Current state of directoriescan be updatet here: http://www.ilias.de/docu/goto_docu_dcl_5192.html

Killing, Alexander [alex], 30 May 2016: I tried to replace the syntax highlighter in ILIAS by using GeShi, unfortuntately I run into problems:

  • GeShi does not support auto-indentation in version 1.0, this is planned for 1.1 but 1.1 development it in alpha and we cannot expect any beta or stable release this year.
  • Extracting the auto-indentation from our old syntax highlighter is close to impossible, since the code is very messy (one huge function) and coupled with all the other highlighting code.
  • I see the following alternatives
    • Use GeShi and abandon auto-indentation (I have no idea how much users rely on this but this would certainly make some existing code snippets look bad).
    • Keep our old syntax highlighter and make it PHP7 compatible (I did this in the trunk).
    • Try to hack auto-indentation into GeShi (I think this would come with some major additional effort/costs).
    • Look for alternatives. I already did a quick search and did not find anything server side that would fit our needs. There are client side Javascript solutions, however I would prefer to have this server side (no time lack in user experience, easier handling in HTML exports, smaller export packages, possible PDF export). Popular JS client side solution would be highlight.js or prism.js (no auto-indentation). But we would run into the same issues when we want to create PDFs as we do with MathJax.

Killing, Alexander [alex], 30 May 2016: Our current status with topics 2.1 to 2.4: We have tackled these issues in roughly 80% of our code directories (please note that 80% of the directories does not necessarily match 80% of our code).

JourFixe, ILIAS [jourfixe], June 06, 2016: We decided to use GeShi instead of the old syntax highlighting _and_ to abandon auto-indentation with 5.2. If anyone objects, please notify Killing, Alexander [alex] until June 20.

Killing, Alexander [alex] 14 Aug 2016: I created an Abandon Auto-Indentation in Source Code Elements page.

6 Implementation

PHP7 compatibility has been implemented for the entire code of ILIAS 5.2.

Test Cases

PHP7-Compatibility will be tested by any TestCase since the installation used for testers is based on PHP7.

Approval

PHP7 Support for ILIAS 5.2 has been approved by the developers during the implementation of all new features in trunk.

Last edited: 16. Sep 2016, 09:05, Kunkel, Matthias [mkunkel]