@@ -972,15 +972,38 @@ public static function polyfillTokenizerConstants(): void
972972 // numbering scheme from 135_000.
973973 $ nextTokenNumber = 135000 ;
974974
975+ // This variable is necessary to avoid collisions with any other
976+ // libraries which also polyfill T_* constants.
977+ // array_flip()/isset() because in_array() is slow.
978+ $ existingConstants = array_flip (get_defined_constants (true )['tokenizer ' ]);
979+ foreach ((get_defined_constants (true )['user ' ] ?? []) as $ k => $ v ) {
980+ if (isset ($ k [2 ]) === false || $ k [0 ] !== 'T ' || $ k [1 ] !== '_ ' ) {
981+ // We only care about T_* constants.
982+ continue ;
983+ }
984+
985+ if (isset ($ existingConstants [$ v ]) === true ) {
986+ throw new \Exception ("Externally polyfilled tokenizer constant value collision detected! $ k has the same value as {$ existingConstants [$ v ]}" );
987+ }
988+
989+ $ existingConstants [$ v ] = $ k ;
990+ }
991+
975992 $ polyfillMappingTable = [];
976993
977994 foreach ($ tokensToPolyfill as $ tokenName ) {
995+ if (isset (get_defined_constants (true )['tokenizer ' ][$ tokenName ]) === true ) {
996+ // This is a PHP native token, which is already defined by PHP.
997+ continue ;
998+ }
999+
9781000 if (defined ($ tokenName ) === false ) {
979- while (isset ($ polyfillMappingTable [$ nextTokenNumber ]) === true ) {
1001+ while (isset ($ existingConstants [$ nextTokenNumber ]) === true ) {
9801002 $ nextTokenNumber ++;
9811003 }
9821004
9831005 define ($ tokenName , $ nextTokenNumber );
1006+ $ existingConstants [$ nextTokenNumber ] = $ tokenName ;
9841007 }
9851008
9861009 $ polyfillMappingTable [constant ($ tokenName )] = $ tokenName ;
0 commit comments