@@ -976,15 +976,38 @@ public static function polyfillTokenizerConstants(): void
976976 // numbering scheme from 135_000.
977977 $ nextTokenNumber = 135000 ;
978978
979+ // This variable is necessary to avoid collisions with any other
980+ // libraries which also polyfill T_* constants.
981+ // array_flip()/isset() because in_array() is slow.
982+ $ existingConstants = array_flip (get_defined_constants (true )['tokenizer ' ]);
983+ foreach ((get_defined_constants (true )['user ' ] ?? []) as $ k => $ v ) {
984+ if (isset ($ k [2 ]) === false || $ k [0 ] !== 'T ' || $ k [1 ] !== '_ ' ) {
985+ // We only care about T_* constants.
986+ continue ;
987+ }
988+
989+ if (isset ($ existingConstants [$ v ]) === true ) {
990+ throw new \Exception ("Externally polyfilled tokenizer constant value collision detected! $ k has the same value as {$ existingConstants [$ v ]}" );
991+ }
992+
993+ $ existingConstants [$ v ] = $ k ;
994+ }
995+
979996 $ polyfillMappingTable = [];
980997
981998 foreach ($ tokensToPolyfill as $ tokenName ) {
999+ if (isset (get_defined_constants (true )['tokenizer ' ][$ tokenName ]) === true ) {
1000+ // This is a PHP native token, which is already defined by PHP.
1001+ continue ;
1002+ }
1003+
9821004 if (defined ($ tokenName ) === false ) {
983- while (isset ($ polyfillMappingTable [$ nextTokenNumber ]) === true ) {
1005+ while (isset ($ existingConstants [$ nextTokenNumber ]) === true ) {
9841006 $ nextTokenNumber ++;
9851007 }
9861008
9871009 define ($ tokenName , $ nextTokenNumber );
1010+ $ existingConstants [$ nextTokenNumber ] = $ tokenName ;
9881011 }
9891012
9901013 $ polyfillMappingTable [constant ($ tokenName )] = $ tokenName ;
0 commit comments