Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions sitemap.xml
Original file line number Diff line number Diff line change
Expand Up @@ -81,4 +81,7 @@
<url>
<loc>https://scherzer.dev/Blog/20260309-php-friends</loc>
</url>
<url>
<loc>https://scherzer.dev/Blog/20260410-define-deprecated</loc>
</url>
</urlset>
109 changes: 109 additions & 0 deletions src/Blog/posts/20260410-define-deprecated.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
---
extensions:
pygments: true
title: Introducing define_deprecated() for PHP
---

# Introducing define_deprecated() for PHP

In PHP 8.5, I introduced support for [attributes on constants][blog-attribs],
which allows marking compile-time global constants as deprecated. However,
that functionality was not made easily available when defining constants at
*runtime*, or in code that supports older versions of PHP. My new library,
[danielescherzer/define-deprecated][lib-def-dep], provides that support.

## Overview

PHP 8.5's support for attributes on constants introduced new syntax that older
versions of PHP cannot parse. This creates a problem for libraries that want to
support multiple versions of PHP: even *declaring* a constant with attributes
will cause a parser error on older versions of PHP. The solution is to wrap the
constant declaration in [`eval()`][docs-eval], which ensures that the code is
parsed at runtime, making it possible to conditionally execute it on PHP 8.5+.

While `eval()` is often avoided, here it provides a controlled way to
conditionally use syntax that older versions of PHP are unable to understand.
Exhaustive tests, and the use of [`var_export()`][docs-var-export], confirm that
`eval()` does not present an opportunity for executing arbitrary code, even when
passing untrusted inputs to the library. That said, on PHP 8.4, as attributes
are unavailable, `eval()` is unnecessary; the declaration of constants can be
delegated to the existing function for creating new constants at runtime:
[`define()`][docs-define]. `eval()` is only required for, and used on, PHP 8.5+.

My new library exposes a new global function, `define_deprecated()`, in the
`\DanielEScherzer\DefineDeprecated` namespace with the following signature:

```php startinline=True
function define_deprecated(
string $constant_name,
mixed $value,
?string $message,
?string $since
): bool {
// ...
}
```

The first two parameters, `$constant_name` and `$value`, correspond to the
parameters for the `define()` function, or to the constant name and value used
in compile-time declarations. The remaining two parameters, `$message` and
`$since`, correspond to the parameters of the
[`#[\Deprecated]`][docs-deprecated] attribute - the message explaining why the
constant is deprecated, and the version in which the constant was deprecated.

While the `#[\Deprecated]` attribute does allow the `$message` and `$since` to
be omitted (defaulting to `null`), this function requires them to be explicitly
passed (even if `null`) to encourage documenting deprecations.

## Example

To make use of the new library, install the package via composer, for example:

```bash
composer require danielescherzer/define-deprecated
```

After installing the package, you can define a deprecated constant like this:

```php
<?php

use function DanielEScherzer\DefineDeprecated\define_deprecated;

define_deprecated( 'MY_CONSTANT', true, 'Do not use this', '1.0' );

// This will output "bool(true)", and on PHP 8.5+ also emit deprecation warnings
var_dump( MY_CONSTANT );
```

## Notes

The library supports, and is tested against, PHP 8.1 and newer. Older versions
of PHP had different behavior for the `define()` function, and have been
end-of-life for long enough that they were not worth trying to support.

The library has been published with version 1.0.0 and should be fully ready to
use. No additional functional changes are expected, though obviously any bugs
that are reported will be addressed. You can see the source code
[on GitHub][src-repo].

Because much of the code is version specific (`eval()` is only needed for PHP
8.5+), a code coverage report for just PHP 8.4 or just PHP 8.5 would not be
very helpful. Combining the code coverage reports between the tests run on PHP
8.4 and the tests run on PHP 8.5 required some creativity; check out the
[`coverage/MergeCoverage.php`][src-MergeCoverage] script and the
[`coverage` CI job][src-CoverageJob] if you are interested.

If you need to maintain cross-version compatibility but want to take advantage
of modern PHP features, `define_deprecated()` provides a quick and practical
solution.

