[ Index ] |
PHP Cross Reference of YOURLS |
[Summary view] [Print] [Text view]
1 <?php 2 /** 3 * 4 * This file is part of Aura for PHP. 5 * 6 * @license https://opensource.org/licenses/MIT MIT 7 * 8 */ 9 namespace Aura\Sql; 10 11 use Aura\Sql\Exception; 12 use Aura\Sql\Parser\ParserInterface; 13 use Aura\Sql\Profiler\ProfilerInterface; 14 use BadMethodCallException; 15 use PDO; 16 use PDOStatement; 17 18 /** 19 * 20 * Provides array quoting, profiling, a new `perform()` method, new `fetch*()` 21 * methods, and new `yield*()` methods. 22 * 23 * @package Aura.Sql 24 * 25 */ 26 abstract class AbstractExtendedPdo extends PDO implements ExtendedPdoInterface 27 { 28 /** 29 * 30 * The internal PDO connection. 31 * 32 * @var PDO 33 * 34 */ 35 protected $pdo; 36 37 /** 38 * 39 * Tracks and logs query profiles. 40 * 41 * @var ProfilerInterface 42 * 43 */ 44 protected $profiler; 45 46 /** 47 * 48 * Parses queries to rebuild them for easier parameter binding. 49 * 50 * @var ParserInterface 51 * 52 */ 53 protected $parser; 54 55 /** 56 * 57 * Prefix to use when quoting identifier names. 58 * 59 * @var string 60 * 61 */ 62 protected $quoteNamePrefix = '"'; 63 64 /** 65 * 66 * Suffix to use when quoting identifier names. 67 * 68 * @var string 69 * 70 */ 71 protected $quoteNameSuffix = '"'; 72 73 /** 74 * 75 * Find this string when escaping identifier names. 76 * 77 * @var string 78 * 79 */ 80 protected $quoteNameEscapeFind = '"'; 81 82 /** 83 * 84 * Use this as the replacement when escaping identifier names. 85 * 86 * @var string 87 * 88 */ 89 protected $quoteNameEscapeRepl = '""'; 90 91 /** 92 * 93 * Proxies to PDO methods created for specific drivers; in particular, 94 * `sqlite` and `pgsql`. 95 * 96 * @param string $name The PDO method to call; e.g. `sqliteCreateFunction` 97 * or `pgsqlGetPid`. 98 * 99 * @param array $arguments Arguments to pass to the called method. 100 * 101 * @return mixed 102 * 103 * @throws BadMethodCallException when the method does not exist. 104 * 105 */ 106 public function __call($name, array $arguments) 107 { 108 $this->connect(); 109 110 if (! method_exists($this->pdo, $name)) { 111 $class = get_class($this); 112 $message = "Class '{$class}' does not have a method '{$name}'"; 113 throw new BadMethodCallException($message); 114 } 115 116 return call_user_func_array([$this->pdo, $name], $arguments); 117 } 118 119 /** 120 * 121 * Begins a transaction and turns off autocommit mode. 122 * 123 * @return bool True on success, false on failure. 124 * 125 * @see http://php.net/manual/en/pdo.begintransaction.php 126 * 127 */ 128 #[\ReturnTypeWillChange] 129 public function beginTransaction() 130 { 131 $this->connect(); 132 $this->profiler->start(__FUNCTION__); 133 $result = $this->pdo->beginTransaction(); 134 $this->profiler->finish(); 135 return $result; 136 } 137 138 /** 139 * 140 * Commits the existing transaction and restores autocommit mode. 141 * 142 * @return bool True on success, false on failure. 143 * 144 * @see http://php.net/manual/en/pdo.commit.php 145 * 146 */ 147 #[\ReturnTypeWillChange] 148 public function commit() 149 { 150 $this->connect(); 151 $this->profiler->start(__FUNCTION__); 152 $result = $this->pdo->commit(); 153 $this->profiler->finish(); 154 return $result; 155 } 156 157 /** 158 * 159 * Connects to the database. 160 * 161 * @return null 162 * 163 */ 164 abstract public function connect(); 165 166 /** 167 * 168 * Disconnects from the database. 169 * 170 * @return null 171 * 172 */ 173 abstract public function disconnect(); 174 175 /** 176 * 177 * Gets the most recent error code. 178 * 179 * @return string 180 * 181 */ 182 #[\ReturnTypeWillChange] 183 public function errorCode() 184 { 185 $this->connect(); 186 return $this->pdo->errorCode(); 187 } 188 189 /** 190 * 191 * Gets the most recent error info. 192 * 193 * @return array 194 * 195 */ 196 #[\ReturnTypeWillChange] 197 public function errorInfo() 198 { 199 $this->connect(); 200 return $this->pdo->errorInfo(); 201 } 202 203 /** 204 * 205 * Executes an SQL statement and returns the number of affected rows. 206 * 207 * @param string $statement The SQL statement to prepare and execute. 208 * 209 * @return int|false The number of affected rows. 210 * 211 * @see http://php.net/manual/en/pdo.exec.php 212 * 213 */ 214 #[\ReturnTypeWillChange] 215 public function exec($statement) 216 { 217 $this->connect(); 218 $this->profiler->start(__FUNCTION__); 219 $affectedRows = $this->pdo->exec($statement); 220 $this->profiler->finish($statement); 221 return $affectedRows; 222 } 223 224 /** 225 * 226 * Performs a statement and returns the number of affected rows. 227 * 228 * @param string $statement The SQL statement to prepare and execute. 229 * 230 * @param array $values Values to bind to the query. 231 * 232 * @return int 233 * 234 */ 235 public function fetchAffected($statement, array $values = []) 236 { 237 $sth = $this->perform($statement, $values); 238 return $sth->rowCount(); 239 } 240 241 /** 242 * 243 * Fetches a sequential array of rows from the database; the rows 244 * are returned as associative arrays. 245 * 246 * @param string $statement The SQL statement to prepare and execute. 247 * 248 * @param array $values Values to bind to the query. 249 * 250 * @return array 251 * 252 */ 253 public function fetchAll($statement, array $values = []) 254 { 255 $sth = $this->perform($statement, $values); 256 return $sth->fetchAll(self::FETCH_ASSOC); 257 } 258 259 /** 260 * 261 * Fetches an associative array of rows from the database; the rows 262 * are returned as associative arrays, and the array of rows is keyed 263 * on the first column of each row. 264 * 265 * N.b.: If multiple rows have the same first column value, the last 266 * row with that value will override earlier rows. 267 * 268 * @param string $statement The SQL statement to prepare and execute. 269 * 270 * @param array $values Values to bind to the query. 271 * 272 * @return array 273 * 274 */ 275 public function fetchAssoc($statement, array $values = []) 276 { 277 $sth = $this->perform($statement, $values); 278 $data = []; 279 while ($row = $sth->fetch(self::FETCH_ASSOC)) { 280 $data[current($row)] = $row; 281 } 282 return $data; 283 } 284 285 /** 286 * 287 * Fetches the first column of rows as a sequential array. 288 * 289 * @param string $statement The SQL statement to prepare and execute. 290 * 291 * @param array $values Values to bind to the query. 292 * 293 * @return array 294 * 295 */ 296 public function fetchCol($statement, array $values = []) 297 { 298 $sth = $this->perform($statement, $values); 299 return $sth->fetchAll(self::FETCH_COLUMN, 0); 300 } 301 302 /** 303 * 304 * Fetches multiple from the database as an associative array. The first 305 * column will be the index key. 306 * 307 * @param string $statement The SQL statement to prepare and execute. 308 * 309 * @param array $values Values to bind to the query. 310 * 311 * @param int $style a fetch style defaults to PDO::FETCH_COLUMN for single 312 * values, use PDO::FETCH_NAMED when fetching a multiple columns 313 * 314 * @return array 315 * 316 */ 317 public function fetchGroup( 318 $statement, 319 array $values = [], 320 $style = PDO::FETCH_COLUMN 321 ) { 322 $sth = $this->perform($statement, $values); 323 return $sth->fetchAll(self::FETCH_GROUP | $style); 324 } 325 326 /** 327 * 328 * Fetches one row from the database as an object where the column values 329 * are mapped to object properties. 330 * 331 * Warning: PDO "injects property-values BEFORE invoking the constructor - 332 * in other words, if your class initializes property-values to defaults 333 * in the constructor, you will be overwriting the values injected by 334 * fetchObject() !" 335 * 336 * <http://www.php.net/manual/en/pdostatement.fetchobject.php#111744> 337 * 338 * @param string $statement The SQL statement to prepare and execute. 339 * 340 * @param array $values Values to bind to the query. 341 * 342 * @param string $class The name of the class to create. 343 * 344 * @param array $args Arguments to pass to the object constructor. 345 * 346 * @return object|false 347 * 348 */ 349 public function fetchObject( 350 $statement, 351 array $values = [], 352 $class = 'stdClass', 353 array $args = [] 354 ) { 355 $sth = $this->perform($statement, $values); 356 357 if (! empty($args)) { 358 return $sth->fetchObject($class, $args); 359 } 360 361 return $sth->fetchObject($class); 362 } 363 364 /** 365 * 366 * Fetches a sequential array of rows from the database; the rows 367 * are returned as objects where the column values are mapped to 368 * object properties. 369 * 370 * Warning: PDO "injects property-values BEFORE invoking the constructor - 371 * in other words, if your class initializes property-values to defaults 372 * in the constructor, you will be overwriting the values injected by 373 * fetchObject() !" 374 * 375 * <http://www.php.net/manual/en/pdostatement.fetchobject.php#111744> 376 * 377 * @param string $statement The SQL statement to prepare and execute. 378 * 379 * @param array $values Values to bind to the query. 380 * 381 * @param string $class The name of the class to create from each 382 * row. 383 * 384 * @param array $args Arguments to pass to each object constructor. 385 * 386 * @return array 387 * 388 */ 389 public function fetchObjects( 390 $statement, 391 array $values = [], 392 $class = 'stdClass', 393 array $args = [] 394 ) { 395 $sth = $this->perform($statement, $values); 396 397 if (! empty($args)) { 398 return $sth->fetchAll(self::FETCH_CLASS, $class, $args); 399 } 400 401 return $sth->fetchAll(self::FETCH_CLASS, $class); 402 } 403 404 /** 405 * 406 * Fetches one row from the database as an associative array. 407 * 408 * @param string $statement The SQL statement to prepare and execute. 409 * 410 * @param array $values Values to bind to the query. 411 * 412 * @return array 413 * 414 */ 415 public function fetchOne($statement, array $values = []) 416 { 417 $sth = $this->perform($statement, $values); 418 return $sth->fetch(self::FETCH_ASSOC); 419 } 420 421 /** 422 * 423 * Fetches an associative array of rows as key-value pairs (first 424 * column is the key, second column is the value). 425 * 426 * @param string $statement The SQL statement to prepare and execute. 427 * 428 * @param array $values Values to bind to the query. 429 * 430 * @return array 431 * 432 */ 433 public function fetchPairs($statement, array $values = []) 434 { 435 $sth = $this->perform($statement, $values); 436 return $sth->fetchAll(self::FETCH_KEY_PAIR); 437 } 438 439 /** 440 * 441 * Fetches the very first value (i.e., first column of the first row). 442 * 443 * @param string $statement The SQL statement to prepare and execute. 444 * 445 * @param array $values Values to bind to the query. 446 * 447 * @return mixed 448 * 449 */ 450 public function fetchValue($statement, array $values = []) 451 { 452 $sth = $this->perform($statement, $values); 453 return $sth->fetchColumn(0); 454 } 455 456 /** 457 * 458 * Returns the Parser instance. 459 * 460 * @return ParserInterface 461 * 462 */ 463 public function getParser() 464 { 465 return $this->parser; 466 } 467 468 /** 469 * 470 * Return the inner PDO (if any) 471 * 472 * @return \PDO 473 * 474 */ 475 public function getPdo() 476 { 477 return $this->pdo; 478 } 479 480 /** 481 * 482 * Returns the Profiler instance. 483 * 484 * @return ProfilerInterface 485 * 486 */ 487 public function getProfiler() 488 { 489 return $this->profiler; 490 } 491 492 /** 493 * 494 * Is a transaction currently active? 495 * 496 * @return bool 497 * 498 * @see http://php.net/manual/en/pdo.intransaction.php 499 * 500 */ 501 #[\ReturnTypeWillChange] 502 public function inTransaction() 503 { 504 $this->connect(); 505 $this->profiler->start(__FUNCTION__); 506 $result = $this->pdo->inTransaction(); 507 $this->profiler->finish(); 508 return $result; 509 } 510 511 /** 512 * 513 * Is the PDO connection active? 514 * 515 * @return bool 516 * 517 */ 518 public function isConnected() 519 { 520 return (bool) $this->pdo; 521 } 522 523 /** 524 * 525 * Returns the last inserted autoincrement sequence value. 526 * 527 * @param string $name The name of the sequence to check; typically needed 528 * only for PostgreSQL, where it takes the form of `<table>_<column>_seq`. 529 * 530 * @return string|false 531 * 532 * @see http://php.net/manual/en/pdo.lastinsertid.php 533 * 534 */ 535 #[\ReturnTypeWillChange] 536 public function lastInsertId($name = null) 537 { 538 $this->connect(); 539 $this->profiler->start(__FUNCTION__); 540 $result = $this->pdo->lastInsertId($name); 541 $this->profiler->finish(); 542 return $result; 543 } 544 545 /** 546 * 547 * Performs a query with bound values and returns the resulting 548 * PDOStatement; array values will be passed through `quote()` and their 549 * respective placeholders will be replaced in the query string. 550 * 551 * @param string $statement The SQL statement to perform. 552 * 553 * @param array $values Values to bind to the query 554 * 555 * @return PDOStatement 556 * 557 * @see quote() 558 * 559 */ 560 public function perform($statement, array $values = []) 561 { 562 $this->connect(); 563 $sth = $this->prepareWithValues($statement, $values); 564 $this->profiler->start(__FUNCTION__); 565 $sth->execute(); 566 $this->profiler->finish($statement, $values); 567 return $sth; 568 } 569 570 /** 571 * 572 * Prepares an SQL statement for execution. 573 * 574 * @param string $statement The SQL statement to prepare for execution. 575 * 576 * @param array $options Set these attributes on the returned 577 * PDOStatement. 578 * 579 * @return PDOStatement|false 580 * 581 * @see http://php.net/manual/en/pdo.prepare.php 582 * 583 */ 584 #[\ReturnTypeWillChange] 585 public function prepare($statement, $options = []) 586 { 587 $this->connect(); 588 $sth = $this->pdo->prepare($statement, $options); 589 return $sth; 590 } 591 592 /** 593 * 594 * Prepares an SQL statement with bound values. 595 * 596 * This method only binds values that have placeholders in the 597 * statement, thereby avoiding errors from PDO regarding too many bound 598 * values. It also binds all sequential (question-mark) placeholders. 599 * 600 * If a placeholder value is an array, the array is converted to a string 601 * of comma-separated quoted values; e.g., for an `IN (...)` condition. 602 * The quoted string is replaced directly into the statement instead of 603 * using `PDOStatement::bindValue()` proper. 604 * 605 * @param string $statement The SQL statement to prepare for execution. 606 * 607 * @param array $values The values to bind to the statement, if any. 608 * 609 * @return PDOStatement|false 610 * 611 * @see http://php.net/manual/en/pdo.prepare.php 612 * 613 */ 614 public function prepareWithValues($statement, array $values = []) 615 { 616 // if there are no values to bind ... 617 if (empty($values)) { 618 // ... use the normal preparation 619 return $this->prepare($statement); 620 } 621 622 $this->connect(); 623 624 // rebuild the statement and values 625 $parser = clone $this->parser; 626 list ($statement, $values) = $parser->rebuild($statement, $values); 627 628 // prepare the statement 629 $sth = $this->pdo->prepare($statement); 630 631 // for the placeholders we found, bind the corresponding data values 632 foreach ($values as $key => $val) { 633 $this->bindValue($sth, $key, $val); 634 } 635 636 // done 637 return $sth; 638 } 639 640 /** 641 * 642 * Queries the database and returns a PDOStatement. 643 * 644 * @param string $statement The SQL statement to prepare and execute. 645 * 646 * @param mixed ...$fetch Optional fetch-related parameters. 647 * 648 * @return PDOStatement|false 649 * 650 * @see http://php.net/manual/en/pdo.query.php 651 * 652 */ 653 #[\ReturnTypeWillChange] 654 public function query($statement, ...$fetch) 655 { 656 $this->connect(); 657 $this->profiler->start(__FUNCTION__); 658 $sth = $this->pdo->query($statement, ...$fetch); 659 $this->profiler->finish($sth->queryString); 660 return $sth; 661 } 662 663 /** 664 * 665 * Quotes a value for use in an SQL statement. 666 * 667 * This differs from `PDO::quote()` in that it will convert an array into 668 * a string of comma-separated quoted values. 669 * 670 * @param mixed $value The value to quote. 671 * 672 * @param int $type A data type hint for the database driver. 673 * 674 * @return string|false The quoted value. 675 * 676 * @see http://php.net/manual/en/pdo.quote.php 677 * 678 */ 679 #[\ReturnTypeWillChange] 680 public function quote($value, $type = self::PARAM_STR) 681 { 682 $this->connect(); 683 684 // non-array quoting 685 if (! is_array($value)) { 686 return $this->pdo->quote((string) $value, $type); 687 } 688 689 // quote array values, not keys, then combine with commas 690 foreach ($value as $k => $v) { 691 $value[$k] = $this->pdo->quote($v, $type); 692 } 693 return implode(', ', $value); 694 } 695 696 /** 697 * 698 * Quotes a multi-part (dotted) identifier name. 699 * 700 * @param string $name The multi-part identifier name. 701 * 702 * @return string The multi-part identifier name, quoted. 703 * 704 */ 705 public function quoteName($name) 706 { 707 if (strpos($name, '.') === false) { 708 return $this->quoteSingleName($name); 709 } 710 711 return implode( 712 '.', 713 array_map( 714 [$this, 'quoteSingleName'], 715 explode('.', $name) 716 ) 717 ); 718 } 719 720 /** 721 * 722 * Quotes a single identifier name. 723 * 724 * @param string $name The identifier name. 725 * 726 * @return string The quoted identifier name. 727 * 728 */ 729 public function quoteSingleName($name) 730 { 731 $name = str_replace( 732 $this->quoteNameEscapeFind, 733 $this->quoteNameEscapeRepl, 734 $name 735 ); 736 return $this->quoteNamePrefix 737 . $name 738 . $this->quoteNameSuffix; 739 } 740 741 /** 742 * 743 * Rolls back the current transaction, and restores autocommit mode. 744 * 745 * @return bool True on success, false on failure. 746 * 747 * @see http://php.net/manual/en/pdo.rollback.php 748 * 749 */ 750 #[\ReturnTypeWillChange] 751 public function rollBack() 752 { 753 $this->connect(); 754 $this->profiler->start(__FUNCTION__); 755 $result = $this->pdo->rollBack(); 756 $this->profiler->finish(); 757 return $result; 758 } 759 760 /** 761 * 762 * Sets the Parser instance. 763 * 764 * @param ParserInterface $parser The Parser instance. 765 * 766 */ 767 public function setParser(ParserInterface $parser) 768 { 769 $this->parser = $parser; 770 } 771 772 /** 773 * 774 * Sets the Profiler instance. 775 * 776 * @param ProfilerInterface $profiler The Profiler instance. 777 * 778 */ 779 public function setProfiler(ProfilerInterface $profiler) 780 { 781 $this->profiler = $profiler; 782 } 783 784 /** 785 * 786 * Yields rows from the database. 787 * 788 * @param string $statement The SQL statement to prepare and execute. 789 * 790 * @param array $values Values to bind to the query. 791 * 792 * @return \Generator 793 * 794 */ 795 public function yieldAll($statement, array $values = []) 796 { 797 $sth = $this->perform($statement, $values); 798 while ($row = $sth->fetch(self::FETCH_ASSOC)) { 799 yield $row; 800 } 801 } 802 803 /** 804 * 805 * Yields rows from the database keyed on the first column of each row. 806 * 807 * @param string $statement The SQL statement to prepare and execute. 808 * 809 * @param array $values Values to bind to the query. 810 * 811 * @return \Generator 812 * 813 */ 814 public function yieldAssoc($statement, array $values = []) 815 { 816 $sth = $this->perform($statement, $values); 817 while ($row = $sth->fetch(self::FETCH_ASSOC)) { 818 $key = current($row); 819 yield $key => $row; 820 } 821 } 822 823 /** 824 * 825 * Yields the first column of each row. 826 * 827 * @param string $statement The SQL statement to prepare and execute. 828 * 829 * @param array $values Values to bind to the query. 830 * 831 * @return \Generator 832 * 833 */ 834 public function yieldCol($statement, array $values = []) 835 { 836 $sth = $this->perform($statement, $values); 837 while ($row = $sth->fetch(self::FETCH_NUM)) { 838 yield $row[0]; 839 } 840 } 841 842 /** 843 * 844 * Yields objects where the column values are mapped to object properties. 845 * 846 * Warning: PDO "injects property-values BEFORE invoking the constructor - 847 * in other words, if your class initializes property-values to defaults 848 * in the constructor, you will be overwriting the values injected by 849 * fetchObject() !" 850 * <http://www.php.net/manual/en/pdostatement.fetchobject.php#111744> 851 * 852 * @param string $statement The SQL statement to prepare and execute. 853 * 854 * @param array $values Values to bind to the query. 855 * 856 * @param string $class The name of the class to create from each 857 * row. 858 * 859 * @param array $args Arguments to pass to each object constructor. 860 * 861 * @return \Generator 862 * 863 */ 864 public function yieldObjects( 865 $statement, 866 array $values = [], 867 $class = 'stdClass', 868 array $args = [] 869 ) { 870 $sth = $this->perform($statement, $values); 871 872 if (empty($args)) { 873 while ($instance = $sth->fetchObject($class)) { 874 yield $instance; 875 } 876 } else { 877 while ($instance = $sth->fetchObject($class, $args)) { 878 yield $instance; 879 } 880 } 881 } 882 883 /** 884 * 885 * Yields key-value pairs (first column is the key, second column is the 886 * value). 887 * 888 * @param string $statement The SQL statement to prepare and execute. 889 * 890 * @param array $values Values to bind to the query. 891 * 892 * @return \Generator 893 * 894 */ 895 public function yieldPairs($statement, array $values = []) 896 { 897 $sth = $this->perform($statement, $values); 898 while ($row = $sth->fetch(self::FETCH_NUM)) { 899 yield $row[0] => $row[1]; 900 } 901 } 902 903 /** 904 * 905 * Bind a value using the proper PDO::PARAM_* type. 906 * 907 * @param PDOStatement $sth The statement to bind to. 908 * 909 * @param mixed $key The placeholder key. 910 * 911 * @param mixed $val The value to bind to the statement. 912 * 913 * @return boolean 914 * 915 * @throws Exception\CannotBindValue when the value to be bound is not 916 * bindable (e.g., array, object, or resource). 917 * 918 */ 919 protected function bindValue(PDOStatement $sth, $key, $val) 920 { 921 if (is_int($val)) { 922 return $sth->bindValue($key, $val, self::PARAM_INT); 923 } 924 925 if (is_bool($val)) { 926 return $sth->bindValue($key, $val, self::PARAM_BOOL); 927 } 928 929 if (is_null($val)) { 930 return $sth->bindValue($key, $val, self::PARAM_NULL); 931 } 932 933 if (! is_scalar($val)) { 934 $type = gettype($val); 935 throw new Exception\CannotBindValue( 936 "Cannot bind value of type '{$type}' to placeholder '{$key}'" 937 ); 938 } 939 940 return $sth->bindValue($key, $val); 941 } 942 943 /** 944 * 945 * Returns a new Parser instance. 946 * 947 * @param string $driver Return a parser for this driver. 948 * 949 * @return ParserInterface 950 * 951 */ 952 protected function newParser($driver) 953 { 954 $class = 'Aura\Sql\Parser\\' . ucfirst($driver) . 'Parser'; 955 if (! class_exists($class)) { 956 $class = 'Aura\Sql\Parser\SqliteParser'; 957 } 958 return new $class(); 959 } 960 961 /** 962 * 963 * Sets quoting properties based on the PDO driver. 964 * 965 * @param string $driver The PDO driver name. 966 * 967 * @return null 968 * 969 */ 970 protected function setQuoteName($driver) 971 { 972 switch ($driver) { 973 case 'mysql': 974 $this->quoteNamePrefix = '`'; 975 $this->quoteNameSuffix = '`'; 976 $this->quoteNameEscapeFind = '`'; 977 $this->quoteNameEscapeRepl = '``'; 978 return; 979 case 'sqlsrv': 980 $this->quoteNamePrefix = '['; 981 $this->quoteNameSuffix = ']'; 982 $this->quoteNameEscapeFind = ']'; 983 $this->quoteNameEscapeRepl = ']['; 984 return; 985 default: 986 $this->quoteNamePrefix = '"'; 987 $this->quoteNameSuffix = '"'; 988 $this->quoteNameEscapeFind = '"'; 989 $this->quoteNameEscapeRepl = '""'; 990 return; 991 } 992 } 993 994 /** 995 * 996 * Retrieve a database connection attribute 997 * 998 * @param int $attribute 999 * @return mixed 1000 */ 1001 #[\ReturnTypeWillChange] 1002 public function getAttribute($attribute) 1003 { 1004 $this->connect(); 1005 return $this->pdo->getAttribute($attribute); 1006 } 1007 1008 /** 1009 * 1010 * Set a database connection attribute 1011 * 1012 * @param int $attribute 1013 * @param mixed $value 1014 * @return bool 1015 */ 1016 #[\ReturnTypeWillChange] 1017 public function setAttribute($attribute, $value) 1018 { 1019 $this->connect(); 1020 return $this->pdo->setAttribute($attribute, $value); 1021 } 1022 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Tue Jan 21 05:10:11 2025 | Cross-referenced by PHPXref 0.7.1 |