Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:129366 X-Original-To: internals@lists.php.net Delivered-To: internals@lists.php.net Received: from php-smtp4.php.net (php-smtp4.php.net [45.112.84.5]) by lists.php.net (Postfix) with ESMTPS id 57C521A00BC for ; Fri, 21 Nov 2025 13:45:45 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1763732749; bh=JJFj9HSPQfJkoYa3msSVAleozeebVLm54g+iYX2mXss=; h=References:In-Reply-To:From:Date:Subject:To:Cc:From; b=lY8na8jnZQR4+pbvGN90ZjQd4/QPf50SwLvMgNCr22OA4nZTDRKSR5vYAomWRZgYM 2Rk6TI0eHPHuZKnkzgtXkeuLjwg0d+3KG0stdMS2eXUBNR3Xj+bseSgUr3VrHDRt7v xd0IJhR9fDd3LfacSksczX8rG0MkEhYLCd4TB3USwFP1zMgVyMpFH32jf+HrmGpuZY T0ENau+Q2rit9EG7LTVEqxEgxuvrRtVmCzCO2QBqjr795iN/llvOWgihEyK9tHcBLf 3pNCVrAxFNqv6h49EBiJKvfIDVB8IikQCINdgN1+CnWvE81lNSmvoUmQbP1KtRx6b5 imFEeb7ZiO+eg== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 116911804C5 for ; Fri, 21 Nov 2025 13:45:46 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on php-smtp4.php.net X-Spam-Level: X-Spam-Status: No, score=0.6 required=5.0 tests=BAYES_50,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,DMARC_PASS,FREEMAIL_FROM, RCVD_IN_DNSWL_NONE,RCVD_IN_MSPIKE_H2,SPF_HELO_NONE,T_SPF_TEMPERROR autolearn=no autolearn_force=no version=4.0.1 X-Spam-Virus: No X-Envelope-From: Received: from mail-vk1-f171.google.com (mail-vk1-f171.google.com [209.85.221.171]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by php-smtp4.php.net (Postfix) with ESMTPS for ; Fri, 21 Nov 2025 13:45:45 +0000 (UTC) Received: by mail-vk1-f171.google.com with SMTP id 71dfb90a1353d-559966a86caso554123e0c.2 for ; Fri, 21 Nov 2025 05:45:40 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20230601; t=1763732740; x=1764337540; darn=lists.php.net; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:from:to:cc:subject:date :message-id:reply-to; bh=B5M7Tx6A9E4AQuonRCAZfPPSk74rcL+aRQ/5djvb6VQ=; b=G1pBEDbBbbFy80teGTyKwm0r1yNI376uib6fz/Yv1LlaOyqxQaKSZ/D0PoCINRV+Ch hLCQhNLp6Vl1aoHR6qPwLq+/xxplUP/2Tqzb3dZJPj09baeRXDmy+kvHy+6ic57ytoKL etJ3OnyDUAvAZV+vXqqEp9OYBuFnvJ1TKZMXEajvl/OpQXRRQMDa8xoMssCd2ngEdZzV 7OLXzZ16C1Dnuum6yDFwM/UV5B26Ost/bI2kOgVj/rxVj+2QIMgBzFddCuq9hArqZjiP Iz6GP4CWGPuaHUXUANjJbY3AAUJvcad6naemP3W8Gj5OLVaNgMHqv9MSdVE+7L5h0XG2 OrxA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1763732740; x=1764337540; h=content-transfer-encoding:cc:to:subject:message-id:date:from :in-reply-to:references:mime-version:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to; bh=B5M7Tx6A9E4AQuonRCAZfPPSk74rcL+aRQ/5djvb6VQ=; b=BS7oYSlp9npcJdrpOQxFCT2rztlpTlqfZGPhqtK++cFHGnmMbLY8OUPUyl6Osxnimm Rvlug1T+m3REW4BJmcQ8Zjl8i3vj0/U5kKdwAtgQKFfMPMuHINkhelFH48ZAEoCRAFqc /QYci245i/AGLUOFjnQJjwLHHlNIq/Pj+nIHocXTtW6sTsG3ZfqAq64SJ1GGSZwqunX4 2WO60KN+TNa2K82vzL7h6+u1FdSiXnPXJo7FY1yvGvZr1geDnaVQVypISbPnUgfnWZ+R LtOibbkTvfSHqmFAWITzc9AoGYKRf0fyoNxgeu/ditukb0YkzgKTkcvDnWwVP7dX8YH7 gGzw== X-Forwarded-Encrypted: i=1; AJvYcCUyqKlOIzddIEGuHZmxy4EGbcAjZvPU2+9apVwAA3fc3ctHY8yceCWtBb9t3xBuayvHDBWwyJWU+zw=@lists.php.net X-Gm-Message-State: AOJu0YyZ7L3OdPMtZC1Sa3kirHIqIMcN7q898B57jkpLwK7tHPUvPN9z c6zuF5Ug/34DcvqriZ9Nlc3fIbEpxVPbF8MSROr9R5HKuEiAcZ7MvEjr8Cat3caNrZOsMg0EyEz K1xMhuTU514nI2kFv70VEiBGRaUL1vQc= X-Gm-Gg: ASbGncsONOhJvWW83GMqcmbWMKxVbI83maxQ7z7rrTaSYA5QZdbDEZbgiyeGUlgSG7I hZWRweFIfgEkLbp754px88abq+XL8yoE1GkqPDyqne6bglqN/kEmZh2EOUp0qZYjLihkRmPCLXA jsS5UjrA1cnIk99tUXdYiZRiGmpHneIpEo8gLmYqu7P3bU5kAKH4UsTenlqygR8b+HB3/kHRMyn Ms9GcF9CJuMIPGkdM22XQHHvjFZ1GSCl3bEZfRUVvC9H/V/4g8zXOcl9RoV5gz7xXRbMleaFN6d khhjDkQXJnCK56B2RYRsqeuHJqPSJCyHUfq6uQ== X-Google-Smtp-Source: AGHT+IHxnaP2o2yydaBKUeEK6Q5ApizkgdotEkuOjN0gbXKuKVtQFA6YxeXlnidHU2DQIktrn3pgwq0kT2Rx81JKZD4= X-Received: by 2002:a05:6102:808f:b0:519:534a:6c5e with SMTP id ada2fe7eead31-5e1de2d11ebmr594737137.33.1763732739911; Fri, 21 Nov 2025 05:45:39 -0800 (PST) Precedence: list list-help: list-unsubscribe: list-post: List-Id: x-ms-reactions: disallow MIME-Version: 1.0 References: In-Reply-To: Date: Fri, 21 Nov 2025 15:45:28 +0200 X-Gm-Features: AWmQ_bm4XIls9-wHvcrRHT5vbwYH8y-4y285s7rvvw3j3gmoRAQy_3PIq_uOnJ0 Message-ID: Subject: Re: [PHP-DEV] [VOTE] True Async RFC 1.6 To: Deleu Cc: Jakub Zelenka , "Rowan Tommins [IMSoP]" , internals@lists.php.net Content-Type: text/plain; charset="UTF-8" Content-Transfer-Encoding: quoted-printable From: edmond.ht@gmail.com (Edmond Dantes) Hello. To use AMPHP you don=E2=80=99t need to run its server. But let=E2=80=99s si= mplify the situation. You have Fiber. With Fiber you can build an EventLoop + Scheduler, create two coroutines, and then run code inside them that, for example, renders a template. It will require a fair amount of code, but it=E2=80=99s possible. At the same time, ob_start/ob_end will immediately break, because they don=E2=80=99t support Fiber switching. This is a known bug. And if you pass global state into closures, and that state changes unpredictably, the application logic will essentially break. **What=E2=80=99s different with TrueAsync** 1. You don=E2=80=99t need to write a lot of code. Yes, just spawn(); 2. `ob_start` and `ob_end` will work correctly. 3. If closures share a variable that multiple coroutines write to unpredictably, the application will still break. In other words, no matter how asynchrony is implemented in PHP (and other langs), it will always require correct handling of shared memory. And I want to clarify a bit. This is not about a global variable. It=E2=80= =99s about shared memory. These are not the same things. A local variable can be passed into a closure by reference. But if you don=E2=80=99t call WP() inside a coroutine, nothing prevents you from using asynchrony. In TrueAsync there is a Dockerfile for FPM, you can install it locally and try running WordPress. I=E2=80=99m sure something will break, but not everything at once :) > My understanding of AMPHP is that things only become async if you explici= tly run AMPHP as your web server. It either has no effect > if your application is running Apache + mod_php OR your application 100% = breaks with nothing getting executed at all. Is this not true? You can use it without a server. The only difference is that the coroutines won=E2=80=99t live longer than the HTTP request. The same applie= s to TrueAsync when running under FPM. > When I try to open my website locally it will either have everything brok= en or it will just work regularly and nothing will be running async. There = is no other option. It won=E2=80=99t break on its own. It will only break if that =E2=80=9Csomething=E2=80=9D shares a variable or= resource with your code. If you write code according to SOLID principles, the chance of breakage is very low. If someone writes coroutine code and completely ignores memory handling, it=E2=80=99s the same as writing an infinite loop. Can they do th= at? Yes. Can you download that code? Yes. Can it break everything? It can. What=E2=80=99s the conclusion? > I do `composer update` one day and test my home page and it works. But de= eply nested somewhere there is a feature that will use Package A which > then spawns a coroutine and leads to my global state code behaving weirdl= y. It's not a fatal error. It's not very clear at all to me that something = changed, > but now my array indexes are triggering DB updates out of order. The exact same thing will happen in code without coroutines if, for example, you have a class, you pass an array to it by reference, and that class silently corrupts your values. You don=E2=80=99t need asynchrony for that to happen. ```php data =3D &$data; } public function loadUser() { // looks like a harmless read return $this->data['user'] ?? null; } public function updateInternally() { // silently mutates the external array $this->data['user'] =3D 'hacked'; $this->data['counter'] =3D ($this->data['counter'] ?? 0) + 1; } } // --------------------- $shared =3D [ 'user' =3D> 'admin', 'counter' =3D> 0, ]; // create the class, passing the array by reference $storage =3D new Storage($shared); echo $storage->loadUser() . PHP_EOL; // admin // somewhere else this method is called, modifying the shared array $storage->updateInternally(); print_r($shared); // the array is now corrupted unexpectedly ``` There is no asynchrony in the example above. It=E2=80=99s just normal code.= It breaks application logic because the class secretly holds the array and modifies it without permission. And a coroutine is just a regular object. If you pass a referenced array into a coroutine and then say something =E2=80=9Caccidentally=E2=80= =9D broke, it wasn=E2=80=99t accidental. Did the array get there by accident? No. Did som= e developer write the code by accident? No. It=E2=80=99s a bit different from synchronous code, but the meaning is exactly the same. I have a mental habit: when I write asynchronous code, I always assume that any object shared between coroutines can change at any moment. Similarly, if you hand off memory ownership to another class or share memory, you have to keep in mind that there is a chance some developer might accidentally do something wrong. The only difference between synchronous and asynchronous code is that you don=E2=80=99t have a precise moment in time when the change happens. An= d yes, that makes debugging harder. It makes finding bugs harder. But it=E2=80=99s not something fundamentally new. Yes, making the same mistakes with AMPHP is harder, because you need to install a whole package and so on. But that=E2=80=99s not a guarantee :)