[blog-attribs]: ./20250429-attributes-on-constants
[docs-define]: https://www.php.net/manual/en/function.define.php
[docs-deprecated]: https://www.php.net/manual/en/class.deprecated.php
[docs-eval]: https://www.php.net/manual/en/function.eval.php
[docs-var-export]: https://www.php.net/manual/en/function.var-export.php
[lib-def-dep]: https://packagist.org/packages/danielescherzer/define-deprecated
[src-CoverageJob]: https://github.com/DanielEScherzer/define-deprecated/blob/v1.0.0/.github/workflows/ci.yml#L32
[src-MergeCoverage]: https://github.com/DanielEScherzer/define-deprecated/blob/v1.0.0/coverage/MergeCoverage.php
[src-repo]: https://github.com/DanielEScherzer/define-deprecated
7 changes: 6 additions & 1 deletion src/Pages/OpenSourcePage.php
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,11 @@ class OpenSourcePage extends BasePage {
'link' => 'https://packagist.org/packages/danielescherzer/commonmark-ext-pygments-highlighter',
'desc' => 'CommonMark extension for code highlighting with Pygments',
],
'define-deprecated' => [
'name' => 'danielescherzer/define-deprecated',
'link' => 'https://packagist.org/packages/danielescherzer/define-deprecated',
'desc' => 'Allow defining deprecated global constants at runtime without dropping PHP <8.5 support',
],
'html-builder' => [
'name' => 'danielescherzer/html-builder',
'link' => 'https://packagist.org/packages/danielescherzer/html-builder',
Expand Down Expand Up @@ -345,7 +350,7 @@ private function addPackagesSection(): void {
'p',
[],
<<<END
I also wrote multiple open-source PHP packages - though they are currently
I also wrote multiple open-source PHP packages - though some are currently
primarily used by me, I am a firm supporter of open-source code and figured that
they might be useful to others. The packages that I have created so far are:
END,
Expand Down
9 changes: 5 additions & 4 deletions tests/data/Home.html
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,8 @@
Computer Science and Political Science and graduating <em>magna cum laude</em> in 2024 with a Bachelor of Science degree. As part of my work in Computer
Science, I chose to write an honors thesis in my senior year, see <a href="./Thesis">here</a> for details. I continued at Tufts for graduate school, graduating in 2025 with
a Master of Science in Computer Science degree.</p><p>See the links in the navigation bar above for more information about my
experience.</p><h2 class="subsection-header">Contact</h2><ul><li><a href="https://www.linkedin.com/in/daniel-scherzer-520539263/" target="_blank" class="external-link">LinkedIn</a></li><li>Email: <code>daniel.e.scherzer@gmail.com</code></li></ul><h2 class="subsection-header">Blog</h2><p>I also have a blog. You can see a full index of my posts <a href="/Blog">here</a>. My latest blog post is: </p><div class="blog-preview"><h3>Friends in PHP</h3><span class="blog-preview-date">Monday, 09 March 2026</span><p>As I mentioned in <a href="./Blog/20260302-confoo">my last blog post</a>, while at ConFoo I and a few
other developers worked on some ideas for adding friendship support to PHP. To
be clear, these are just ideas at the moment, but I figured they were worth
sharing. <a href="/Blog/20260309-php-friends">Continue reading...</a></p></div></div><div class="des-footer"><div class="des-footer--content">Content is © 2026 Daniel Scherzer</div></div></body></html>
experience.</p><h2 class="subsection-header">Contact</h2><ul><li><a href="https://www.linkedin.com/in/daniel-scherzer-520539263/" target="_blank" class="external-link">LinkedIn</a></li><li>Email: <code>daniel.e.scherzer@gmail.com</code></li></ul><h2 class="subsection-header">Blog</h2><p>I also have a blog. You can see a full index of my posts <a href="/Blog">here</a>. My latest blog post is: </p><div class="blog-preview"><h3>Introducing define_deprecated() for PHP</h3><span class="blog-preview-date">Friday, 10 April 2026</span><p>In PHP 8.5, I introduced support for <a href="./Blog/20250429-attributes-on-constants">attributes on constants</a>,
which allows marking compile-time global constants as deprecated. However,
that functionality was not made easily available when defining constants at
<em>runtime</em>, or in code that supports older versions of PHP. My new library,
<a rel="noopener noreferrer" target="_blank" class="external-link" href="https://packagist.org/packages/danielescherzer/define-deprecated">danielescherzer/define-deprecated</a>, provides that support. <a href="/Blog/20260410-define-deprecated">Continue reading...</a></p></div></div><div class="des-footer"><div class="des-footer--content">Content is © 2026 Daniel Scherzer</div></div></body></html>
4 changes: 2 additions & 2 deletions tests/data/OpenSource.html
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
decide between the volunteers (luckily there were plenty of candidates) and I
was one of the two &quot;rookie&quot; candidates chosen to help with the release. You can
read more in <a href="/Blog/20250417-php85-release-manager">my blog post</a>.</p><p>PHP uses a process of requests for comment when proposing and implementing major
changes; my RFCs include:</p><ul><li>March 2026: <a href="https://wiki.php.net/rfc/override_constants" target="_blank" class="external-link">#[\Override] for class constants</a> - Extend #[\Override] to target class constants (in draft)</li><li>March 2026: <a href="https://wiki.php.net/rfc/debugable-enums" target="_blank" class="external-link">Debugable Enums</a> - Allow __debugInfo() on enums (under discussion)</li><li>July 2025: <a href="https://wiki.php.net/rfc/deprecated_traits" target="_blank" class="external-link">#[\Deprecated] for traits</a> - Support the #[\Deprecated] attribute on traits (implemented in PHP 8.5)</li><li>July 2025: <a href="https://wiki.php.net/rfc/filter_throw_on_failure" target="_blank" class="external-link">FILTER_THROW_ON_FAILURE</a> - Add FILTER_THROW_ON_FAILURE flag to the filter extension (implemented in PHP 8.5)</li><li>June 2025: <a href="https://wiki.php.net/rfc/delayedtargetvalidation_attribute" target="_blank" class="external-link">#[\DelayedTargetValidation] attribute</a> - Delaying compile-time attribute target validation errors with #[\DelayedTargetValidation] (implemented in PHP 8.5)</li><li>March 2025: <a href="https://wiki.php.net/rfc/final_promotion" target="_blank" class="external-link">Final Property Promotion</a> - Adding support for final modifiers in constructor property promotion (implemented in PHP 8.5)</li><li>November 2024: <a href="https://wiki.php.net/rfc/attributes-on-constants" target="_blank" class="external-link">Attributes on Constants</a> - Adding support for attributes on compile-time constants (implemented in PHP 8.5)</li></ul><h3 class="subsection-header">Packages</h3><p>I also wrote multiple open-source PHP packages - though they are currently
changes; my RFCs include:</p><ul><li>March 2026: <a href="https://wiki.php.net/rfc/override_constants" target="_blank" class="external-link">#[\Override] for class constants</a> - Extend #[\Override] to target class constants (in draft)</li><li>March 2026: <a href="https://wiki.php.net/rfc/debugable-enums" target="_blank" class="external-link">Debugable Enums</a> - Allow __debugInfo() on enums (under discussion)</li><li>July 2025: <a href="https://wiki.php.net/rfc/deprecated_traits" target="_blank" class="external-link">#[\Deprecated] for traits</a> - Support the #[\Deprecated] attribute on traits (implemented in PHP 8.5)</li><li>July 2025: <a href="https://wiki.php.net/rfc/filter_throw_on_failure" target="_blank" class="external-link">FILTER_THROW_ON_FAILURE</a> - Add FILTER_THROW_ON_FAILURE flag to the filter extension (implemented in PHP 8.5)</li><li>June 2025: <a href="https://wiki.php.net/rfc/delayedtargetvalidation_attribute" target="_blank" class="external-link">#[\DelayedTargetValidation] attribute</a> - Delaying compile-time attribute target validation errors with #[\DelayedTargetValidation] (implemented in PHP 8.5)</li><li>March 2025: <a href="https://wiki.php.net/rfc/final_promotion" target="_blank" class="external-link">Final Property Promotion</a> - Adding support for final modifiers in constructor property promotion (implemented in PHP 8.5)</li><li>November 2024: <a href="https://wiki.php.net/rfc/attributes-on-constants" target="_blank" class="external-link">Attributes on Constants</a> - Adding support for attributes on compile-time constants (implemented in PHP 8.5)</li></ul><h3 class="subsection-header">Packages</h3><p>I also wrote multiple open-source PHP packages - though some are currently
primarily used by me, I am a firm supporter of open-source code and figured that
they might be useful to others. The packages that I have created so far are:</p><ul><li><a href="https://packagist.org/packages/danielescherzer/common-phpcs" target="_blank" class="external-link">danielescherzer/common-phpcs</a> - Collection of common codesniffer standards for my projects</li><li><a href="https://packagist.org/packages/danielescherzer/commonmark-ext-pygments-highlighter" target="_blank" class="external-link">danielescherzer/commonmark-ext-pygments-highlighter</a> - CommonMark extension for code highlighting with Pygments</li><li><a href="https://packagist.org/packages/danielescherzer/html-builder" target="_blank" class="external-link">danielescherzer/html-builder</a> - Tools for building HTML</li></ul><h3 class="subsection-header">Website</h3><p>The source code for my website is also public, in case the code is useful to
they might be useful to others. The packages that I have created so far are:</p><ul><li><a href="https://packagist.org/packages/danielescherzer/common-phpcs" target="_blank" class="external-link">danielescherzer/common-phpcs</a> - Collection of common codesniffer standards for my projects</li><li><a href="https://packagist.org/packages/danielescherzer/commonmark-ext-pygments-highlighter" target="_blank" class="external-link">danielescherzer/commonmark-ext-pygments-highlighter</a> - CommonMark extension for code highlighting with Pygments</li><li><a href="https://packagist.org/packages/danielescherzer/define-deprecated" target="_blank" class="external-link">danielescherzer/define-deprecated</a> - Allow defining deprecated global constants at runtime without dropping PHP &lt;8.5 support</li><li><a href="https://packagist.org/packages/danielescherzer/html-builder" target="_blank" class="external-link">danielescherzer/html-builder</a> - Tools for building HTML</li></ul><h3 class="subsection-header">Website</h3><p>The source code for my website is also public, in case the code is useful to
others. The actual text about me is probably not going to be relevant, but my
setup, configuration, and style pages may be useful. See the code <a href="https://github.com/DanielEScherzer/website-content" target="_blank" class="external-link">here</a>.</p></div><div class="des-footer"><div class="des-footer--content">Content is © 2026 Daniel Scherzer</div></div></body></html>
6 changes: 5 additions & 1 deletion tests/data/blog-index.html
Original file line number Diff line number Diff line change
@@ -1,5 +1,9 @@
<!DOCTYPE html>
<html lang="en"><head><link rel="icon" href="data:,"><meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1"><link rel="stylesheet" type="text/css" href="/resources/default-styles.css"><title>Blog index</title><link rel="stylesheet" type="text/css" href="/resources/blog-styles.css"></head><body><div class="des-navbar"><a href="/Home">Home</a><a href="/files/Resume.pdf">Résumé</a><a href="/OpenSource">Open Source</a><a href="/Work">Work</a><strong class="des-strong-page-link">Blog</strong></div><div class="content-wrapper"><h1>Blog index</h1><div class="blog-preview"><h2>Friends in PHP</h2><span class="blog-preview-date">Monday, 09 March 2026</span><p>As I mentioned in <a href="./Blog/20260302-confoo">my last blog post</a>, while at ConFoo I and a few
<html lang="en"><head><link rel="icon" href="data:,"><meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1"><link rel="stylesheet" type="text/css" href="/resources/default-styles.css"><title>Blog index</title><link rel="stylesheet" type="text/css" href="/resources/blog-styles.css"></head><body><div class="des-navbar"><a href="/Home">Home</a><a href="/files/Resume.pdf">Résumé</a><a href="/OpenSource">Open Source</a><a href="/Work">Work</a><strong class="des-strong-page-link">Blog</strong></div><div class="content-wrapper"><h1>Blog index</h1><div class="blog-preview"><h2>Introducing define_deprecated() for PHP</h2><span class="blog-preview-date">Friday, 10 April 2026</span><p>In PHP 8.5, I introduced support for <a href="./Blog/20250429-attributes-on-constants">attributes on constants</a>,
which allows marking compile-time global constants as deprecated. However,
that functionality was not made easily available when defining constants at
<em>runtime</em>, or in code that supports older versions of PHP. My new library,
<a rel="noopener noreferrer" target="_blank" class="external-link" href="https://packagist.org/packages/danielescherzer/define-deprecated">danielescherzer/define-deprecated</a>, provides that support. <a href="/Blog/20260410-define-deprecated">Continue reading...</a></p></div><div class="blog-preview"><h2>Friends in PHP</h2><span class="blog-preview-date">Monday, 09 March 2026</span><p>As I mentioned in <a href="./Blog/20260302-confoo">my last blog post</a>, while at ConFoo I and a few
other developers worked on some ideas for adding friendship support to PHP. To
be clear, these are just ideas at the moment, but I figured they were worth
sharing. <a href="/Blog/20260309-php-friends">Continue reading...</a></p></div><div class="blog-preview"><h2>ConFoo 2026</h2><span class="blog-preview-date">Monday, 02 March 2026</span><p>Last week, I was in Montreal for the ConFoo conference, where I gave two talks,
Expand Down
Loading