Skip to content

PHP Warning: Constant already defined when processing multiple sources with __halt_compiler() #18850

Closed

Description

@ProgerXP

Description

Whenever PHP processes more then one __halt_compiler() statement in one session, it emits this cryptic warning:

PHP Warning:  Constant  already defined in ...

Note the empty constant name.

There are several ways to trigger this. Here's one:

# echo '<?php __halt_compiler();' >inc.php
# php -a
php > include('inc.php');
php > include('inc.php');
PHP Warning:  Constant  already defined in /tmp/inc.php on line 1

Here's another:

# php -r "eval('?><?php __halt_compiler();'); eval('?><?php __halt_compiler();');"

PHP Version

PHP 8.4.5 (cli) (built: Mar 12 2025 16:58:15) (NTS)
Copyright (c) The PHP Group
Zend Engine v4.4.5, Copyright (c) Zend Technologies

Operating System

No response

Activity

  1. Sannis commented on Jun 23, 2025

    @Sannis
    Contributor

    Confirm this with 8.0.30:

    php -v
    PHP 8.0.30-master-850_prod-centos (cli) (built: Nov  2 2023 08:51:55) ( NTS )
    Copyright (c) The PHP Group
    Zend Engine v4.0.30-dev, Copyright (c) Zend Technologies
    
    php -r "eval('?><?php __halt_compiler();'); eval('?><?php __halt_compiler();');"
    
    Warning: Constant  already defined in Command line code(1) : eval()'d code on line 1
    
  2. iluuu1994 commented on Jun 23, 2025

    @iluuu1994
    Member

    Thanks for the report.

    This is because __halt_compiler() also declares the __COMPILER_HALT_OFFSET__ constant:
    https://www.php.net/manual/en/function.halt-compiler.php

    This design is really just dubious, so I'm not sure this can be fixed without replacing the constant with a function, like compiler_halt_get_last_offset(). So, I'm tending towards closing this as a #wontfix.

  3. ProgerXP commented on Jun 23, 2025

    @ProgerXP
    Author

    Why not just avoid declaring __COMPILER_HALT_OFFSET__ if it's already declared? Any approach is better then the current obscure warning.

  4. iluuu1994 commented on Jun 23, 2025

    @iluuu1994
    Member

    Any approach is better then the current obscure warning.

    Not necessarily. If you expect __COMPILER_HALT_OFFSET__ to be something else, then no warning is not better.

  5. bwoebi commented on Jun 23, 2025

    @bwoebi
    Member

    I'd honestly expect __COMPILER_HALT_OFFSET__ to work like __FILE__ - i.e. you'd get the offset of the current file. (Which you might then assign to a variable or something.)

  6. iluuu1994 commented on Jun 23, 2025

    @iluuu1994
    Member

    Might be sensible. However, any such change here is breaking. As such, this will at least require some discussion.

  7. ProgerXP commented on Jun 23, 2025

    @ProgerXP
    Author

    I'd honestly expect __COMPILER_HALT_OFFSET__ to work like __FILE__ - i.e. you'd get the offset of the current file.

    Doesn't it already work like that?

    # echo '<?php __halt_compiler();' >inc.php
    # php -a
    php > include('inc.php');
    php > include('inc.php');
    PHP Warning:  Constant  already defined in /tmp/inc.php on line 1
    php > echo __COMPILER_HALT_OFFSET__;
    PHP Warning:  Uncaught Error: Undefined constant "__COMPILER_HALT_OFFSET__"
    
  8. iluuu1994 commented on Jun 23, 2025

    @iluuu1994
    Member

    Actually, yes, you are right. __COMPILER_HALT_OFFSET__ is mangled with the current file name. So, suppressing the warning might be feasible after all, given that __halt_compiler(); will always occur in the same place for a given file.

  9. added 2 commits that reference this issue on Aug 13, 2025
    bdf5202
    a3de2ce
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions