PdoCaster.php 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124
  1. <?php
  2. /*
  3. * This file is part of the Symfony package.
  4. *
  5. * (c) Fabien Potencier <fabien@symfony.com>
  6. *
  7. * For the full copyright and license information, please view the LICENSE
  8. * file that was distributed with this source code.
  9. */
  10. namespace Symfony\Component\VarDumper\Caster;
  11. use Symfony\Component\VarDumper\Cloner\Stub;
  12. /**
  13. * Casts PDO related classes to array representation.
  14. *
  15. * @author Nicolas Grekas <p@tchwork.com>
  16. *
  17. * @final
  18. *
  19. * @internal since Symfony 7.3
  20. */
  21. class PdoCaster
  22. {
  23. private const PDO_ATTRIBUTES = [
  24. 'CASE' => [
  25. \PDO::CASE_LOWER => 'LOWER',
  26. \PDO::CASE_NATURAL => 'NATURAL',
  27. \PDO::CASE_UPPER => 'UPPER',
  28. ],
  29. 'ERRMODE' => [
  30. \PDO::ERRMODE_SILENT => 'SILENT',
  31. \PDO::ERRMODE_WARNING => 'WARNING',
  32. \PDO::ERRMODE_EXCEPTION => 'EXCEPTION',
  33. ],
  34. 'TIMEOUT',
  35. 'PREFETCH',
  36. 'AUTOCOMMIT',
  37. 'PERSISTENT',
  38. 'DRIVER_NAME',
  39. 'SERVER_INFO',
  40. 'ORACLE_NULLS' => [
  41. \PDO::NULL_NATURAL => 'NATURAL',
  42. \PDO::NULL_EMPTY_STRING => 'EMPTY_STRING',
  43. \PDO::NULL_TO_STRING => 'TO_STRING',
  44. ],
  45. 'CLIENT_VERSION',
  46. 'SERVER_VERSION',
  47. 'STATEMENT_CLASS',
  48. 'EMULATE_PREPARES',
  49. 'CONNECTION_STATUS',
  50. 'STRINGIFY_FETCHES',
  51. 'DEFAULT_FETCH_MODE' => [
  52. \PDO::FETCH_ASSOC => 'ASSOC',
  53. \PDO::FETCH_BOTH => 'BOTH',
  54. \PDO::FETCH_LAZY => 'LAZY',
  55. \PDO::FETCH_NUM => 'NUM',
  56. \PDO::FETCH_OBJ => 'OBJ',
  57. ],
  58. ];
  59. public static function castPdo(\PDO $c, array $a, Stub $stub, bool $isNested): array
  60. {
  61. $attr = [];
  62. $errmode = $c->getAttribute(\PDO::ATTR_ERRMODE);
  63. $c->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
  64. foreach (self::PDO_ATTRIBUTES as $k => $v) {
  65. if (!isset($k[0])) {
  66. $k = $v;
  67. $v = [];
  68. }
  69. try {
  70. $attr[$k] = 'ERRMODE' === $k ? $errmode : $c->getAttribute(\constant('PDO::ATTR_'.$k));
  71. if ($v && isset($v[$attr[$k]])) {
  72. $attr[$k] = new ConstStub($v[$attr[$k]], $attr[$k]);
  73. }
  74. } catch (\Exception) {
  75. }
  76. }
  77. if (isset($attr[$k = 'STATEMENT_CLASS'][1])) {
  78. if ($attr[$k][1]) {
  79. $attr[$k][1] = new ArgsStub($attr[$k][1], '__construct', $attr[$k][0]);
  80. }
  81. $attr[$k][0] = new ClassStub($attr[$k][0]);
  82. }
  83. $prefix = Caster::PREFIX_VIRTUAL;
  84. $a += [
  85. $prefix.'inTransaction' => method_exists($c, 'inTransaction'),
  86. $prefix.'errorInfo' => $c->errorInfo(),
  87. $prefix.'attributes' => new EnumStub($attr),
  88. ];
  89. if ($a[$prefix.'inTransaction']) {
  90. $a[$prefix.'inTransaction'] = $c->inTransaction();
  91. } else {
  92. unset($a[$prefix.'inTransaction']);
  93. }
  94. if (!isset($a[$prefix.'errorInfo'][1], $a[$prefix.'errorInfo'][2])) {
  95. unset($a[$prefix.'errorInfo']);
  96. }
  97. $c->setAttribute(\PDO::ATTR_ERRMODE, $errmode);
  98. return $a;
  99. }
  100. public static function castPdoStatement(\PDOStatement $c, array $a, Stub $stub, bool $isNested): array
  101. {
  102. $prefix = Caster::PREFIX_VIRTUAL;
  103. $a[$prefix.'errorInfo'] = $c->errorInfo();
  104. if (!isset($a[$prefix.'errorInfo'][1], $a[$prefix.'errorInfo'][2])) {
  105. unset($a[$prefix.'errorInfo']);
  106. }
  107. return $a;
  108. }
  109. }