# PHP header files, restrict to declaring code only

- Thread: https://externals.io/message/105660
- Original archive: https://news-web.php.net/php.internals/105660
- Started by Lynn on 2019-05-10T12:29:23+00:00
- Messages: 10
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #105660 — Lynn — 2019-05-10T12:29:23+00:00

URL: https://externals.io/message/105660#105660

Hello everyone!

This is my first mail to the internals, my apologies if I made a mistake
somewhere.

I would like to propose a new type of php "file" called "phph", short for
"php-header".
This file could receive an optional open-tag: `<?phph` or perhaps a
`declare(header=1)`,
not sure what's more feasible, or if there are better solutions. This open
tag could be
optional for forward compatibility towards omitting the tag.

Php-header files would be allowed to only contain declaring code. This
means that any code
that would run "while loading", would not be allowed and cause a syntax
error in the same
fashion as trying to add a function call in the middle of a class
declaration.

```php
<?php
// forward compatible? change default in a major version?
// any other ideas?
declare(header=1);

// syntax errors:
echo 'foo';
$a = 'b';

// valid
class Foo {}
interface Bar {}
function baz() {}
// etc
```

By restricting it to declaration only, it would make it possible to add
extra features to
classes, such as annotations as there are a lot less edge cases to think
about:

```php
<?php
@trigger_error('Foo is deprecated as of 2.0, use Bar instead',
E_USER_DEPRECATED);
class Foo {}
```

New scenario could be:
```php
<?php
declare(header=1);

use Php\Debugging\Annotations\Deprecated;

@Deprecated('Foo is deprecated as of 2.0, use Bar instead');
class Foo {}
```

This is a pretty rough sketch, and I'm not exactly sure if this is doable.
I'm really eager
to have native support for annotations and perhaps this idea could inspire
someone with a
solution to make this feasible.

Regards,
Lynn van der Berg

---

## #105661 — Nikita Popov — 2019-05-10T12:37:04+00:00

URL: https://externals.io/message/105660#105661

> Hello everyone!
>
> This is my first mail to the internals, my apologies if I made a mistake
> somewhere.
>
> I would like to propose a new type of php "file" called "phph", short for
> "php-header".
> This file could receive an optional open-tag: `<?phph` or perhaps a
> `declare(header=1)`,
> not sure what's more feasible, or if there are better solutions. This open
> tag could be
> optional for forward compatibility towards omitting the tag.
>
> Php-header files would be allowed to only contain declaring code. This
> means that any code
> that would run "while loading", would not be allowed and cause a syntax
> error in the same
> fashion as trying to add a function call in the middle of a class
> declaration.
>
> ```php
> <?php
> // forward compatible? change default in a major version?
> // any other ideas?
> declare(header=1);
>
> // syntax errors:
> echo 'foo';
> $a = 'b';
>
> // valid
> class Foo {}
> interface Bar {}
> function baz() {}
> // etc
> ```
>
> By restricting it to declaration only, it would make it possible to add
> extra features to
> classes, such as annotations as there are a lot less edge cases to think
> about:
>
> ```php
> <?php
> @trigger_error('Foo is deprecated as of 2.0, use Bar instead',
> E_USER_DEPRECATED);
> class Foo {}
> ```
>
> New scenario could be:
> ```php
> <?php
> declare(header=1);
>
> use Php\Debugging\Annotations\Deprecated;
>
> @Deprecated('Foo is deprecated as of 2.0, use Bar instead');
> class Foo {}
> ```
>
> This is a pretty rough sketch, and I'm not exactly sure if this is doable.
> I'm really eager
> to have native support for annotations and perhaps this idea could inspire
> someone with a
> solution to make this feasible.
>
> Regards,
> Lynn van der Berg
>

Hi Lynn,

I'm not sure I understood what the benefit of introducing a header file
concept will be. Could you elaborate more on how this will help annotations
(or other functionality)?

Nikita

---

## #105662 — Lynn — 2019-05-10T13:14:55+00:00

URL: https://externals.io/message/105660#105662

Hi Nikita,

By limiting a header file to declaring code only, a couple of issues could
be tackled:

1. No side effects when loading files. You can assume the global state
remains the same, no
   code is executed by this file, and no output can be sent.
2. Certain features, can be restricted to php-header files only, meaning it
does not affect
   "normal" PHP files. This might open up a whole new range of syntax
possibilities that
   are currently blocked, such as `@trigger_error()` vs `@Annotation()`.

I can understand if those reasons are not enough to merit a whole new
concept as a header
file as it might introduce more complexity than it's worth.

Regards,
Lynn van der Berg




> 
>
> > […]
>
> Hi Lynn,
>
> I'm not sure I understood what the benefit of introducing a header file
> concept will be. Could you elaborate more on how this will help annotations
> (or other functionality)?
>
> Nikita

---

## #105663 — Dustin Wheeler — 2019-05-10T13:40:44+00:00

URL: https://externals.io/message/105660#105663

