3 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
4 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
5 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
6 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
7 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
8 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
9 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
10 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
11 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
12 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
13 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
15 * This software consists of voluntary contributions made by many individuals
16 * and is licensed under the MIT license. For more information, see
17 * <http://www.doctrine-project.org>.
20 namespace Doctrine\DBAL\Query;
22 use Doctrine\DBAL\Query\Expression\CompositeExpression,
23 Doctrine\DBAL\Connection;
26 * QueryBuilder class is responsible to dynamically create SQL queries.
28 * Important: Verify that every feature you use will work with your database vendor.
29 * SQL Query Builder does not attempt to validate the generated SQL at all.
31 * The query builder does no validation whatsoever if certain features even work with the
32 * underlying database vendor. Limit queries and joins are NOT applied to UPDATE and DELETE statements
33 * even if some vendors such as MySQL support it.
35 * @license http://www.opensource.org/licenses/lgpl-license.php LGPL
36 * @link www.doctrine-project.com
38 * @author Guilherme Blanco <guilhermeblanco@hotmail.com>
39 * @author Benjamin Eberlei <kontakt@beberlei.de>
43 /* The query types. */
48 /** The builder states. */
49 const STATE_DIRTY = 0;
50 const STATE_CLEAN = 1;
53 * @var Doctrine\DBAL\Connection DBAL Connection
55 private $connection = null;
58 * @var array The array of SQL parts collected.
60 private $sqlParts = array(
72 * @var string The complete SQL string for this query.
77 * @var array The query parameters.
79 private $params = array();
82 * @var array The parameter type map of this query.
84 private $paramTypes = array();
87 * @var integer The type of query this is. Can be select, update or delete.
89 private $type = self::SELECT;
92 * @var integer The state of the query object. Can be dirty or clean.
94 private $state = self::STATE_CLEAN;
97 * @var integer The index of the first result to retrieve.
99 private $firstResult = null;
102 * @var integer The maximum number of results to retrieve.
104 private $maxResults = null;
107 * The counter of bound parameters used with {@see bindValue)
111 private $boundCounter = 0;
114 * Initializes a new <tt>QueryBuilder</tt>.
116 * @param \Doctrine\DBAL\Connection $connection DBAL Connection
118 public function __construct(Connection $connection)
120 $this->connection = $connection;
124 * Gets an ExpressionBuilder used for object-oriented construction of query expressions.
125 * This producer method is intended for convenient inline usage. Example:
128 * $qb = $conn->createQueryBuilder()
130 * ->from('users', 'u')
131 * ->where($qb->expr()->eq('u.id', 1));
134 * For more complex expression construction, consider storing the expression
135 * builder object in a local variable.
137 * @return \Doctrine\DBAL\Query\Expression\ExpressionBuilder
139 public function expr()
141 return $this->connection->getExpressionBuilder();
145 * Get the type of the currently built query.
149 public function getType()
155 * Get the associated DBAL Connection for this query builder.
157 * @return \Doctrine\DBAL\Connection
159 public function getConnection()
161 return $this->connection;
165 * Get the state of this query builder instance.
167 * @return integer Either QueryBuilder::STATE_DIRTY or QueryBuilder::STATE_CLEAN.
169 public function getState()
175 * Execute this query using the bound parameters and their types.
177 * Uses {@see Connection::executeQuery} for select statements and {@see Connection::executeUpdate}
178 * for insert, update and delete statements.
182 public function execute()
184 if ($this->type == self::SELECT) {
185 return $this->connection->executeQuery($this->getSQL(), $this->params, $this->paramTypes);
187 return $this->connection->executeUpdate($this->getSQL(), $this->params, $this->paramTypes);
192 * Get the complete SQL string formed by the current specifications of this QueryBuilder.
195 * $qb = $em->createQueryBuilder()
197 * ->from('User', 'u')
198 * echo $qb->getSQL(); // SELECT u FROM User u
201 * @return string The sql query string.
203 public function getSQL()
205 if ($this->sql !== null && $this->state === self::STATE_CLEAN) {
211 switch ($this->type) {
213 $sql = $this->getSQLForDelete();
217 $sql = $this->getSQLForUpdate();
222 $sql = $this->getSQLForSelect();
226 $this->state = self::STATE_CLEAN;
233 * Sets a query parameter for the query being constructed.
236 * $qb = $conn->createQueryBuilder()
238 * ->from('users', 'u')
239 * ->where('u.id = :user_id')
240 * ->setParameter(':user_id', 1);
243 * @param string|integer $key The parameter position or name.
244 * @param mixed $value The parameter value.
245 * @param string|null $type PDO::PARAM_*
246 * @return QueryBuilder This QueryBuilder instance.
248 public function setParameter($key, $value, $type = null)
250 if ($type !== null) {
251 $this->paramTypes[$key] = $type;
254 $this->params[$key] = $value;
260 * Sets a collection of query parameters for the query being constructed.
263 * $qb = $conn->createQueryBuilder()
265 * ->from('users', 'u')
266 * ->where('u.id = :user_id1 OR u.id = :user_id2')
267 * ->setParameters(array(
273 * @param array $params The query parameters to set.
274 * @param array $types The query parameters types to set.
275 * @return QueryBuilder This QueryBuilder instance.
277 public function setParameters(array $params, array $types = array())
279 $this->paramTypes = $types;
280 $this->params = $params;
286 * Gets all defined query parameters for the query being constructed.
288 * @return array The currently defined query parameters.
290 public function getParameters()
292 return $this->params;
296 * Gets a (previously set) query parameter of the query being constructed.
298 * @param mixed $key The key (index or name) of the bound parameter.
299 * @return mixed The value of the bound parameter.
301 public function getParameter($key)
303 return isset($this->params[$key]) ? $this->params[$key] : null;
307 * Sets the position of the first result to retrieve (the "offset").
309 * @param integer $firstResult The first result to return.
310 * @return \Doctrine\DBAL\Query\QueryBuilder This QueryBuilder instance.
312 public function setFirstResult($firstResult)
314 $this->state = self::STATE_DIRTY;
315 $this->firstResult = $firstResult;
320 * Gets the position of the first result the query object was set to retrieve (the "offset").
321 * Returns NULL if {@link setFirstResult} was not applied to this QueryBuilder.
323 * @return integer The position of the first result.
325 public function getFirstResult()
327 return $this->firstResult;
331 * Sets the maximum number of results to retrieve (the "limit").
333 * @param integer $maxResults The maximum number of results to retrieve.
334 * @return \Doctrine\DBAL\Query\QueryBuilder This QueryBuilder instance.
336 public function setMaxResults($maxResults)
338 $this->state = self::STATE_DIRTY;
339 $this->maxResults = $maxResults;
344 * Gets the maximum number of results the query object was set to retrieve (the "limit").
345 * Returns NULL if {@link setMaxResults} was not applied to this query builder.
347 * @return integer Maximum number of results.
349 public function getMaxResults()
351 return $this->maxResults;
355 * Either appends to or replaces a single, generic query part.
357 * The available parts are: 'select', 'from', 'set', 'where',
358 * 'groupBy', 'having' and 'orderBy'.
360 * @param string $sqlPartName
361 * @param string $sqlPart
362 * @param boolean $append
363 * @return \Doctrine\DBAL\Query\QueryBuilder This QueryBuilder instance.
365 public function add($sqlPartName, $sqlPart, $append = false)
367 $isArray = is_array($sqlPart);
368 $isMultiple = is_array($this->sqlParts[$sqlPartName]);
370 if ($isMultiple && !$isArray) {
371 $sqlPart = array($sqlPart);
374 $this->state = self::STATE_DIRTY;
377 if ($sqlPartName == "orderBy" || $sqlPartName == "groupBy" || $sqlPartName == "select" || $sqlPartName == "set") {
378 foreach ($sqlPart as $part) {
379 $this->sqlParts[$sqlPartName][] = $part;
381 } else if ($isArray && is_array($sqlPart[key($sqlPart)])) {
382 $key = key($sqlPart);
383 $this->sqlParts[$sqlPartName][$key][] = $sqlPart[$key];
384 } else if ($isMultiple) {
385 $this->sqlParts[$sqlPartName][] = $sqlPart;
387 $this->sqlParts[$sqlPartName] = $sqlPart;
393 $this->sqlParts[$sqlPartName] = $sqlPart;
399 * Specifies an item that is to be returned in the query result.
400 * Replaces any previously specified selections, if any.
403 * $qb = $conn->createQueryBuilder()
404 * ->select('u.id', 'p.id')
405 * ->from('users', 'u')
406 * ->leftJoin('u', 'phonenumbers', 'p', 'u.id = p.user_id');
409 * @param mixed $select The selection expressions.
410 * @return QueryBuilder This QueryBuilder instance.
412 public function select($select = null)
414 $this->type = self::SELECT;
416 if (empty($select)) {
420 $selects = is_array($select) ? $select : func_get_args();
422 return $this->add('select', $selects, false);
426 * Adds an item that is to be returned in the query result.
429 * $qb = $conn->createQueryBuilder()
431 * ->addSelect('p.id')
432 * ->from('users', 'u')
433 * ->leftJoin('u', 'phonenumbers', 'u.id = p.user_id');
436 * @param mixed $select The selection expression.
437 * @return QueryBuilder This QueryBuilder instance.
439 public function addSelect($select = null)
441 $this->type = self::SELECT;
443 if (empty($select)) {
447 $selects = is_array($select) ? $select : func_get_args();
449 return $this->add('select', $selects, true);
453 * Turns the query being built into a bulk delete query that ranges over
457 * $qb = $conn->createQueryBuilder()
458 * ->delete('users', 'u')
459 * ->where('u.id = :user_id');
460 * ->setParameter(':user_id', 1);
463 * @param string $delete The table whose rows are subject to the deletion.
464 * @param string $alias The table alias used in the constructed query.
465 * @return QueryBuilder This QueryBuilder instance.
467 public function delete($delete = null, $alias = null)
469 $this->type = self::DELETE;
475 return $this->add('from', array(
482 * Turns the query being built into a bulk update query that ranges over
486 * $qb = $conn->createQueryBuilder()
487 * ->update('users', 'u')
488 * ->set('u.password', md5('password'))
489 * ->where('u.id = ?');
492 * @param string $update The table whose rows are subject to the update.
493 * @param string $alias The table alias used in the constructed query.
494 * @return QueryBuilder This QueryBuilder instance.
496 public function update($update = null, $alias = null)
498 $this->type = self::UPDATE;
504 return $this->add('from', array(
511 * Create and add a query root corresponding to the table identified by the
512 * given alias, forming a cartesian product with any existing query roots.
515 * $qb = $conn->createQueryBuilder()
517 * ->from('users', 'u')
520 * @param string $from The table
521 * @param string $alias The alias of the table
522 * @return QueryBuilder This QueryBuilder instance.
524 public function from($from, $alias)
526 return $this->add('from', array(
533 * Creates and adds a join to the query.
536 * $qb = $conn->createQueryBuilder()
538 * ->from('users', 'u')
539 * ->join('u', 'phonenumbers', 'p', 'p.is_primary = 1');
542 * @param string $fromAlias The alias that points to a from clause
543 * @param string $join The table name to join
544 * @param string $alias The alias of the join table
545 * @param string $condition The condition for the join
546 * @return QueryBuilder This QueryBuilder instance.
548 public function join($fromAlias, $join, $alias, $condition = null)
550 return $this->innerJoin($fromAlias, $join, $alias, $condition);
554 * Creates and adds a join to the query.
557 * $qb = $conn->createQueryBuilder()
559 * ->from('users', 'u')
560 * ->innerJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
563 * @param string $fromAlias The alias that points to a from clause
564 * @param string $join The table name to join
565 * @param string $alias The alias of the join table
566 * @param string $condition The condition for the join
567 * @return QueryBuilder This QueryBuilder instance.
569 public function innerJoin($fromAlias, $join, $alias, $condition = null)
571 return $this->add('join', array(
573 'joinType' => 'inner',
574 'joinTable' => $join,
575 'joinAlias' => $alias,
576 'joinCondition' => $condition
582 * Creates and adds a left join to the query.
585 * $qb = $conn->createQueryBuilder()
587 * ->from('users', 'u')
588 * ->leftJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
591 * @param string $fromAlias The alias that points to a from clause
592 * @param string $join The table name to join
593 * @param string $alias The alias of the join table
594 * @param string $condition The condition for the join
595 * @return QueryBuilder This QueryBuilder instance.
597 public function leftJoin($fromAlias, $join, $alias, $condition = null)
599 return $this->add('join', array(
601 'joinType' => 'left',
602 'joinTable' => $join,
603 'joinAlias' => $alias,
604 'joinCondition' => $condition
610 * Creates and adds a right join to the query.
613 * $qb = $conn->createQueryBuilder()
615 * ->from('users', 'u')
616 * ->rightJoin('u', 'phonenumbers', 'p', 'p.is_primary = 1');
619 * @param string $fromAlias The alias that points to a from clause
620 * @param string $join The table name to join
621 * @param string $alias The alias of the join table
622 * @param string $condition The condition for the join
623 * @return QueryBuilder This QueryBuilder instance.
625 public function rightJoin($fromAlias, $join, $alias, $condition = null)
627 return $this->add('join', array(
629 'joinType' => 'right',
630 'joinTable' => $join,
631 'joinAlias' => $alias,
632 'joinCondition' => $condition
638 * Sets a new value for a column in a bulk update query.
641 * $qb = $conn->createQueryBuilder()
642 * ->update('users', 'u')
643 * ->set('u.password', md5('password'))
644 * ->where('u.id = ?');
647 * @param string $key The column to set.
648 * @param string $value The value, expression, placeholder, etc.
649 * @return QueryBuilder This QueryBuilder instance.
651 public function set($key, $value)
653 return $this->add('set', $key .' = ' . $value, true);
657 * Specifies one or more restrictions to the query result.
658 * Replaces any previously specified restrictions, if any.
661 * $qb = $conn->createQueryBuilder()
663 * ->from('users', 'u')
664 * ->where('u.id = ?');
666 * // You can optionally programatically build and/or expressions
667 * $qb = $conn->createQueryBuilder();
669 * $or = $qb->expr()->orx();
670 * $or->add($qb->expr()->eq('u.id', 1));
671 * $or->add($qb->expr()->eq('u.id', 2));
673 * $qb->update('users', 'u')
674 * ->set('u.password', md5('password'))
678 * @param mixed $predicates The restriction predicates.
679 * @return QueryBuilder This QueryBuilder instance.
681 public function where($predicates)
683 if ( ! (func_num_args() == 1 && $predicates instanceof CompositeExpression) ) {
684 $predicates = new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args());
687 return $this->add('where', $predicates);
691 * Adds one or more restrictions to the query results, forming a logical
692 * conjunction with any previously specified restrictions.
695 * $qb = $conn->createQueryBuilder()
697 * ->from('users', 'u')
698 * ->where('u.username LIKE ?')
699 * ->andWhere('u.is_active = 1');
702 * @param mixed $where The query restrictions.
703 * @return QueryBuilder This QueryBuilder instance.
706 public function andWhere($where)
708 $where = $this->getQueryPart('where');
709 $args = func_get_args();
711 if ($where instanceof CompositeExpression && $where->getType() === CompositeExpression::TYPE_AND) {
712 $where->addMultiple($args);
714 array_unshift($args, $where);
715 $where = new CompositeExpression(CompositeExpression::TYPE_AND, $args);
718 return $this->add('where', $where, true);
722 * Adds one or more restrictions to the query results, forming a logical
723 * disjunction with any previously specified restrictions.
726 * $qb = $em->createQueryBuilder()
728 * ->from('users', 'u')
729 * ->where('u.id = 1')
730 * ->orWhere('u.id = 2');
733 * @param mixed $where The WHERE statement
734 * @return QueryBuilder $qb
737 public function orWhere($where)
739 $where = $this->getQueryPart('where');
740 $args = func_get_args();
742 if ($where instanceof CompositeExpression && $where->getType() === CompositeExpression::TYPE_OR) {
743 $where->addMultiple($args);
745 array_unshift($args, $where);
746 $where = new CompositeExpression(CompositeExpression::TYPE_OR, $args);
749 return $this->add('where', $where, true);
753 * Specifies a grouping over the results of the query.
754 * Replaces any previously specified groupings, if any.
757 * $qb = $conn->createQueryBuilder()
759 * ->from('users', 'u')
763 * @param mixed $groupBy The grouping expression.
764 * @return QueryBuilder This QueryBuilder instance.
766 public function groupBy($groupBy)
768 if (empty($groupBy)) {
772 $groupBy = is_array($groupBy) ? $groupBy : func_get_args();
774 return $this->add('groupBy', $groupBy, false);
779 * Adds a grouping expression to the query.
782 * $qb = $conn->createQueryBuilder()
784 * ->from('users', 'u')
785 * ->groupBy('u.lastLogin');
786 * ->addGroupBy('u.createdAt')
789 * @param mixed $groupBy The grouping expression.
790 * @return QueryBuilder This QueryBuilder instance.
792 public function addGroupBy($groupBy)
794 if (empty($groupBy)) {
798 $groupBy = is_array($groupBy) ? $groupBy : func_get_args();
800 return $this->add('groupBy', $groupBy, true);
804 * Specifies a restriction over the groups of the query.
805 * Replaces any previous having restrictions, if any.
807 * @param mixed $having The restriction over the groups.
808 * @return QueryBuilder This QueryBuilder instance.
810 public function having($having)
812 if ( ! (func_num_args() == 1 && $having instanceof CompositeExpression)) {
813 $having = new CompositeExpression(CompositeExpression::TYPE_AND, func_get_args());
816 return $this->add('having', $having);
820 * Adds a restriction over the groups of the query, forming a logical
821 * conjunction with any existing having restrictions.
823 * @param mixed $having The restriction to append.
824 * @return QueryBuilder This QueryBuilder instance.
826 public function andHaving($having)
828 $having = $this->getQueryPart('having');
829 $args = func_get_args();
831 if ($having instanceof CompositeExpression && $having->getType() === CompositeExpression::TYPE_AND) {
832 $having->addMultiple($args);
834 array_unshift($args, $having);
835 $having = new CompositeExpression(CompositeExpression::TYPE_AND, $args);
838 return $this->add('having', $having);
842 * Adds a restriction over the groups of the query, forming a logical
843 * disjunction with any existing having restrictions.
845 * @param mixed $having The restriction to add.
846 * @return QueryBuilder This QueryBuilder instance.
848 public function orHaving($having)
850 $having = $this->getQueryPart('having');
851 $args = func_get_args();
853 if ($having instanceof CompositeExpression && $having->getType() === CompositeExpression::TYPE_OR) {
854 $having->addMultiple($args);
856 array_unshift($args, $having);
857 $having = new CompositeExpression(CompositeExpression::TYPE_OR, $args);
860 return $this->add('having', $having);
864 * Specifies an ordering for the query results.
865 * Replaces any previously specified orderings, if any.
867 * @param string $sort The ordering expression.
868 * @param string $order The ordering direction.
869 * @return QueryBuilder This QueryBuilder instance.
871 public function orderBy($sort, $order = null)
873 return $this->add('orderBy', $sort . ' ' . (! $order ? 'ASC' : $order), false);
877 * Adds an ordering to the query results.
879 * @param string $sort The ordering expression.
880 * @param string $order The ordering direction.
881 * @return QueryBuilder This QueryBuilder instance.
883 public function addOrderBy($sort, $order = null)
885 return $this->add('orderBy', $sort . ' ' . (! $order ? 'ASC' : $order), true);
889 * Get a query part by its name.
891 * @param string $queryPartName
892 * @return mixed $queryPart
894 public function getQueryPart($queryPartName)
896 return $this->sqlParts[$queryPartName];
900 * Get all query parts.
902 * @return array $sqlParts
904 public function getQueryParts()
906 return $this->sqlParts;
912 * @param array $queryPartNames
913 * @return QueryBuilder
915 public function resetQueryParts($queryPartNames = null)
917 if (is_null($queryPartNames)) {
918 $queryPartNames = array_keys($this->sqlParts);
921 foreach ($queryPartNames as $queryPartName) {
922 $this->resetQueryPart($queryPartName);
929 * Reset single SQL part
931 * @param string $queryPartName
932 * @return QueryBuilder
934 public function resetQueryPart($queryPartName)
936 $this->sqlParts[$queryPartName] = is_array($this->sqlParts[$queryPartName])
939 $this->state = self::STATE_DIRTY;
944 private function getSQLForSelect()
946 $query = 'SELECT ' . implode(', ', $this->sqlParts['select']) . ' FROM ';
948 $fromClauses = array();
950 // Loop through all FROM clauses
951 foreach ($this->sqlParts['from'] as $from) {
952 $fromClause = $from['table'] . ' ' . $from['alias'];
954 if (isset($this->sqlParts['join'][$from['alias']])) {
955 foreach ($this->sqlParts['join'][$from['alias']] as $join) {
956 $fromClause .= ' ' . strtoupper($join['joinType'])
957 . ' JOIN ' . $join['joinTable'] . ' ' . $join['joinAlias']
958 . ' ON ' . ((string) $join['joinCondition']);
962 $fromClauses[$from['alias']] = $fromClause;
965 // loop through all JOIN clasues for validation purpose
966 foreach ($this->sqlParts['join'] as $fromAlias => $joins) {
967 if ( ! isset($fromClauses[$fromAlias]) ) {
968 throw QueryException::unknownFromAlias($fromAlias, array_keys($fromClauses));
972 $query .= implode(', ', $fromClauses)
973 . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '')
974 . ($this->sqlParts['groupBy'] ? ' GROUP BY ' . implode(', ', $this->sqlParts['groupBy']) : '')
975 . ($this->sqlParts['having'] !== null ? ' HAVING ' . ((string) $this->sqlParts['having']) : '')
976 . ($this->sqlParts['orderBy'] ? ' ORDER BY ' . implode(', ', $this->sqlParts['orderBy']) : '');
978 return ($this->maxResults === null && $this->firstResult == null)
980 : $this->connection->getDatabasePlatform()->modifyLimitQuery($query, $this->maxResults, $this->firstResult);
984 * Converts this instance into an UPDATE string in SQL.
988 private function getSQLForUpdate()
990 $table = $this->sqlParts['from']['table'] . ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : '');
991 $query = 'UPDATE ' . $table
992 . ' SET ' . implode(", ", $this->sqlParts['set'])
993 . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '');
999 * Converts this instance into a DELETE string in SQL.
1003 private function getSQLForDelete()
1005 $table = $this->sqlParts['from']['table'] . ($this->sqlParts['from']['alias'] ? ' ' . $this->sqlParts['from']['alias'] : '');
1006 $query = 'DELETE FROM ' . $table . ($this->sqlParts['where'] !== null ? ' WHERE ' . ((string) $this->sqlParts['where']) : '');
1012 * Gets a string representation of this QueryBuilder which corresponds to
1013 * the final SQL query being constructed.
1015 * @return string The string representation of this QueryBuilder.
1017 public function __toString()
1019 return $this->getSQL();
1023 * Create a new named parameter and bind the value $value to it.
1025 * This method provides a shortcut for PDOStatement::bindValue
1026 * when using prepared statements.
1028 * The parameter $value specifies the value that you want to bind. If
1029 * $placeholder is not provided bindValue() will automatically create a
1030 * placeholder for you. An automatic placeholder will be of the name
1031 * ':dcValue1', ':dcValue2' etc.
1033 * For more information see {@link http://php.net/pdostatement-bindparam}
1038 * $q->eq( 'id', $q->bindValue( $value ) );
1039 * $stmt = $q->executeQuery(); // executed with 'id = 2'
1042 * @license New BSD License
1043 * @link http://www.zetacomponents.org
1044 * @param mixed $value
1045 * @param mixed $type
1046 * @param string $placeHolder the name to bind with. The string must start with a colon ':'.
1047 * @return string the placeholder name used.
1049 public function createNamedParameter( $value, $type = \PDO::PARAM_STR, $placeHolder = null )
1051 if ( $placeHolder === null ) {
1052 $this->boundCounter++;
1053 $placeHolder = ":dcValue" . $this->boundCounter;
1055 $this->setParameter(substr($placeHolder, 1), $value, $type);
1057 return $placeHolder;
1061 * Create a new positional parameter and bind the given value to it.
1063 * Attention: If you are using positional parameters with the query builder you have
1064 * to be very careful to bind all parameters in the order they appear in the SQL
1065 * statement , otherwise they get bound in the wrong order which can lead to serious
1066 * bugs in your code.
1070 * $qb = $conn->createQueryBuilder();
1071 * $qb->select('u.*')
1072 * ->from('users', 'u')
1073 * ->where('u.username = ' . $qb->createPositionalParameter('Foo', PDO::PARAM_STR))
1074 * ->orWhere('u.username = ' . $qb->createPositionalParameter('Bar', PDO::PARAM_STR))
1077 * @param mixed $value
1078 * @param mixed $type
1081 public function createPositionalParameter($value, $type = \PDO::PARAM_STR)
1083 $this->boundCounter++;
1084 $this->setParameter($this->boundCounter, $value, $type);