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.

    1. Create a dedicated launcher directory with a copied php binary for PHP 7.4.
    2. Skip Totara’s Composer bootstrap if necessary and install PHPUnit dependencies manually with a Composer version that still supports the locked package set.
    3. 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 supports legacy Moodle and Totara estates, including test tooling, upgrade prep, and version-specific debugging. Need help? Contact us.

    Contact us