Making ExcelBook::save() atomic is easy to describe. Write the workbook to a temporary file, then rename it into place. A save that dies halfway leaves the original file untouched.
The obvious way to build that staged file is to ask LibXL for the finished archive as one buffer and write the buffer out. It works. It also costs 67.7 MB of peak RSS on a 3.3 MB workbook, and the PHP-side copy counts against memory_limit. The streaming writer php_excel used before the staging work costs 0.7 MB for the same file. That is roughly twenty times the workbook size in RAM, spent by a change whose whole purpose was safety.
That one arrived and was fixed inside the same release window, so no published version carries it. It is still a fair summary of the last two weeks. Nine of my PHP extensions released today. Between them they add one new method, one set of interfaces, and a few error constants. Everything else is a bug fixed, a value rejected, a limit enforced, or a cost paid back down.
The previous roundup...
ExcelBook::save() to a file:// path used to truncate your existing file before it finished writing the new one. If the write was short or got interrupted, you were left with neither the old file nor a complete new one. php_excel 2.4.0 fixes that: the write goes to a temp file and renames into place, so a failed save leaves your original intact.
That fix doesn't make a good changelog headline. It's also most of what shipped across seven of my PHP extensions in the last month. Some of it is new capability, a new Markdown engine, twelve more chart types, a columnar serializer, native JSON columns in ClickHouse. Most of it is the other kind of work: rejecting a bad value instead of storing it, throwing on the untrusted path instead of trusting it, failing a write cleanly instead of half-committing it. This is the second roundup in the series; the June one covered the version-floor drops. Here is what landed since.
mdparser 0.4.3: a new engine under the same API
mdparser swapped its entire parsing backe...
Most libraries raise their minimum PHP version over time. Drop 8.1, require 8.2, then 8.3, because every release you can assume lets you delete a pile of compatibility shims. This round I went the other way. php_excel, fastchart, and fastjson now build on PHP 8.1, phpser dropped to 8.2, and all four had required 8.3 a release ago. php_clickhouse already runs on everything from 7.4 up, so it sat this one out.
The reason is mundane but worth stating: for a native extension, the minimum PHP version is a packaging decision, not a language-feature decision. None of these extensions needed an 8.3-only engine API. The floor was set high because that was the version I built and tested against first, and lowering it just meant wiring the older versions into CI and fixing whatever broke. A shop pinned to 8.1 on a long-term-support distro gets the same speedups as one on 8.5. That's the whole point of shipping a C extension instead of a Composer package.
Here is what else landed since the last set of releases.
php...
I generate a lot of UUIDs. Primary keys, cache keys, event IDs, request-trace IDs. Probably too many, if I'm honest about it. On a busy request path the same function gets called dozens of times before the response is even assembled, and across a fleet that adds up to a number of UUIDs per second I would rather not write down.
For years that cost was invisible to me, the way a single random_bytes() call is invisible until you make a few billion of them. Then it showed up in a profile, sitting higher than it had any right to, and I started paying attention to where the time actually went. It went to two places: pulling fresh entropy from the kernel once per UUID, and formatting 16 raw bytes into the 36-character canonical string. Both are cheap. Neither is free. Multiply by "too many" and you get a real slice of CPU spent doing nothing but minting identifiers.
So I wrote fast_uuid, a PHP extension that does UUID generation in pure C. This post is about why the two existing options each left a gap, what...
I've reached for igbinary on nearly every PHP project I've shipped in the last decade. It's smaller and faster than PHP's native serialize(), it's stable, and it has been the obvious default for so long that reaching for it stopped being a decision.
So phpser started as curiosity, not a complaint. igbinary is good. Could a serializer built specifically for cache workloads do better?
I wanted two things from it. It should be fast on the shapes a cache actually holds, where a value is decoded far more often than it's encoded. And it should be safe to decode bytes from a store an attacker might reach, because unserialize() on untrusted input is one of PHP's oldest exploit primitives. igbinary gives you the speed; the safety you bolt on yourself. phpser builds in both.
On the shapes that matter for caches it encodes 10 to 70% faster than igbinary and decodes 12 to 75% faster, with packed numeric data also 65% smaller on the wire. Its signed mode refuses to decode any payload that wasn't produced with yo...
- «
- 1
- …
- »