php / php/php-src

PHP 8.4.0RC4: Zend Observer does not work for PDO query() method when the new PDO connect() is used

オープン
#16,857 コメント 7 件 リアクション 0 件 担当者 0 名 GitHub で見る

まだ誰も着手していません。

Bug Category: Documentation Extension: pdo (core) Status: Needs Triage
主要言語
C
スター
40.4k
フォーク
8.1k
平均マージ
2日 13時間
マージ済み PR(30日)
96

説明

Description

Problem Description
We have a custom PHP extension that registers as an observer for PDO extension's methods like __construct(), query(), etc., and our extension's handler functions get invoked when any of these PDO methods are being executed. This code is pretty generic from our side and is the same for all PDO methods we observe. But starting from PHP 8.4.0, our observer functions/function handlers are not being invoked when PDO query() method is being executed (when connect() is used) - the execution directly goes to PDO query() method instead of our registered function handlers. There is some crucial, unexplained behavioral difference I want to highlight here considering PHP introduced connect() method to create PDO objects. We adapted our code to also register observer & function handler for the new connect() method and our function handler is being invoked correctly for connect() method but not for query() method that is executed after the connect().

So:
If PDO::__construct() is used by PHP app, our extension's function handlers for __construct() AND query() are both correctly invoked by the Zend engine.
If PDO::connect() is used by PHP app, only connect() function handler in our extension is invoked but not the function handler for query().

This is inconsistent behaviour from the Zend engine.

Just to clarify how we use Zend observer API:
During MINIT:

  1. We use zend_observer_fcall_register() to register begin and end function handlers.
  2. We use the CG() macro to get class entry object for "PDO" class and overwrite the zend_function->internal_function_handler with our own function for __construct(), connect(), query()

We verified some aspects during runtime using a debugger :

  1. Looking into the CG hashtable after we register our functions - we can confirm that zend_function->internal_function_handler for both connect() and query() hold the pointers to our extension's overwritten function handler, not the original PDO methods. 2. Inside ZEND_DO_FCALL_SPEC_OBSERVER_HANDLER() in zend_vm_execute.h from where these two functions/PDO methods are eventually invoked, we can see that the fbc->internal_function.handler for during query() execution holds some unresolved address - that is neither pointing to zim_PDO_query() or our extension's overwritten function handler.

Strange thing is, for the PDO connect() execution, fbc->internal_function.handler does point to our extension's function handler. As I said, registering observer and overwriting function handlers for these functions in the CG hashtable is generic and has been working on PHP 8.3.

PHP Version

PHP 8.4.0RC4

Operating System

No response

コントリビューションガイド

コントリビューションガイドを開く

はじめの一歩

  1. issue を最後まで読み、次にプロジェクトのコントリビューションガイドを読みます。
  2. 着手することを issue にコメントします — 二人が同じ作業をするのを防げます。
  3. リポジトリをフォークし、ブランチを切って変更します。
  4. issue 番号を参照したプルリクエストを送ります。

調査の方向性

Issue で説明されている Zend observer の登録と handler の上書きを使って、PDO::__construct() と PDO::connect() に続く query() の違いを再現してください。zend_vm_execute.h の ZEND_DO_FCALL_SPEC_OBSERVER_HANDLER() から開始し、CG hashtable 内の PDO エントリを調べてください。connect() 後に query() が登録済みの observer handler を一貫して呼び出せば完了です。

索引モデルが issue の本文から書いたものです。

評価

技術スタック
c, php
領域
backend, compilers
issue の種類
バグ
難易度
4/5
見積もり時間
3〜5日
活発さ
停滞
明瞭さ
おおむね明確
初心者へのやさしさ
35/100

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。