Skip to content

Trampoline autoloader will get reregistered and cannot be unregistered #10011

Closed
@Girgias

Description

@Girgias

Description

Found while working on #8294, currently it is possible to register a trampoline as an autoloader but there is no way to remove it nor is it prevented from being registered multiple times.

The following code: https://3v4l.org/0mYUn

<?php

class TrampolineTest {
    public function __call(string $name, array $arguments) {
        echo 'Trampoline for ', $name, PHP_EOL;
    }
}
$o = new TrampolineTest();
$callback1 = [$o, 'trampoline1'];
$callback2 = [$o, 'trampoline2'];

spl_autoload_register($callback1);
spl_autoload_register($callback2);
spl_autoload_register($callback1); // 2nd call ignored

var_dump(spl_autoload_functions());

var_dump(class_exists("TestClass", true));

echo "Unregister trampoline:\n";
var_dump(spl_autoload_unregister($callback1));
var_dump(spl_autoload_unregister($callback1));
var_dump(spl_autoload_unregister($callback2));

var_dump(spl_autoload_functions());
var_dump(class_exists("TestClass", true));

Resulted in this output:

array(3) {
  [0]=>
  array(2) {
    [0]=>
    object(TrampolineTest)#1 (0) {
    }
    [1]=>
    string(11) "trampoline1"
  }
  [1]=>
  array(2) {
    [0]=>
    object(TrampolineTest)#1 (0) {
    }
    [1]=>
    string(11) "trampoline2"
  }
  [2]=>
  array(2) {
    [0]=>
    object(TrampolineTest)#1 (0) {
    }
    [1]=>
    string(11) "trampoline1"
  }
}
Trampoline for trampoline1
Trampoline for trampoline2
Trampoline for trampoline1
bool(false)
Unregister trampoline:
bool(false)
bool(false)
bool(false)
array(3) {
  [0]=>
  array(2) {
    [0]=>
    object(TrampolineTest)#1 (0) {
    }
    [1]=>
    string(11) "trampoline1"
  }
  [1]=>
  array(2) {
    [0]=>
    object(TrampolineTest)#1 (0) {
    }
    [1]=>
    string(11) "trampoline2"
  }
  [2]=>
  array(2) {
    [0]=>
    object(TrampolineTest)#1 (0) {
    }
    [1]=>
    string(11) "trampoline1"
  }
}
Trampoline for trampoline1
Trampoline for trampoline2
Trampoline for trampoline1
bool(false)

But I expected this output instead:

array(2) {
  [0]=>
  array(2) {
    [0]=>
    object(TrampolineTest)#1 (0) {
    }
    [1]=>
    string(11) "trampoline1"
  }
  [1]=>
  array(2) {
    [0]=>
    object(TrampolineTest)#1 (0) {
    }
    [1]=>
    string(11) "trampoline2"
  }
}
Trampoline for trampoline1
Trampoline for trampoline2
bool(false)
Unregister trampoline:
bool(true)
bool(false)
bool(true)
bool(false)

PHP Version

All

Operating System

No response

Metadata

Metadata

Assignees

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions