ValueBinder.php 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151
  1. <?php
  2. /**
  3. * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
  4. * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  5. *
  6. * Licensed under The MIT License
  7. * For full copyright and license information, please see the LICENSE.txt
  8. * Redistributions of files must retain the above copyright notice.
  9. *
  10. * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
  11. * @link https://cakephp.org CakePHP(tm) Project
  12. * @since 3.0.0
  13. * @license https://opensource.org/licenses/mit-license.php MIT License
  14. */
  15. namespace Cake\Database;
  16. /**
  17. * Value binder class manages list of values bound to conditions.
  18. *
  19. * @internal
  20. */
  21. class ValueBinder
  22. {
  23. /**
  24. * Array containing a list of bound values to the conditions on this
  25. * object. Each array entry is another array structure containing the actual
  26. * bound value, its type and the placeholder it is bound to.
  27. *
  28. * @var array
  29. */
  30. protected $_bindings = [];
  31. /**
  32. * A counter of the number of parameters bound in this expression object
  33. *
  34. * @var int
  35. */
  36. protected $_bindingsCount = 0;
  37. /**
  38. * Associates a query placeholder to a value and a type
  39. *
  40. * @param string|int $param placeholder to be replaced with quoted version
  41. * of $value
  42. * @param mixed $value The value to be bound
  43. * @param string|int $type the mapped type name, used for casting when sending
  44. * to database
  45. * @return void
  46. */
  47. public function bind($param, $value, $type = 'string')
  48. {
  49. $this->_bindings[$param] = compact('value', 'type') + [
  50. 'placeholder' => is_int($param) ? $param : substr($param, 1)
  51. ];
  52. }
  53. /**
  54. * Creates a unique placeholder name if the token provided does not start with ":"
  55. * otherwise, it will return the same string and internally increment the number
  56. * of placeholders generated by this object.
  57. *
  58. * @param string $token string from which the placeholder will be derived from,
  59. * if it starts with a colon, then the same string is returned
  60. * @return string to be used as a placeholder in a query expression
  61. */
  62. public function placeholder($token)
  63. {
  64. $number = $this->_bindingsCount++;
  65. if ($token[0] !== ':' && $token !== '?') {
  66. $token = sprintf(':%s%s', $token, $number);
  67. }
  68. return $token;
  69. }
  70. /**
  71. * Creates unique named placeholders for each of the passed values
  72. * and binds them with the specified type.
  73. *
  74. * @param array|\Traversable $values The list of values to be bound
  75. * @param string $type The type with which all values will be bound
  76. * @return array with the placeholders to insert in the query
  77. */
  78. public function generateManyNamed($values, $type = 'string')
  79. {
  80. $placeholders = [];
  81. foreach ($values as $k => $value) {
  82. $param = $this->placeholder('c');
  83. $this->_bindings[$param] = [
  84. 'value' => $value,
  85. 'type' => $type,
  86. 'placeholder' => substr($param, 1),
  87. ];
  88. $placeholders[$k] = $param;
  89. }
  90. return $placeholders;
  91. }
  92. /**
  93. * Returns all values bound to this expression object at this nesting level.
  94. * Subexpression bound values will not be returned with this function.
  95. *
  96. * @return array
  97. */
  98. public function bindings()
  99. {
  100. return $this->_bindings;
  101. }
  102. /**
  103. * Clears any bindings that were previously registered
  104. *
  105. * @return void
  106. */
  107. public function reset()
  108. {
  109. $this->_bindings = [];
  110. $this->_bindingsCount = 0;
  111. }
  112. /**
  113. * Resets the bindings count without clearing previously bound values
  114. *
  115. * @return void
  116. */
  117. public function resetCount()
  118. {
  119. $this->_bindingsCount = 0;
  120. }
  121. /**
  122. * Binds all the stored values in this object to the passed statement.
  123. *
  124. * @param \Cake\Database\StatementInterface $statement The statement to add parameters to.
  125. * @return void
  126. */
  127. public function attachTo($statement)
  128. {
  129. $bindings = $this->bindings();
  130. if (empty($bindings)) {
  131. return;
  132. }
  133. foreach ($bindings as $b) {
  134. $statement->bindValue($b['placeholder'], $b['value'], $b['type']);
  135. }
  136. }
  137. }