Connector.php 3.3KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138
  1. <?php
  2. namespace Illuminate\Database\Connectors;
  3. use PDO;
  4. use Exception;
  5. use Throwable;
  6. use Doctrine\DBAL\Driver\PDOConnection;
  7. use Illuminate\Database\DetectsLostConnections;
  8. class Connector
  9. {
  10. use DetectsLostConnections;
  11. /**
  12. * The default PDO connection options.
  13. *
  14. * @var array
  15. */
  16. protected $options = [
  17. PDO::ATTR_CASE => PDO::CASE_NATURAL,
  18. PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
  19. PDO::ATTR_ORACLE_NULLS => PDO::NULL_NATURAL,
  20. PDO::ATTR_STRINGIFY_FETCHES => false,
  21. PDO::ATTR_EMULATE_PREPARES => false,
  22. ];
  23. /**
  24. * Create a new PDO connection.
  25. *
  26. * @param string $dsn
  27. * @param array $config
  28. * @param array $options
  29. * @return \PDO
  30. */
  31. public function createConnection($dsn, array $config, array $options)
  32. {
  33. list($username, $password) = [
  34. $config['username'] ?? null, $config['password'] ?? null,
  35. ];
  36. try {
  37. return $this->createPdoConnection(
  38. $dsn, $username, $password, $options
  39. );
  40. } catch (Exception $e) {
  41. return $this->tryAgainIfCausedByLostConnection(
  42. $e, $dsn, $username, $password, $options
  43. );
  44. }
  45. }
  46. /**
  47. * Create a new PDO connection instance.
  48. *
  49. * @param string $dsn
  50. * @param string $username
  51. * @param string $password
  52. * @param array $options
  53. * @return \PDO
  54. */
  55. protected function createPdoConnection($dsn, $username, $password, $options)
  56. {
  57. if (class_exists(PDOConnection::class) && ! $this->isPersistentConnection($options)) {
  58. return new PDOConnection($dsn, $username, $password, $options);
  59. }
  60. return new PDO($dsn, $username, $password, $options);
  61. }
  62. /**
  63. * Determine if the connection is persistent.
  64. *
  65. * @param array $options
  66. * @return bool
  67. */
  68. protected function isPersistentConnection($options)
  69. {
  70. return isset($options[PDO::ATTR_PERSISTENT]) &&
  71. $options[PDO::ATTR_PERSISTENT];
  72. }
  73. /**
  74. * Handle an exception that occurred during connect execution.
  75. *
  76. * @param \Throwable $e
  77. * @param string $dsn
  78. * @param string $username
  79. * @param string $password
  80. * @param array $options
  81. * @return \PDO
  82. *
  83. * @throws \Exception
  84. */
  85. protected function tryAgainIfCausedByLostConnection(Throwable $e, $dsn, $username, $password, $options)
  86. {
  87. if ($this->causedByLostConnection($e)) {
  88. return $this->createPdoConnection($dsn, $username, $password, $options);
  89. }
  90. throw $e;
  91. }
  92. /**
  93. * Get the PDO options based on the configuration.
  94. *
  95. * @param array $config
  96. * @return array
  97. */
  98. public function getOptions(array $config)
  99. {
  100. $options = $config['options'] ?? [];
  101. return array_diff_key($this->options, $options) + $options;
  102. }
  103. /**
  104. * Get the default PDO connection options.
  105. *
  106. * @return array
  107. */
  108. public function getDefaultOptions()
  109. {
  110. return $this->options;
  111. }
  112. /**
  113. * Set the default PDO connection options.
  114. *
  115. * @param array $options
  116. * @return void
  117. */
  118. public function setDefaultOptions(array $options)
  119. {
  120. $this->options = $options;
  121. }
  122. }