>
> 2. Certain features, can be restricted to php-header files only, meaning it
> does not affect
>    "normal" PHP files. This might open up a whole new range of syntax
> possibilities that
>    are currently blocked, such as `@trigger_error()` vs `@Annotation()`.
>

Hi Lynn, thank you for opening this discussion!

Could you explain how the range of syntax you suggest (regarding
annotations) is currently blocked? I'm not challenging your claim; I
*personally* don't know and am interested. While certainly not
supported natively, comment-based "annotations" can be implemented in
user-land and processed via reflection (See doctrine-annotations[1]).
There has also been previous work and discussion in the annotation
space [2][3][4][5]. Based on my light reading, I couldn't find any
objections to annotations with side-effects, but I could see that as
an argument. However, I'm more curious what your perspective is.

Personally, I really like the idea of being able to declare
"side-effect free" as a feature. I don't know if I prefer the idea of
a `phph` file, distinguished by extension (so I'm glad you mention
alternatives such as `declare`). That said, I think that's mostly from
shock and not wanting to ever go back to a world that included *.php4,
*.php5, *.phtml, etc. :)

Hope all is well,

1: https://www.doctrine-project.org/projects/doctrine-annotations/en/latest/index.html
2: https://wiki.php.net/rfc/annotations
3: https://externals.io/message/82813
4: https://externals.io/message/64895
5: https://externals.io/message/64722

-- 
Dustin Wheeler | Software Developer
NC State University
mdwheele@ncsu.edu
"If you don't know where you're going, it's easy to iteratively not get there."

---

## #105664 — Lynn — 2019-05-10T14:12:31+00:00

URL: https://externals.io/message/105660#105664

> 
> > […]
> it
> > […]
>
> Hi Lynn, thank you for opening this discussion!
>
> Could you explain how the range of syntax you suggest (regarding
> annotations) is currently blocked? I'm not challenging your claim; I
> *personally* don't know and am interested. While certainly not
> supported natively, comment-based "annotations" can be implemented in
> user-land and processed via reflection (See doctrine-annotations[1]).
> There has also been previous work and discussion in the annotation
> space [2][3][4][5]. Based on my light reading, I couldn't find any
> objections to annotations with side-effects, but I could see that as
> an argument. However, I'm more curious what your perspective is.
>

Hi Dustin,

Currently with Doctrine Annotations, inspired by that of Java as far as I
know, the syntax
would be ambiguous, at least until the closing semi-colon. I'm no expert on
which syntax is or
isn't possible, I remember this one being a potential issue and introducing
complexity in the
parser due to the silencing operator.

```php
@SomeAnnotation()
class {}
// versus
@SomeFunctionBeingSilenced();
class {}
```
You are correct that annotations are possible via user-land packages. I'm
personally hoping to
see this feature come to native PHP, making it possible to simplify the
usage and possibly
performance. I've been brainstorming around another feature to unify
variable inspections,
which would make annotation reading a whole lot simpler [1], but could also
be done in
Reflection. Annotations are my primary example for header files, as they
share the same
concept, they are declaring code only and they don't have side effects.


> Personally, I really like the idea of being able to declare
> "side-effect free" as a feature. I don't know if I prefer the idea of
> a `phph` file, distinguished by extension (so I'm glad you mention
> alternatives such as `declare`). That said, I think that's mostly from
> shock and not wanting to ever go back to a world that included *.php4,
> *.php5, *.phtml, etc. :)
>

I'm not sure if a `.phph` file extension is required for this feature to
work, though it might
simplify its implementation. While I certainly share your concern about
multiple extensions, my
experience with other languages makes me believe that this would not be
much of an issue. With
header files being an opt-in feature, it hopefully won't make php more
complex for developers
new to PHP.


> Hope all is well,
>
> 1:
> https://www.doctrine-project.org/projects/doctrine-annotations/en/latest/index.html
> 2: https://wiki.php.net/rfc/annotations
> 3: https://externals.io/message/82813
> 4: https://externals.io/message/64895
> 5: https://externals.io/message/64722
>
> --
> Dustin Wheeler | Software Developer
> NC State University
> mdwheele@ncsu.edu
> "If you don't know where you're going, it's easy to iteratively not get
> there."
>
> --
> 
> 
>

Apologies for my previous message being top posted, I hope this message
arrives in a better format!

Regards,
Lynn van der Berg

1:
https://gist.github.com/linaori/af50c1692e3d360d2e550b05e6121e58#future-possibilities

---

## #105668 — Niklas Keller — 2019-05-10T21:09:03+00:00

URL: https://externals.io/message/105660#105668

Instead of introducing a declare option or special open tag, how about
another "include" construct, that only allows side-effect free (apart
from class loading) operations?

e.g. "require_noexec 'foobar.php'"

Regards, Niklas

---

## #105684 — Lynn — 2019-05-13T09:59:49+00:00

URL: https://externals.io/message/105660#105684

