Skip to content

sqlsrv_fetch_object modifies full qualified class names #119

@xalopp

Description

@xalopp

sqlsrv_fetch_object modifies the full qualified class names of the supplied class.

The following PHP Code

<?php

namespace Doctrine\Tests\DBAL\Functional;

class A {
    public $accountNumber;
}

$idx = array_search(__NAMESPACE__.'\\A',get_declared_classes());
echo "orig class ".__NAMESPACE__.'\\A'." exits: ".(class_exists(__NAMESPACE__.'\\A')?'yes':'no').PHP_EOL;
echo "lower class ".strtolower(__NAMESPACE__.'\\A')." exits: ".(class_exists(strtolower(__NAMESPACE__.'\\A'))?'yes':'no').PHP_EOL;
echo 'BEFORE:  '.get_declared_classes()[$idx].PHP_EOL;

$serverName        = "192.168.123.41";
$connectionOptions = ["Database" => "AdventureWorks2016CTP3", "Uid" => "test", "PWD" => 'test'];

$conn = sqlsrv_connect( $serverName, $connectionOptions);
if($conn === false) {
    die(print_r(sqlsrv_errors(), true));
}

$sql = "SELECT [AccountNumber] FROM Sales.Customer";
$stmt = sqlsrv_query( $conn, $sql);
if($stmt === false ) {
    die(print_r(sqlsrv_errors(), true));
}

$obj = sqlsrv_fetch_object($stmt, __NAMESPACE__.'\\A');

echo "orig class ".__NAMESPACE__.'\\A'." exits: ".(class_exists(__NAMESPACE__.'\\A')?'yes':'no').PHP_EOL;
echo "lower class ".strtolower(__NAMESPACE__.'\\A')." exits: ".(class_exists(strtolower(__NAMESPACE__.'\\A'))?'yes':'no').PHP_EOL;
echo 'AFTER:  '.get_declared_classes()[$idx].PHP_EOL;

produces on Ubuntu 16.04 PHP 7.0.9-1+deb.sury.org~xenial+1 (cli) ( NTS ) with sqlsrv driver version 4.0.2 following output:

orig class Doctrine\Tests\DBAL\Functional\A exits: yes
lower class doctrine\tests\dbal\functional\a exits: yes
BEFORE:  Doctrine\Tests\DBAL\Functional\A
orig class Doctrine\Tests\DBAL\Functional\A exits: no
lower class doctrine\tests\dbal\functional\a exits: yes
AFTER:  doctrine\tests\dbal\functional\a

as you can see, the full qualified class name changed completely to lowercase and class_exists is unable to find the class with its original name! 😵

Unfortunately, the source code of the Linux version isn't release yet, but I'm persuaded that the bug also exists on Windows, for PHP5 and PHP7.

I suspect the line https://github.com/Azure/msphpsql/blob/PHP-7.0/sqlsrv/stmt.cpp#L797 is causing the problem, because the lowercase class name is create here and used in https://github.com/Azure/msphpsql/blob/PHP-7.0/sqlsrv/stmt.cpp#L825 to instantiate the corresponding object.

Since zend_lookup_class which is called in https://github.com/Azure/msphpsql/blob/PHP-7.0/sqlsrv/stmt.cpp#L816 is using the lower cased class name internally, it's not required to call it with a lower cased class name.

I would recommend to use in sqlsrv_fetch_object the class name, spelled as returned from get_declared_classes.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions