Проблема со вторым PDOStatement

Ar2r

Новичок
Товарищи, требуется помощь.

Есть упрощенный класс для работы с БД:
PHP:
class DB extends PDO
{
    public static $query_count = 0; //счётчик запросов

    public function __construct(/*string*/$dsn, /*string*/$user, /*string*/$pass, $driver_option = array())
    {
        parent::__construct($dsn,$user,$pass,$driver_option);
        $this->setAttribute(PDO::ATTR_STATEMENT_CLASS, array('DB_statement', array($this)));
    }
    public function DBexec($statement)
    {
        $rows = parent::exec($statement);
        self::$query_count ++;
        return $rows;
    }
    public function DBquery($sql)
    {
        self::$query_count ++;
        return parent::query($sql);
    }
}

class DB_statement extends PDOStatement
{
    protected $db;

    protected function __construct(DB $db)
    {
        $this->db = $db;
    }
    public function DBexecute($parameters = array())
    {
        DB::$query_count ++;
        return parent::execute($parameters);
    }
}
Есть скрипт выполняющий два запроса к БД:
PHP:
$DB2 = new DB("dblib:host=MSCSSQL01;dbname=IT", '***', '***');

$res = $DB2->DBquery("SELECT 'x' as x");
var_dump($res);
print_r($res->fetchAll());

$res = $DB2->DBquery("SELECT 'y' as y");
var_dump($res);
print_r($res->fetchAll());
Результат:
Код:
class DB_statement#2 (2) {
  protected $db =>
  class DB#1 (0) {
  }
  public $queryString =>
  string(15) "SELECT 'x' as x"
}
Array
(
    [0] => Array
        (
            [x] => x
            [0] => x
        )

)
class DB_statement#3 (2) {
  protected $db =>
  class DB#1 (0) {
  }
  public $queryString =>
  string(15) "SELECT 'y' as y"
}
Array
(
)
Второй массив с данными пустой.

А вот если выполнить unset или $res2 использовать, то проблема не проявляется.

PHP:
 $DB2 = new DB("dblib:host=MSCSSQL01;dbname=IT", '***', '***');

$res = $DB2->DBquery("SELECT 'x' as x");
var_dump($res);
print_r($res->fetchAll());

unset($res);

$res = $DB2->DBquery("SELECT 'y' as y");
var_dump($res);
print_r($res->fetchAll());

И отличный результат получаем.

Код:
class DB_statement#2 (2) {
  protected $db =>
  class DB#1 (0) {
  }
  public $queryString =>
  string(15) "SELECT 'x' as x"
}
Array
(
    [0] => Array
        (
            [x] => x
            [0] => x
        )

)
class DB_statement#2 (2) {
  protected $db =>
  class DB#1 (0) {
  }
  public $queryString =>
  string(15) "SELECT 'y' as y"
}
Array
(
    [0] => Array
        (
            [y] => y
            [0] => y
        )

)
Подскажите, как правильно должен быть написал Wrapper для PDO? У всех классов для PDO аналогичная проблема.
 

fixxxer

К.О.
Партнер клуба
А на чистом pdo воспроизводится? Если да, судя по dsn, это unixodbc/freetds, припоминаю за ними подобный багодром, пробуй на последних версиях оных. У меня как раз на prepared-ах был подобный ад (запросе на 4-5-м вообще в корку падало), обновлениями не вылечилось, плюнул и поднял виндовс-сервер. Но это было 2 с лишним года назад - могли и исправить уже.
 
Последнее редактирование:

Ar2r

Новичок
А на чистом pdo воспроизводится? Если да, судя по dsn, это unixodbc/freetds
Благодарю, получается что проблема скорее всего с FreeTDS.
На новом сервере данная ошибка отсутствует.

Сервер CentOS 5 с ошибкой:
Код:
$ tsql -C
Compile-time settings (established with the "configure" script)
  Version: freetds v0.82
  freetds.conf directory: /etc
  MS db-lib source compatibility: yes
  Sybase binary compatibility: yes
  Thread safety: yes
  iconv library: yes
  TDS version: 4.2
  iODBC: no
  unixodbc: yes
Сервер CentOS 6 без ошибки:
Код:
$ tsql -C
Compile-time settings (established with the "configure" script)
  Version: freetds v0.91
  freetds.conf directory: /etc
  MS db-lib source compatibility: yes
  Sybase binary compatibility: yes
  Thread safety: yes
  iconv library: yes
  TDS version: 4.2
  iODBC: no
  unixodbc: yes
  SSPI "trusted" logins: no
  Kerberos: yes
 

Ar2r

Новичок
Есть хорошая и плохая новость.

Хорошая: PHP 5.4.* Из основного CentOS 6.5 репозитория не имеет данной ошибки.

Плохая: PHP 5.3 из стандартного репозитория CentOS 5-6 собрано с кривым FreeTDS. Версия установленного бинарника FreeTDS не имеет значения. Имеет значение только параметры, с которыми собран PHP в репозитории.

Итого: Единственный рабочий вариант PHP 5.3 под CentOS 6.5 - ставить из REMI репозитория:

Код:
yum  --enablerepo="remi" downgrade $(rpm -qa --qf "%{NAME}\n" | grep -v ioncube | grep ^php | awk '{print $1"-5.3.3"}') --skip-broken

Код:
[webdev@vsweb06 www]$ php -v
PHP 5.3.3 (cli) (built: Dec 11 2013 03:29:57)
Copyright (c) 1997-2010 The PHP Group
Zend Engine v2.3.0, Copyright (c) 1998-2010 Zend Technologies
    with Xdebug v2.2.1, Copyright (c) 2002-2012, by Derick Rethans
[webdev@vsweb06 www]$ php /var/www/html/stuff2/hasanov/sdb.php
<pre><hr><hr>
Not exist
class PDOStatement#3 (1) {
  public $queryString =>
  string(16) "SELECT 'x2' as x"
}
Array
(
    [0] => Array
        (
            [x] => x2
        )

)
<hr>
Exist
class PDOStatement#4 (1) {
  public $queryString =>
  string(16) "SELECT 'y2' as y"
}
Array
(
    [0] => Array
        (
            [y] => y2
        )

)
Код:
[webdev@vsweb06 www]$ tsql -C
Compile-time settings (established with the "configure" script)
                            Version: freetds v0.91
            freetds.conf directory: /etc
    MS db-lib source compatibility: yes
        Sybase binary compatibility: yes
                      Thread safety: yes
                      iconv library: yes
                        TDS version: 4.2
                              iODBC: no
                          unixodbc: yes
              SSPI "trusted" logins: no
                          Kerberos: yes
 
Последнее редактирование:
Сверху