> Instead of introducing a declare option or special open tag, how about
> another "include" construct, that only allows side-effect free (apart
> from class loading) operations?
>
> e.g. "require_noexec 'foobar.php'"
>
> Regards, Niklas
>

Hi Niklas,

That's indeed a very interesting alternative! I've given it some thought in
regards in
the context of no side-effects and I really like the idea as it sounds
easier to implement.

With an alternative as such, I see one major roadblock, perhaps it can be
solved?

These days I personally hardly ever write require/include statements,
composer does
this for me with autoloading. For composer it would probably mean an "all
or nothing" when
it comes to picking the keyword to "require" or "require without
side-effects". This makes it hard,
if not impossible, to trigger deprecations from deprecated interfaces,
unless you use something
too hook into autoloading and check if there were `@deprecated` annotations
on the class,
interface, etc. This means that a feature that worked by default, would be
broken and risk
potential issues when upgrading.

Following this strategy, it would put the responsibility of loading the
files at the developer that
consumes the (public) API, rather than the developer that (public) API. I
believe the public API
should define whether or not it can, or must be, be loaded without side
effects without any worries
for the developer consuming that public API. This is why I initially tried
to come up with a
strategy that allows you to define it in the file (one way or another).

Note that my example with composer is tailored around my specific use-case
and that a new
function, keyword or statement might be more suitable for developers that
explicitly load their
code without autoloading.

Regards,
Lynn van der Berg

---

## #105685 — johannes@schlueters.de — 2019-05-13T12:48:57+00:00

URL: https://externals.io/message/105660#105685

> Hi Nikita,
> 
> By limiting a header file to declaring code only, a couple of issues
> could
> be tackled:
> 
> 1. No side effects when loading files. You can assume the global
> state
> remains the same, no
>    code is executed by this file, and no output can be sent.

Mind that this won't be side-effect free. Declaring a class/function is
a side-effect in itself.

For dealing with syntax differences we could use the declare()
statement, as used for strict_types or encoding.

A question is whether it is worthwhile to have multiple syntaxes in
parallel. This adds burden for developers using PHP, (i.e. copying code
from tutorials or other files might fail sometimes etc.) tools
processing PHP (IDEs, code analyzers, ...) and language developers (new
syntax changes have to be evaluated for both contexts)

If this were a strategy to transition to a new syntax (deprecating "old
PHP") such a mechanism would be the way to go. For just having
alternatives to avoid a syntax conflict cost imo is too big.

johannes

---

## #105706 — Larry Garfield — 2019-05-14T18:48:11+00:00

URL: https://externals.io/message/105660#105706

> 
> > […]
> 
> Mind that this won't be side-effect free. Declaring a class/function is
> a side-effect in itself.
> 
> For dealing with syntax differences we could use the declare()
> statement, as used for strict_types or encoding.
> 
> A question is whether it is worthwhile to have multiple syntaxes in
> parallel. This adds burden for developers using PHP, (i.e. copying code
> from tutorials or other files might fail sometimes etc.) tools
> processing PHP (IDEs, code analyzers, ...) and language developers (new
> syntax changes have to be evaluated for both contexts)
> 
> If this were a strategy to transition to a new syntax (deprecating "old
> PHP") such a mechanism would be the way to go. For just having
> alternatives to avoid a syntax conflict cost imo is too big.
> 
> johannes

Another possible place such a marker could be useful is in the new preloading functionality in 5.4.  Any file that is preloaded is going to never execute again, ever.  That means preloading a file that has both symbol declarations and executing global code could lead to weird results.  I could see a preloader that would only try to preload symbol-only files.

That said... most polyfill files, of which there are a decent number, do some variation on:

<?php

if (!function_exists('coolness')) {
  function coolness(int $coolLevel) { ... }
}
?>

Which would then be incompatible with such a check, yet are perfectly valid to preload; maybe even an especially good case for preloading.  So such a strict check is probably unwise.

Maybe it would be helpful for the various experimental "precompile PHP" efforts, like what Anthony Ferrara has been doing?  I've no idea there.

I appreciate the intent here, and agree most code files should be symbol-only, but I'm not sure there's a strong enough use case in practice for it.  That said, were it to be adopted I would strongly favor a declare rather than a different file extension or tag.  Something like:

<?php
declare('strict_types=1');
declare('this file only declares symbols, error if it tries to do anything else');

class Blah { ...}
?>

That would be the least obtrusive way of adding it, I think.

--Larry Garfield

---

## #105715 — Robert Hickman — 2019-05-15T15:37:22+00:00

URL: https://externals.io/message/105660#105715

>
> That said... most polyfill files, of which there are a decent number, do some variation on:
>
> <?php
>
> if (!function_exists('coolness')) {
>   function coolness(int $coolLevel) { ... }
> }
> ?>
>

I can see quite a lot that could be done with preloading by executing
code once, essentially compile time code execution. For example,
choose which database interface is being used once, instead of every
time the script runs. Or compile 'fluent call chains' into a more
efficient form. If the AST were accessible, there is quite a lot more
that could be done.
