php

  • Closure::call binds a closure without bindTo

    Running a closure in the scope of an object took two steps: bindTo() to produce a new closure, then invoking it. call() does both, and it is considerably…

  • PHP 7 replaced most fatals with an Error you can catch

    Calling a method on null used to end the request with a fatal that no handler could intercept, which is why every framework had a register_shutdown_function checking error_get_last().…

  • wp_remote_get returns an array or a WP_Error, never both

    The HTTP API returns a response array on success and a WP_Error on failure, and the two share no shape at all — so any code that reaches…

  • random_bytes and random_int are finally in core

    Generating a secure token used to mean openssl_random_pseudo_bytes() with its easily-ignored $strong out-parameter, or mcrypt_create_iv(), or a userland library working out which of those existed. PHP 7 put…

  • WP_Error is not an exception and will not stop anything

    WP_Error is a return value. Creating one has no effect on control flow, so a function that builds one and does not return it has done nothing at…

  • Queues, workers and the jobs that fail twice

    The email that arrived four times and the charge that arrived twice. What makes a job safe to run again, and keeping workers alive without them serving stale…

  • define() takes an array constant now

    const has accepted arrays since 5.6, but define() had not — which mattered because const cannot be used conditionally or inside a function, so anything computed at bootstrap…

  • The shutdown hook runs after the response is sent

    shutdown is the last action WordPress fires, and by then the output has already gone to the client — so it is the right place for bookkeeping and…

  • Generators can return a value as well as yield

    A generator yields a sequence, and until PHP 7 that was all it could produce — so a function streaming rows had no way to also report how…

  • Extracting a service without a rewrite

    The reporting code had one caller and a six-hour test run. Finding the seam, dealing with the shared schema honestly, and routing traffic gradually rather than switching.