Newsgroups: php.internals Path: news.php.net Xref: news.php.net php.internals:126215 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 qa.php.net (Postfix) with ESMTPS id D3DD91A00BC for ; Tue, 21 Jan 2025 05:39:35 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/simple; d=php.net; s=mail; t=1737437804; bh=k/FV3V0XeZLPkkikW+CejI3ZA5sSNyIcYC2wNPtlEbc=; h=Date:To:From:Subject:From; b=Z2BHdztPrvYfu1JWtn5HopO3my/rg74fZr/Gy8lLT/NYWR+IYEND9Fw7Kwnvuwo9r +kUSIAEGYH0CClTQ8StvvsleehL4jw7EOQR9XanpTVFj4xwpjq4QDUTZtbBbUt/E47 V6fxl34vxo79+Y9+O2+WXtjduXFJVN139kWWhcG8uHdpa+yYAXYFzhj3kZ3EHkw+l1 /ggrvYDlont8Ga8IMoBfCYm5vT/p5MtHagqUZcC+f2JF7V3fscEr74qpi7btzhfAR3 2BMI49B1GRVXeDqRMm9l854O84vxtc+s/wdeARJ9mAmGyn68tSIrQQnDo17ZSBZ3vR w8kNov7By279Q== Received: from php-smtp4.php.net (localhost [127.0.0.1]) by php-smtp4.php.net (Postfix) with ESMTP id 6954D180084 for ; Tue, 21 Jan 2025 05:36:42 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 4.0.0 (2022-12-13) 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,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H3,RCVD_IN_MSPIKE_WL,SPF_HELO_PASS,SPF_PASS autolearn=no autolearn_force=no version=4.0.0 X-Spam-Virus: No X-Envelope-From: Received: from mail-4317.proton.ch (mail-4317.proton.ch [185.70.43.17]) (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 ; Tue, 21 Jan 2025 05:36:41 +0000 (UTC) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gpb.moe; s=protonmail3; t=1737437970; x=1737697170; bh=k/FV3V0XeZLPkkikW+CejI3ZA5sSNyIcYC2wNPtlEbc=; h=Date:To:From:Subject:Message-ID:Feedback-ID:From:To:Cc:Date: Subject:Reply-To:Feedback-ID:Message-ID:BIMI-Selector: List-Unsubscribe:List-Unsubscribe-Post; b=3NCwmmB0DOCHXoITaJ2ZBNqwTQPiTJ5e3M+gh9xnJX51py8QLz+YwKvN7eXfjakhr 8blrgsorAGyd3RuylYEThkFgmE/e8yCMG1nGrRPjsRb84XqEaUk/bz68HnhwCxNWFw yX/ODeWxXPwnlHPXl29AFmQ67UVMMev1e0/CtFm+3aywTMElVgpIyeIUlM39IchSuc YQVfq6vo2oWjpYrPfCQebZe5W1/s3YYJ2VUUMS2Bm9A9yvLAgoaw9L9MuxyHoyWpWt /rZO4He+qJ1GFIrp/AGceBQxIX80VSDLC80XKy/BUAMIvQuUx1qYQob/DjQg2+JTMO nRWUByNXzrPmg== Date: Tue, 21 Jan 2025 05:39:26 +0000 To: PHP internals Subject: [PHP-DEV] Use usual semantics for PDO::FETCH_CLASS constructor arguments Message-ID: Feedback-ID: 96993444:user:proton X-Pm-Message-ID: fb57a2c90137d2f3860a53f76081a2676ba4834b Precedence: bulk list-help: list-post: List-Id: internals.lists.php.net x-ms-reactions: disallow MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Transfer-Encoding: quoted-printable From: internals@gpb.moe ("Gina P. Banyard") Hello internals, For the past few weeks I have been refactoring the PDO extension to reduce = the complexity of the implementation but also lower the memory requirement = of the _pdo_stmt_t struct. And in this process I rediscovered an oddity which prevents removing the us= age of the FCI struct (which takes 64 bytes) from it. The constructor arguments for the class are passed as a PHP array to PDOSta= tement::setFetchMode(), PDOStatement::fetchAll(), and PDOStatment::fetchObj= ect(). However, this array of parameters does not have the same semantics as the $= args parameter of call_user_func_array(). (CUFA for short.) The reason for this is that it uses a rather unintuitive and obscure Zend A= PI called zend_fcall_info_args_ex(), this API sets the arguments of a call by copying each argument one after th= e other as a positional argument. And if a zend_function pointer is provided, it will check if the function a= rgument should be passed by reference and automatically wrap values into a = reference without a warning. This behaviour is at odds with passing a keyed array to CUFA, where the key= will act as a named argument look-up, and with normal calling semantics wh= ere a by-ref argument being passed by value will trigger an E_WARNING. Moreover, this API is effectively unused. A SourceGraph search [1] came up = with 9 results, where only 2 of them are relevant: - The UOPZ extension - The Zephir project, which allows generating a PHP C extension from PHPesq= ue code - All other 7 projects are extensions generated by using Zephir I have submitted PRs to Zephir [2] and UOPZ [3] that have been merged that = remove the usage of this API by instead passing the HashTable pointer of th= e array as the named_params field of the FCI. Thus, the only remaining usage of this API I can find is now in PDO. This conversion of using the named_params field of the FCI for calling the = constructor can also be done for PDO, allowing the removal of the FCI from _pdo_stmt_t, convert the ctor_arg zval= (which takes 16 bytes) to a HashTable* (taking only 8 bytes), and remove v= arious copies of the constructor arguments. Doing this causes some minor BC breaks as this aligns the behaviour with CU= FA which can be seen in the latest PR implementation. [4] It is possible to emulate the previous behaviour, but this requires doing a= deep copy of the constructor arguments, negating that benefit. To me, these minor BC breaks are acceptable as: - by-ref arguments in a constructor seems already rare, even more so in an = object that represents a database row - having an argument array behave differently than CUFA or what you would r= eceive with variadic arugments is somewhat a language inconsistency. Thoughts? For reference, this is effectively the same point I raised in a previous in= ternals thread, which didn't really get much attention. [5] Best regards, Gina P. Banyard [1] https://sourcegraph.com/search?q=3Dcontext:global+lang:C+zend_fcall_inf= o_args_ex+-file:zend_API.h+-file:zend_API.c+-file:pdo_stmt.c&patternType=3D= keyword&sm=3D0 [2] Zephir PR: https://github.com/zephir-lang/zephir/pull/2443 [3] UOPZ PR: https://github.com/krakjoe/uopz/pull/188 [4] https://github.com/php/php-src/pull/17427 [5] https://externals.io/message/118847