private function interceptMySQLiSelectDb()

in agent/php/ElasticApm/Impl/AutoInstrument/MySQLiAutoInstrumentation.php [261:336]


    private function interceptMySQLiSelectDb(RegistrationContextInterface $ctx): void
    {
        /**
         * @param ?string      $className
         * @param string       $funcName
         * @param ?object      $interceptedCallThis
         * @param array<mixed> $interceptedCallArgs
         *
         * @return ?callable
         */
        $preHook = function (
            ?string $className,
            string $funcName,
            ?object $interceptedCallThis,
            array $interceptedCallArgs
        ): ?callable {
            if (!$this->util->verifyInstanceOf(mysqli::class, $interceptedCallThis)) {
                return null;
            }
            /** @var mysqli $interceptedCallThis */

            /** @var ?string $currentDbName */
            $currentDbName = $this->mapPerObject->getOr(
                $interceptedCallThis,
                DbAutoInstrumentationUtil::PER_OBJECT_KEY_DB_NAME,
                null /* <- defaultValue */
            );

            if (
                !$this->util->verifyMinArgsCount(1, $interceptedCallArgs)
                || !$this->util->verifyIsString($interceptedCallArgs[0])
            ) {
                return null;
            }
            /** @var string $newDbName */
            $newDbName = $interceptedCallArgs[0];

            $span = self::beginSpan(
                $className,
                $funcName,
                $currentDbName,
                null /* <- statement */
            );
            return AutoInstrumentationUtil::createInternalFuncPostHookFromEndSpan(
                $span,
                /**
                 * doBeforeSpanEnd
                 *
                 * @param bool  $hasExitedByException
                 * @param mixed $returnValueOrThrown
                 */
                function (
                    bool $hasExitedByException,
                    $returnValueOrThrown
                ) use (
                    $interceptedCallThis,
                    $newDbName,
                    $span
                ): void {
                    if ($hasExitedByException) {
                        return;
                    }
                    if ($this->util->verifyIsBool($returnValueOrThrown) && $returnValueOrThrown) {
                        DbAutoInstrumentationUtil::setServiceForDbSpan($span, self::DB_TYPE, $newDbName);
                        $this->mapPerObject->set(
                            $interceptedCallThis,
                            DbAutoInstrumentationUtil::PER_OBJECT_KEY_DB_NAME,
                            $newDbName
                        );
                    }
                }
            );
        };

        $this->interceptCallsTo($ctx, self::MYSQLI_CLASS_NAME, 'select_db', $preHook);
    }