<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">
    <title><![CDATA[The PHP Foundation]]></title>
    <link href="https://thephp.foundation/atom.xml" rel="self"/>
    <link href="https://thephp.foundation/"/>
    <updated>2026-09-11T16:57:16+00:00</updated>
    <id>https://thephp.foundation/</id>
        <generator uri="http://sculpin.io/">Sculpin</generator>
            <entry>
            <title type="html"><![CDATA[How to Calculate 0.1 Plus 0.2 Correctly in PHP?]]></title>
            <link href="https://thephp.foundation/blog/2026/09/11/how-to-calculate-0-point-1-plus-0-point-2-correctly-in-php/"/>
            <updated>2026-09-11T00:00:00+00:00</updated>
            <id>https://thephp.foundation/blog/2026/09/11/how-to-calculate-0-point-1-plus-0-point-2-correctly-in-php/</id>
            <content type="html"><![CDATA[<p><em>The PHP Foundation thanks guest author Weilin Du for this post!</em></p>

<hr />

<p>Quick quiz before you read:</p>

<pre><code class="php">&lt;?php
var_dump(0.1 + 0.2 === 0.3);
</code></pre>

<p><a href="https://3v4l.org/Qimvu">This returns false</a>. Now, as developers who proudly know <a href="https://en.wikipedia.org/wiki/IEEE_754">IEEE's floating rules</a>, many of you may take a sip of your coffee and say: Hey, that's not news anymore. We all know this classic case that warns generations of junior developers that calculating directly with floats might cause bugs.</p>

<p>However, let's see this case here (64-bit):</p>

<pre><code class="php">&lt;?php
var_dump((9223372036854775808 - 1) === 9223372036854775807);
</code></pre>

<p>Well, obviously this is an integer calculation. This is surely not affected by any strange floating-point behavior and should return true. We don't need to consider using any high-precision math extensions (BCMath, GMP) here, right?</p>

<p>Right?</p>

<h1 id="how-php-floats-work">How PHP floats work</h1>

<p>PHP's <code>float</code> type is platform-dependent, but it normally uses the IEEE 754 binary64 format which has a sign, an exponent and 53 bits of binary precision. The <a href="https://www.php.net/manual/en/language.types.float.php">PHP manual</a> describes the practical result as roughly 14 decimal digits of precision and a maximum relative rounding error on the order of <code>1.11e-16</code>.</p>

<p>The important word is <strong>binary</strong>. A float represents a finite sum of powers of two. Fractions such as <code>0.5</code> (<code>1/2</code>) and <code>0.125</code> (<code>1/8</code>) have finite binary representations, so they can be stored exactly. <code>0.1</code> (<code>1/10</code>) cannot: its binary representation repeats forever, just as <code>1/3</code> repeats forever in decimal.</p>

<p>PHP therefore stores the nearest representable binary value. We can make those approximations visible by printing enough digits:</p>

<pre><code class="php">&lt;?php
printf("%.17g\n", 0.1);         // 0.10000000000000001
printf("%.17g\n", 0.2);         // 0.20000000000000001
printf("%.17g\n", 0.1 + 0.2);   // 0.30000000000000004
</code></pre>

<h1 id="where-precision-gets-lost">Where precision gets lost</h1>

<h2 id="playing-with-floats">Playing with floats</h2>

<p>Both sides of the original comparison are floats, but they arrive at different nearby binary values:</p>

<pre><code class="php">&lt;?php
$sum = 0.1 + 0.2; // float(0.30000000000000004)

var_dump($sum === 0.3);              // false
var_dump(abs($sum - 0.3) &lt; 1e-12);   // true
</code></pre>

<h2 id="playing-with-big-integers">Playing with big integers</h2>

<p>PHP integers are signed and platform-dependent. The maximum value of an integer is given by <a href="https://www.php.net/manual/en/reserved.constants.php#constant.php-int-max"><code>PHP_INT_MAX</code></a>.</p>

<p>On a 64-bit build, their range normally ends at <code>9223372036854775807</code>. According to the manual's <a href="https://www.php.net/manual/en/language.types.integer.php#language.types.integer.overflow">integer overflow rules</a>, a literal or operation outside the integer range becomes a float:</p>

<pre><code class="php">&lt;?php
var_dump(PHP_INT_MAX);       // int(9223372036854775807)
var_dump(PHP_INT_MAX + 1);   // float(9.223372036854776E+18)
</code></pre>

<p>Bingo! A binary64 float has enough range to hold a number of this magnitude, but not enough precision to distinguish every integer around it. So, let's go back to the example at the beginning.</p>

<pre><code class="php">&lt;?php
var_dump(((PHP_INT_MAX + 1) - 1) === PHP_INT_MAX);           // false
var_dump((9223372036854775808 - 1) === 9223372036854775807); // false (64-bit)
</code></pre>

<p>Once an integer has overflowed into a float, converting it back cannot recover the lost low-order digits.</p>

<h1 id="how-to-calculate-floats-in-php-correctly">How to calculate floats in PHP correctly</h1>

<p>Fine fine fine, floats are strange, many may say. But, is there a way in PHP to do those calculations correctly? Surely yes!</p>

<h2 id="working-safely-with-native-floats">Working safely with native floats</h2>

<p>Floats are compact, fast, and well suited to approximate quantities. Using them correctly means accepting that their last digits are not exact. Here are some recommendations to work with PHP's native floats correctly:</p>

<h3 id="do-not-blindly-cast-floats-to-integers%21">Do not blindly cast floats to integers!</h3>

<p>Quiz time again! What does the following code output?</p>

<pre><code class="php">&lt;?php

$value = 0.58 * 100;

echo $value, "\n";
var_dump(intval($value));
var_dump((int) $value);
</code></pre>

<p>The output value is:</p>

<pre><code>58
int(57)
int(57)
</code></pre>

<p>Interesting, isn't it? <code>intval()</code> and an <code>(int)</code> cast do not round to the nearest integer. They discard the fractional part by rounding towards zero. If this particular calculation is supposed to produce the nearest whole number, calling <a href="https://www.php.net/manual/en/function.round.php"><code>round()</code></a> first gives the expected result:</p>

<pre><code class="php">&lt;?php
$value = 0.58 * 100;
$result = (int) round($value);

var_dump($result); // int(58)
</code></pre>

<p><em>So be careful when casting a float to an integer.</em></p>

<p>One may ask: wait, why does <code>echo $value, "\n";</code> return <code>58</code> in this case? That leads to the second question:</p>

<h3 id="the-ini-setting-%60precision%60-does-not-fix-the-calculation">The INI setting <code>precision</code> does NOT fix the calculation</h3>

<pre><code class="php">&lt;?php
ini_set('precision', '14'); // 14 is the default value.

$value = 0.58 * 100;

echo $value, "\n";        // 58
var_dump(intval($value)); // int(57)
</code></pre>

<p>Why can the same value, displayed as <code>58</code> by echo, be converted to <code>57</code> here? Printing the value with <code>echo</code> uses the configured <code>precision</code> that "hides" the final digits. Integer conversion does not use that rounded text obviously. It reads the stored float directly, and the stored value is slightly smaller than <code>58</code>.</p>

<p>The <a href="https://www.php.net/manual/en/ini.core.php#ini.precision"><code>precision</code> php.ini directive</a> only controls how many digits are used when a float is converted to a string. It does not change the value in memory or the arithmetic performed by the processor:</p>

<pre><code class="php">&lt;?php
$sum = 0.1 + 0.2;

ini_set('precision', '17');
echo $sum, "\n"; // 0.30000000000000004

ini_set('precision', '14');
echo $sum, "\n"; // 0.3

var_dump($sum === 0.3); // bool(false)
</code></pre>

<p>Both <code>echo</code> statements read the same float. One representation hides the final digits and the other reveals them, but neither changes the result of the strict comparison.</p>

<p>PHP also has a separate <code>serialize_precision</code> directive. Despite its name, it controls the textual representation of floats produced not only by <code>serialize()</code>, but also by functions such as <code>json_encode()</code> and <code>var_dump()</code>. It does not affect the arithmetic that produced them. <em>They are NOT math features.</em></p>

<h3 id="comparing-floats-for-equality-based-on-tolerance">Comparing floats for equality based on tolerance</h3>

<p>When approximate values are appropriate, the PHP manual recommends comparing them using an acceptable error bound instead of direct equality. The simple check shown earlier works when all values have a similar and known scale:</p>

<pre><code class="php">&lt;?php
$actual = 0.1 + 0.2;
$expected = 0.3;

var_dump(abs($actual - $expected) &lt; 1e-12); // bool(true)
</code></pre>

<p>The tolerance must come from the domain. <code>1e-12</code> is suitable for this small demo, but it is certainly not a magic value that fits every calculation.</p>

<p><a href="https://www.php.net/manual/en/reserved.constants.php#constant.php-float-epsilon"><code>PHP_FLOAT_EPSILON</code></a> describes the spacing between representable floats around <code>1.0</code>; it is not automatically the right tolerance for every magnitude or every application. See the manual's guidance on <a href="https://www.php.net/manual/en/language.types.float.php#language.types.float.comparison">comparing floats</a> for the basic epsilon approach.</p>

<h3 id="exact-fixed-scale-arithmetic-with-integers">Exact fixed-scale arithmetic with integers</h3>

<p>When a value has a fixed smallest unit, storing that unit as an integer avoids binary fractions completely. For example, money is often stored as cents:</p>

<pre><code class="php">&lt;?php
$unitPriceInCents = 58;
$quantity = 3;
$totalInCents = $unitPriceInCents * $quantity;

var_dump($totalInCents); // int(174)
</code></pre>

<p>The conversion into minor units must also be exact. Do not receive <code>0.58</code> as a float and assume <code>(int) ($value * 100)</code> is safe; that is the same conversion bug we saw above. Parse a validated decimal string or use decimal arithmetic at the input boundary.</p>

<p>Native integers still have the <code>PHP_INT_MAX</code> limit. If the scaled values may exceed it, use an arbitrary-precision representation from the start.</p>

<h2 id="core-extensions-can-help%21">Core extensions can help!</h2>

<p>Yelk. I don't want to remember these rules nor convert all my floats to integers by changing the units for precision. Well, here come the core extensions that might help you.</p>

<h2 id="playing-with-floats%3F-use-bcmath">Playing with floats? Use BCMath</h2>

<p><a href="https://www.php.net/manual/en/book.bc.php">BCMath</a> performs arbitrary-precision decimal arithmetic. Its traditional functions receive and return strings, so the decimal input does not pass through a binary float first:</p>

<pre><code class="php">&lt;?php
$sum = bcadd('0.1', '0.2', 1);
$scaled = bcmul('0.58', '100', 0);

var_dump($sum);    // string(3) "0.3"
var_dump($scaled); // string(2) "58"
</code></pre>

<p>PHP 8.4 and later also provide the immutable <a href="https://www.php.net/manual/en/class.bcmath-number.php"><code>BcMath\Number</code></a> object with support for ordinary arithmetic operators:</p>

<pre><code class="php">&lt;?php
use BcMath\Number;

$sum = new Number('0.1') + new Number('0.2');

echo $sum, "\n"; // 0.3
</code></pre>

<p>The quotation marks are important. Construct the calculation from decimal strings such as <code>'0.1'</code>, but NOT from floats that may have already lost precision. Converting an approximate float to a BCMath value later cannot reconstruct the original exact decimal input.</p>

<p>BCMath is a good fit for prices, balances, rates, and other values where decimal places have an exact meaning.</p>

<h2 id="playing-with-big-integers%3F-use-gmp">Playing with big integers? Use GMP</h2>

<p>The <a href="https://www.php.net/manual/en/book.gmp.php">GMP extension</a> works with arbitrary-length integers. It is not enabled by default and requires the external GMP library. It can calculate the large-integer example from the beginning without overflowing into a float:</p>

<pre><code class="php">&lt;?php
$number = gmp_init('9223372036854775808', 10);
$result = gmp_sub($number, '1');

echo gmp_strval($result), "\n"; // 9223372036854775807
</code></pre>

<p>Likewise, large inputs must be strings. Writing <code>9223372036854775808</code> as a PHP numeric literal first would allow PHP to convert it to a float before GMP receives it, which is already too late.</p>

<p>GMP represents integers rather than decimal fractions, so it cannot directly store <code>0.1</code>. It can handle fixed-scale values if the application represents every amount as an integer number of minor units. BCMath is usually clearer when the decimal scale itself is part of the data.</p>

<h1 id="conclusion">Conclusion</h1>

<h2 id="how-to-calculate-0.1-plus-0.2-correctly-in-php%3F">How to calculate 0.1 plus 0.2 correctly in PHP?</h2>

<p>So, how should PHP calculate <code>0.1 + 0.2</code>? If the values are approximate, native float addition is already performing the expected binary calculation. Compare the result with an appropriate tolerance and format it for display. If the answer must be the exact decimal <code>0.3</code>, start with a decimal representation:</p>

<pre><code class="php">&lt;?php
echo bcadd('0.1', '0.2', 1); // 0.3
</code></pre>

<p>There is no <code>php.ini</code> switch that changes a binary float into an exact decimal. Correctness comes from choosing the representation before the calculation begins.</p>

<h2 id="still-evolving">Still evolving</h2>

<p>Both BCMath and GMP are in active development. For example, PHP 8.6 adds two new functions to GMP: <code>gmp_prev_prime</code> and <code>gmp_powm_sec</code>. Those are useful functions! The PHP language is moving fast to make every PHP developer's life easier.</p>

<p>The PHP language is alive forever, with all the passion, work and pure love our dear contributors put in. Thank you for reading and using PHP!</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[Welcoming Daniel Scherzer to the Ecosystem Security Team]]></title>
            <link href="https://thephp.foundation/blog/2026/09/09/welcome-daniel-scherzer/"/>
            <updated>2026-09-09T00:00:00+00:00</updated>
            <id>https://thephp.foundation/blog/2026/09/09/welcome-daniel-scherzer/</id>
            <content type="html"><![CDATA[<p>When the Ecosystem Security Team was established with funding from the <a href="https://thephp.foundation/blog/2026/05/18/announcing-ecosystem-security-team/">Alpha-Omega “Security Engineer in Residence” grant</a>, its mission was to improve the security of all aspects of the PHP ecosystem. Under the leadership of Volker Dusch, the team has <a href="https://thephp.foundation/blog/2026/06/23/one-month-of-ecosystem-security-engineering/">accomplished many things</a>.</p>

<p>As predicted, the increasing popularity of AI tools has brought an influx of security reports and PRs from the community to php-src itself. The triaging, reviewing, and handling of issues that do not fall within PHP’s definition of a <a href="https://github.com/php/php-src/blob/master/SECURITY.md">“security vulnerability,”</a> but that do improve the quality of PHP are tasks that are time-consuming for both php-src maintainers and for Volker and the team. Even if these are not security issues, they are useful hardening work and impactful nonetheless. These fixes also prevent future reports that would generate increased workload for the team.</p>

<p><img src="/assets/post-images/2026/daniel-scherzer/daniel-scherzer.jpg" width="300" alt="headshot of daniel scherzer" class="mb-4 sm:mr-4 sm:float-left"/>To help manage this influx, the PHP Foundation is happy to add <a href="https://scherzer.dev/">Daniel Scherzer</a> to the Ecosystem Security Team on a short-term basis, as part of the aforementioned Alpha-Omega grant. Daniel will be working on this body of outstanding issues that harden PHP but that do not qualify as security vulnerabilities.</p>

<p>Daniel got his start in open-source software by contributing to PHP, where he currently serves as the maintainer of the Reflection extension, as a release manager for PHP 8.5, and as the veteran release manager for PHP 8.6. Daniel will be a huge asset not only to the Ecosystem Security Team but also to the PHP community, through his work on hardening PHP itself.</p>

<p>Welcome, Daniel!</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[Digital Sovereignty Is Written in PHP]]></title>
            <link href="https://thephp.foundation/blog/2026/09/02/digital-sovereignty-is-written-in-php/"/>
            <updated>2026-09-02T00:00:00+00:00</updated>
            <id>https://thephp.foundation/blog/2026/09/02/digital-sovereignty-is-written-in-php/</id>
            <content type="html"><![CDATA[<p>Germany is spending €108 million to move its federal websites onto a PHP application.</p>

<p>The money is the budget for the eleventh version of the Government Site Builder, the German federal administration's standard content management solution: <a href="https://www.plan2.net/blog-news/blogbeitrag/deutschland-investiert-108-millionen-euro-in-typo3">€26.88 million for product development and support, €73.2 million for migration and relaunch, €8 million for operations</a>, phased over four years. <a href="https://www.itzbund.de/DE/itloesungen/standardloesungen/gsb/gsb.html">More than 80 federal agencies and institutions already use it, and they have built well over 250 websites with it</a>.</p>

<p>In 2025, The PHP Foundation received <a href="https://thephp.foundation/blog/2026/05/27/impact-and-transparency-report-2025/">$730,534 in total contributions</a>.</p>

<p>I am not going to argue from those two numbers that PHP deserves better treatment. What I want to describe is something that has gone largely unnoticed, including by those of us who work on PHP: across Europe, public administrations have already decided what their digital infrastructure runs on. They decided it in procurement documents, framework agreements, and coalition agreements. And when those documents say "digital sovereignty", what they describe, over and over, is a PHP application.</p>

<h2 id="where-citizens-actually-reach-their-governments">Where citizens actually reach their governments</h2>

<p>The European Commission is the largest case: At the Drupal4Gov EU conference in Brussels in January 2026, the team behind the Europa Web Publishing Platform described what they operate: <a href="https://drunomics.com/en/blog/drupal4gov-eu-2026-how-drupal-powers-european-governments-247">770 live sites for 44 different Commission services, 700 million visits and 2.2 billion page views per year</a>. The move to a shared Drupal platform began in 2019, because letting each Directorate-General maintain its own customised codebase had made security patching and consistent user experience progressively harder. The reusable parts are public, in the <a href="https://github.com/openeuropa">OpenEuropa</a> and <a href="https://github.com/ec-europa">ec-europa</a> organisations on GitHub.</p>

<p>The European Union Aviation Safety Agency runs its <a href="https://www.easa.europa.eu/en/domains/environment/sustainability-portal">Sustainability Portal</a> on Drupal: a regulatory compliance platform serving over 350 airlines and 31 national authorities for the ReFuelEU Aviation regulation. Analytics run on Matomo, email on Mautic. Three PHP applications carry an aviation compliance regime.</p>

<p>In the Netherlands, DICTU's <a href="https://www.drupal.org/project/govnl_cms_project">GovNL CMS</a> brings government website deployment down from three months to ten minutes using design tokens, Drupal Recipes, and automated infrastructure. In France, the Drupal base theme for the state design system is <a href="https://www.drupal.org/project/dsfr">monitored by the Service d'Information du Gouvernement and DINUM</a>, so the French state supervises PHP code as part of its own design authority. In the United Kingdom and Ireland, <a href="https://localgovdrupal.org">LocalGov Drupal</a> has over 58 councils sharing a common codebase and pooling development budgets, with reported savings of 50 to 80 percent against building a council website from scratch. In Australia, <a href="https://www.govcms.gov.au/why-govcms">GovCMS</a> hosts more than 370 websites for 115 government agencies, has been running for over a decade, and holds an OFFICIAL:Sensitive security classification.</p>

<p>Not one of these is a pilot project. Each of them carries the everyday traffic between a government and the people it serves.</p>

<h2 id="germany%27s-shortlist-only-had-php-entries">Germany's shortlist only had PHP entries</h2>

<p>The German case is worth looking at closely, because the decision is documented rather than inferred.</p>

<p>The <a href="https://produkt.gsb.bund.de/gsb11">Government Site Builder (GSB)</a> became, in version 11, a measure under the federal Ministry of the Interior's service consolidation programme. It is <a href="https://de.wikipedia.org/wiki/Government_Site_Builder">built entirely from open-source components and published on the OpenCoDE platform</a>, and it is <a href="https://typo3.com/solutions/industries/public-sector/government-site-builder">based on TYPO3</a>. The evaluation that led there had narrowed the field to <a href="https://www.cms-garden.org/de/magazin/der-neue-government-site-builder-powered-by-typo3">Drupal and TYPO3</a>: the shortlist for the German federal government's standard content management system consisted exclusively of PHP applications. The work was then split. <a href="https://www.cps-it.de/aktuelles/open-source-fuer-den-bund">A consortium led by CPS, with 3pc, brandung, DFAU, in2code, THE BRETTINGHAMS and queo, develops GSB 11 itself</a> over four years. In March 2025, <a href="https://www.pagemachine.de/typo3-cms/government-site-builder-mit-typo3">a consortium of 17 TYPO3 agencies led by the Materna Group won the migration lot</a> and will move hundreds of federal websites across.</p>

<p>The most telling detail is not German at all: When Swiss parliamentarians criticised their own federal administration for procuring a closed-source CMS, they held up the German decision as the model to follow: <a href="https://parldigi.ch/de/parldigi-direkt-open-source-in-der-verwaltung-deutschland-machts-vor/">"Deutschland machts vor"</a>, Germany is showing how it's done. A national decision to standardise on a PHP application is now cited in a foreign parliament as best practice.</p>

<h2 id="the-sovereign-workplace-is-a-php-application">The sovereign workplace is a PHP application</h2>

<p>In these programmes, digital sovereignty is described in practice by naming specific pieces of software.</p>

<p>The ITZBund's Bundescloud includes the SIB-Box, <a href="https://www.itzbund.de/DE/itloesungen/egovernment/bundescloud/bundescloud.html">built on Nextcloud</a>, serving <a href="https://www.linux-magazin.de/news/bundesverwaltung-setzt-auf-nextcloud/">roughly 300,000 federal users</a>. <a href="https://opendesk.eu/blog/opendesk-1-0-veroeffentlicht/">openDesk</a>, the sovereign workplace built by the Zentrum für Digitale Souveränität, integrates Nextcloud alongside Collabora, Element, Open-Xchange, OpenProject, and XWiki. It is <a href="https://bmds.bund.de/themen/digitale-souveraenitaet/digitale-souveraenitaet-in-der-oeffentlichen-verwaltung/souveraener-arbeitsplatz">anchored in the German coalition agreement: by October 2028 the federal administration is to have a digitally sovereign alternative to proprietary IT workplaces</a>. The state of Baden-Württemberg has already <a href="https://www.btc-ag.com/cloud-blog/der-souveraene-arbeitsplatz-opendesk-nextcloud-workspace/">migrated close to 60,000 teacher workplaces</a>; the Bundeswehr has a framework agreement; the Robert Koch Institute and several ministries run components in production. The International Criminal Court in The Hague intends to adopt it.</p>

<p>Nextcloud Server is a PHP application: versions 33 and 34 <a href="https://github.com/nextcloud/server/wiki/Releases-and-PHP-versions">support PHP 8.2 through 8.5</a>, and the <a href="https://docs.nextcloud.com/server/stable/admin_manual/installation/php_configuration.html">administration manual</a> still opens the installation chapter with PHP configuration. That claim needs a caveat, because the picture has changed: the Files High Performance Backend is <a href="https://nextcloud.com/blog/nextcloud-faster-than-ever-introducing-files-high-performance-back-end/">written in Rust</a>, and the <a href="https://nextcloud.com/blog/a-new-data-access-architecture-for-nextcloud-introducing-the-ada-engine/">ADA engine announced in 2026</a> rewrites the file access layer in PHP, Go, and Rust. PHP carries the application and the business logic, but the I/O-bound paths increasingly do not. MediaWiki, which runs Wikipedia, is built the same way.</p>

<h2 id="the-asymmetry">The asymmetry</h2>

<p>€108 million for one national migration. 770 sites at the European Commission. 370 across the Australian government. Around 300,000 users in the German federal cloud. Tens of thousands of teacher workplaces in one German state alone.</p>

<p>And $730,534 in contributions to The PHP Foundation in 2025, from <a href="https://thephp.foundation/blog/2026/05/27/impact-and-transparency-report-2025/">536 organisations and individuals, substantially fewer than the previous year, with expenses exceeding donations by roughly $139,000</a>, a deliberate choice to maintain technical headcount. <a href="https://thephp.foundation/structure/">Thirteen contracted engineers</a> maintain the language underneath all of it.</p>

<p>I want to be careful about the conclusion here, because nobody in this story has acted badly. What the numbers show is a structural gap: the institutions most dependent on PHP have no established mechanism by which that dependency turns into maintenance funding. Nobody designed that gap; it is what happens when infrastructure is free at the point of use.</p>

<p>One institution has already built the mechanism. The Sovereign Tech Agency, funded by the German government, commissioned work that produced the <a href="https://thephp.foundation/blog/2024/10/21/web-services-tool-for-php-fpm/">PHP-FPM Web Services Tool</a> and the <a href="https://thephp.foundation/blog/2025/10/30/php-streams-evolution/">evolution of PHP's stream layer for async, security and performance</a>. Public money went into the substrate and shipped capability came back out. The mechanism exists and it works. What it lacks is the habit of being used.</p>

<h2 id="what-would-make-it-normal">What would make it normal</h2>

<p>At Drupal4Gov EU, <a href="https://www.youtube.com/watch?v=dKBdQMQf1bw&amp;list=PLNubpNMwP36QH5Y3RlbOiV4f9hjlrxCOo&amp;index=15">Tiffany Farriss, now Interim CEO of the Drupal Association, proposed a set of procurement changes</a> that translate directly to any language ecosystem. They are worth repeating here because they require no goodwill, only a change to how tenders are scored, and because the first of them fits inside a framework that European procurement already uses:</p>

<ol>
<li><strong>A sovereignty criterion with real weight:</strong> Twenty percent of tender evaluation points awarded for verified open-source contributions, as a distinct assessment criterion under the MEAT framework, the Most Economically Advantageous Tender. That puts software transparency and digital sovereignty next to the qualitative, environmental and social criteria a tender is already allowed to score.</li>
<li><strong>A maintenance line item:</strong> A share of contract value allocated to upstream maintenance of the components the delivery depends on, budgeted at the outset rather than found later. Farriss deliberately does not fix the number and would rather see one settled in public: her own estimate is 2 to 5 percent, depending on the budget and the duration of the project, and up to 10 percent on complex ones.</li>
<li><strong>A 30-day upstream rule:</strong> Non-sensitive code developed under public contract contributed back within 30 days, so that the next administration inherits it instead of paying for it again.</li>
</ol>

<p>An administration that adopts these does not need to know or care that its CMS is written in PHP. It only needs to accept that the code it depends on has maintainers, and that maintainers have budgets.</p>

<h2 id="what-we-are-asking">What we are asking</h2>

<p>If you work in or with a public administration: the software your organisation depends on almost certainly includes several PHP applications, and quite possibly the ones your sovereignty strategy is built around. The three proposals above belong in your next tender rather than in your next strategy document.</p>

<p>If you are an agency delivering these contracts: put the line item in the bid. You are in a better position than anyone to make upstream maintenance a normal cost of delivery rather than an act of charity.</p>

<p>And if you know a case we have missed, a ministry, a municipality, a health service, a statistics office running on PHP, tell us. This article covers Europe and one Australian platform because that is as far as the research went. We would like to publish those cases here, written by the people who built them.</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[Roman Pronskiy Leaves The PHP Foundation Board and Brent Roose Joins]]></title>
            <link href="https://thephp.foundation/blog/2026/09/01/welcome-brent-roose/"/>
            <updated>2026-09-01T00:00:00+00:00</updated>
            <id>https://thephp.foundation/blog/2026/09/01/welcome-brent-roose/</id>
            <content type="html"><![CDATA[<p><img src="/assets/post-images/2026/brent-roose/brent-roose.jpg" width="300" alt="headshot of brent roose" class="mb-4 sm:mr-4 sm:float-left"/>The PHP Foundation is excited to announce the addition of <a href="https://stitcher.io/">Brent Roose</a> from JetBrains to the Foundation's Board of Directors. Brent fills the JetBrains Platinum Sponsor seat and was unanimously voted to join by the existing members.</p>

<p>Brent is a developer advocate for PHP at JetBrains, but he is also a writer, content creator, event organizer, community leader, and open source contributor. He is a well-recognized voice on <a href="https://www.youtube.com/@phpannotated">PHP Annotated</a>, maintains an active blog at <a href="https://stitcher.io/">stitcher.io</a>, and is the creator of the <a href="https://github.com/tempestphp/tempest-framework">Tempest</a> framework for PHP, one of his bigger open source projects.</p>

<blockquote>
  <p><em>PHP has been my passion for over 15 years, and I'm happy to contribute to its success in any way I can. I'm looking forward to joining the Foundation board and see what the future holds for this amazing language and community. --Brent Roose</em></p>
</blockquote>

<p>As Roman Pronskiy's term comes to an end, Brent will be replacing Roman as the JetBrains representative on the Board. As one of the founding members and first Executive Director of The PHP Foundation, Roman's impact is undeniable. The PHP Foundation would not be where it is today without his influence, his effort, and his guidance. We are incredibly grateful for his dedication and commitment to the Foundation's mission and the sustainability of the PHP language. Thank you for everything, Roman! ❤️🐘</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[Join Us for The PHP Foundation Community Hour]]></title>
            <link href="https://thephp.foundation/blog/2026/08/31/join-us-for-the-php-foundation-community-hour/"/>
            <updated>2026-08-31T00:00:00+00:00</updated>
            <id>https://thephp.foundation/blog/2026/08/31/join-us-for-the-php-foundation-community-hour/</id>
            <content type="html"><![CDATA[<p>Here at The PHP Foundation, we are continuously looking for ways in which we can increase our connections with the PHP community, especially when the goal is to improve the sustainability of the PHP language. Increasing the contributor pool ties in directly with sustainability, so encouraging contributions back to the PHP ecosystem is something we want to foster and support.</p>

<p><strong>As part of this effort, we are excited to be launching a monthly one-hour interactive podcast in partnership with the folks at <a href="https://www.phparch.com/">PHP Architect</a>.</strong> This podcast will be called <strong>The PHP Foundation Community Hour</strong> and will feature various Foundation staff, contractors, and friends who will be sharing tips and insight into different contribution paths. These will be hosted on the second Thursday of every month on the <a href="https://www.phparch.com/php-foundation-community-hour-podcast/">PHP Architect podcast platform</a>.</p>

<p>The PHP Foundation Community Hour is meant to be a casual interactive session and we welcome your questions before and during the event. If you want to submit a question beforehand to our guests, you can use <a href="https://forms.gle/aeAq34EXyhs3wZBQ7">this form</a> to do so. Please keep in mind that while we may choose to answer select questions that fall outside our topic, we are mostly focused on helping people understand how they can contribute to PHP.</p>

<p>Our first episode is coming in a few weeks! Here are the details:</p>

<ul>
<li>First Episode Time/Date: September 10, 2026 at 12:30 pm Eastern / 16:30 UTC</li>
<li>Topic: Getting Started with Contributing to PHP</li>
<li>Guest: Matt Stauffer</li>
<li>Host: Elizabeth Barron</li>
<li><a href="https://calendar.google.com/calendar/ical/c_ce0269971d31f57bb6a079df26f0e97aae764cf6d93aab43c509b20002339275%40group.calendar.google.com/public/basic.ics">Subscribe to the calendar through an .ics link</a> to see upcoming guests</li>
<li><a href="https://www.phparch.com/php-foundation-community-hour-podcast/">Subscribe on Spotify, YouTube, and other platforms</a></li>
</ul>

<p>We want to extend a heap of gratitude to the folks at <a href="https://www.phparch.com/">PHP Architect</a> for providing the infrastructure, platform, and technical support that enables us to host these events.</p>

<p>Hope you can join us on September 10!</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[So You Received a Security Report. Now What?]]></title>
            <link href="https://thephp.foundation/blog/2026/08/19/so-you-received-a-security-report-now-what/"/>
            <updated>2026-08-19T00:00:00+00:00</updated>
            <id>https://thephp.foundation/blog/2026/08/19/so-you-received-a-security-report-now-what/</id>
            <content type="html"><![CDATA[<p><strong>A guide for PHP project maintainers, from the PHP Foundation Ecosystem Security Team</strong></p>

<blockquote>
  <p>You maintain a PHP project. Someone (maybe Volker from the PHP Foundation, maybe an
  independent researcher) has just told you that your project may have a security
  vulnerability. You might be feeling overwhelmed, or unsure whether you can trust the
  report, or simply unsure what the correct next step is.</p>
  
  <p>Take a breath. <strong>Nothing bad has happened.</strong> A report is not a breach. It is a
  head start: someone is telling you privately about a potential problem. You have
  time to validate it, assess it, and you get to decide what to do next. This guide
  walks you through the whole process, and it ends with concrete steps to make your
  project more resilient for the next time.</p>
  
  <p>And at any point where you get stuck: <strong>you are not alone.</strong> You can always ask the
  Ecosystem Security Team for help. Contact details are at the <a href="#10.-getting-help">end of this
  guide</a>.</p>
</blockquote>

<hr />

<h2 id="how-to-use-this-guide">How to use this guide</h2>

<ul>
<li><strong>Do not read it front to back.</strong> Jump to the stage you are at. Each section starts
with a short "You are here if…" signpost.</li>
<li><strong>Expect to come back over several days.</strong> Handling a security report properly
usually takes more than one sitting, and that is fine.</li>
<li><strong>If you only have five minutes right now,</strong> read the <a href="#cheatsheet">Cheatsheet</a> and
section <a href="#1.-do-not-panic-and-do-not-go-public">1</a>.</li>
</ul>

<p>A word on your authority before we start: <strong>you are the maintainer.</strong> You decide what
is in scope, what the timeline is, and whether a report is valid. Handling a report
well does not mean dropping everything or working weekends. It means following a small
number of steps in the right order, at a pace you can sustain. You do not owe anyone
heroics; see <a href="https://mikemcquaid.com/open-source-maintainers-owe-you-nothing/">Open Source Maintainers Owe You
Nothing</a>.</p>

<hr />

<h2 id="cheatsheet">Cheatsheet</h2>

<p>The whole process on one screen. Details in the numbered sections below.</p>

<ol>
<li><strong>Don't panic, don't go public.</strong> Keep the vulnerability private until a fix is
released. → <a href="#1.-do-not-panic-and-do-not-go-public">§1</a></li>
<li><strong>Acknowledge the report</strong> within a few days, even before you have assessed it.
→ <a href="#2.-acknowledge-the-report">§2</a></li>
<li><strong>Triage:</strong> understand the claim, then decide: valid, invalid, or out of scope.
→ <a href="#3.-triage-the-report">§3</a></li>
<li><strong>Reproduce safely.</strong> Never run proof-of-concept code on your own machine; use an
isolated environment. → <a href="#4.-handle-proof-of-concept-code-safely">§4</a></li>
<li><strong>Fix privately.</strong> Use a temporary private fork; do not push to any public branch.
→ <a href="#5.-prepare-the-fix-privately">§5</a></li>
<li><strong>Write the advisory.</strong> For Composer packages, three fields decide whether the
tooling works: set the ecosystem to <strong>Composer</strong>, use the exact Packagist package
name, and give precise affected-version ranges. Composer will actively <strong>block</strong>
installation of the versions you list.
→ <a href="#6.-write-the-github-security-advisory">§6</a></li>
<li><strong>Publish in the right order:</strong> merge → tag &amp; release → publish the advisory →
submit it to FriendsOfPHP → announce.
→ <a href="#7.-coordinate-the-release-and-publication">§7</a></li>
<li><strong>Wrap up:</strong> credit the reporter, check older branches, do a short retrospective.
→ <a href="#8.-wrap-up">§8</a></li>
<li><strong>Improve your posture</strong> so the next report is easier: SECURITY.md, private
vulnerability reporting, 2FA, hardened CI. → <a href="#9.-improving-your-security-posture-for-the-long-term">§9</a></li>
<li><strong>Ask for help</strong> whenever you are unsure. → <a href="#10.-getting-help">§10</a></li>
</ol>

<hr />

<h2 id="1.-do-not-panic-and-do-not-go-public">1. Do not panic and do not go public</h2>

<p><em>You are here if: a report just landed and your pulse went up.</em></p>

<p>The single most important principle is <strong>coordinated disclosure</strong>: the details of a
vulnerability stay private until a fixed version exists and users can protect
themselves. The moment the details are public, every attacker in the world has them,
and your users do not yet have a fix. So until you publish:</p>

<ul>
<li><strong>Do not</strong> open a public issue about it, reference it in a public pull request, or
mention it in a public commit message.</li>
<li><strong>Do not</strong> push a fix to <code>main</code> or any public branch. A commit titled "fix SQL
injection in login handler" <em>is</em> the disclosure.</li>
<li><strong>Do not</strong> post the details on social media, a blog, or a mailing list, and be
careful with vague teasers, which invite people to go looking. Announcing an
upcoming security release is a legitimate practice that many projects follow, so
that users can plan to update quickly; if you do it, keep the announcement to the
date and the fact that a security release is coming, never the component, the
symptom, or the versions involved.</li>
<li><strong>Do not</strong> go silent on the reporter either. Silence is how well-meaning reporters
become frustrated reporters who eventually publish on their own.</li>
</ul>

<p>Also worth internalizing early: <strong>a report is a claim, not a verdict.</strong> It may be a
serious finding, a minor issue, a duplicate, a bug without security impact, or simply
wrong. Part of your job in the next steps is to find out which, and <em>you</em> make that
call, ideally in dialogue with the reporter.</p>

<p>If the report came from the PHP Foundation Ecosystem Security Team, it has already
been through triage and usually comes with a reproducer. That raises the odds it is
real, but it does not take the decision away from you.</p>

<h2 id="2.-acknowledge-the-report">2. Acknowledge the report</h2>

<p><em>You are here if: you have read the report once and have not replied yet.</em></p>

<p>Reply quickly, even if you have nothing substantial to say yet. A short message buys
you time and goodwill:</p>

<blockquote>
  <p>Thanks for the report. I've received it and will look into it as soon as I can.
  I maintain this project in my spare time. I'll get back to you here.</p>
</blockquote>

<p>That is genuinely all it takes. If you already know you can keep a commitment, adding
a timeframe ("please allow up to two weeks for a first assessment") is a courtesy to
the reporter, but only promise what you can meet: "two weeks" kept is better than
"tomorrow" broken. If the report arrived by email but your
repository has <a href="https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability">GitHub Private Vulnerability
Reporting</a>
enabled (see <a href="#9.-improving-your-security-posture-for-the-long-term">§9</a>), this is a
good moment to move the conversation there: it keeps the discussion and the patch in
one private place. Do not expect it to do your release planning, though — an advisory
has no field for an embargo or a disclosure date, so the timeline is something you and
the reporter agree on in the conversation and then keep to.</p>

<h2 id="3.-triage-the-report">3. Triage the report</h2>

<p><em>You are here if: you have acknowledged the report and now need to decide what it is.</em></p>

<p>Read the report carefully and try to answer four questions:</p>

<ol>
<li><strong>What is the claimed weakness?</strong> (e.g. SQL injection, path traversal, insecure
deserialization, often given as a <a href="https://cwe.mitre.org/">CWE</a> identifier)</li>
<li><strong>Who can trigger it, and from where?</strong> Does it require an authenticated admin, or
can any anonymous user on the internet trigger it? Does it require unusual
configuration?</li>
<li><strong>What can an attacker actually achieve?</strong> Reading data, modifying data, executing
code, denial of service?</li>
<li><strong>Which versions are affected?</strong> Including older major and minor versions that
people still use.</li>
</ol>

<p>The answers determine everything downstream: severity, urgency, and what the fix and
advisory should say. Three notes from practice:</p>

<ul>
<li><strong>Ask questions.</strong> A good reporter would rather answer three clarifying questions
than watch you guess. If the threat model is unclear ("is this exploitable if the
attacker controls that config value? In my project, they never do"), say so. That
discussion is the most valuable part of triage.</li>
<li><strong>"Works as designed" is a legitimate answer.</strong> If exploiting the issue requires the
attacker to already have capabilities that your documented security model says are
trusted, it may not be a vulnerability in your project. Explain your reasoning to
the reporter; if they disagree, the Ecosystem Security Team can act as a neutral
second opinion.</li>
<li><strong>A real bug without security impact is still worth fixing</strong>, just through your
normal, public process, without an advisory.</li>
</ul>

<p>If the volume or quality of reports is a problem in itself (for example, a flood of
low-effort AI-generated reports), that is exactly one of the things the Ecosystem
Security Team exists to help with. Forward them; do not let them eat your motivation.</p>

<h2 id="4.-handle-proof-of-concept-code-safely">4. Handle proof-of-concept code safely</h2>

<p><em>You are here if: the report includes a script, a payload, a crafted file, or
step-by-step exploitation instructions.</em></p>

<p>This section exists because it is the mistake with the worst possible failure mode.</p>

<p><strong>Never run proof-of-concept code directly on your own machine.</strong> Not "just this
once", not because the reporter seems trustworthy, not because you skimmed the code
and it looked fine. Your development machine holds your SSH keys, your GPG keys, your
Packagist and GitHub credentials, your password manager, and, if you use one, your
authenticated AI coding agent. A malicious or merely careless PoC that runs with your
user account can compromise all of it. For a maintainer, that is not just a personal
problem: <strong>your credentials are a supply-chain attack on everyone who installs your
package.</strong></p>

<p>And remember what a PoC <em>is</em>: a program written by a stranger, designed to break
software. Treat it with exactly the suspicion that description deserves. Even an
honest reporter's PoC may delete files, open network connections, or hammer your CPU
as a side effect of demonstrating the bug.</p>

<p>Instead, reproduce in an <strong>isolated, disposable environment</strong>. The best one is the one
you will actually use, so start at the top of this list and only move down if the
issue demands it:</p>

<ul>
<li><strong>A microVM sandbox</strong> is the sweet spot: roughly as convenient as a container, but
running its own kernel instead of sharing the host's, so the boundary is enforced by
hardware. <a href="https://docs.docker.com/ai/sandboxes/">Docker Sandboxes</a> (<code>sbx</code>) gives
each sandbox its own filesystem, network stack, and Docker daemon, with network
access denied by default. Benjamin Eberlei describes <a href="https://www.beberlei.de/post/sbx-sandboxed-claude-complete-with-php-and-tools">a ready-made sbx setup with
PHP, Composer, and the usual
extensions</a>
that you can lift straight into this workflow.</li>
<li><strong>A container</strong> (Docker/Podman) is convenient for typical PHP-level issues and fine
for most web-application-class vulnerabilities. How much isolation you get depends
on where you run it: on Linux, containers share the host kernel, so anything that
smells like memory corruption, native extensions, or kernel interaction deserves a
stronger boundary. On macOS and Windows, Docker Desktop and OrbStack already run
your containers inside a lightweight Linux VM, so a kernel boundary sits between the
container and your actual machine.</li>
<li><strong>A well-secured virtual machine</strong> is the belt-and-braces option: a fresh VM with a
current OS, no credentials or personal data inside, no shared folders into your host,
clipboard sharing disabled, and a snapshot taken <em>before</em> you run anything so you can
roll back afterwards. If the PoC does not need internet access, disable networking
entirely, or restrict it to host-only.</li>
<li><strong>A cloud throwaway</strong> (a short-lived VM at any provider, destroyed afterwards) works
too, as long as no credentials of yours live on it.</li>
</ul>

<p>Inside the isolated environment, the workflow is simple: check out the affected
version of your project, install dependencies, run the PoC, observe. Read the PoC
before running it. Not as a substitute for isolation, but because understanding
<em>how</em> it triggers the bug is exactly the insight you need for the fix and for the
regression test. In fact, this is the natural moment to turn the reproducer into a
failing test (<a href="#5.-prepare-the-fix-privately">§5</a>). Many maintainers treat "I have a
test that fails" as the point at which they accept a report, on the grounds that you
cannot accept what you cannot reproduce.</p>

<p>Two closing rules for this section:</p>

<ul>
<li><strong>Crafted input files are code.</strong> A "harmless" <code>.phar</code>, image, XML document, or
serialized payload attached to a report is an exploit delivery vehicle by
definition. The same isolation rules apply to opening or parsing them.</li>
<li><strong>If you cannot reproduce safely, ask for help</strong> instead of taking the shortcut.
Building reproducers in isolated environments is one of the Ecosystem Security
Team's core services.</li>
</ul>

<h2 id="5.-prepare-the-fix-privately">5. Prepare the fix privately</h2>

<p><em>You are here if: the issue is confirmed and you are ready to write code.</em></p>

<p>GitHub Security Advisories give you a <strong>temporary private fork</strong> for exactly this
purpose. On the advisory page, click <em>"Start a temporary private fork"</em>. Then:</p>

<ol>
<li>Do all of the work in the private fork and open the pull request <strong>there</strong>, never
against your public repository.</li>
<li><strong>Write the regression test first.</strong> A test that fails on the vulnerable code is
the proof that you have really understood and reproduced the issue, and once the
fix is in you can no longer watch it fail. If you built a reproducer during triage
(<a href="#4.-handle-proof-of-concept-code-safely">§4</a>), you already have most of it;
distill it into a safe, minimal test case that demonstrates the <em>condition</em> rather
than shipping a working exploit. This is the part of the work that keeps paying
off: the bug can never quietly come back.</li>
<li><strong>Then write the fix</strong>, and keep commit messages neutral while working; the
advisory will tell the full story later. (Referencing the GHSA ID in the final
commit is fine, since it only resolves to something public after publication.)</li>
<li><strong>Sweep for the same class of bug</strong> before you go any further. Publishing an
advisory puts a spotlight on that weakness class, for human readers and for the
people pointing LLMs at your code, so you want to be reasonably confident that the
same mistake is not sitting three files over, waiting to be found the day after
you publish.</li>
<li>Invite the reporter as a collaborator on the advisory and let them verify the fix.
They already have a working reproducer, so it costs them little. How much weight
their confirmation carries is your judgement call: a researcher who handed you a
precise reproducer is the best-qualified person to confirm the hole is closed,
while a report generated in bulk by a tool is not.</li>
<li>Decide <strong>which versions</strong> get the fix. If you still support older major versions,
users on those versions deserve a patched release too, or an explicit statement in
the advisory that they must upgrade. Severity, the age of the older version, and
the effort a backport would take should all feed into that decision.</li>
</ol>

<p>Gotchas that bite first-timers:</p>

<ul>
<li>CI does not run in temporary private forks. Run your test suite locally (in a safe
environment) before merging.</li>
<li>Don't <code>git push --no-verify</code> out of habit. Hooks that scan for secrets or enforce
checks exist for days exactly like this one.</li>
<li>The temporary private fork <strong>does not outlive the advisory</strong>: depending on where you
are in the process, publishing removes it, or GitHub asks you to delete it before it
lets you publish. Either way, make sure everything you need (the commits, the
discussion outcomes) has landed somewhere permanent first.</li>
<li><strong>Do not fix silently.</strong> A patch released without an advisory leaves every
downstream user blind: <code>composer audit</code> won't warn them, Dependabot won't open a PR,
and most people do not update their dependencies often, so they stay vulnerable
until they happen to. The advisory is not an admission of failure; it is the
mechanism by which your fix actually reaches people.</li>
</ul>

<h2 id="6.-write-the-github-security-advisory">6. Write the GitHub Security Advisory</h2>

<p><em>You are here if: the fix exists and you are filling in the advisory form.</em></p>

<p>You create the advisory in your repository under <strong>Security → Advisories → New
draft security advisory</strong>. The click-by-click walkthrough of that form (every field,
the CVSS calculator, adding credits, adding multiple affected products) is GitHub's
<a href="https://docs.github.com/en/code-security/how-tos/report-and-fix-vulnerabilities/fix-reported-vulnerabilities/create-repository-advisory">Creating a repository security
advisory</a>.
(If the report arrived via private vulnerability reporting, the draft advisory
already exists; you edit that one rather than creating a new one.) This section
focuses on the part the walkthrough cannot do for you: what to put <em>into</em> the fields.</p>

<p>The advisory is a machine-readable document as much as a human-readable one. Tools
across the ecosystem, among them the <a href="https://github.com/advisories">GitHub Advisory
Database</a>, <a href="https://osv.dev/">OSV.dev</a>, Dependabot,
Packagist, and <code>composer audit</code>, consume it to warn your users automatically. Getting
the metadata right is what makes that machinery work.</p>

<p><strong>For PHP packages installable via Composer, the crucial details are:</strong></p>

<ul>
<li><strong>Ecosystem: select <code>Composer</code>.</strong> Not "Other", not "GitHub Actions", not left empty.
Only advisories filed under the Composer ecosystem are matched against
<code>composer.json</code>/<code>composer.lock</code> files, which is what makes <code>composer audit</code> and
Dependabot alerts fire for your users.</li>
<li><strong>Package name: the exact Packagist name</strong>, in <code>vendor/package</code> form. For example
<code>phpunit/phpunit</code>, not <code>PHPUnit</code> and not the GitHub repository slug if it differs.
A typo here silently breaks the matching. The check takes five seconds: append what
you typed to <code>https://packagist.org/packages/</code> and it must land on your package,
the way <a href="https://packagist.org/packages/phpunit/phpunit">packagist.org/packages/phpunit/phpunit</a>
does.</li>
<li><strong>Affected version ranges: precise and Composer-flavored</strong>, e.g.
<code>&gt;= 10.0.0, &lt; 10.5.17</code>, and one <em>Affected product</em> entry per affected release
series if you patched several (a single field cannot hold multiple ranges). The
exact syntax has non-obvious rules (supported operators, spacing, how suffixes
like <code>-beta1</code> are ordered), documented in GitHub's <a href="https://docs.github.com/en/code-security/tutorials/fix-reported-vulnerabilities/write-security-advisories">Best practices for writing
repository security advisories</a>,
which is worth five minutes before you fill in this field. It is what version
constraint resolution runs against; "all versions before X" prose in the
description does not replace it. And getting these ranges right matters more than
it used to, because Composer no longer merely <em>reports</em> your advisory. It
<em>enforces</em> it. Read on.</li>
<li><strong>Patched version: the version you are about to release</strong>, the one you want users to
move to. It is what the tooling offers people as the way out, so it belongs in the
form even though you have not tagged it yet at the time you draft the advisory.</li>
</ul>

<h3 id="composer-blocks-the-versions-your-advisory-lists">Composer blocks the versions your advisory lists</h3>

<p>Since <a href="https://phpunit.expert/articles/the-bouncer-in-the-dependency-resolver.html">Composer 2.9</a>,
security advisory enforcement lives in the dependency resolver itself, on by default
for every PHP project. When Composer resolves dependencies (<code>composer update</code>,
<code>require</code>, <code>remove</code>), versions covered by a published advisory are removed from the
candidate pool before the solver runs. As far as the resolver is concerned, they
simply do not exist. <a href="https://blog.packagist.com/composer-2-10-release/">Composer
2.10</a> generalized this into a
unified <em>dependency policy</em> framework that also covers packages flagged as malware
(those are blocked even during <code>composer install</code> from an existing lock file) and
abandoned packages. This machinery replaced the older <code>roave/security-advisories</code>
conflict-package approach. For the full mechanics (pool filtering, <code>config.policy</code>
configuration, ignore rules, escape hatches), see <a href="https://phpunit.expert/articles/the-bouncer-in-the-dependency-resolver.html">The Bouncer in the Dependency
Resolver</a>
and Packagist's <a href="https://blog.packagist.com/an-update-on-composer-packagist-supply-chain-security/">supply chain security
update</a>.</p>

<p>For you as the advisory author, this has three practical consequences:</p>

<ol>
<li><strong>Your advisory directly protects users, even those who never read it.</strong> This is
the strongest argument against fixing silently (<a href="#5.-prepare-the-fix-privately">§5</a>):
an advisory does not just inform, it actively keeps the vulnerable versions out of
<code>vendor/</code> directories across the ecosystem.</li>
<li><strong>Overbroad version ranges cause real breakage.</strong> Once your advisory data reaches
Composer (see step 4 in <a href="#7.-coordinate-the-release-and-publication">§7</a> for what
governs how long that takes), every version it covers becomes uninstallable by
default, everywhere, for everyone. If the ranges
sweep in versions that were never vulnerable, users of those versions face failing
builds, and their bug reports will land in <em>your</em> inbox. This is not hypothetical:
for a PHPUnit advisory in April 2026, GitHub silently rewrote the carefully
specified affected versions (<code>12.5.21</code> and <code>13.1.5</code>) into broad ranges, which made
every older PHPUnit version uninstallable overnight, including all of PHPUnit 11,
which was never affected. The full timeline is documented in <a href="https://phpunit.expert/articles/the-bouncer-in-the-dependency-resolver.html#a-real-world-example">The Bouncer in the
Dependency Resolver</a>.</li>
<li><strong>Know the FriendsOfPHP route, in both directions.</strong> Packagist aggregates
advisories from the GitHub Advisory Database <em>and</em> from
<a href="https://github.com/FriendsOfPHP/security-advisories"><code>FriendsOfPHP/security-advisories</code></a>,
and the FriendsOfPHP data takes precedence. That makes a pull request there both
the fastest way to get your advisory in front of Composer in the first place
(<a href="#7.-coordinate-the-release-and-publication">§7</a>) and the fastest way to fix what
Composer enforces if the published affected-version data turns out to be wrong,
whether through your own mistake or an edit on GitHub's side. For a correction,
send a PR to the <a href="https://github.com/github/advisory-database">GitHub Advisory
Database</a> as well, so that the two
sources do not disagree.</li>
</ol>

<p>The flip side is worth telling your <em>users</em> about, too (in your announcement or your
documentation): with a current Composer, they are protected by default, and
<code>composer audit</code> in CI tells them when an already-locked version has since gained an
advisory.</p>

<p>The rest of the form:</p>

<ul>
<li><strong>Title:</strong> one line, specific, no drama. "SQL injection in report export via
<code>sort</code> parameter" beats "Critical security issue".</li>
<li><strong>Description:</strong> enough for a user to understand <em>whether they are affected</em> and
<em>what to do</em> (upgrade to which version; workaround if one exists). Aim for the
middle ground: too much detail hands attackers a ready-made exploit, too little
starves the tools and the humans reading it. You do not need to include the PoC.</li>
<li><strong>CWE:</strong> pick the closest weakness class. The reporter's suggestion is usually right.</li>
<li><strong>CVSS / severity:</strong> score honestly. If required conditions lower the practical
severity (authentication needed, non-default configuration), reflect that in the
vector rather than in an argument in the description. Keep this in proportion,
though: the score is far less important than the advisory itself. If CVSS makes your
eyes glaze over, an LLM will produce a reasonable first vector for you, and the
Ecosystem Security Team will happily check it; scoring help is a two-minute favor.
Do not let the number hold up the publication.</li>
<li><strong>CVE:</strong> you can request a CVE ID through GitHub from the advisory (GitHub is a CNA
and this is the normal path for Composer packages). Be clear about what it buys you.
A CVE ID is a stable identifier for people outside your immediate ecosystem: Linux
distributions shipping your code, corporate vulnerability management, other CNAs
coordinating a shared issue. What actually protects the average user of your package
is the GHSA, which is what Composer, <code>composer audit</code>, and Dependabot act on. CVE
requests through GitHub currently take weeks to come back, so treat the ID as
something that arrives when it arrives: request it once you have <em>accepted</em> the
report, and never delay the fix, the release, or the advisory while waiting for it.
If a coordinating party such as a CNA has already reserved a CVE for this issue, use
<em>"I have an existing CVE ID"</em> instead of requesting a second one.</li>
<li><strong>Credit:</strong> add the reporter (and anyone who helped) in the credits section. It
costs you nothing and it is a large part of what makes responsible reporting worth
a researcher's while.</li>
</ul>

<h2 id="7.-coordinate-the-release-and-publication">7. Coordinate the release and publication</h2>

<p><em>You are here if: fix ready, advisory drafted, everyone in the private thread agrees.</em></p>

<p>Order matters. On the day you have chosen for your release, follow these steps:</p>

<ol>
<li><strong>Merge</strong> the fix from the private fork.</li>
<li><strong>Tag and release</strong> the fixed version(s), and confirm the release actually shows
up on Packagist before continuing.</li>
<li><strong>Publish the advisory.</strong> From this moment the vulnerability is public, which is
fine, because the fix already is too.</li>
<li><strong>Send a pull request to
<a href="https://github.com/FriendsOfPHP/security-advisories"><code>FriendsOfPHP/security-advisories</code></a>.</strong>
Do not skip this on the grounds that you have already filed a GHSA. Composer does
not look at the advisories published on individual repositories; it goes through
Packagist, which consumes the <em>reviewed</em> GitHub Advisory Database, and GitHub's
review step currently lags behind repository-level publication by days or even
weeks. Until your advisory clears that queue, <code>composer audit</code> stays quiet and the
dependency resolver keeps handing out the vulnerable versions. The FriendsOfPHP
pull request is what closes that gap promptly. And if your project is not hosted
on GitHub at all, this is not an optimization: it is the only route into the
ecosystem's tooling.</li>
<li><strong>Announce</strong> through your normal channels (release notes, Mastodon, Discord, blog),
linking to the advisory. Keep it factual: what the issue is, who is affected, which
version to upgrade to.</li>
</ol>

<p>The gap between step 2 and step 3 should be minutes to hours, not days: a public fix
without an advisory is a window in which attackers can diff your release while your
users have no warning to upgrade.</p>

<p>Two coordination notes:</p>

<ul>
<li>If the report came through a coordinator such as a CNA, agree on the publication
date with them in advance so CVE publication and any wider announcement can happen
in step. The Ecosystem Security Team does not normally ask you to coordinate your
release with us; if a particular case ever calls for it, we will say so explicitly.
We do not want to stand between a report and a fix.</li>
<li>If details leak early (someone tweets, a public issue appears, you spot the bug
being discussed), the embargo is effectively over. Publish what you have as soon as
possible, even if the situation is not as tidy as you wanted.</li>
</ul>

<h2 id="8.-wrap-up">8. Wrap up</h2>

<p><em>You are here if: the advisory is published and the adrenaline is fading.</em></p>

<ul>
<li><strong>Verify the pipeline worked:</strong> the advisory appears in the GitHub Advisory
Database, <code>composer audit</code> flags the vulnerable version in a test project, and
Dependabot alerts fire where expected. Do not expect all of this on publication day:
the advisory on your repository has to clear GitHub's review queue before Composer
sees it, which is exactly what the FriendsOfPHP pull request
(<a href="#7.-coordinate-the-release-and-publication">§7</a>) is there to short-circuit. If it
still has not arrived after a few days, check the ecosystem and package-name fields
first (<a href="#6.-write-the-github-security-advisory">§6</a>); those are the usual suspects
when matching silently fails.</li>
<li><strong>Verify the blocking is not too eager:</strong> in a scratch project, check that the
<em>fixed</em> version and unaffected release series still install and update cleanly.
Compare the affected-version ranges shown in the <a href="https://github.com/advisories">GitHub Advisory
Database</a> against what you wrote (they have been
known to change during publication), and keep an eye on your issue tracker for
"cannot install version X" reports in the first days after publishing. The
correction path is described in <a href="#composer-blocks-the-versions-your-advisory-lists">§6</a>.</li>
<li><strong>Thank the reporter</strong> once more, in public if they are comfortable with that.</li>
<li><strong>Check your other supported branches</strong> one final time; it is easy to patch the
current major and forget the LTS branch.</li>
<li><strong>Hold a fifteen-minute retrospective with yourself:</strong> How did this bug get in?
Would a static analyzer, a stricter type, or a test convention have caught it? The
sweep for siblings of this bug should already be behind you at this point
(<a href="#5.-prepare-the-fix-privately">§5</a>); what you are looking for here is the one
structural change that stops the whole class from recurring. One such improvement
per incident compounds quickly.</li>
</ul>

<h2 id="9.-improving-your-security-posture-for-the-long-term">9. Improving your security posture for the long term</h2>

<p><em>You are here if: the storm has passed and you want the next one to be smaller. This
section is also the right starting point if no report has arrived yet and you simply
want to prepare.</em></p>

<p>You do not need to do all of this in one weekend. The list is roughly ordered by
value-for-effort; even the first three items put you ahead of most projects.</p>

<p><strong>Make it easy to report to you</strong></p>

<ol>
<li><strong>Enable GitHub Private Vulnerability Reporting</strong> (repository → Settings →
Advanced Security → Private vulnerability reporting → Enable). Without it,
reporters must choose between emailing you cold and opening a public issue, and
some will choose the public issue.</li>
<li><strong>Add a <code>SECURITY.md</code></strong> stating how to report (ideally: "use private vulnerability
reporting on this repository"), which versions you support with security fixes,
and roughly what response time to expect. Three honest sentences beat a page of
boilerplate.</li>
<li><strong>Watch your own security tab.</strong> Two different things land there and both are worth
a notification: <em>security advisories</em>, which is where a report about <strong>your</strong> code
arrives, and <em>Dependabot alerts</em>, which tell you that a dependency <strong>you</strong> use has
a published vulnerability. Make sure you are notified about both: watch the
repository with security alerts enabled, and check the notification settings on
your GitHub account, so that neither sits unseen for months.</li>
</ol>

<p><strong>Protect your accounts and releases</strong></p>

<ol start="4">
<li><strong>Strong 2FA/MFA everywhere that can publish:</strong> GitHub, Packagist, your email
account (which can reset the other two). Prefer passkeys or hardware keys over SMS.
Audit who else has publish rights and remove stale access. On Packagist this is
becoming a visible property of your packages, not just private hygiene:
<a href="https://blog.packagist.com/an-update-on-composer-packagist-supply-chain-security/">Packagist.org will surface maintainer MFA status publicly</a>
in its transparency log and on profiles, with mandatory MFA as the stated
long-term direction. Most of the recent supply-chain attacks in the PHP ecosystem
began with a taken-over maintainer account.</li>
<li><strong>Protect your release path:</strong> branch protection on <code>main</code>, tag protection for
release tags, and no long-lived personal access tokens with broad scopes lying
around in CI secrets or on disk.</li>
<li><strong>Never re-tag a released version.</strong> If a release has a problem, ship a new
version; do not overwrite the tag. Mirrors, scanners, and lock files already hold
copies of the original, and two variants of "the same" version circulating is a
mess your users cannot untangle. Packagist.org now
<a href="https://blog.packagist.com/an-update-on-composer-packagist-supply-chain-security/">enforces this</a>:
stable versions are immutable, and upstream re-tagging is detected and rejected,
not least because silently rewritten tags were the core move in recent attacks on
compromised packages.</li>
</ol>

<p><strong>Reduce your attack surface</strong></p>

<ol start="7">
<li><strong>Delete what does not need to exist.</strong> Every branch in your repository is a door:
a target for pull requests that carry along modified workflow files, build
scripts, or configuration the pipeline will happily execute. This class of attack
is known as <a href="https://owasp.org/www-project-top-10-ci-cd-security-risks/CICD-SEC-04-Poisoned-Pipeline-Execution">Poisoned Pipeline Execution</a>
(OWASP CICD-SEC-4). A branch that does not exist cannot receive a poisoned pull
request, and no door protects better than the one that was never built.
Review your branches and remove stale experiments, leftovers from old sprints,
and "we might still need this" remnants. The same goes for unused workflows,
third-party actions, and permissions nobody questions anymore. See <a href="https://phpunit.expert/articles/the-attack-surface-begins-in-the-repository.html">The attack
surface begins in the
repository</a>
for the full argument, including real-world PPE incidents from SolarWinds to
PyTorch.</li>
</ol>

<p><strong>Harden your automation</strong></p>

<ol start="8">
<li><p><strong>Treat your workflow files as security-relevant code.</strong> They run with
credentials, network access, and write permission to your repository. The five
weakness classes that show up almost everywhere, PHPUnit's own workflows included
(52 findings before hardening, zero after):</p>

<ul>
<li><strong>Template injection:</strong> never interpolate
<code>${{ ... }}</code> expressions (branch names, PR titles,
and other attacker-controllable values) directly into shell scripts; pass them
through <code>env:</code> variables instead. This is the GitHub Actions equivalent of SQL
injection.</li>
<li><strong>Credential persistence:</strong> set <code>persist-credentials: false</code> on
<code>actions/checkout</code>, so the workflow token does not sit in <code>.git/config</code> for
every later step (or exfiltrated artifact) to read.</li>
<li><strong>Unpinned actions:</strong> pin every action to a full commit SHA with the tag as a
comment. A floating tag like <code>@v4</code> can be repointed at malicious code by anyone
who compromises the action, which is exactly how the <code>tj-actions/changed-files</code>
attack reached 23,000 repositories. Let Renovate or Dependabot keep the SHAs
current.</li>
<li><strong>Overly broad permissions:</strong> set <code>permissions: {}</code> at the workflow level and
grant minimal scopes per job, with a comment explaining each grant. Set the
baseline for the whole repository, too: under Settings → Actions → General →
Workflow permissions, choose read-only, so that a workflow which forgets to
declare <code>permissions:</code> does not start out with write access to your repository.</li>
<li><strong>Unnecessary third-party actions:</strong> if the runner's built-in tooling (e.g. the
<code>gh</code> CLI) can do the job, drop the wrapper action. Every action is more code
running next to your secrets, and one more upstream that can be compromised to
reach you.</li>
</ul>

<p>You do not need to memorize this list: run <a href="https://docs.zizmor.sh/">zizmor</a>
against <code>.github/workflows</code>, fix what it finds, and add it to CI so regressions
are caught immediately. A full walkthrough, taking each weakness in turn with an
example exploit and its fix, is in <a href="https://phpunit.expert/articles/hardening-github-actions-workflows.html">Hardening GitHub Actions
workflows</a>.
Be especially careful with the <code>pull_request_target</code> and <code>workflow_run</code> triggers,
which run with the base repository's permissions against fork contributions.</p></li>
<li><strong>Run <code>composer audit</code> in CI</strong> so you learn about vulnerable dependencies from
your pipeline rather than from your users, and know that with a current Composer,
your users' resolvers block advisory-affected and malware-flagged versions of
<em>your</em> dependencies too (<a href="#composer-blocks-the-versions-your-advisory-lists">§6</a>).
Add a static analyzer (PHPStan or Psalm) at a level that at least catches the
classics: unvalidated input flowing into queries, file paths, or <code>unserialize()</code>.</li>
</ol>

<p><strong>Build habits</strong></p>

<ol start="10">
<li><strong>Keep an isolated reproduction environment ready</strong> (<a href="#4.-handle-proof-of-concept-code-safely">§4</a>),
so that "spin up the VM" is a two-minute routine rather than a reason to take the
dangerous shortcut.</li>
<li><strong>Treat security reports as a normal category of work,</strong> with the small process
from this guide, rather than as emergencies. The calmer the routine, the better
every individual case goes.</li>
<li><strong>Know who to call.</strong> Which brings us to the final section.</li>
</ol>

<h2 id="10.-getting-help">10. Getting help</h2>

<p>You never have to work through any of this alone. The <strong>PHP Foundation Ecosystem
Security Team</strong> exists precisely to support maintainers like you: with triage,
reproduction of findings in isolated environments, impact analysis, deduplication of
report floods, fix validation, severity scoring, and coordinated disclosure. Asking
early is always better than guessing; there is no question too basic.</p>

<ul>
<li><strong>Email:</strong> <a href="&#x6d;&#97;&#x69;&#108;&#x74;&#x6f;&#58;&#x76;&#111;&#x6c;&#x6b;&#101;&#x72;&#64;&#x74;&#x68;&#101;&#x70;&#104;&#x70;&#x2e;&#102;&#x6f;&#117;&#x6e;&#x64;&#97;&#x74;&#105;&#x6f;&#x6e;">volker@thephp.foundation</a>
(Volker Dusch, Ecosystem AI Security Engineer in Residence at the PHP Foundation)</li>
<li><strong>Discord:</strong> <code>#ecosystem-security</code> on the phpc community server
(<a href="https://discord.com/invite/RYajXKxuuK">invite</a>), where Volker is <code>@edorian</code></li>
<li><strong>Background on the team:</strong>
<a href="https://thephp.foundation/blog/2026/05/18/announcing-ecosystem-security-team/">Announcing the Ecosystem Security Team</a> ·
<a href="https://thephp.foundation/blog/2026/06/23/one-month-of-ecosystem-security-engineering/">One Month of Ecosystem Security Engineering</a></li>
</ul>

<h3 id="further-reading">Further reading</h3>

<ul>
<li><a href="https://alpha-omega-security.github.io/maintainers-security-advisory-guide/">The Maintainer's Guide to GitHub Security Advisories</a>
(Alpha-Omega): the in-depth, ecosystem-agnostic companion to this document, with a
cheatsheet, FAQ, and workarounds for GitHub platform limitations</li>
<li><a href="https://docs.github.com/en/code-security/security-advisories/guidance-on-reporting-and-writing-information-about-vulnerabilities/privately-reporting-a-security-vulnerability">GitHub Docs: Privately reporting a security vulnerability</a></li>
<li><a href="https://docs.github.com/en/code-security/how-tos/report-and-fix-vulnerabilities/fix-reported-vulnerabilities/create-repository-advisory">GitHub Docs: Creating a repository security advisory</a>:
the click-by-click walkthrough of the advisory form, including the CVSS
calculator and credit types</li>
<li><a href="https://docs.github.com/en/code-security/tutorials/fix-reported-vulnerabilities/write-security-advisories">GitHub Docs: Best practices for writing repository security advisories</a>:
the reference for ecosystem, package name, and affected-version syntax,
including operators and prerelease-suffix pitfalls</li>
<li><a href="https://getcomposer.org/doc/03-cli.md#audit">Composer: <code>composer audit</code></a> and the
<a href="https://getcomposer.org/doc/06-config.md#policy">dependency policy configuration</a></li>
<li><a href="https://phpunit.expert/articles/the-bouncer-in-the-dependency-resolver.html">The Bouncer in the Dependency Resolver</a>
(Sebastian Bergmann): how Composer's advisory and malware blocking works under the
hood, including a real-world case of an advisory blocking too much</li>
<li><a href="https://blog.packagist.com/an-update-on-composer-packagist-supply-chain-security/">An update on Composer &amp; Packagist supply chain security</a>
and the <a href="https://blog.packagist.com/composer-2-10-release/">Composer 2.10 release announcement</a>
(Packagist): the current state and roadmap covering dependency policies, version
immutability, the transparency log, and MFA</li>
<li><a href="https://phpunit.expert/articles/the-attack-surface-begins-in-the-repository.html">The attack surface begins in the repository</a>
and <a href="https://phpunit.expert/articles/hardening-github-actions-workflows.html">Hardening GitHub Actions workflows</a>
(Sebastian Bergmann): Poisoned Pipeline Execution and the concrete workflow
weaknesses behind <a href="#9.-improving-your-security-posture-for-the-long-term">§9</a></li>
<li><a href="https://cwe.mitre.org/">CWE (Common Weakness Enumeration)</a> and
<a href="https://www.first.org/cvss/">CVSS (Common Vulnerability Scoring System)</a></li>
<li><a href="https://cna.erlef.org/maintainer-process">EEF CNA Maintainer Process</a>: the Erlang
ecosystem's equivalent process, a model for this guide</li>
</ul>

<hr />

<p><em>If anything here was unclear, took too long to figure out, or turned out to be wrong
in practice, please tell us; that feedback directly improves the experience of the
next maintainer. You can reach us at the addresses in <a href="#10.-getting-help">§10</a>.</em></p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[How to Contribute to PHP]]></title>
            <link href="https://thephp.foundation/blog/2026/08/17/how-to-contribute-to-php/"/>
            <updated>2026-08-17T00:00:00+00:00</updated>
            <id>https://thephp.foundation/blog/2026/08/17/how-to-contribute-to-php/</id>
            <content type="html"><![CDATA[<p>PHP has powered a huge portion of the web for a <em>long</em> time now. It's launched untold numbers of careers and businesses, and many developers attribute their entire careers to the language. But when we find ourselves wanting to give back, it's not always clear how; sure, PHP is open source, but where do we contribute? How?</p>

<p>I've run into that wall before. My immediate issue was that I didn't write C, followed pretty immediately by how overwhelming it felt to learn the entire RFC-and-mailing-list-driven contribution process.</p>

<p>Thankfully, it turns out there are many ways to contribute to PHP, and writing C or proposing an RFC are just two of many options. I'm glad to share I've found <em>many</em> other ways to give back, and I'm confident you can as well.</p>

<p>When we talk about "contributing to PHP," there are really two ways: <strong>contributing directly to the PHP project</strong>, and <strong>contributing to the broader PHP ecosystem</strong>. Both are needed and both are valid, so we'll walk through both in this guide. Wherever any potential path gets technical, we'll point you to the canonical instructions rather than duplicate them here.</p>

<h2 id="php%2C-the-php-foundation%2C-and-the-ecosystem">PHP, the PHP Foundation, and the ecosystem</h2>

<p>Before we go any further, I want to clear up the difference between a few different concepts with "PHP" in their names which we'll be referring to throughout this post:</p>

<ul>
<li><strong>The PHP project</strong> — a language, and the open-source project around it: the implementation, tests, documentation, and releases, and the technical decision-making that guides it all.</li>
<li><strong>The PHP ecosystem</strong> — everything else built around PHP: packages, frameworks, tooling, conferences, education, communities, and publications.</li>
<li><strong>The PHP Foundation</strong> — an organization that supports the long-term health of PHP, including funding programmers and coordinating and supporting community initiatives.</li>
</ul>

<p>And to clear up an important governance distinction, since this is posted on the PHP Foundation's blog: the Foundation does not own PHP, it doesn't govern its development, and it doesn't dictate RFCs. PHP is an independent open-source project with its own contributors and its own decision-making process, and we like it that way! The Foundation exists to support that work.</p>

<h1 id="part-one%3A-contributing-directly-to-php">Part One: Contributing directly to PHP</h1>

<h2 id="core-contribution-is-broader-than-you-might-think">Core contribution is broader than you might think</h2>

<p>When most people picture the idea of "contributing to PHP core," the first thing that comes to mind is proposing a new language feature. But that's actually the deepest end of that pool, and it's only a small part of the work it takes to run a language.</p>

<p>There are so many other ways people can contribute to the project, including testing releases, reporting bugs, reproducing bugs others have reported, writing tests, improving documentation, reviewing changes, fixing issues, participating in internals discussion, and, yes, RFCs.</p>

<p>Let's walk through these, roughly from the lowest barrier to entry to the highest.</p>

<h2 id="1.-test-prereleases">1. Test prereleases</h2>

<p>Every new major, minor, or patch PHP version ships with a prerelease. Patch versions just get an RC (release candidate), and major/minor versions receive a series of prereleases — alphas, betas, and release candidates — before the final release. These exist so the community can catch problems while they're still cheap to fix. The more real-world code that runs against a prerelease, the more confident everyone can be that the final release won't break things.</p>

<p>If you maintain a package, run its test suite against the next prerelease. If you run a large real-world application, run its tests on the prerelease, or point a local or staging environment at it. When something breaks, you've found either a genuine regression worth reporting or a change you'll need to prepare for, both of which are valuable.</p>

<p>If you want to go a step further, test against PHP's master branch continuously rather than only at prerelease time; projects like PHPUnit and Xdebug already do this, so they catch regressions the moment they land. One caveat: don't gate your CI on it. Let a master-branch build fail without failing your whole suite, since you're deliberately testing against unreleased, in-progress code. PHPUnit's Sebastian Bergmann has written up <a href="https://phpunit.expert/articles/how-php-and-its-ecosystem-test-each-other.html">how PHP and its ecosystem test each other this way</a>.</p>

<p>PHP announces each alpha, beta, and release candidate on <a href="https://www.php.net/">php.net</a>, together with the source downloads and release schedule for that version. You can use your preferred version management or container tooling to install the prerelease, or <a href="https://github.com/php/php-src#building-php-source-code">build it yourself locally</a>, and then run your application's or package's test suite against it. If you find something that looks like a regression in PHP itself, reduce it to the smallest reproduction you can and report it to the <a href="https://github.com/php/php-src/issues"><code>php-src</code> issue tracker</a>.</p>

<p><strong>First step:</strong> Grab the current prerelease and run something you already maintain against it.</p>

<h2 id="2.-report-and-reproduce-bugs">2. Report and reproduce bugs</h2>

<p>A good bug report is itself a contribution, and so is confirming or reproducing someone else's.</p>

<p>Before you file anything, search the <a href="https://github.com/php/php-src/issues">existing <code>php-src</code> issues in GitHub</a>; this problem may already be known. If it isn't, the most valuable thing you can do is reduce it to a <strong>minimal reproduction</strong>: the smallest snippet of code that will reliably trigger the undesirable behavior, along with your PHP version, platform, and any other relevant environment details. The <a href="https://github.com/php/php-src/blob/master/CONTRIBUTING.md"><code>php-src</code> contribution guide</a> has additional guidance on filing and working with issues.</p>

<p>And to clear up a common misconception, it's still valuable to report a bug even if you don't know how to fix it.</p>

<p><strong>First step:</strong> Search the issues, then either file your own issue or try to reproduce someone else's unconfirmed report.</p>

<h2 id="3.-improve-documentation">3. Improve documentation</h2>

<p>PHP's documentation is vast, and like all large (and long-running) documentation projects, it still contains plenty of unclear passages, missing examples, and pages describing behavior that has changed since its writing. Improving any of these helps every developer who lands on that page after you.</p>

<p>For small changes, you don't even need to set up the documentation project locally: the PHP manual's <a href="https://doc.php.net/guide/contributing.md">contribution guide</a> explains how to propose an edit directly through GitHub. If you're interested in translation work, there's a separate <a href="https://doc.php.net/guide/translating.md">translation guide</a>.</p>

<p>Here are a few concrete examples: clarifying a confusing sentence, adding a clear example to a function that lacks (and needs) one, documenting an edge case you had to discover the hard way, correcting behavior that's drifted over versions, or improving a translation into your language. And "improving the docs" isn't only about what's written: the documentation project also has tooling (CI, linting, etc.) that welcomes contributions.</p>

<p><strong>First step:</strong> The next time a docs page confuses you, propose a fix instead of just closing the tab in frustration.</p>

<h2 id="4.-write-tests">4. Write tests</h2>

<p>PHP has its own test format, called <strong>PHPT</strong>: plain-text files that describe a bit of PHP to run and the output it should produce. They're how the language guards against regressions, and they're a natural bridge between everyday PHP development and working in <code>php-src</code>.</p>

<p>A PHPT test is deliberately simple. At its core it's three sections: the description, a section describing the code to run, and a section describing the expected output:</p>

<pre><code>--TEST--
strlen() returns the number of bytes in a string
--FILE--
&lt;?php
var_dump(strlen("hello"));
?&gt;
--EXPECT--
int(5)
</code></pre>

<p>The <a href="https://php.github.io/php-src/miscellaneous/writing-tests.html"><code>php-src</code> testing guide</a> walks through the full PHPT format and how to write useful tests; once you're working from a local PHP build, the <a href="https://php.github.io/php-src/miscellaneous/running-tests.html">test-running guide</a> explains how to execute them.</p>

<p>Similar to how it's valuable to report an issue even if you don't know how to fix it, it's valuable to write a test for a bug even if you don't know how to fix it. If you can write PHPT that reliably fails on a known bug, you've pinned the problem down precisely and made the process of writing and validating a fix that much easier.</p>

<p><strong>First step:</strong> Turn a bug you've reproduced into a failing PHPT.</p>

<h2 id="5.-fix-or-review-issues-in-php-src">5. Fix or review issues in php-src</h2>

<p>This is the point where contribution moves into the implementation itself, and where knowing some C starts to matter. It's a bigger step, but still very clear. Here's generally how it works:</p>

<ol>
<li>Get PHP building locally.</li>
<li>Find a scoped, well-defined existing problem to work on.</li>
<li>Comprehend the problem, and reproduce it for yourself locally.</li>
<li>Add or update tests that capture the correct behavior.</li>
<li>Implement the fix.</li>
<li>Open a pull request.</li>
<li>Work through any review with the maintainers.</li>
</ol>

<p>I know "just get PHP building locally" is doing a lot of work in that first step. The <a href="https://php.github.io/php-src/"><code>php-src</code> developer documentation</a> and <a href="https://github.com/php/php-src/blob/master/CONTRIBUTING.md">CONTRIBUTING.md</a> are the best places to start with setting up a development environment and understanding the contribution workflow.</p>

<p>There's also the other half of this process: <strong>reviewing and testing someone else's pull request.</strong> Pull down an open PR, build it, check that it does what it claims, and then leave your findings on the PR. And this may actually be simpler than opening your first PR from scratch.</p>

<p><strong>First step:</strong> Get PHP building locally, then browse the <a href="https://github.com/php/php-src/issues"><code>php-src</code> issues</a> for a narrowly scoped, already-verified bug in an area you understand.</p>

<h2 id="6.-participate-in-internals">6. Participate in internals</h2>

<p>Technical discussion about the direction of PHP happens openly on the <a href="https://www.php.net/mailing-lists.php">internals mailing list</a>, PHP's long-running development mailing list. You don't have to write C to follow along, and you don't have to be an established contributor to add value.</p>

<p>In fact, many people participating in internals conversations aren't traditional core developers. That goes both ways: it means you, even as a newcomer, are as welcome to participate as anyone, but it also means not every reply you might receive should carry the same weight. That means a strong objection from one participant can't be seen as the same as a decision; weigh feedback by its reasoning and don't be discouraged by a single dissenting voice.</p>

<p>The internals mailing list also does have a <a href="https://github.com/php/php-src/blob/master/docs/mailinglist-rules.md">written guide</a>, which lays out how to participate. I'd recommend reading the whole thing before you post.</p>

<p><strong>First step:</strong> Subscribe to the <a href="https://www.php.net/mailing-lists.php">internals mailing list</a>, or browse past and current discussions on <a href="https://externals.io/">externals.io</a>, and just listen for a while.</p>

<h2 id="7.-rfcs%3A-changing-the-language-itself">7. RFCs: changing the language itself</h2>

<p>RFCs (Requests for Comments) are the processes by which significant changes to the language are formally proposed and decided. They're the part of contributing to core that gets the most attention, so it's worth being clear about what they are and aren't.</p>

<p>First: <strong>not every code change requires an RFC.</strong> Plenty of bug fixes land through ordinary pull requests. RFCs exist for new features and other changes significant enough to need formal decision-making through the RFC process.</p>

<p>Second: <strong>an RFC is much more than an idea.</strong> A proposal that will be taken seriously requires research into prior art, careful design, analysis of backward-compatibility impact, a credible implementation plan (and often an implementation), a period of discussion, revision in response to feedback, a formal vote, and technical review throughout. The idea is the easy part; everything around it is the work.</p>

<p>Two things newcomers often miss:</p>

<ul>
<li><strong>You can contribute to an RFC without being its author.</strong> Testing a proposed implementation, poking holes in the design, surfacing a compatibility problem, or providing real-world use cases all move a proposal forward.</li>
<li><strong>An accepted proposal still has to become good software.</strong> A "yes" vote is the beginning of the implementation's real life, not the end.</li>
</ul>

<p>If you're not ready to author an RFC yourself, a great way to learn the process is to follow one that's currently under discussion. Read the proposal and its linked internals discussion, try the implementation if one is available, and look for places where your own experience can add useful evidence: compatibility concerns, interactions with existing features, real-world use cases, or behavior the proposal may not have considered. You don't need voting privileges to participate in the discussion or test the implementation.</p>

<p><strong>First step:</strong> Browse the <a href="https://wiki.php.net/rfc">current RFC list</a>, choose one that's under discussion, and follow it end to end. If you're considering proposing your own change, start with the official <a href="https://wiki.php.net/rfc/howto">How to create an RFC</a> guide.</p>

<h1 id="part-two%3A-contributing-to-php%27s-ecosystem">Part Two: Contributing to PHP's ecosystem</h1>

<p>The PHP project is only part of the story. Most developers spend more of their time in the ecosystem around it — the packages, frameworks, tools, communities, and education that make PHP an ecosystem, not just a language. Contributing here is not a consolation prize for people who can't work on core; for most of the community, it's where their highest-value contributions actually live.</p>

<h2 id="1.-help-existing-open-source-projects">1. Help existing open-source projects</h2>

<p>The packages, frameworks, and tools you already use are maintained by real people; often very few of them, and often unpaid. They almost all need help: issue triage, pull-request review, documentation, testing against upcoming PHP versions, and general maintenance. Abandoned-but-widely-used projects sometimes need someone to step in and adopt them entirely — and that includes PHP's own bundled extensions, many of which have few or no active maintainers, so a domain you know well may be a genuine gap you can fill.</p>

<p>It's tempting to think the way to contribute is to build something new. But <em>creating another package is not necessarily more valuable than maintaining one thousands of people already depend on.</em> In fact, it's often worse. Strengthening what exists is often the more valuable choice.</p>

<p><strong>First step:</strong> Pick a dependency you rely on and spend an hour in its issue tracker.</p>

<h2 id="2.-teach-and-help-developers">2. Teach and help developers</h2>

<p>Teaching is infrastructure. An ecosystem is only as healthy as its ability to bring new people in and help existing developers level up, and that ability runs almost entirely on people who take the time to explain things.</p>

<p>That includes writing tutorials and documentation, producing upgrade guides, giving talks, mentoring, answering questions in forums and chat, and helping newcomers land their very first contribution. None of this requires permission, and all of it builds on the rest.</p>

<p><strong>First step:</strong> Write up the last thing you had to figure out the hard way.</p>

<h2 id="3.-strengthen-php-communities">3. Strengthen PHP communities</h2>

<p>The PHP community exists because people build and sustain the spaces it lives in: local meetups, conferences, online communities.</p>

<p>You don't need to start a conference. Consider volunteering to assist a local meetup, or simply working to make a newcomer feel welcome in one. Or, if you haven't attended one yet, just show up!</p>

<p><strong>First step:</strong> Show up to a local or online PHP community and meet people; if you're already there and want to do more, ask how you can help.</p>

<h2 id="4.-help-php-show-up-outside-the-php-bubble">4. Help PHP show up outside the PHP bubble</h2>

<p>Plenty of the world's developers have formed their impression of PHP from someone else's read on the language from the '90s. The best way to update these impressions is to make sure PHP is represented accurately where non-PHP developers actually are.</p>

<p>That looks like giving PHP talks at general software conferences, contributing PHP SDKs or examples to language-neutral projects, adding modern PHP examples to developer education, publishing case studies from real applications, and improving PHP support in general-purpose developer tooling.</p>

<p>That outward-facing work is exactly what the Foundation's Ambassador Program is built to coordinate.</p>

<h1 id="part-three%3A-php-foundation-opportunities">Part Three: PHP Foundation opportunities</h1>

<p>In addition to everything above, the Foundation explicitly offers some structured ways to plug in. These are intentionally building space for contributions outside of code, like marketing, conference speaking, research, and more.</p>

<p>In 2026, the Foundation is launching six <strong>Special Interest Groups</strong>, covering the following areas: ecosystem security, <a href="https://thephp.foundation/blog/2026/06/19/the-php-ambassador-program-is-open/">PHP advocacy</a>, <a href="https://thephp.foundation/blog/2026/08/03/kicking-off-the-php-onboarding-initiative/">onboarding</a>, cryptography, community events, and accessibility and inclusion. The Foundation also periodically looks for community participation in surveys, consultations, and other initiatives.</p>

<p>And for people or organizations that don't have contributor time to spare, <a href="https://thephp.foundation/sponsor/"><strong>financial support</strong> to the Foundation</a> is another way to enable this work — funding the contributors and initiatives that keep PHP moving.</p>

<h2 id="when-you-get-stuck-or-hear-nothing-back">When you get stuck (or hear nothing back)</h2>

<p>At some point you'll get stuck in one of these processes, or you'll open a pull request and hear nothing back for a while. Both are normal, and neither means you necessarily did anything wrong. Contribution runs largely based on the work of volunteers, and volunteer attention is limited.</p>

<p>When you need help, there are a few good places to turn:</p>

<ul>
<li><strong>General questions and getting unstuck:</strong> The <a href="https://phpc.chat/">PHP Community Discord</a> is the most active real-time gathering spot, with channels ranging from beginner questions to core development. There's even a <code>#php-src-help</code> channel specifically for this sort of work. For longer-form questions, the <a href="https://www.reddit.com/r/PHP/">r/PHP subreddit</a> and the <a href="https://stackoverflow.com/questions/tagged/php"><code>php</code> tag on Stack Overflow</a> are both well-trafficked.</li>
<li><strong>Core and internals questions:</strong> For questions specific to working on <code>php-src</code>, that same Discord has a <code>#php-internals</code> channel where core developers hang out, and the <a href="https://www.php.net/mailing-lists.php">internals mailing list</a> is the canonical venue for development discussion.</li>
<li><strong>A <code>php-src</code> PR or RFC that's gone quiet:</strong> The internals mailing list is the right place to politely follow up. A short, respectful message linking your PR or proposal is a normal and accepted way to ask for eyes on stalled work.</li>
</ul>

<h2 id="pick-one-thing">Pick one thing</h2>

<p>You don't have to try everything in this article. Pick one that fits your current level of experience and available time, and run with it.</p>

<ul>
<li><strong>If you have 30 minutes:</strong> fix a confusing docs page, confirm an open issue, or answer someone's question.</li>
<li><strong>If you have an afternoon:</strong> test a prerelease, build a minimal reproducible example, or investigate a bug.</li>
<li><strong>If you want a project:</strong> write a test, take on a scoped issue, or help maintain a package you depend on.</li>
<li><strong>If you want an ongoing role:</strong> review contributions, maintain software, organize community, or get involved in internals or Foundation work.</li>
</ul>

<p>Whatever you pick, hold onto this:</p>

<p><strong>If you write PHP, you are qualified to contribute to PHP.</strong> Don't let anyone tell you otherwise.</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[PHP Ambassadors: Six Weeks In]]></title>
            <link href="https://thephp.foundation/blog/2026/08/13/php-ambassadors-six-weeks-in/"/>
            <updated>2026-08-13T00:00:00+00:00</updated>
            <id>https://thephp.foundation/blog/2026/08/13/php-ambassadors-six-weeks-in/</id>
            <content type="html"><![CDATA[<p>When we <a href="https://thephp.foundation/blog/2026/06/19/the-php-ambassador-program-is-open/">launched the PHP Ambassador Program</a> on June 19, 2026, we honestly didn’t know what to expect. We knew the need for something like this was definitely there, and it <em>seemed</em> like something the community would be interested in being a part of. But as they say, “you never know how a thing is going to go, until it goes.”  I mentioned in my <a href="https://thephp.foundation/blog/2026/06/11/integrating-community-feedback-into-foundation-strategy-part2/">strategy document</a> that I was hoping to enlist 10 people to attend a regular cadence of meetings. (Honestly, 10 people seemed like a reasonable number.)</p>

<p>Not only did you all surpass that number by leaps and bounds, you continue to show up and join the group. <em>We now have 150 people who have expressed interest in the Program</em>. I couldn’t be more excited about your enthusiasm!</p>

<h2 id="what-we-learned">What we learned</h2>

<p>Some things we’ve learned about this group:</p>

<ul>
<li><strong>Maintain flexible infrastructure choices:</strong> When starting a new community, it's important to remember that it’s ok to try different options for infrastructure. Every community takes on a life of its own, and for this group, GitHub Discussions did not seem to take hold as a place where the community wanted to interact. As well, Google Meet did not provide us with the options for meeting management that we wanted. And third, inviting folks individually to meetings became unwieldy and got me flagged as a spammer. So instead of using GitHub, Google Meet, and Google invites, we are using Discord, Zoom, and a Google calendar to manage this community's interactions and these meetings.</li>
<li><strong>Divide and conquer:</strong> We had enough interest to break the larger group into smaller, more focused groups:

<ul>
<li>Research: focused on locating and vetting sources of information and truth that the community can use in their articles and presentations</li>
<li>Marketing: focused on the messaging of PHP (including the php.net website)</li>
<li>Speakers: focused on providing structure and resources for people who want to give talks outside the PHP ecosystem</li>
</ul></li>
<li><strong>Give opportunities for overlap:</strong> As our topics of discussion became more focused, many people wanted to be in more than one group at a time. Also, a 30 minute breakout once a month is not enough to make real progress.  For those reasons, we have afforded each group their own meeting space, while maintaining the monthly meeting that includes everyone. Allowing people to participate in more than one group at a time means there will be more opportunities for cross-pollination and coordination among the three subgroups.</li>
</ul>

<h2 id="group-progress">Group Progress</h2>

<p>Ideas are great, but what about actions? We have a goal in each group to build tangible assets and to keep momentum going. Launching is hard, but maintaining engagement and providing real outcomes is harder. So let's talk about what each of these groups is currently working on.</p>

<h3 id="research">Research</h3>

<p>As the smallest of the three groups, we tasked ourselves with identifying and listing the current available resources that are out there around PHP usage and other data points that might be of interest to our community. We felt that it was important to have a lay of the land as a starting point. We are still working on putting this into a format that we can share in the <a href="https://github.com/ThePHPF/SIG-ambassadors/tree/main/subgroup-research">Research portion of the SIG-Ambassador Repo</a>, but we have some notes started. If you know of a source of data that should be included, please share with us by <a href="https://github.com/ThePHPF/SIG-ambassadors/issues">opening an issue in the repo</a>.</p>

<p><strong>Group Info:</strong></p>

<ul>
<li>Discord channel: <a href="https://discord.com/channels/356354025865740288/1530212583833997392">#php-amb-research</a></li>
<li>GitHub repo: <a href="https://github.com/ThePHPF/SIG-ambassadors/tree/main/subgroup-research">Research subgroup</a></li>
<li>Next meeting: <strong>Friday, August 28, 2026 at 13:00 UTC</strong></li>
</ul>

<h3 id="marketing">Marketing</h3>

<p>There is an <a href="https://github.com/php/web-php/pull/1962">active draft PR</a> that proposes some initial structural updates to the php.net website. The original PR was created largely from the work of Mark Randall, and it has gone through several collaborative iterations. The php.net website was one of the things most mentioned to me in the <a href="https://thephp.foundation/blog/2026/04/16/integrating-community-feedback-into-foundation-strategy-part1/">Listening Tour</a> as a place that could use some help, so it’s great to see this next iteration being created by the community. I would venture to say this is the first in many iterations to come! Thanks to <a href="https://www.linkedin.com/in/mattstauffer/">Matt Stauffer</a> for shepherding this group and keeping progress moving forward.</p>

<p><strong>Group Info:</strong></p>

<ul>
<li>Discord channel: <a href="https://discord.com/channels/356354025865740288/1530212454309826571">#php-amb-marketing</a></li>
<li>GitHub repo: <a href="https://github.com/ThePHPF/SIG-ambassadors/tree/main/subgroup-marketing">Marketing subgroup</a></li>
<li>Next meeting: <strong>Friday, August 14, 2026 at 14:00 UTC</strong></li>
</ul>

<h3 id="speakers">Speakers</h3>

<p><a href="https://www.linkedin.com/in/secondej/">James Seconde</a> from Vonage has done an amazing job shepherding this third and final group: the speakers. He has started a PR that offers <a href="https://github.com/ThePHPF/SIG-ambassadors/pull/24">guidelines for a more structured, Foundation-backed Speaker Program</a>. The community has chimed in, but we are still open to receiving feedback on how a program like this might work. This group has also started compiling a <a href="https://docs.google.com/spreadsheets/d/1TCy25FqB_c2n1UhwtGN4AdL_plMPHQceNi6UpOSjBok/edit">spreadsheet of events</a> outside our PHP bubble as a resource for PHP Ambassador speakers (or anyone else in the community). We would appreciate more eyes on this and the addition of more information. If you have thoughts on either of these things, we highly encourage you to join this group!</p>

<p><strong>Group Info:</strong></p>

<ul>
<li>Discord channel: <a href="https://discord.com/channels/356354025865740288/1530212493019058257">#php-amb-speakers</a></li>
<li>GitHub repo: <a href="https://github.com/ThePHPF/SIG-ambassadors/tree/main/subgroup-speakers">Speakers subgroup</a></li>
<li>Next meeting: <strong>Thursday, August 27, 2026 at 13:00 UTC</strong></li>
</ul>

<h2 id="join-us%21">Join us!</h2>

<p>If shaping the messaging around PHP and improving the perception of the language outside our bubbles is important to you, we would love to include you in this group!</p>

<p>Even if you aren’t sure where you fit in, you can participate in the larger effort:</p>

<ul>
<li>Discord: <a href="https://discord.com/channels/356354025865740288/1521534247813255229">#php-ambassadors</a></li>
<li>Repo: <a href="https://github.com/ThePHPF/SIG-ambassadors/tree/main">SIG-Ambassadors</a></li>
<li>Calendar of meetings: <a href="https://calendar.google.com/calendar/u/3?cid=Y19lMzY3ZGQyMzRiNTkwZGExY2M1NjM3ZTEyZmE2ODJlYjA0YzZkOWU4N2E5OWY1ZDY2YzMxNjI5YmIxYTE4MDNkQGdyb3VwLmNhbGVuZGFyLmdvb2dsZS5jb20">Subscribe here</a></li>
<li>Next meeting: <strong>Friday, August 14, 2026 at 13:00 UTC</strong></li>
</ul>

<p>To be added to the mailing list where you will be kept up-to-date on all the PHP Ambassador news, register your interest using <a href="https://forms.gle/cAFDZ1gC22ajxx6VA">this form</a>. (Of course you can unsubscribe at any time, and we will still love you. We promise.)</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[Anne McCarthy Joins The PHP Foundation Board]]></title>
            <link href="https://thephp.foundation/blog/2026/08/04/anne-mccarthy-joins-the-board/"/>
            <updated>2026-08-04T00:00:00+00:00</updated>
            <id>https://thephp.foundation/blog/2026/08/04/anne-mccarthy-joins-the-board/</id>
            <content type="html"><![CDATA[<p><img src="/assets/post-images/2026/anne-mccarthy/anne-mccarthy.jpg" width="300" alt="photo of anne mccarthy giving a presentation" class="mb-4 sm:mr-4 sm:float-left"/>The PHP Foundation Governing Board consists of a variety of folks from across the PHP ecosystem that share a vested interest in the success and sustainability of PHP. Representatives from the community, the core contribution team, and sponsors comprise this team to provide guidance and insight into the Foundation's objectives and initiatives. After a unanimous decision, we are incredibly pleased to be adding <a href="https://www.linkedin.com/in/anneguionmccarthy/">Anne McCarthy</a>, Architect and Open Source Director for Automattic, to our Board as a platinum sponsor representative.</p>

<p>Anne brings 15 years of technical and open source experience, and has spent the last 12 years at Automattic, dedicated to improving the experience of the WordPress community of users and contributors alike. They bring a balanced mix of thoughtful empathy and deep technical knowledge and will be a tremendous asset to the Foundation moving forward.</p>

<blockquote>
  <p>Open source comes down to people trying, caring, and showing up to benefit the collective. This feels like an especially powerful act in today's world so it's a real honor to join the PHP Foundation Board to support those who have given so much to PHP and all the other projects built with it. -- Anne McCarthy</p>
</blockquote>

<p>You can find Anne mostly in Seattle, WA where mountains and dogs both fill their soul with a special kind of joy. Please join us in welcoming Anne to The PHP Foundation Governing Board!</p>
]]></content>
        </entry>
            <entry>
            <title type="html"><![CDATA[Kicking off the PHP Onboarding Initiative Special Interest Group]]></title>
            <link href="https://thephp.foundation/blog/2026/08/03/kicking-off-the-php-onboarding-initiative/"/>
            <updated>2026-08-03T00:00:00+00:00</updated>
            <id>https://thephp.foundation/blog/2026/08/03/kicking-off-the-php-onboarding-initiative/</id>
            <content type="html"><![CDATA[<p>One of the most common pieces of feedback we hear from the PHP community is that the newcomer experience could use some improvement, and that we may be losing new users because of it. This is something that we as a community can address, and it's why The PHP Foundation made it part of our <a href="https://thephp.foundation/blog/2026/06/11/integrating-community-feedback-into-foundation-strategy-part2/#3.-php-onboarding-initiative">strategy document</a> for the rest of 2026. Improving that experience matters a lot to us, because a better new user experience means more community growth and retention. We are launching the PHP Onboarding Initiative Special Interest Group to provide space for collaborative problem solving in this area.</p>

<p>Some of the identified issues in the PHP newcomer experience include:</p>

<ul>
<li><strong>Where to begin:</strong> It is difficult for new PHP users to know where to start. There are many resources and tutorials available, but it is hard to know which ones are updated and accurate, and the sheer number of them is overwhelming. Building and helping people find resources that cater to their needs is something that would be helpful for newcomers.</li>
<li><strong>Minding the gap:</strong> The <a href="http://php.net/docs">php.net Manual</a> is a fantastic resource, but it is more of a reference than an educational resource for beginners that are learning to code. There is a current gap between documentation for complete beginners and users who already grasp the basics and use the manual differently.</li>
<li><strong>Limited presence in formal education:</strong> PHP is largely missing in universities and bootcamps. Although there are some places in the world where PHP (or a related framework/project) is taught, the presence of PHP is inconsistent. There won't be a "one-size-fits-all" approach to building more partnerships with educational institutions. But this is something that we can figure out together. (Also, this may overlap with the mission of the <a href="https://github.com/ThePHPF/SIG-ambassadors">PHP Ambassadors</a> Special Interest Group that has already launched.)</li>
<li><strong>Finding your people:</strong> The onboarding experience differs greatly among newcomers, with some having connections to the community, and others fending for themselves. It would be ideal if we could provide a more consistent approach to bringing newcomers together and connecting them with the community.</li>
<li><strong>Mentorship is hard to find:</strong> Although there have been previous attempts at mentorship programs, those have proven challenging to sustain. But <a href="https://www.linuxfoundation.org/hubfs/LF%20Research/LFX%20Mentorship%20in%20Open%20Source%20-%20Report.pdf?hsLang=en">research shows</a> that mentorship can make all the difference when it comes to retaining users and turning them into potential contributors and community members, especially when it comes to those from marginalized and underrepresented groups.</li>
<li><strong>Installation process</strong> Ensuring that this process is as easy and straightforward as possible, and centering the experience of new users is something that we should continue to be mindful of. Because this will likely involve the php.net website, this is another potential overlap with the mission of the <a href="https://github.com/ThePHPF/SIG-ambassadors">Marketing Subgroup of the PHP Ambassadors</a> Special Interest Group.</li>
</ul>

<p>These problems are not new and they aren't easy to solve, but one thing about the PHP community that I personally love is its dedication to sharing knowledge with new learners and helping newcomers find their way. This sense of community and support for newcomers is why many of us are still here (including myself!). Wouldn't it be great if we could come together and create a better and more consistent experience for newcomers to PHP?</p>

<p>If this is something that is of interest to you, we are hosting a kick-off meeting on <strong>Monday, August 24 at 13:00 UTC</strong>. To request an invite to this meeting, please register your interest using <a href="https://forms.gle/VNmijQm4gWjuDjnJA">this form</a>. Note: if you have already indicated your interest through this form, you do not need to submit it again.</p>

<p>If you cannot attend this meeting, that's okay! You are welcome to join the #the-php-foundation channel in the <a href="https://discord.phpc.social/">#phpc Discord server</a> for access to this and the other Special Interest Group chats. We also have a <a href="https://github.com/ThePHPF/SIG-onboarding">GitHub repository</a> where you can connect asynchronously.</p>
]]></content>
        </entry>
    </feed>