php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #78095 get_class_methods() does not show all methods of a specific PDO driver
Submitted: 2019-06-01 18:08 UTC Modified: -
From: celsowm at gmail dot com Assigned:
Status: Open Package: PDO related
PHP Version: 7.3.6 OS: Windows
Private report: No CVE-ID: None
 [2019-06-01 18:08 UTC] celsowm at gmail dot com
Description:
------------
I was trying to get all method for each PDO driver (I have all of them installed on my PC Windows).

But if I try, for example, using Postgres (pdo_pgsql):

var_dump(get_class_methods($pdo));

The result is:

array(17) { [0]=> string(11) "__construct" [1]=> string(7) "prepare" [2]=> string(16) "beginTransaction" [3]=> string(6) "commit" [4]=> string(8) "rollBack" [5]=> string(13) "inTransaction" [6]=> string(12) "setAttribute" [7]=> string(4) "exec" [8]=> string(5) "query" [9]=> string(12) "lastInsertId" [10]=> string(9) "errorCode" [11]=> string(9) "errorInfo" [12]=> string(12) "getAttribute" [13]=> string(5) "quote" [14]=> string(8) "__wakeup" [15]=> string(7) "__sleep" [16]=> string(19) "getAvailableDrivers" } 

But this list is incomplete because PDO Postgres includes methods like:

$pdo->pgsqlCopyToArray('my_table');

Test script:
---------------
<?php

$options = [
    PDO::ATTR_ERRMODE            => PDO::ERRMODE_EXCEPTION,
    PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
    PDO::ATTR_EMULATE_PREPARES   => false,
];

$server    = "localhost";
$dsn       = "pgsql:host=$server;port=5432;dbname=livraria;";
$user      = "postgres";
$senha     = "admin";

$pdo = new PDO($dsn, $user, $senha, $options);
var_dump(get_class_methods($pdo));
var_dump(array_column((new ReflectionClass($pdo))->getMethods(), 'name'));
var_dump($pdo->pgsqlCopyToArray('livro'));




Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2019-06-03 11:27 UTC] daverandom@php.net
It's probably not practical to provide the expected result here. Worth noting is that the function is called get_**class**_methods() - the additional methods provided by some drivers are not members of the class, rather they are handled by an internal mechanism which is effectively the same as the __call() magic method.

That said, it would perhaps be a little less surprising if the class had a dummy __call() method, so they aren't totally "invisible" as now?
 [2019-06-04 16:23 UTC] celsowm at gmail dot com
@daverandom, another point:

method_exists($pdo, 'pgsqlCopyToArray') returns TRUE !

Unfortunately I am a newbie on PHP Internals but, doing some search on zend_builtin_functions.c I found some interesting things like zend_class_entry->function_table, used by both method_exists and get_class_methods.

While get_class_methods uses only "function_table" (doing a ZEND_HASH_FOREACH_STR_KEY_PTR)method_exists try things like Z_OBJ_HT_P(klass)->get_method
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Mon Oct 14 03:01:27 2024 UTC