Legacy Totara and Moodle checkouts requiring PHP 7.4 run into problems when the host's default PHP is newer. This guide shows how to create a dedicated PHP launcher directory and bypass Totara's PATH reset behavior so PHPUnit uses the correct interpreter.

Running the correct version of PHP and PHPUnit for a specific Moodle release is a prerequisite for reliable plugin tests. This guide covers setting up a parallel PHP 7.4 environment alongside a newer system PHP, and configuring PHPUnit to use it — working around the PATH reset issue in Totara's PHPUnit bootstrap.

Use this when a legacy Totara/Moodle checkout needs PHPUnit under PHP 7.4, but the host default php binary is a newer version and Totara's PHPUnit bootstrap keeps resolving nested php calls to the wrong interpreter.

Scope

This applies when all of the following are true:

  • the application requires PHP 7.4 for test tooling
  • `/usr/bin/php` points to a newer version
  • Totara's `test/phpunit/phpunit.php` bootstrap is used
  • Composer dependency install is blocked by a newer Composer or audit defaults

Why the normal PATH trick fails

Totara's PHPUnit wrapper resets PATH using dirname(PHP_BINARY). If you start it with /usr/bin/php7.4, it prepends /usr/bin again, and nested php calls still resolve to /usr/bin/php instead of PHP 7.4.

  • Create a dedicated launcher directory with a copied `php` binary for PHP 7.4.
  • Skip Totara's Composer bootstrap if necessary and install PHPUnit dependencies manually with a Composer version that still supports the locked package set.
  • Use Totara's lower-level `server/admin/tool/phpunit/cli/util.php` entrypoint directly, not `test/phpunit/phpunit.php init`, if the wrapper still leaks to the system PHP.

Example

Assumptions:

  • PHP 7.4 binary: `/usr/bin/php7.4`
  • project root: `/path/to/project/totara`

Create the launcher:

mkdir -p /tmp/php74bin
cp /usr/bin/php7.4 /tmp/php74bin/php
/tmp/php74bin/php -r 'echo PHP_BINARY, PHP_EOL;'

Expected output:

/tmp/php74bin/php

If the Totara checkout expects totara/config.php, provide the instance bridge temporarily:

ln -sf /path/to/instance/config.php /path/to/project/totara/config.php

Prepare Composer manually when Totara's init step cannot:

cd /path/to/project/totara
curl -L https://getcomposer.org/download/2.6.6/composer.phar -o composer.phar
/tmp/php74bin/php composer.phar --version
/tmp/php74bin/php composer.phar -d test/phpunit update phpunit/phpunit brianium/paratest -W

Provide a PHPUnit config if the instance config does not define phpunit_* settings:

cat > /tmp/project-phpunit-config.php <<'PHP'
<?php
$CFG = new stdClass();
$CFG->dataroot = '/tmp/project_phpunit_data';
$CFG->dbtype = 'pgsql';
$CFG->dblibrary = 'native';
$CFG->dbhost = 'localhost';
$CFG->dbname = 'project_db';
$CFG->dbuser = 'dbuser';
$CFG->dbpass = 'dbpass';
$CFG->prefix = 'phpu_';
$CFG->dboptions = [
    'dbpersist' => false,
    'dbsocket' => false,
    'dbport' => '',
];
PHP
ln -sf /tmp/project-phpunit-config.php /path/to/project/totara/test/phpunit/config.php

Initialize the isolated PHPUnit site directly:

cd /path/to/project/totara
/tmp/php74bin/php -d max_input_vars=5000 server/admin/tool/phpunit/cli/util.php --install
/tmp/php74bin/php -d max_input_vars=5000 server/admin/tool/phpunit/cli/util.php --buildconfig

Run a targeted test:

cd /path/to/project/totara
/tmp/php74bin/php -d max_input_vars=5000 server/admin/tool/phpunit/cli/util.php --run --filter local_multitenant_delete_capability_testcase server/local/multitenant/tests/delete_capability_test.php

Cleanup:

rm -f /path/to/project/totara/config.php
rm -f /path/to/project/totara/test/phpunit/config.php

Notes

  • Prefer a project-local `composer.phar` instead of changing the system Composer.
  • If Composer still blocks old locked packages, either use an older Composer release or repair the PHPUnit lockfile under PHP 7.4.
  • Do not use a shell wrapper script for `php`; in this environment `PHP_BINARY` still resolved to the original binary path. A copied PHP 7.4 binary worked.
  • The `test/phpunit/phpunit.php init` wrapper may still leak to the host default `php`. If that happens, use `server/admin/tool/phpunit/cli/util.php` directly.

Solin specializes in Moodle development tooling and test infrastructure.

Contact us